From c538fced0453c93f19725dad5d2f2c2fc3000adb Mon Sep 17 00:00:00 2001 From: plumedbot Date: Thu, 17 Oct 2024 16:45:04 +0000 Subject: [PATCH] Update to plumed/plumed2@9bfe572 --- .nojekyll | 0 README.md | 12 + coverage-libs/amber.png | Bin 0 -> 141 bytes .../asmjit/arch.cpp.func-sort-c.html | 80 + coverage-libs/asmjit/arch.cpp.func.html | 80 + coverage-libs/asmjit/arch.cpp.gcov.html | 263 + coverage-libs/asmjit/arch.h.func-sort-c.html | 72 + coverage-libs/asmjit/arch.h.func.html | 72 + coverage-libs/asmjit/arch.h.gcov.html | 304 + .../asmjit/assembler.cpp.func-sort-c.html | 144 + coverage-libs/asmjit/assembler.cpp.func.html | 144 + coverage-libs/asmjit/assembler.cpp.gcov.html | 549 + .../asmjit/assembler.h.func-sort-c.html | 72 + coverage-libs/asmjit/assembler.h.func.html | 72 + coverage-libs/asmjit/assembler.h.gcov.html | 259 + .../asmjit/codebuilder.cpp.func-sort-c.html | 204 + .../asmjit/codebuilder.cpp.func.html | 204 + .../asmjit/codebuilder.cpp.gcov.html | 686 + .../asmjit/codebuilder.h.func-sort-c.html | 72 + coverage-libs/asmjit/codebuilder.h.func.html | 72 + coverage-libs/asmjit/codebuilder.h.gcov.html | 1020 + .../asmjit/codecompiler.cpp.func-sort-c.html | 216 + .../asmjit/codecompiler.cpp.func.html | 216 + .../asmjit/codecompiler.cpp.gcov.html | 675 + .../asmjit/codecompiler.h.func-sort-c.html | 72 + coverage-libs/asmjit/codecompiler.h.func.html | 72 + coverage-libs/asmjit/codecompiler.h.gcov.html | 843 + .../asmjit/codeemitter.cpp.func-sort-c.html | 196 + .../asmjit/codeemitter.cpp.func.html | 196 + .../asmjit/codeemitter.cpp.gcov.html | 338 + .../asmjit/codeemitter.h.func-sort-c.html | 72 + coverage-libs/asmjit/codeemitter.h.func.html | 72 + coverage-libs/asmjit/codeemitter.h.gcov.html | 604 + .../asmjit/codeholder.cpp.func-sort-c.html | 172 + coverage-libs/asmjit/codeholder.cpp.func.html | 172 + coverage-libs/asmjit/codeholder.cpp.gcov.html | 799 + .../asmjit/codeholder.h.func-sort-c.html | 72 + coverage-libs/asmjit/codeholder.h.func.html | 72 + coverage-libs/asmjit/codeholder.h.gcov.html | 853 + .../asmjit/constpool.cpp.func-sort-c.html | 104 + coverage-libs/asmjit/constpool.cpp.func.html | 104 + coverage-libs/asmjit/constpool.cpp.gcov.html | 613 + .../asmjit/constpool.h.func-sort-c.html | 72 + coverage-libs/asmjit/constpool.h.func.html | 72 + coverage-libs/asmjit/constpool.h.gcov.html | 362 + .../asmjit/cpuinfo.cpp.func-sort-c.html | 84 + coverage-libs/asmjit/cpuinfo.cpp.func.html | 84 + coverage-libs/asmjit/cpuinfo.cpp.gcov.html | 776 + .../asmjit/cpuinfo.h.func-sort-c.html | 72 + coverage-libs/asmjit/cpuinfo.h.func.html | 72 + coverage-libs/asmjit/cpuinfo.h.gcov.html | 478 + .../asmjit/func.cpp.func-sort-c.html | 100 + coverage-libs/asmjit/func.cpp.func.html | 100 + coverage-libs/asmjit/func.cpp.gcov.html | 288 + coverage-libs/asmjit/func.h.func-sort-c.html | 72 + coverage-libs/asmjit/func.h.func.html | 72 + coverage-libs/asmjit/func.h.gcov.html | 1403 + .../asmjit/globals.cpp.func-sort-c.html | 84 + coverage-libs/asmjit/globals.cpp.func.html | 84 + coverage-libs/asmjit/globals.cpp.gcov.html | 220 + .../asmjit/globals.h.func-sort-c.html | 72 + coverage-libs/asmjit/globals.h.func.html | 72 + coverage-libs/asmjit/globals.h.gcov.html | 446 + coverage-libs/asmjit/index-sort-f.html | 603 + coverage-libs/asmjit/index-sort-l.html | 603 + coverage-libs/asmjit/index.html | 603 + .../asmjit/inst.cpp.func-sort-c.html | 80 + coverage-libs/asmjit/inst.cpp.func.html | 80 + coverage-libs/asmjit/inst.cpp.gcov.html | 179 + coverage-libs/asmjit/inst.h.func-sort-c.html | 72 + coverage-libs/asmjit/inst.h.func.html | 72 + coverage-libs/asmjit/inst.h.gcov.html | 213 + .../asmjit/logging.cpp.func-sort-c.html | 172 + coverage-libs/asmjit/logging.cpp.func.html | 172 + coverage-libs/asmjit/logging.cpp.gcov.html | 600 + .../asmjit/logging.h.func-sort-c.html | 72 + coverage-libs/asmjit/logging.h.func.html | 72 + coverage-libs/asmjit/logging.h.gcov.html | 393 + .../asmjit/moved_string.h.func-sort-c.html | 72 + coverage-libs/asmjit/moved_string.h.func.html | 72 + coverage-libs/asmjit/moved_string.h.gcov.html | 394 + .../asmjit/operand.h.func-sort-c.html | 72 + coverage-libs/asmjit/operand.h.func.html | 72 + coverage-libs/asmjit/operand.h.gcov.html | 1675 + .../asmjit/osutils.cpp.func-sort-c.html | 92 + coverage-libs/asmjit/osutils.cpp.func.html | 92 + coverage-libs/asmjit/osutils.cpp.gcov.html | 330 + .../asmjit/osutils.h.func-sort-c.html | 72 + coverage-libs/asmjit/osutils.h.func.html | 72 + coverage-libs/asmjit/osutils.h.gcov.html | 283 + .../asmjit/regalloc.cpp.func-sort-c.html | 124 + coverage-libs/asmjit/regalloc.cpp.func.html | 124 + coverage-libs/asmjit/regalloc.cpp.gcov.html | 696 + .../asmjit/regalloc_p.h.func-sort-c.html | 72 + coverage-libs/asmjit/regalloc_p.h.func.html | 72 + coverage-libs/asmjit/regalloc_p.h.gcov.html | 673 + .../asmjit/runtime.cpp.func-sort-c.html | 120 + coverage-libs/asmjit/runtime.cpp.func.html | 120 + coverage-libs/asmjit/runtime.cpp.gcov.html | 249 + .../asmjit/runtime.h.func-sort-c.html | 72 + coverage-libs/asmjit/runtime.h.func.html | 72 + coverage-libs/asmjit/runtime.h.gcov.html | 303 + .../asmjit/string.cpp.func-sort-c.html | 128 + coverage-libs/asmjit/string.cpp.func.html | 128 + coverage-libs/asmjit/string.cpp.gcov.html | 455 + coverage-libs/asmjit/utils.h.func-sort-c.html | 72 + coverage-libs/asmjit/utils.h.func.html | 72 + coverage-libs/asmjit/utils.h.gcov.html | 1463 + .../asmjit/vmem.cpp.func-sort-c.html | 128 + coverage-libs/asmjit/vmem.cpp.func.html | 128 + coverage-libs/asmjit/vmem.cpp.gcov.html | 1179 + .../asmjit/x86assembler.cpp.func-sort-c.html | 100 + .../asmjit/x86assembler.cpp.func.html | 100 + .../asmjit/x86assembler.cpp.gcov.html | 4721 +++ .../asmjit/x86assembler.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86assembler.h.func.html | 72 + coverage-libs/asmjit/x86assembler.h.gcov.html | 201 + .../asmjit/x86builder.cpp.func-sort-c.html | 92 + coverage-libs/asmjit/x86builder.cpp.func.html | 92 + coverage-libs/asmjit/x86builder.cpp.gcov.html | 168 + .../asmjit/x86compiler.cpp.func-sort-c.html | 100 + .../asmjit/x86compiler.cpp.func.html | 100 + .../asmjit/x86compiler.cpp.gcov.html | 478 + .../asmjit/x86compiler.h.func-sort-c.html | 80 + coverage-libs/asmjit/x86compiler.h.func.html | 80 + coverage-libs/asmjit/x86compiler.h.gcov.html | 398 + .../asmjit/x86emitter.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86emitter.h.func.html | 72 + coverage-libs/asmjit/x86emitter.h.gcov.html | 5225 +++ .../asmjit/x86inst.cpp.func-sort-c.html | 80 + coverage-libs/asmjit/x86inst.cpp.func.html | 80 + coverage-libs/asmjit/x86inst.cpp.gcov.html | 3829 ++ .../asmjit/x86inst.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86inst.h.func.html | 72 + coverage-libs/asmjit/x86inst.h.gcov.html | 2623 ++ .../asmjit/x86instimpl.cpp.func-sort-c.html | 84 + .../asmjit/x86instimpl.cpp.func.html | 84 + .../asmjit/x86instimpl.cpp.gcov.html | 833 + .../asmjit/x86internal.cpp.func-sort-c.html | 128 + .../asmjit/x86internal.cpp.func.html | 128 + .../asmjit/x86internal.cpp.gcov.html | 1458 + .../asmjit/x86logging.cpp.func-sort-c.html | 104 + coverage-libs/asmjit/x86logging.cpp.func.html | 104 + coverage-libs/asmjit/x86logging.cpp.gcov.html | 786 + .../asmjit/x86misc.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86misc.h.func.html | 72 + coverage-libs/asmjit/x86misc.h.gcov.html | 493 + .../asmjit/x86operand.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86operand.h.func.html | 72 + coverage-libs/asmjit/x86operand.h.gcov.html | 1209 + .../asmjit/x86regalloc.cpp.func-sort-c.html | 188 + .../asmjit/x86regalloc.cpp.func.html | 188 + .../asmjit/x86regalloc.cpp.gcov.html | 4164 +++ .../asmjit/x86regalloc_p.h.func-sort-c.html | 72 + .../asmjit/x86regalloc_p.h.func.html | 72 + .../asmjit/x86regalloc_p.h.gcov.html | 810 + .../asmjit/zone.cpp.func-sort-c.html | 160 + coverage-libs/asmjit/zone.cpp.func.html | 160 + coverage-libs/asmjit/zone.cpp.gcov.html | 935 + coverage-libs/asmjit/zone.h.func-sort-c.html | 80 + coverage-libs/asmjit/zone.h.func.html | 80 + coverage-libs/asmjit/zone.h.gcov.html | 1233 + coverage-libs/blas/blas.cpp.func-sort-c.html | 216 + coverage-libs/blas/blas.cpp.func.html | 216 + coverage-libs/blas/blas.cpp.gcov.html | 3766 ++ coverage-libs/blas/index-sort-f.html | 93 + coverage-libs/blas/index-sort-l.html | 93 + coverage-libs/blas/index.html | 93 + coverage-libs/emerald.png | Bin 0 -> 141 bytes coverage-libs/gcov.css | 519 + coverage-libs/glass.png | Bin 0 -> 167 bytes coverage-libs/index-sort-f.html | 143 + coverage-libs/index-sort-l.html | 143 + coverage-libs/index.html | 143 + coverage-libs/lapack/index-sort-f.html | 93 + coverage-libs/lapack/index-sort-l.html | 93 + coverage-libs/lapack/index.html | 93 + .../lapack/lapack.cpp.func-sort-c.html | 796 + coverage-libs/lapack/lapack.cpp.func.html | 796 + coverage-libs/lapack/lapack.cpp.gcov.html | 31099 ++++++++++++++++ .../CompiledExpression.cpp.func-sort-c.html | 148 + .../lepton/CompiledExpression.cpp.func.html | 148 + .../lepton/CompiledExpression.cpp.gcov.html | 585 + .../CompiledExpression.h.func-sort-c.html | 72 + .../lepton/CompiledExpression.h.func.html | 72 + .../lepton/CompiledExpression.h.gcov.html | 240 + .../lepton/Exception.h.func-sort-c.html | 88 + coverage-libs/lepton/Exception.h.func.html | 88 + coverage-libs/lepton/Exception.h.gcov.html | 169 + .../ExpressionProgram.cpp.func-sort-c.html | 120 + .../lepton/ExpressionProgram.cpp.func.html | 120 + .../lepton/ExpressionProgram.cpp.gcov.html | 220 + .../ExpressionTreeNode.cpp.func-sort-c.html | 132 + .../lepton/ExpressionTreeNode.cpp.func.html | 132 + .../lepton/ExpressionTreeNode.cpp.gcov.html | 263 + .../lepton/Operation.cpp.func-sort-c.html | 300 + coverage-libs/lepton/Operation.cpp.func.html | 300 + coverage-libs/lepton/Operation.cpp.gcov.html | 746 + .../lepton/Operation.h.func-sort-c.html | 1232 + coverage-libs/lepton/Operation.h.func.html | 1232 + coverage-libs/lepton/Operation.h.gcov.html | 1378 + .../ParsedExpression.cpp.func-sort-c.html | 156 + .../lepton/ParsedExpression.cpp.func.html | 156 + .../lepton/ParsedExpression.cpp.gcov.html | 527 + .../ParsedExpression.h.func-sort-c.html | 72 + .../lepton/ParsedExpression.h.func.html | 72 + .../lepton/ParsedExpression.h.gcov.html | 241 + .../lepton/Parser.cpp.func-sort-c.html | 112 + coverage-libs/lepton/Parser.cpp.func.html | 112 + coverage-libs/lepton/Parser.cpp.gcov.html | 584 + coverage-libs/lepton/index-sort-f.html | 183 + coverage-libs/lepton/index-sort-l.html | 183 + coverage-libs/lepton/index.html | 183 + .../molfile/Gromacs.h.func-sort-c.html | 216 + coverage-libs/molfile/Gromacs.h.func.html | 216 + coverage-libs/molfile/Gromacs.h.gcov.html | 2089 ++ .../molfile/crdplugin.cpp.func-sort-c.html | 108 + coverage-libs/molfile/crdplugin.cpp.func.html | 108 + coverage-libs/molfile/crdplugin.cpp.gcov.html | 338 + .../molfile/dcdplugin.cpp.func-sort-c.html | 148 + coverage-libs/molfile/dcdplugin.cpp.func.html | 148 + coverage-libs/molfile/dcdplugin.cpp.gcov.html | 1393 + .../molfile/endianswap.h.func-sort-c.html | 88 + coverage-libs/molfile/endianswap.h.func.html | 88 + coverage-libs/molfile/endianswap.h.gcov.html | 293 + .../molfile/fastio.h.func-sort-c.html | 100 + coverage-libs/molfile/fastio.h.func.html | 100 + coverage-libs/molfile/fastio.h.gcov.html | 759 + .../gromacsplugin.cpp.func-sort-c.html | 164 + .../molfile/gromacsplugin.cpp.func.html | 164 + .../molfile/gromacsplugin.cpp.gcov.html | 936 + coverage-libs/molfile/index-sort-f.html | 173 + coverage-libs/molfile/index-sort-l.html | 173 + coverage-libs/molfile/index.html | 173 + .../molfile/pdbplugin.cpp.func-sort-c.html | 128 + coverage-libs/molfile/pdbplugin.cpp.func.html | 128 + coverage-libs/molfile/pdbplugin.cpp.gcov.html | 724 + .../molfile/periodic_table.h.func-sort-c.html | 88 + .../molfile/periodic_table.h.func.html | 88 + .../molfile/periodic_table.h.gcov.html | 324 + .../molfile/readpdb.h.func-sort-c.html | 104 + coverage-libs/molfile/readpdb.h.func.html | 104 + coverage-libs/molfile/readpdb.h.gcov.html | 523 + coverage-libs/ruby.png | Bin 0 -> 141 bytes coverage-libs/snow.png | Bin 0 -> 141 bytes coverage-libs/updown.png | Bin 0 -> 117 bytes coverage-libs/xdrfile/index-sort-f.html | 113 + coverage-libs/xdrfile/index-sort-l.html | 113 + coverage-libs/xdrfile/index.html | 113 + .../xdrfile/xdrfile.cpp.func-sort-c.html | 396 + coverage-libs/xdrfile/xdrfile.cpp.func.html | 396 + coverage-libs/xdrfile/xdrfile.cpp.gcov.html | 2724 ++ .../xdrfile/xdrfile_trr.cpp.func-sort-c.html | 100 + .../xdrfile/xdrfile_trr.cpp.func.html | 100 + .../xdrfile/xdrfile_trr.cpp.gcov.html | 605 + .../xdrfile/xdrfile_xtc.cpp.func-sort-c.html | 92 + .../xdrfile/xdrfile_xtc.cpp.func.html | 92 + .../xdrfile/xdrfile_xtc.cpp.gcov.html | 241 + .../AdjacencyMatrixBase.cpp.func-sort-c.html | 124 + .../adjmat/AdjacencyMatrixBase.cpp.func.html | 124 + .../adjmat/AdjacencyMatrixBase.cpp.gcov.html | 468 + .../AdjacencyMatrixBase.h.func-sort-c.html | 92 + .../adjmat/AdjacencyMatrixBase.h.func.html | 92 + .../adjmat/AdjacencyMatrixBase.h.gcov.html | 195 + coverage/adjmat/Bridge.cpp.func-sort-c.html | 84 + coverage/adjmat/Bridge.cpp.func.html | 84 + coverage/adjmat/Bridge.cpp.gcov.html | 152 + .../adjmat/BridgeMatrix.cpp.func-sort-c.html | 88 + coverage/adjmat/BridgeMatrix.cpp.func.html | 88 + coverage/adjmat/BridgeMatrix.cpp.gcov.html | 212 + .../adjmat/ContactMatrix.cpp.func-sort-c.html | 92 + coverage/adjmat/ContactMatrix.cpp.func.html | 92 + coverage/adjmat/ContactMatrix.cpp.gcov.html | 201 + ...ContactMatrixShortcut.cpp.func-sort-c.html | 84 + .../ContactMatrixShortcut.cpp.func.html | 84 + .../ContactMatrixShortcut.cpp.gcov.html | 208 + .../DistanceMatrix.cpp.func-sort-c.html | 88 + coverage/adjmat/DistanceMatrix.cpp.func.html | 88 + coverage/adjmat/DistanceMatrix.cpp.gcov.html | 163 + .../adjmat/HbondMatrix.cpp.func-sort-c.html | 88 + coverage/adjmat/HbondMatrix.cpp.func.html | 88 + coverage/adjmat/HbondMatrix.cpp.gcov.html | 238 + .../adjmat/Neighbors.cpp.func-sort-c.html | 112 + coverage/adjmat/Neighbors.cpp.func.html | 112 + coverage/adjmat/Neighbors.cpp.gcov.html | 213 + .../TopologyMatrix.cpp.func-sort-c.html | 88 + coverage/adjmat/TopologyMatrix.cpp.func.html | 88 + coverage/adjmat/TopologyMatrix.cpp.gcov.html | 346 + .../TorsionsMatrix.cpp.func-sort-c.html | 104 + coverage/adjmat/TorsionsMatrix.cpp.func.html | 104 + coverage/adjmat/TorsionsMatrix.cpp.gcov.html | 237 + coverage/adjmat/index-sort-f.html | 193 + coverage/adjmat/index-sort-l.html | 193 + coverage/adjmat/index.html | 193 + coverage/amber.png | Bin 0 -> 141 bytes coverage/annfunc/ANN.cpp.func-sort-c.html | 96 + coverage/annfunc/ANN.cpp.func.html | 96 + coverage/annfunc/ANN.cpp.gcov.html | 473 + coverage/annfunc/index-sort-f.html | 93 + coverage/annfunc/index-sort-l.html | 93 + coverage/annfunc/index.html | 93 + coverage/bias/ABMD.cpp.func-sort-c.html | 88 + coverage/bias/ABMD.cpp.func.html | 88 + coverage/bias/ABMD.cpp.gcov.html | 262 + coverage/bias/Bias.cpp.func-sort-c.html | 88 + coverage/bias/Bias.cpp.func.html | 88 + coverage/bias/Bias.cpp.gcov.html | 168 + coverage/bias/Bias.h.func-sort-c.html | 84 + coverage/bias/Bias.h.func.html | 84 + coverage/bias/Bias.h.gcov.html | 159 + coverage/bias/BiasValue.cpp.func-sort-c.html | 88 + coverage/bias/BiasValue.cpp.func.html | 88 + coverage/bias/BiasValue.cpp.gcov.html | 193 + .../ExtendedLagrangian.cpp.func-sort-c.html | 92 + .../bias/ExtendedLagrangian.cpp.func.html | 92 + .../bias/ExtendedLagrangian.cpp.gcov.html | 337 + coverage/bias/External.cpp.func-sort-c.html | 88 + coverage/bias/External.cpp.func.html | 88 + coverage/bias/External.cpp.gcov.html | 256 + coverage/bias/LWalls.cpp.func-sort-c.html | 88 + coverage/bias/LWalls.cpp.func.html | 88 + coverage/bias/LWalls.cpp.gcov.html | 240 + coverage/bias/MaxEnt.cpp.func-sort-c.html | 116 + coverage/bias/MaxEnt.cpp.func.html | 116 + coverage/bias/MaxEnt.cpp.gcov.html | 559 + coverage/bias/MetaD.cpp.func-sort-c.html | 184 + coverage/bias/MetaD.cpp.func.html | 184 + coverage/bias/MetaD.cpp.gcov.html | 2380 ++ .../bias/MovingRestraint.cpp.func-sort-c.html | 88 + coverage/bias/MovingRestraint.cpp.func.html | 88 + coverage/bias/MovingRestraint.cpp.gcov.html | 356 + coverage/bias/PBMetaD.cpp.func-sort-c.html | 132 + coverage/bias/PBMetaD.cpp.func.html | 132 + coverage/bias/PBMetaD.cpp.gcov.html | 1390 + coverage/bias/Restraint.cpp.func-sort-c.html | 88 + coverage/bias/Restraint.cpp.func.html | 88 + coverage/bias/Restraint.cpp.gcov.html | 212 + .../RestraintShortcut.cpp.func-sort-c.html | 84 + coverage/bias/RestraintShortcut.cpp.func.html | 84 + coverage/bias/RestraintShortcut.cpp.gcov.html | 187 + .../bias/ReweightBase.cpp.func-sort-c.html | 88 + coverage/bias/ReweightBase.cpp.func.html | 88 + coverage/bias/ReweightBase.cpp.gcov.html | 129 + coverage/bias/ReweightBase.h.func-sort-c.html | 96 + coverage/bias/ReweightBase.h.func.html | 96 + coverage/bias/ReweightBase.h.gcov.html | 129 + .../bias/ReweightBias.cpp.func-sort-c.html | 88 + coverage/bias/ReweightBias.cpp.func.html | 88 + coverage/bias/ReweightBias.cpp.gcov.html | 175 + .../bias/ReweightMetad.cpp.func-sort-c.html | 88 + coverage/bias/ReweightMetad.cpp.func.html | 88 + coverage/bias/ReweightMetad.cpp.gcov.html | 172 + ...htTemperaturePressure.cpp.func-sort-c.html | 88 + .../ReweightTemperaturePressure.cpp.func.html | 88 + .../ReweightTemperaturePressure.cpp.gcov.html | 341 + coverage/bias/UWalls.cpp.func-sort-c.html | 88 + coverage/bias/UWalls.cpp.func.html | 88 + coverage/bias/UWalls.cpp.gcov.html | 239 + coverage/bias/Walls.cpp.func-sort-c.html | 84 + coverage/bias/Walls.cpp.func.html | 84 + coverage/bias/Walls.cpp.gcov.html | 195 + coverage/bias/index-sort-f.html | 283 + coverage/bias/index-sort-l.html | 283 + coverage/bias/index.html | 283 + .../cltools/Benchmark.cpp.func-sort-c.html | 180 + coverage/cltools/Benchmark.cpp.func.html | 180 + coverage/cltools/Benchmark.cpp.gcov.html | 928 + .../cltools/Completion.cpp.func-sort-c.html | 100 + coverage/cltools/Completion.cpp.func.html | 100 + coverage/cltools/Completion.cpp.gcov.html | 211 + coverage/cltools/Driver.cpp.func-sort-c.html | 120 + coverage/cltools/Driver.cpp.func.html | 120 + coverage/cltools/Driver.cpp.gcov.html | 1327 + .../cltools/DriverDouble.cpp.func-sort-c.html | 84 + coverage/cltools/DriverDouble.cpp.func.html | 84 + coverage/cltools/DriverDouble.cpp.gcov.html | 113 + .../cltools/DriverFloat.cpp.func-sort-c.html | 88 + coverage/cltools/DriverFloat.cpp.func.html | 88 + coverage/cltools/DriverFloat.cpp.gcov.html | 118 + .../cltools/GenExample.cpp.func-sort-c.html | 108 + coverage/cltools/GenExample.cpp.func.html | 108 + coverage/cltools/GenExample.cpp.gcov.html | 419 + coverage/cltools/GenJson.cpp.func-sort-c.html | 100 + coverage/cltools/GenJson.cpp.func.html | 100 + coverage/cltools/GenJson.cpp.gcov.html | 269 + .../cltools/GenTemplate.cpp.func-sort-c.html | 100 + coverage/cltools/GenTemplate.cpp.func.html | 100 + coverage/cltools/GenTemplate.cpp.gcov.html | 178 + coverage/cltools/Info.cpp.func-sort-c.html | 100 + coverage/cltools/Info.cpp.func.html | 100 + coverage/cltools/Info.cpp.gcov.html | 199 + coverage/cltools/Manual.cpp.func-sort-c.html | 100 + coverage/cltools/Manual.cpp.func.html | 100 + coverage/cltools/Manual.cpp.gcov.html | 177 + .../cltools/PdbRenumber.cpp.func-sort-c.html | 100 + coverage/cltools/PdbRenumber.cpp.func.html | 100 + coverage/cltools/PdbRenumber.cpp.gcov.html | 274 + .../cltools/ShowGraph.cpp.func-sort-c.html | 124 + coverage/cltools/ShowGraph.cpp.func.html | 124 + coverage/cltools/ShowGraph.cpp.gcov.html | 403 + .../cltools/SimpleMD.cpp.func-sort-c.html | 152 + coverage/cltools/SimpleMD.cpp.func.html | 152 + coverage/cltools/SimpleMD.cpp.gcov.html | 684 + .../cltools/SumHills.cpp.func-sort-c.html | 104 + coverage/cltools/SumHills.cpp.func.html | 104 + coverage/cltools/SumHills.cpp.gcov.html | 701 + .../SwitchingPlotter.cpp.func-sort-c.html | 100 + .../cltools/SwitchingPlotter.cpp.func.html | 100 + .../cltools/SwitchingPlotter.cpp.gcov.html | 268 + coverage/cltools/index-sort-f.html | 253 + coverage/cltools/index-sort-l.html | 253 + coverage/cltools/index.html | 253 + coverage/cltools/kT.cpp.func-sort-c.html | 100 + coverage/cltools/kT.cpp.func.html | 100 + coverage/cltools/kT.cpp.gcov.html | 163 + coverage/cltools/pesmd.cpp.func-sort-c.html | 100 + coverage/cltools/pesmd.cpp.func.html | 100 + coverage/cltools/pesmd.cpp.gcov.html | 388 + .../ClusterDiameter.cpp.func-sort-c.html | 84 + .../clusters/ClusterDiameter.cpp.func.html | 84 + .../clusters/ClusterDiameter.cpp.gcov.html | 175 + .../ClusterDistribution.cpp.func-sort-c.html | 108 + .../ClusterDistribution.cpp.func.html | 108 + .../ClusterDistribution.cpp.gcov.html | 261 + .../ClusterNatoms.cpp.func-sort-c.html | 84 + coverage/clusters/ClusterNatoms.cpp.func.html | 84 + coverage/clusters/ClusterNatoms.cpp.gcov.html | 140 + .../ClusterProperties.cpp.func-sort-c.html | 84 + .../clusters/ClusterProperties.cpp.func.html | 84 + .../clusters/ClusterProperties.cpp.gcov.html | 167 + .../ClusterWeights.cpp.func-sort-c.html | 96 + .../clusters/ClusterWeights.cpp.func.html | 96 + .../clusters/ClusterWeights.cpp.gcov.html | 188 + .../ClusterWithSurface.cpp.func-sort-c.html | 84 + .../clusters/ClusterWithSurface.cpp.func.html | 84 + .../clusters/ClusterWithSurface.cpp.gcov.html | 157 + .../ClusteringBase.cpp.func-sort-c.html | 96 + .../clusters/ClusteringBase.cpp.func.html | 96 + .../clusters/ClusteringBase.cpp.gcov.html | 168 + .../ClusteringBase.h.func-sort-c.html | 80 + coverage/clusters/ClusteringBase.h.func.html | 80 + coverage/clusters/ClusteringBase.h.gcov.html | 142 + .../DFSClustering.cpp.func-sort-c.html | 92 + coverage/clusters/DFSClustering.cpp.func.html | 92 + coverage/clusters/DFSClustering.cpp.gcov.html | 226 + .../OutputCluster.cpp.func-sort-c.html | 84 + coverage/clusters/OutputCluster.cpp.func.html | 84 + coverage/clusters/OutputCluster.cpp.gcov.html | 169 + coverage/clusters/index-sort-f.html | 183 + coverage/clusters/index-sort-l.html | 183 + coverage/clusters/index.html | 183 + coverage/colvar/Angle.cpp.func-sort-c.html | 100 + coverage/colvar/Angle.cpp.func.html | 100 + coverage/colvar/Angle.cpp.gcov.html | 271 + coverage/colvar/Cell.cpp.func-sort-c.html | 88 + coverage/colvar/Cell.cpp.func.html | 88 + coverage/colvar/Cell.cpp.gcov.html | 184 + .../colvar/ColvarShortcut.h.func-sort-c.html | 144 + coverage/colvar/ColvarShortcut.h.func.html | 144 + coverage/colvar/ColvarShortcut.h.gcov.html | 150 + .../colvar/ContactMap.cpp.func-sort-c.html | 92 + coverage/colvar/ContactMap.cpp.func.html | 92 + coverage/colvar/ContactMap.cpp.gcov.html | 403 + .../colvar/Coordination.cpp.func-sort-c.html | 88 + coverage/colvar/Coordination.cpp.func.html | 88 + coverage/colvar/Coordination.cpp.gcov.html | 231 + .../CoordinationBase.cpp.func-sort-c.html | 104 + .../colvar/CoordinationBase.cpp.func.html | 104 + .../colvar/CoordinationBase.cpp.gcov.html | 288 + coverage/colvar/DHEnergy.cpp.func-sort-c.html | 88 + coverage/colvar/DHEnergy.cpp.func.html | 88 + coverage/colvar/DHEnergy.cpp.gcov.html | 220 + coverage/colvar/DRMSD.cpp.func-sort-c.html | 84 + coverage/colvar/DRMSD.cpp.func.html | 84 + coverage/colvar/DRMSD.cpp.gcov.html | 347 + .../DihedralCorrelation.cpp.func-sort-c.html | 100 + .../colvar/DihedralCorrelation.cpp.func.html | 100 + .../colvar/DihedralCorrelation.cpp.gcov.html | 256 + coverage/colvar/Dimer.cpp.func-sort-c.html | 92 + coverage/colvar/Dimer.cpp.func.html | 92 + coverage/colvar/Dimer.cpp.gcov.html | 394 + coverage/colvar/Dipole.cpp.func-sort-c.html | 100 + coverage/colvar/Dipole.cpp.func.html | 100 + coverage/colvar/Dipole.cpp.gcov.html | 301 + coverage/colvar/Distance.cpp.func-sort-c.html | 100 + coverage/colvar/Distance.cpp.func.html | 100 + coverage/colvar/Distance.cpp.gcov.html | 385 + coverage/colvar/EEFSolv.cpp.func-sort-c.html | 104 + coverage/colvar/EEFSolv.cpp.func.html | 104 + coverage/colvar/EEFSolv.cpp.gcov.html | 1254 + coverage/colvar/ERMSD.cpp.func-sort-c.html | 88 + coverage/colvar/ERMSD.cpp.func.html | 88 + coverage/colvar/ERMSD.cpp.gcov.html | 290 + coverage/colvar/Energy.cpp.func-sort-c.html | 92 + coverage/colvar/Energy.cpp.func.html | 92 + coverage/colvar/Energy.cpp.gcov.html | 201 + coverage/colvar/ExtraCV.cpp.func-sort-c.html | 84 + coverage/colvar/ExtraCV.cpp.func.html | 84 + coverage/colvar/ExtraCV.cpp.gcov.html | 156 + coverage/colvar/Fake.cpp.func-sort-c.html | 92 + coverage/colvar/Fake.cpp.func.html | 92 + coverage/colvar/Fake.cpp.gcov.html | 200 + coverage/colvar/GHBFIX.cpp.func-sort-c.html | 88 + coverage/colvar/GHBFIX.cpp.func.html | 88 + coverage/colvar/GHBFIX.cpp.gcov.html | 294 + coverage/colvar/Gyration.cpp.func-sort-c.html | 88 + coverage/colvar/Gyration.cpp.func.html | 88 + coverage/colvar/Gyration.cpp.gcov.html | 447 + .../GyrationShortcut.cpp.func-sort-c.html | 84 + .../colvar/GyrationShortcut.cpp.func.html | 84 + .../colvar/GyrationShortcut.cpp.gcov.html | 259 + .../MultiColvarTemplate.h.func-sort-c.html | 360 + .../colvar/MultiColvarTemplate.h.func.html | 360 + .../colvar/MultiColvarTemplate.h.gcov.html | 284 + .../colvar/MultiRMSD.cpp.func-sort-c.html | 84 + coverage/colvar/MultiRMSD.cpp.func.html | 84 + coverage/colvar/MultiRMSD.cpp.gcov.html | 207 + coverage/colvar/PCARMSD.cpp.func-sort-c.html | 92 + coverage/colvar/PCARMSD.cpp.func.html | 92 + coverage/colvar/PCARMSD.cpp.gcov.html | 342 + coverage/colvar/PathMSD.cpp.func-sort-c.html | 84 + coverage/colvar/PathMSD.cpp.func.html | 84 + coverage/colvar/PathMSD.cpp.gcov.html | 204 + .../colvar/PathMSDBase.cpp.func-sort-c.html | 104 + coverage/colvar/PathMSDBase.cpp.func.html | 104 + coverage/colvar/PathMSDBase.cpp.gcov.html | 413 + .../colvar/PathMSDBase.h.func-sort-c.html | 72 + coverage/colvar/PathMSDBase.h.func.html | 72 + coverage/colvar/PathMSDBase.h.gcov.html | 177 + coverage/colvar/Plane.cpp.func-sort-c.html | 100 + coverage/colvar/Plane.cpp.func.html | 100 + coverage/colvar/Plane.cpp.gcov.html | 253 + coverage/colvar/Position.cpp.func-sort-c.html | 100 + coverage/colvar/Position.cpp.func.html | 100 + coverage/colvar/Position.cpp.gcov.html | 314 + .../ProjectionOnAxis.cpp.func-sort-c.html | 88 + .../colvar/ProjectionOnAxis.cpp.func.html | 88 + .../colvar/ProjectionOnAxis.cpp.gcov.html | 246 + .../colvar/PropertyMap.cpp.func-sort-c.html | 88 + coverage/colvar/PropertyMap.cpp.func.html | 88 + coverage/colvar/PropertyMap.cpp.gcov.html | 233 + .../colvar/Puckering.cpp.func-sort-c.html | 96 + coverage/colvar/Puckering.cpp.func.html | 96 + coverage/colvar/Puckering.cpp.gcov.html | 496 + coverage/colvar/RMSD.cpp.func-sort-c.html | 88 + coverage/colvar/RMSD.cpp.func.html | 88 + coverage/colvar/RMSD.cpp.gcov.html | 307 + .../colvar/RMSDShortcut.cpp.func-sort-c.html | 84 + coverage/colvar/RMSDShortcut.cpp.func.html | 84 + coverage/colvar/RMSDShortcut.cpp.gcov.html | 183 + .../colvar/RMSDVector.cpp.func-sort-c.html | 120 + coverage/colvar/RMSDVector.cpp.func.html | 120 + coverage/colvar/RMSDVector.cpp.gcov.html | 367 + .../SelectMassCharge.cpp.func-sort-c.html | 100 + .../colvar/SelectMassCharge.cpp.func.html | 100 + .../colvar/SelectMassCharge.cpp.gcov.html | 238 + coverage/colvar/Template.cpp.func-sort-c.html | 88 + coverage/colvar/Template.cpp.func.html | 88 + coverage/colvar/Template.cpp.gcov.html | 191 + coverage/colvar/Torsion.cpp.func-sort-c.html | 100 + coverage/colvar/Torsion.cpp.func.html | 100 + coverage/colvar/Torsion.cpp.gcov.html | 338 + coverage/colvar/Volume.cpp.func-sort-c.html | 88 + coverage/colvar/Volume.cpp.func.html | 88 + coverage/colvar/Volume.cpp.gcov.html | 162 + coverage/colvar/index-sort-f.html | 463 + coverage/colvar/index-sort-l.html | 463 + coverage/colvar/index.html | 463 + coverage/config/Config.inc.func-sort-c.html | 176 + coverage/config/Config.inc.func.html | 176 + coverage/config/Config.inc.gcov.html | 289 + .../config/ConfigInstall.inc.func-sort-c.html | 176 + coverage/config/ConfigInstall.inc.func.html | 176 + coverage/config/ConfigInstall.inc.gcov.html | 289 + coverage/config/index-sort-f.html | 103 + coverage/config/index-sort-l.html | 103 + coverage/config/index.html | 103 + .../ContourFindingBase.cpp.func-sort-c.html | 88 + .../contour/ContourFindingBase.cpp.func.html | 88 + .../contour/ContourFindingBase.cpp.gcov.html | 123 + .../ContourFindingBase.h.func-sort-c.html | 76 + .../contour/ContourFindingBase.h.func.html | 76 + .../contour/ContourFindingBase.h.gcov.html | 149 + .../DistanceFromContour.cpp.func-sort-c.html | 92 + .../contour/DistanceFromContour.cpp.func.html | 92 + .../contour/DistanceFromContour.cpp.gcov.html | 322 + ...stanceFromContourBase.cpp.func-sort-c.html | 104 + .../DistanceFromContourBase.cpp.func.html | 104 + .../DistanceFromContourBase.cpp.gcov.html | 221 + ...DistanceFromContourBase.h.func-sort-c.html | 80 + .../DistanceFromContourBase.h.func.html | 80 + .../DistanceFromContourBase.h.gcov.html | 155 + ...eFromSphericalContour.cpp.func-sort-c.html | 92 + ...DistanceFromSphericalContour.cpp.func.html | 92 + ...DistanceFromSphericalContour.cpp.gcov.html | 184 + .../contour/DumpContour.cpp.func-sort-c.html | 104 + coverage/contour/DumpContour.cpp.func.html | 104 + coverage/contour/DumpContour.cpp.gcov.html | 179 + .../contour/FindContour.cpp.func-sort-c.html | 112 + coverage/contour/FindContour.cpp.func.html | 112 + coverage/contour/FindContour.cpp.gcov.html | 267 + .../contour/FindContour.h.func-sort-c.html | 80 + coverage/contour/FindContour.h.func.html | 80 + coverage/contour/FindContour.h.gcov.html | 127 + .../FindContourSurface.cpp.func-sort-c.html | 108 + .../contour/FindContourSurface.cpp.func.html | 108 + .../contour/FindContourSurface.cpp.gcov.html | 315 + .../FindSphericalContour.cpp.func-sort-c.html | 108 + .../FindSphericalContour.cpp.func.html | 108 + .../FindSphericalContour.cpp.gcov.html | 279 + coverage/contour/index-sort-f.html | 193 + coverage/contour/index-sort-l.html | 193 + coverage/contour/index.html | 193 + coverage/core/Action.cpp.func-sort-c.html | 224 + coverage/core/Action.cpp.func.html | 224 + coverage/core/Action.cpp.gcov.html | 444 + coverage/core/Action.h.func-sort-c.html | 224 + coverage/core/Action.h.func.html | 224 + coverage/core/Action.h.gcov.html | 561 + .../core/ActionAnyorder.cpp.func-sort-c.html | 84 + coverage/core/ActionAnyorder.cpp.func.html | 84 + coverage/core/ActionAnyorder.cpp.gcov.html | 114 + .../core/ActionAnyorder.h.func-sort-c.html | 80 + coverage/core/ActionAnyorder.h.func.html | 80 + coverage/core/ActionAnyorder.h.gcov.html | 124 + .../core/ActionAtomistic.cpp.func-sort-c.html | 184 + coverage/core/ActionAtomistic.cpp.func.html | 184 + coverage/core/ActionAtomistic.cpp.gcov.html | 561 + .../core/ActionAtomistic.h.func-sort-c.html | 112 + coverage/core/ActionAtomistic.h.func.html | 112 + coverage/core/ActionAtomistic.h.gcov.html | 385 + .../ActionForInterface.cpp.func-sort-c.html | 88 + .../core/ActionForInterface.cpp.func.html | 88 + .../core/ActionForInterface.cpp.gcov.html | 125 + .../ActionForInterface.h.func-sort-c.html | 100 + coverage/core/ActionForInterface.h.func.html | 100 + coverage/core/ActionForInterface.h.gcov.html | 166 + .../core/ActionPilot.cpp.func-sort-c.html | 96 + coverage/core/ActionPilot.cpp.func.html | 96 + coverage/core/ActionPilot.cpp.gcov.html | 131 + coverage/core/ActionPilot.h.func-sort-c.html | 72 + coverage/core/ActionPilot.h.func.html | 72 + coverage/core/ActionPilot.h.gcov.html | 134 + .../core/ActionRegister.cpp.func-sort-c.html | 108 + coverage/core/ActionRegister.cpp.func.html | 108 + coverage/core/ActionRegister.cpp.gcov.html | 190 + .../core/ActionRegister.h.func-sort-c.html | 4728 +++ coverage/core/ActionRegister.h.func.html | 4728 +++ coverage/core/ActionRegister.h.gcov.html | 199 + coverage/core/ActionSet.cpp.func-sort-c.html | 88 + coverage/core/ActionSet.cpp.func.html | 88 + coverage/core/ActionSet.cpp.gcov.html | 128 + coverage/core/ActionSet.h.func-sort-c.html | 196 + coverage/core/ActionSet.h.func.html | 196 + coverage/core/ActionSet.h.gcov.html | 226 + .../core/ActionSetup.cpp.func-sort-c.html | 84 + coverage/core/ActionSetup.cpp.func.html | 84 + coverage/core/ActionSetup.cpp.gcov.html | 124 + coverage/core/ActionSetup.h.func-sort-c.html | 80 + coverage/core/ActionSetup.h.func.html | 80 + coverage/core/ActionSetup.h.gcov.html | 124 + .../core/ActionShortcut.cpp.func-sort-c.html | 124 + coverage/core/ActionShortcut.cpp.func.html | 124 + coverage/core/ActionShortcut.cpp.gcov.html | 322 + .../core/ActionShortcut.h.func-sort-c.html | 84 + coverage/core/ActionShortcut.h.func.html | 84 + coverage/core/ActionShortcut.h.gcov.html | 147 + .../core/ActionToGetData.cpp.func-sort-c.html | 100 + coverage/core/ActionToGetData.cpp.func.html | 100 + coverage/core/ActionToGetData.cpp.gcov.html | 161 + .../core/ActionToGetData.h.func-sort-c.html | 80 + coverage/core/ActionToGetData.h.func.html | 80 + coverage/core/ActionToGetData.h.gcov.html | 134 + .../core/ActionToPutData.cpp.func-sort-c.html | 140 + coverage/core/ActionToPutData.cpp.func.html | 140 + coverage/core/ActionToPutData.cpp.gcov.html | 260 + .../core/ActionToPutData.h.func-sort-c.html | 96 + coverage/core/ActionToPutData.h.func.html | 96 + coverage/core/ActionToPutData.h.gcov.html | 172 + .../ActionWithArguments.cpp.func-sort-c.html | 128 + .../core/ActionWithArguments.cpp.func.html | 128 + .../core/ActionWithArguments.cpp.gcov.html | 436 + .../ActionWithArguments.h.func-sort-c.html | 100 + coverage/core/ActionWithArguments.h.func.html | 100 + coverage/core/ActionWithArguments.h.gcov.html | 215 + .../ActionWithMatrix.cpp.func-sort-c.html | 160 + coverage/core/ActionWithMatrix.cpp.func.html | 160 + coverage/core/ActionWithMatrix.cpp.gcov.html | 319 + .../core/ActionWithMatrix.h.func-sort-c.html | 96 + coverage/core/ActionWithMatrix.h.func.html | 96 + coverage/core/ActionWithMatrix.h.gcov.html | 226 + .../core/ActionWithValue.cpp.func-sort-c.html | 204 + coverage/core/ActionWithValue.cpp.func.html | 204 + coverage/core/ActionWithValue.cpp.gcov.html | 415 + .../core/ActionWithValue.h.func-sort-c.html | 100 + coverage/core/ActionWithValue.h.func.html | 100 + coverage/core/ActionWithValue.h.gcov.html | 329 + .../ActionWithVector.cpp.func-sort-c.html | 288 + coverage/core/ActionWithVector.cpp.func.html | 288 + coverage/core/ActionWithVector.cpp.gcov.html | 847 + .../core/ActionWithVector.h.func-sort-c.html | 100 + coverage/core/ActionWithVector.h.func.html | 100 + coverage/core/ActionWithVector.h.gcov.html | 267 + ...ActionWithVirtualAtom.cpp.func-sort-c.html | 100 + .../core/ActionWithVirtualAtom.cpp.func.html | 100 + .../core/ActionWithVirtualAtom.cpp.gcov.html | 207 + .../ActionWithVirtualAtom.h.func-sort-c.html | 96 + .../core/ActionWithVirtualAtom.h.func.html | 96 + .../core/ActionWithVirtualAtom.h.gcov.html | 196 + coverage/core/CLTool.cpp.func-sort-c.html | 112 + coverage/core/CLTool.cpp.func.html | 112 + coverage/core/CLTool.cpp.gcov.html | 292 + coverage/core/CLTool.h.func-sort-c.html | 132 + coverage/core/CLTool.h.func.html | 132 + coverage/core/CLTool.h.gcov.html | 241 + coverage/core/CLToolMain.cpp.func-sort-c.html | 92 + coverage/core/CLToolMain.cpp.func.html | 92 + coverage/core/CLToolMain.cpp.gcov.html | 363 + .../core/CLToolRegister.cpp.func-sort-c.html | 100 + coverage/core/CLToolRegister.cpp.func.html | 100 + coverage/core/CLToolRegister.cpp.gcov.html | 167 + .../core/CLToolRegister.h.func-sort-c.html | 72 + coverage/core/CLToolRegister.h.func.html | 72 + coverage/core/CLToolRegister.h.gcov.html | 184 + coverage/core/Colvar.cpp.func-sort-c.html | 100 + coverage/core/Colvar.cpp.func.html | 100 + coverage/core/Colvar.cpp.gcov.html | 149 + coverage/core/Colvar.h.func-sort-c.html | 88 + coverage/core/Colvar.h.func.html | 88 + coverage/core/Colvar.h.gcov.html | 193 + .../DataPassingObject.cpp.func-sort-c.html | 188 + coverage/core/DataPassingObject.cpp.func.html | 188 + coverage/core/DataPassingObject.cpp.gcov.html | 263 + .../core/DataPassingObject.h.func-sort-c.html | 72 + coverage/core/DataPassingObject.h.func.html | 72 + coverage/core/DataPassingObject.h.gcov.html | 162 + .../DataPassingTools.cpp.func-sort-c.html | 104 + coverage/core/DataPassingTools.cpp.func.html | 104 + coverage/core/DataPassingTools.cpp.gcov.html | 148 + .../core/DataPassingTools.h.func-sort-c.html | 80 + coverage/core/DataPassingTools.h.func.html | 80 + coverage/core/DataPassingTools.h.gcov.html | 130 + .../DomainDecomposition.cpp.func-sort-c.html | 204 + .../core/DomainDecomposition.cpp.func.html | 204 + .../core/DomainDecomposition.cpp.gcov.html | 578 + .../DomainDecomposition.h.func-sort-c.html | 84 + coverage/core/DomainDecomposition.h.func.html | 84 + coverage/core/DomainDecomposition.h.gcov.html | 190 + .../ExchangePatterns.cpp.func-sort-c.html | 100 + coverage/core/ExchangePatterns.cpp.func.html | 100 + coverage/core/ExchangePatterns.cpp.gcov.html | 148 + .../core/FlexibleBin.cpp.func-sort-c.html | 100 + coverage/core/FlexibleBin.cpp.func.html | 100 + coverage/core/FlexibleBin.cpp.gcov.html | 412 + coverage/core/GREX.cpp.func-sort-c.html | 96 + coverage/core/GREX.cpp.func.html | 96 + coverage/core/GREX.cpp.gcov.html | 291 + .../core/GenericMolInfo.cpp.func-sort-c.html | 144 + coverage/core/GenericMolInfo.cpp.func.html | 144 + coverage/core/GenericMolInfo.cpp.gcov.html | 448 + .../core/GenericMolInfo.h.func-sort-c.html | 80 + coverage/core/GenericMolInfo.h.func.html | 80 + coverage/core/GenericMolInfo.h.gcov.html | 165 + coverage/core/Group.cpp.func-sort-c.html | 88 + coverage/core/Group.cpp.func.html | 88 + coverage/core/Group.cpp.gcov.html | 305 + coverage/core/Group.h.func-sort-c.html | 80 + coverage/core/Group.h.func.html | 80 + coverage/core/Group.h.gcov.html | 117 + coverage/core/ModuleMap.cpp.func-sort-c.html | 76 + coverage/core/ModuleMap.cpp.func.html | 76 + coverage/core/ModuleMap.cpp.gcov.html | 107 + coverage/core/PbcAction.cpp.func-sort-c.html | 96 + coverage/core/PbcAction.cpp.func.html | 96 + coverage/core/PbcAction.cpp.gcov.html | 157 + coverage/core/PbcAction.h.func-sort-c.html | 76 + coverage/core/PbcAction.h.func.html | 76 + coverage/core/PbcAction.h.gcov.html | 135 + coverage/core/PlumedMain.cpp.func-sort-c.html | 352 + coverage/core/PlumedMain.cpp.func.html | 352 + coverage/core/PlumedMain.cpp.gcov.html | 1592 + coverage/core/PlumedMain.h.func-sort-c.html | 72 + coverage/core/PlumedMain.h.func.html | 72 + coverage/core/PlumedMain.h.gcov.html | 692 + ...PlumedMainInitializer.cpp.func-sort-c.html | 136 + .../core/PlumedMainInitializer.cpp.func.html | 136 + .../core/PlumedMainInitializer.cpp.gcov.html | 566 + .../core/RegisterBase.cpp.func-sort-c.html | 136 + coverage/core/RegisterBase.cpp.func.html | 136 + coverage/core/RegisterBase.cpp.gcov.html | 222 + coverage/core/RegisterBase.h.func-sort-c.html | 160 + coverage/core/RegisterBase.h.func.html | 160 + coverage/core/RegisterBase.h.gcov.html | 401 + coverage/core/TargetDist.cpp.func-sort-c.html | 84 + coverage/core/TargetDist.cpp.func.html | 84 + coverage/core/TargetDist.cpp.gcov.html | 147 + coverage/core/Value.cpp.func-sort-c.html | 212 + coverage/core/Value.cpp.func.html | 212 + coverage/core/Value.cpp.gcov.html | 480 + coverage/core/Value.h.func-sort-c.html | 124 + coverage/core/Value.h.func.html | 124 + coverage/core/Value.h.gcov.html | 583 + coverage/core/WithCmd.h.func-sort-c.html | 104 + coverage/core/WithCmd.h.func.html | 104 + coverage/core/WithCmd.h.gcov.html | 167 + coverage/core/index-sort-f.html | 723 + coverage/core/index-sort-l.html | 723 + coverage/core/index.html | 723 + .../BopsShortcut.cpp.func-sort-c.html | 84 + .../crystdistrib/BopsShortcut.cpp.func.html | 84 + .../crystdistrib/BopsShortcut.cpp.gcov.html | 233 + .../DopsShortcut.cpp.func-sort-c.html | 84 + .../crystdistrib/DopsShortcut.cpp.func.html | 84 + .../crystdistrib/DopsShortcut.cpp.gcov.html | 189 + .../Quaternion.cpp.func-sort-c.html | 100 + .../crystdistrib/Quaternion.cpp.func.html | 100 + .../crystdistrib/Quaternion.cpp.gcov.html | 470 + ...nionBondProductMatrix.cpp.func-sort-c.html | 104 + .../QuaternionBondProductMatrix.cpp.func.html | 104 + .../QuaternionBondProductMatrix.cpp.gcov.html | 460 + ...aternionProductMatrix.cpp.func-sort-c.html | 104 + .../QuaternionProductMatrix.cpp.func.html | 104 + .../QuaternionProductMatrix.cpp.gcov.html | 273 + .../RopsShortcut.cpp.func-sort-c.html | 84 + .../crystdistrib/RopsShortcut.cpp.func.html | 84 + .../crystdistrib/RopsShortcut.cpp.gcov.html | 223 + coverage/crystdistrib/index-sort-f.html | 143 + coverage/crystdistrib/index-sort-l.html | 143 + coverage/crystdistrib/index.html | 143 + .../dimred/ArrangePoints.cpp.func-sort-c.html | 120 + coverage/dimred/ArrangePoints.cpp.func.html | 120 + coverage/dimred/ArrangePoints.cpp.gcov.html | 409 + ...ltiDimensionalScaling.cpp.func-sort-c.html | 84 + ...sicalMultiDimensionalScaling.cpp.func.html | 84 + ...sicalMultiDimensionalScaling.cpp.gcov.html | 312 + coverage/dimred/PCA.cpp.func-sort-c.html | 84 + coverage/dimred/PCA.cpp.func.html | 84 + coverage/dimred/PCA.cpp.gcov.html | 260 + .../dimred/ProjectPoints.cpp.func-sort-c.html | 112 + coverage/dimred/ProjectPoints.cpp.func.html | 112 + coverage/dimred/ProjectPoints.cpp.gcov.html | 259 + coverage/dimred/SMACOF.cpp.func-sort-c.html | 84 + coverage/dimred/SMACOF.cpp.func.html | 84 + coverage/dimred/SMACOF.cpp.gcov.html | 186 + coverage/dimred/SMACOF.h.func-sort-c.html | 76 + coverage/dimred/SMACOF.h.func.html | 76 + coverage/dimred/SMACOF.h.gcov.html | 131 + .../dimred/SketchMap.cpp.func-sort-c.html | 84 + coverage/dimred/SketchMap.cpp.func.html | 84 + coverage/dimred/SketchMap.cpp.gcov.html | 221 + .../SketchMapProjection.cpp.func-sort-c.html | 84 + .../dimred/SketchMapProjection.cpp.func.html | 84 + .../dimred/SketchMapProjection.cpp.gcov.html | 163 + coverage/dimred/index-sort-f.html | 163 + coverage/dimred/index-sort-l.html | 163 + coverage/dimred/index.html | 163 + coverage/drr/DRR.cpp.func-sort-c.html | 172 + coverage/drr/DRR.cpp.func.html | 172 + coverage/drr/DRR.cpp.gcov.html | 634 + coverage/drr/DRR.h.func-sort-c.html | 128 + coverage/drr/DRR.h.func.html | 128 + coverage/drr/DRR.h.gcov.html | 434 + ...cReferenceRestraining.cpp.func-sort-c.html | 108 + .../DynamicReferenceRestraining.cpp.func.html | 108 + .../DynamicReferenceRestraining.cpp.gcov.html | 967 + .../drr/colvar_UIestimator.h.func-sort-c.html | 208 + coverage/drr/colvar_UIestimator.h.func.html | 208 + coverage/drr/colvar_UIestimator.h.gcov.html | 931 + coverage/drr/drrtool.cpp.func-sort-c.html | 120 + coverage/drr/drrtool.cpp.func.html | 120 + coverage/drr/drrtool.cpp.gcov.html | 344 + coverage/drr/index-sort-f.html | 133 + coverage/drr/index-sort-l.html | 133 + coverage/drr/index.html | 133 + coverage/eds/EDS.cpp.func-sort-c.html | 152 + coverage/eds/EDS.cpp.func.html | 152 + coverage/eds/EDS.cpp.gcov.html | 1250 + coverage/eds/index-sort-f.html | 93 + coverage/eds/index-sort-l.html | 93 + coverage/eds/index.html | 93 + coverage/emerald.png | Bin 0 -> 141 bytes ...EnvironmentSimilarity.cpp.func-sort-c.html | 88 + .../EnvironmentSimilarity.cpp.func.html | 88 + .../EnvironmentSimilarity.cpp.gcov.html | 523 + coverage/envsim/index-sort-f.html | 93 + coverage/envsim/index-sort-l.html | 93 + coverage/envsim/index.html | 93 + coverage/fisst/FISST.cpp.func-sort-c.html | 148 + coverage/fisst/FISST.cpp.func.html | 148 + coverage/fisst/FISST.cpp.gcov.html | 735 + coverage/fisst/index-sort-f.html | 103 + coverage/fisst/index-sort-l.html | 103 + coverage/fisst/index.html | 103 + .../legendre_rule_fast.cpp.func-sort-c.html | 100 + .../fisst/legendre_rule_fast.cpp.func.html | 100 + .../fisst/legendre_rule_fast.cpp.gcov.html | 641 + .../FourierTransform.cpp.func-sort-c.html | 108 + .../fourier/FourierTransform.cpp.func.html | 108 + .../fourier/FourierTransform.cpp.gcov.html | 333 + coverage/fourier/index-sort-f.html | 93 + coverage/fourier/index-sort-l.html | 93 + coverage/fourier/index.html | 93 + coverage/function/Bessel.cpp.func-sort-c.html | 96 + coverage/function/Bessel.cpp.func.html | 96 + coverage/function/Bessel.cpp.gcov.html | 272 + .../function/Between.cpp.func-sort-c.html | 84 + coverage/function/Between.cpp.func.html | 84 + coverage/function/Between.cpp.gcov.html | 185 + coverage/function/Between.h.func-sort-c.html | 76 + coverage/function/Between.h.func.html | 76 + coverage/function/Between.h.gcov.html | 118 + .../function/Combine.cpp.func-sort-c.html | 84 + coverage/function/Combine.cpp.func.html | 84 + coverage/function/Combine.cpp.gcov.html | 237 + coverage/function/Combine.h.func-sort-c.html | 72 + coverage/function/Combine.h.func.html | 72 + coverage/function/Combine.h.gcov.html | 120 + coverage/function/Custom.cpp.func-sort-c.html | 96 + coverage/function/Custom.cpp.func.html | 96 + coverage/function/Custom.cpp.gcov.html | 445 + .../function/Ensemble.cpp.func-sort-c.html | 92 + coverage/function/Ensemble.cpp.func.html | 92 + coverage/function/Ensemble.cpp.gcov.html | 349 + .../FuncPathGeneral.cpp.func-sort-c.html | 96 + .../function/FuncPathGeneral.cpp.func.html | 96 + .../function/FuncPathGeneral.cpp.gcov.html | 416 + .../function/FuncPathMSD.cpp.func-sort-c.html | 92 + coverage/function/FuncPathMSD.cpp.func.html | 92 + coverage/function/FuncPathMSD.cpp.gcov.html | 443 + .../FuncSumHills.cpp.func-sort-c.html | 120 + coverage/function/FuncSumHills.cpp.func.html | 120 + coverage/function/FuncSumHills.cpp.gcov.html | 715 + .../function/Function.cpp.func-sort-c.html | 96 + coverage/function/Function.cpp.func.html | 96 + coverage/function/Function.cpp.gcov.html | 138 + coverage/function/Function.h.func-sort-c.html | 84 + coverage/function/Function.h.func.html | 84 + coverage/function/Function.h.gcov.html | 159 + .../FunctionOfMatrix.h.func-sort-c.html | 504 + .../function/FunctionOfMatrix.h.func.html | 504 + .../function/FunctionOfMatrix.h.gcov.html | 517 + .../FunctionOfScalar.h.func-sort-c.html | 392 + .../function/FunctionOfScalar.h.func.html | 392 + .../function/FunctionOfScalar.h.gcov.html | 195 + .../FunctionOfVector.h.func-sort-c.html | 756 + .../function/FunctionOfVector.h.func.html | 756 + .../function/FunctionOfVector.h.gcov.html | 436 + .../FunctionShortcut.h.func-sort-c.html | 256 + .../function/FunctionShortcut.h.func.html | 256 + .../function/FunctionShortcut.h.gcov.html | 167 + .../FunctionTemplateBase.h.func-sort-c.html | 144 + .../function/FunctionTemplateBase.h.func.html | 144 + .../function/FunctionTemplateBase.h.gcov.html | 211 + .../function/Highest.cpp.func-sort-c.html | 92 + coverage/function/Highest.cpp.func.html | 92 + coverage/function/Highest.cpp.gcov.html | 209 + .../function/LessThan.cpp.func-sort-c.html | 84 + coverage/function/LessThan.cpp.func.html | 84 + coverage/function/LessThan.cpp.gcov.html | 186 + coverage/function/LessThan.h.func-sort-c.html | 76 + coverage/function/LessThan.h.func.html | 76 + coverage/function/LessThan.h.gcov.html | 119 + .../LocalEnsemble.cpp.func-sort-c.html | 92 + coverage/function/LocalEnsemble.cpp.func.html | 92 + coverage/function/LocalEnsemble.cpp.gcov.html | 232 + .../function/Moments.cpp.func-sort-c.html | 100 + coverage/function/Moments.cpp.func.html | 100 + coverage/function/Moments.cpp.gcov.html | 232 + .../function/MoreThan.cpp.func-sort-c.html | 84 + coverage/function/MoreThan.cpp.func.html | 84 + coverage/function/MoreThan.cpp.gcov.html | 186 + coverage/function/MoreThan.h.func-sort-c.html | 76 + coverage/function/MoreThan.h.func.html | 76 + coverage/function/MoreThan.h.gcov.html | 119 + .../function/Piecewise.cpp.func-sort-c.html | 88 + coverage/function/Piecewise.cpp.func.html | 88 + coverage/function/Piecewise.cpp.gcov.html | 222 + .../function/Product.cpp.func-sort-c.html | 84 + coverage/function/Product.cpp.func.html | 84 + coverage/function/Product.cpp.gcov.html | 140 + coverage/function/Sort.cpp.func-sort-c.html | 100 + coverage/function/Sort.cpp.func.html | 100 + coverage/function/Sort.cpp.gcov.html | 213 + coverage/function/Stats.cpp.func-sort-c.html | 88 + coverage/function/Stats.cpp.func.html | 88 + coverage/function/Stats.cpp.gcov.html | 315 + coverage/function/Sum.cpp.func-sort-c.html | 92 + coverage/function/Sum.cpp.func.html | 92 + coverage/function/Sum.cpp.gcov.html | 206 + coverage/function/Sum.h.func-sort-c.html | 72 + coverage/function/Sum.h.func.html | 72 + coverage/function/Sum.h.gcov.html | 119 + coverage/function/index-sort-f.html | 383 + coverage/function/index-sort-l.html | 383 + coverage/function/index.html | 383 + coverage/funnel/FPS.cpp.func-sort-c.html | 88 + coverage/funnel/FPS.cpp.func.html | 88 + coverage/funnel/FPS.cpp.gcov.html | 395 + coverage/funnel/Funnel.cpp.func-sort-c.html | 92 + coverage/funnel/Funnel.cpp.func.html | 92 + coverage/funnel/Funnel.cpp.gcov.html | 528 + coverage/funnel/index-sort-f.html | 103 + coverage/funnel/index-sort-l.html | 103 + coverage/funnel/index.html | 103 + coverage/gcov.css | 519 + .../generic/Accumulate.cpp.func-sort-c.html | 108 + coverage/generic/Accumulate.cpp.func.html | 108 + coverage/generic/Accumulate.cpp.gcov.html | 196 + coverage/generic/Average.cpp.func-sort-c.html | 84 + coverage/generic/Average.cpp.func.html | 84 + coverage/generic/Average.cpp.gcov.html | 225 + coverage/generic/Collect.cpp.func-sort-c.html | 108 + coverage/generic/Collect.cpp.func.html | 108 + coverage/generic/Collect.cpp.gcov.html | 212 + .../generic/Committor.cpp.func-sort-c.html | 92 + coverage/generic/Committor.cpp.func.html | 92 + coverage/generic/Committor.cpp.gcov.html | 267 + .../generic/Constant.cpp.func-sort-c.html | 100 + coverage/generic/Constant.cpp.func.html | 100 + coverage/generic/Constant.cpp.gcov.html | 229 + .../generic/CreateMask.cpp.func-sort-c.html | 100 + coverage/generic/CreateMask.cpp.func.html | 100 + coverage/generic/CreateMask.cpp.gcov.html | 203 + coverage/generic/Debug.cpp.func-sort-c.html | 92 + coverage/generic/Debug.cpp.func.html | 92 + coverage/generic/Debug.cpp.gcov.html | 216 + .../generic/DumpAtoms.cpp.func-sort-c.html | 124 + coverage/generic/DumpAtoms.cpp.func.html | 124 + coverage/generic/DumpAtoms.cpp.gcov.html | 438 + .../DumpDerivatives.cpp.func-sort-c.html | 108 + .../generic/DumpDerivatives.cpp.func.html | 108 + .../generic/DumpDerivatives.cpp.gcov.html | 211 + .../generic/DumpForces.cpp.func-sort-c.html | 108 + coverage/generic/DumpForces.cpp.func.html | 108 + coverage/generic/DumpForces.cpp.gcov.html | 195 + .../DumpMassCharge.cpp.func-sort-c.html | 116 + coverage/generic/DumpMassCharge.cpp.func.html | 116 + coverage/generic/DumpMassCharge.cpp.gcov.html | 262 + coverage/generic/DumpPDB.cpp.func-sort-c.html | 104 + coverage/generic/DumpPDB.cpp.func.html | 104 + coverage/generic/DumpPDB.cpp.gcov.html | 273 + .../DumpProjections.cpp.func-sort-c.html | 112 + .../generic/DumpProjections.cpp.func.html | 112 + .../generic/DumpProjections.cpp.gcov.html | 196 + .../generic/DumpVector.cpp.func-sort-c.html | 108 + coverage/generic/DumpVector.cpp.func.html | 108 + coverage/generic/DumpVector.cpp.gcov.html | 209 + .../EffectiveEnergyDrift.cpp.func-sort-c.html | 108 + .../EffectiveEnergyDrift.cpp.func.html | 108 + .../EffectiveEnergyDrift.cpp.gcov.html | 447 + .../generic/EndPlumed.cpp.func-sort-c.html | 88 + coverage/generic/EndPlumed.cpp.func.html | 88 + coverage/generic/EndPlumed.cpp.gcov.html | 156 + .../FitToTemplate.cpp.func-sort-c.html | 100 + coverage/generic/FitToTemplate.cpp.func.html | 100 + coverage/generic/FitToTemplate.cpp.gcov.html | 460 + coverage/generic/Flush.cpp.func-sort-c.html | 92 + coverage/generic/Flush.cpp.func.html | 92 + coverage/generic/Flush.cpp.gcov.html | 167 + .../GatherReplicas.cpp.func-sort-c.html | 96 + coverage/generic/GatherReplicas.cpp.func.html | 96 + coverage/generic/GatherReplicas.cpp.gcov.html | 190 + coverage/generic/Include.cpp.func-sort-c.html | 92 + coverage/generic/Include.cpp.func.html | 92 + coverage/generic/Include.cpp.gcov.html | 255 + .../MassChargeInput.cpp.func-sort-c.html | 84 + .../generic/MassChargeInput.cpp.func.html | 84 + .../generic/MassChargeInput.cpp.gcov.html | 184 + coverage/generic/Ones.cpp.func-sort-c.html | 84 + coverage/generic/Ones.cpp.func.html | 84 + coverage/generic/Ones.cpp.gcov.html | 138 + .../generic/PDB2Constant.cpp.func-sort-c.html | 84 + coverage/generic/PDB2Constant.cpp.func.html | 84 + coverage/generic/PDB2Constant.cpp.gcov.html | 196 + coverage/generic/Plumed.cpp.func-sort-c.html | 120 + coverage/generic/Plumed.cpp.func.html | 120 + coverage/generic/Plumed.cpp.gcov.html | 493 + coverage/generic/Print.cpp.func-sort-c.html | 116 + coverage/generic/Print.cpp.func.html | 116 + coverage/generic/Print.cpp.gcov.html | 263 + .../generic/PrintNDX.cpp.func-sort-c.html | 124 + coverage/generic/PrintNDX.cpp.func.html | 124 + coverage/generic/PrintNDX.cpp.gcov.html | 221 + .../RandomExchanges.cpp.func-sort-c.html | 88 + .../generic/RandomExchanges.cpp.func.html | 88 + .../generic/RandomExchanges.cpp.gcov.html | 178 + coverage/generic/Read.cpp.func-sort-c.html | 120 + coverage/generic/Read.cpp.func.html | 120 + coverage/generic/Read.cpp.gcov.html | 340 + .../generic/ResetCell.cpp.func-sort-c.html | 92 + coverage/generic/ResetCell.cpp.func.html | 92 + coverage/generic/ResetCell.cpp.gcov.html | 283 + coverage/generic/Time.cpp.func-sort-c.html | 96 + coverage/generic/Time.cpp.func.html | 96 + coverage/generic/Time.cpp.gcov.html | 156 + .../generic/UpdateIf.cpp.func-sort-c.html | 112 + coverage/generic/UpdateIf.cpp.func.html | 112 + coverage/generic/UpdateIf.cpp.gcov.html | 234 + .../WholeMolecules.cpp.func-sort-c.html | 96 + coverage/generic/WholeMolecules.cpp.func.html | 96 + coverage/generic/WholeMolecules.cpp.gcov.html | 345 + .../generic/WrapAround.cpp.func-sort-c.html | 96 + coverage/generic/WrapAround.cpp.func.html | 96 + coverage/generic/WrapAround.cpp.gcov.html | 333 + coverage/generic/index-sort-f.html | 413 + coverage/generic/index-sort-l.html | 413 + coverage/generic/index.html | 413 + coverage/glass.png | Bin 0 -> 167 bytes .../ActionWithGrid.cpp.func-sort-c.html | 92 + .../gridtools/ActionWithGrid.cpp.func.html | 92 + .../gridtools/ActionWithGrid.cpp.gcov.html | 131 + .../ConvertToFES.cpp.func-sort-c.html | 84 + coverage/gridtools/ConvertToFES.cpp.func.html | 84 + coverage/gridtools/ConvertToFES.cpp.gcov.html | 175 + .../gridtools/DumpGrid.cpp.func-sort-c.html | 104 + coverage/gridtools/DumpGrid.cpp.func.html | 104 + coverage/gridtools/DumpGrid.cpp.gcov.html | 425 + ...valuateFunctionOnGrid.cpp.func-sort-c.html | 84 + .../EvaluateFunctionOnGrid.cpp.func.html | 84 + .../EvaluateFunctionOnGrid.cpp.gcov.html | 185 + .../EvaluateGridFunction.cpp.func-sort-c.html | 96 + .../EvaluateGridFunction.cpp.func.html | 96 + .../EvaluateGridFunction.cpp.gcov.html | 228 + .../EvaluateGridFunction.h.func-sort-c.html | 76 + .../EvaluateGridFunction.h.func.html | 76 + .../EvaluateGridFunction.h.gcov.html | 167 + .../FindGridOptimum.cpp.func-sort-c.html | 112 + .../gridtools/FindGridOptimum.cpp.func.html | 112 + .../gridtools/FindGridOptimum.cpp.gcov.html | 227 + .../FunctionOfGrid.h.func-sort-c.html | 152 + coverage/gridtools/FunctionOfGrid.h.func.html | 152 + coverage/gridtools/FunctionOfGrid.h.gcov.html | 309 + .../gridtools/Gradient.cpp.func-sort-c.html | 84 + coverage/gridtools/Gradient.cpp.func.html | 84 + coverage/gridtools/Gradient.cpp.gcov.html | 182 + ...GridCoordinatesObject.cpp.func-sort-c.html | 152 + .../GridCoordinatesObject.cpp.func.html | 152 + .../GridCoordinatesObject.cpp.gcov.html | 413 + .../GridCoordinatesObject.h.func-sort-c.html | 80 + .../GridCoordinatesObject.h.func.html | 80 + .../GridCoordinatesObject.h.gcov.html | 243 + .../gridtools/GridSearch.h.func-sort-c.html | 84 + coverage/gridtools/GridSearch.h.func.html | 84 + coverage/gridtools/GridSearch.h.gcov.html | 193 + .../gridtools/Histogram.cpp.func-sort-c.html | 84 + coverage/gridtools/Histogram.cpp.func.html | 84 + coverage/gridtools/Histogram.cpp.gcov.html | 340 + .../InterpolateGrid.cpp.func-sort-c.html | 112 + .../gridtools/InterpolateGrid.cpp.func.html | 112 + .../gridtools/InterpolateGrid.cpp.gcov.html | 258 + .../Interpolator.cpp.func-sort-c.html | 76 + coverage/gridtools/Interpolator.cpp.func.html | 76 + coverage/gridtools/Interpolator.cpp.gcov.html | 151 + .../gridtools/Interpolator.h.func-sort-c.html | 72 + coverage/gridtools/Interpolator.h.func.html | 72 + coverage/gridtools/Interpolator.h.gcov.html | 120 + coverage/gridtools/KDE.cpp.func-sort-c.html | 148 + coverage/gridtools/KDE.cpp.func.html | 148 + coverage/gridtools/KDE.cpp.gcov.html | 654 + .../gridtools/KLEntropy.cpp.func-sort-c.html | 84 + coverage/gridtools/KLEntropy.cpp.func.html | 84 + coverage/gridtools/KLEntropy.cpp.gcov.html | 146 + .../MultiColvarDensity.cpp.func-sort-c.html | 84 + .../MultiColvarDensity.cpp.func.html | 84 + .../MultiColvarDensity.cpp.gcov.html | 234 + .../PairEntropies.cpp.func-sort-c.html | 84 + .../gridtools/PairEntropies.cpp.func.html | 84 + .../gridtools/PairEntropies.cpp.gcov.html | 160 + .../PairEntropy.cpp.func-sort-c.html | 84 + coverage/gridtools/PairEntropy.cpp.func.html | 84 + coverage/gridtools/PairEntropy.cpp.gcov.html | 166 + coverage/gridtools/RDF.cpp.func-sort-c.html | 88 + coverage/gridtools/RDF.cpp.func.html | 88 + coverage/gridtools/RDF.cpp.gcov.html | 208 + .../ReadGridInSetup.cpp.func-sort-c.html | 108 + .../gridtools/ReadGridInSetup.cpp.func.html | 108 + .../gridtools/ReadGridInSetup.cpp.gcov.html | 360 + coverage/gridtools/index-sort-f.html | 313 + coverage/gridtools/index-sort-l.html | 313 + coverage/gridtools/index.html | 313 + coverage/index-sort-f.html | 583 + coverage/index-sort-l.html | 583 + coverage/index.html | 583 + .../isdb/CS2Backbone.cpp.func-sort-c.html | 164 + coverage/isdb/CS2Backbone.cpp.func.html | 164 + coverage/isdb/CS2Backbone.cpp.gcov.html | 1920 + coverage/isdb/Caliber.cpp.func-sort-c.html | 104 + coverage/isdb/Caliber.cpp.func.html | 104 + coverage/isdb/Caliber.cpp.gcov.html | 423 + coverage/isdb/EMMI.cpp.func-sort-c.html | 228 + coverage/isdb/EMMI.cpp.func.html | 228 + coverage/isdb/EMMI.cpp.gcov.html | 1822 + coverage/isdb/EMMIVox.cpp.func-sort-c.html | 176 + coverage/isdb/EMMIVox.cpp.func.html | 176 + coverage/isdb/EMMIVox.cpp.gcov.html | 1653 + .../isdb/FretEfficiency.cpp.func-sort-c.html | 88 + coverage/isdb/FretEfficiency.cpp.func.html | 88 + coverage/isdb/FretEfficiency.cpp.gcov.html | 232 + coverage/isdb/Jcoupling.cpp.func-sort-c.html | 92 + coverage/isdb/Jcoupling.cpp.func.html | 92 + coverage/isdb/Jcoupling.cpp.gcov.html | 469 + .../isdb/Metainference.cpp.func-sort-c.html | 180 + coverage/isdb/Metainference.cpp.func.html | 180 + coverage/isdb/Metainference.cpp.gcov.html | 1878 + .../MetainferenceBase.cpp.func-sort-c.html | 184 + coverage/isdb/MetainferenceBase.cpp.func.html | 184 + coverage/isdb/MetainferenceBase.cpp.gcov.html | 1635 + .../isdb/MetainferenceBase.h.func-sort-c.html | 116 + coverage/isdb/MetainferenceBase.h.func.html | 116 + coverage/isdb/MetainferenceBase.h.gcov.html | 462 + coverage/isdb/NOE.cpp.func-sort-c.html | 92 + coverage/isdb/NOE.cpp.func.html | 92 + coverage/isdb/NOE.cpp.gcov.html | 349 + coverage/isdb/PRE.cpp.func-sort-c.html | 92 + coverage/isdb/PRE.cpp.func.html | 92 + coverage/isdb/PRE.cpp.gcov.html | 415 + coverage/isdb/RDC.cpp.func-sort-c.html | 96 + coverage/isdb/RDC.cpp.func.html | 96 + coverage/isdb/RDC.cpp.gcov.html | 596 + coverage/isdb/Rescale.cpp.func-sort-c.html | 120 + coverage/isdb/Rescale.cpp.func.html | 120 + coverage/isdb/Rescale.cpp.gcov.html | 588 + coverage/isdb/SAXS.cpp.func-sort-c.html | 164 + coverage/isdb/SAXS.cpp.func.html | 164 + coverage/isdb/SAXS.cpp.gcov.html | 8730 +++++ coverage/isdb/Select.cpp.func-sort-c.html | 88 + coverage/isdb/Select.cpp.func.html | 88 + coverage/isdb/Select.cpp.gcov.html | 195 + coverage/isdb/Selector.cpp.func-sort-c.html | 88 + coverage/isdb/Selector.cpp.func.html | 88 + coverage/isdb/Selector.cpp.gcov.html | 168 + coverage/isdb/Shadow.cpp.func-sort-c.html | 92 + coverage/isdb/Shadow.cpp.func.html | 92 + coverage/isdb/Shadow.cpp.gcov.html | 301 + coverage/isdb/index-sort-f.html | 253 + coverage/isdb/index-sort-l.html | 253 + coverage/isdb/index.html | 253 + .../CollectFrames.cpp.func-sort-c.html | 88 + .../landmarks/CollectFrames.cpp.func.html | 88 + .../landmarks/CollectFrames.cpp.gcov.html | 218 + ...FarthestPointSampling.cpp.func-sort-c.html | 104 + .../FarthestPointSampling.cpp.func.html | 104 + .../FarthestPointSampling.cpp.gcov.html | 188 + .../LandmarkSelection.cpp.func-sort-c.html | 84 + .../landmarks/LandmarkSelection.cpp.func.html | 84 + .../landmarks/LandmarkSelection.cpp.gcov.html | 235 + .../landmarks/LogSumExp.cpp.func-sort-c.html | 84 + coverage/landmarks/LogSumExp.cpp.func.html | 84 + coverage/landmarks/LogSumExp.cpp.gcov.html | 153 + coverage/landmarks/index-sort-f.html | 123 + coverage/landmarks/index-sort-l.html | 123 + coverage/landmarks/index.html | 123 + coverage/logmfd/LogMFD.cpp.func-sort-c.html | 124 + coverage/logmfd/LogMFD.cpp.func.html | 124 + coverage/logmfd/LogMFD.cpp.gcov.html | 1315 + coverage/logmfd/index-sort-f.html | 93 + coverage/logmfd/index-sort-l.html | 93 + coverage/logmfd/index.html | 93 + coverage/main/index-sort-f.html | 93 + coverage/main/index-sort-l.html | 93 + coverage/main/index.html | 93 + coverage/main/main.cpp.func-sort-c.html | 76 + coverage/main/main.cpp.func.html | 76 + coverage/main/main.cpp.gcov.html | 147 + .../mapping/AdaptivePath.cpp.func-sort-c.html | 84 + coverage/mapping/AdaptivePath.cpp.func.html | 84 + coverage/mapping/AdaptivePath.cpp.gcov.html | 244 + .../GeometricPath.cpp.func-sort-c.html | 96 + coverage/mapping/GeometricPath.cpp.func.html | 96 + coverage/mapping/GeometricPath.cpp.gcov.html | 214 + ...GeometricPathShortcut.cpp.func-sort-c.html | 84 + .../GeometricPathShortcut.cpp.func.html | 84 + .../GeometricPathShortcut.cpp.gcov.html | 158 + coverage/mapping/PCAVars.cpp.func-sort-c.html | 84 + coverage/mapping/PCAVars.cpp.func.html | 84 + coverage/mapping/PCAVars.cpp.gcov.html | 376 + coverage/mapping/Path.cpp.func-sort-c.html | 100 + coverage/mapping/Path.cpp.func.html | 100 + coverage/mapping/Path.cpp.gcov.html | 423 + .../PathDisplacements.cpp.func-sort-c.html | 104 + .../mapping/PathDisplacements.cpp.func.html | 104 + .../mapping/PathDisplacements.cpp.gcov.html | 253 + ...hProjectionCalculator.cpp.func-sort-c.html | 104 + .../PathProjectionCalculator.cpp.func.html | 104 + .../PathProjectionCalculator.cpp.gcov.html | 219 + ...athReparameterization.cpp.func-sort-c.html | 112 + .../PathReparameterization.cpp.func.html | 112 + .../PathReparameterization.cpp.gcov.html | 305 + .../mapping/PathTools.cpp.func-sort-c.html | 104 + coverage/mapping/PathTools.cpp.func.html | 104 + coverage/mapping/PathTools.cpp.gcov.html | 536 + coverage/mapping/index-sort-f.html | 173 + coverage/mapping/index-sort-l.html | 173 + coverage/mapping/index.html | 173 + .../CovarianceMatrix.cpp.func-sort-c.html | 84 + .../CovarianceMatrix.cpp.func.html | 84 + .../CovarianceMatrix.cpp.gcov.html | 163 + .../Determinent.cpp.func-sort-c.html | 84 + .../matrixtools/Determinent.cpp.func.html | 84 + .../matrixtools/Determinent.cpp.gcov.html | 139 + .../DiagonalizeMatrix.cpp.func-sort-c.html | 100 + .../DiagonalizeMatrix.cpp.func.html | 100 + .../DiagonalizeMatrix.cpp.gcov.html | 229 + .../InvertMatrix.cpp.func-sort-c.html | 100 + .../matrixtools/InvertMatrix.cpp.func.html | 100 + .../matrixtools/InvertMatrix.cpp.gcov.html | 176 + .../MatrixOperationBase.cpp.func-sort-c.html | 92 + .../MatrixOperationBase.cpp.func.html | 92 + .../MatrixOperationBase.cpp.gcov.html | 158 + .../MatrixTimesMatrix.cpp.func-sort-c.html | 112 + .../MatrixTimesMatrix.cpp.func.html | 112 + .../MatrixTimesMatrix.cpp.gcov.html | 245 + .../MatrixTimesVector.cpp.func-sort-c.html | 120 + .../MatrixTimesVector.cpp.func.html | 120 + .../MatrixTimesVector.cpp.gcov.html | 323 + .../OuterProduct.cpp.func-sort-c.html | 108 + .../matrixtools/OuterProduct.cpp.func.html | 108 + .../matrixtools/OuterProduct.cpp.gcov.html | 237 + .../TransposeMatrix.cpp.func-sort-c.html | 104 + .../matrixtools/TransposeMatrix.cpp.func.html | 104 + .../matrixtools/TransposeMatrix.cpp.gcov.html | 209 + .../matrixtools/Voronoi.cpp.func-sort-c.html | 112 + coverage/matrixtools/Voronoi.cpp.func.html | 112 + coverage/matrixtools/Voronoi.cpp.gcov.html | 162 + coverage/matrixtools/index-sort-f.html | 183 + coverage/matrixtools/index-sort-l.html | 183 + coverage/matrixtools/index.html | 183 + coverage/maze/Loss.cpp.func-sort-c.html | 88 + coverage/maze/Loss.cpp.func.html | 88 + coverage/maze/Loss.cpp.gcov.html | 191 + coverage/maze/Loss.h.func-sort-c.html | 84 + coverage/maze/Loss.h.func.html | 84 + coverage/maze/Loss.h.gcov.html | 162 + coverage/maze/Member.h.func-sort-c.html | 80 + coverage/maze/Member.h.func.html | 80 + coverage/maze/Member.h.gcov.html | 142 + coverage/maze/Memetic.cpp.func-sort-c.html | 88 + coverage/maze/Memetic.cpp.func.html | 88 + coverage/maze/Memetic.cpp.gcov.html | 358 + coverage/maze/Memetic.h.func-sort-c.html | 152 + coverage/maze/Memetic.h.func.html | 152 + coverage/maze/Memetic.h.gcov.html | 882 + coverage/maze/Optimizer.cpp.func-sort-c.html | 112 + coverage/maze/Optimizer.cpp.func.html | 112 + coverage/maze/Optimizer.cpp.gcov.html | 584 + coverage/maze/Optimizer.h.func-sort-c.html | 76 + coverage/maze/Optimizer.h.func.html | 76 + coverage/maze/Optimizer.h.gcov.html | 433 + .../maze/Optimizer_Bias.cpp.func-sort-c.html | 96 + coverage/maze/Optimizer_Bias.cpp.func.html | 96 + coverage/maze/Optimizer_Bias.cpp.gcov.html | 508 + ...andom_Acceleration_MD.cpp.func-sort-c.html | 88 + .../maze/Random_Acceleration_MD.cpp.func.html | 88 + .../maze/Random_Acceleration_MD.cpp.gcov.html | 279 + coverage/maze/Random_MT.cpp.func-sort-c.html | 96 + coverage/maze/Random_MT.cpp.func.html | 96 + coverage/maze/Random_MT.cpp.gcov.html | 157 + coverage/maze/Random_MT.h.func-sort-c.html | 88 + coverage/maze/Random_MT.h.func.html | 88 + coverage/maze/Random_MT.h.gcov.html | 232 + .../maze/Random_Walk.cpp.func-sort-c.html | 88 + coverage/maze/Random_Walk.cpp.func.html | 88 + coverage/maze/Random_Walk.cpp.gcov.html | 200 + .../Simulated_Annealing.cpp.func-sort-c.html | 92 + .../maze/Simulated_Annealing.cpp.func.html | 92 + .../maze/Simulated_Annealing.cpp.gcov.html | 351 + coverage/maze/Steered_MD.cpp.func-sort-c.html | 88 + coverage/maze/Steered_MD.cpp.func.html | 88 + coverage/maze/Steered_MD.cpp.gcov.html | 252 + coverage/maze/Tools.h.func-sort-c.html | 88 + coverage/maze/Tools.h.func.html | 88 + coverage/maze/Tools.h.gcov.html | 256 + coverage/maze/index-sort-f.html | 233 + coverage/maze/index-sort-l.html | 233 + coverage/maze/index.html | 233 + .../FusionPoreExpansionP.cpp.func-sort-c.html | 88 + .../FusionPoreExpansionP.cpp.func.html | 88 + .../FusionPoreExpansionP.cpp.gcov.html | 682 + ...FusionPoreNucleationP.cpp.func-sort-c.html | 88 + .../FusionPoreNucleationP.cpp.func.html | 88 + .../FusionPoreNucleationP.cpp.gcov.html | 884 + .../MemFusionP.cpp.func-sort-c.html | 88 + .../membranefusion/MemFusionP.cpp.func.html | 88 + .../membranefusion/MemFusionP.cpp.gcov.html | 685 + coverage/membranefusion/index-sort-f.html | 113 + coverage/membranefusion/index-sort-l.html | 113 + coverage/membranefusion/index.html | 113 + coverage/metatensor/index-sort-f.html | 103 + coverage/metatensor/index-sort-l.html | 103 + coverage/metatensor/index.html | 103 + .../metatensor.cpp.func-sort-c.html | 92 + coverage/metatensor/metatensor.cpp.func.html | 92 + coverage/metatensor/metatensor.cpp.gcov.html | 1046 + .../metatensor/vesin.cpp.func-sort-c.html | 188 + coverage/metatensor/vesin.cpp.func.html | 188 + coverage/metatensor/vesin.cpp.gcov.html | 952 + .../AlphaBeta.cpp.func-sort-c.html | 84 + coverage/multicolvar/AlphaBeta.cpp.func.html | 84 + coverage/multicolvar/AlphaBeta.cpp.gcov.html | 187 + .../multicolvar/Angles.cpp.func-sort-c.html | 84 + coverage/multicolvar/Angles.cpp.func.html | 84 + coverage/multicolvar/Angles.cpp.gcov.html | 251 + .../CoordAngles.cpp.func-sort-c.html | 88 + .../multicolvar/CoordAngles.cpp.func.html | 88 + .../multicolvar/CoordAngles.cpp.gcov.html | 184 + .../multicolvar/Dihcor.cpp.func-sort-c.html | 84 + coverage/multicolvar/Dihcor.cpp.func.html | 84 + coverage/multicolvar/Dihcor.cpp.gcov.html | 183 + .../Distances.cpp.func-sort-c.html | 84 + coverage/multicolvar/Distances.cpp.func.html | 84 + coverage/multicolvar/Distances.cpp.gcov.html | 366 + .../DumpMultiColvar.cpp.func-sort-c.html | 84 + .../multicolvar/DumpMultiColvar.cpp.func.html | 84 + .../multicolvar/DumpMultiColvar.cpp.gcov.html | 141 + .../InPlaneDistances.cpp.func-sort-c.html | 84 + .../InPlaneDistances.cpp.func.html | 84 + .../InPlaneDistances.cpp.gcov.html | 157 + .../MFilterLess.cpp.func-sort-c.html | 84 + .../multicolvar/MFilterLess.cpp.func.html | 84 + .../multicolvar/MFilterLess.cpp.gcov.html | 144 + .../MFilterMore.cpp.func-sort-c.html | 84 + .../multicolvar/MFilterMore.cpp.func.html | 84 + .../multicolvar/MFilterMore.cpp.gcov.html | 154 + .../MultiColvarShortcuts.cpp.func-sort-c.html | 92 + .../MultiColvarShortcuts.cpp.func.html | 92 + .../MultiColvarShortcuts.cpp.gcov.html | 327 + .../multicolvar/Planes.cpp.func-sort-c.html | 88 + coverage/multicolvar/Planes.cpp.func.html | 88 + coverage/multicolvar/Planes.cpp.gcov.html | 188 + .../multicolvar/Torsions.cpp.func-sort-c.html | 84 + coverage/multicolvar/Torsions.cpp.func.html | 84 + coverage/multicolvar/Torsions.cpp.gcov.html | 173 + .../multicolvar/UWalls.cpp.func-sort-c.html | 84 + coverage/multicolvar/UWalls.cpp.func.html | 84 + coverage/multicolvar/UWalls.cpp.gcov.html | 150 + .../multicolvar/XAngle.cpp.func-sort-c.html | 84 + coverage/multicolvar/XAngle.cpp.func.html | 84 + coverage/multicolvar/XAngle.cpp.gcov.html | 178 + .../XYTorsions.cpp.func-sort-c.html | 84 + coverage/multicolvar/XYTorsions.cpp.func.html | 84 + coverage/multicolvar/XYTorsions.cpp.gcov.html | 226 + coverage/multicolvar/index-sort-f.html | 233 + coverage/multicolvar/index-sort-l.html | 233 + coverage/multicolvar/index.html | 233 + coverage/opes/ECVcustom.cpp.func-sort-c.html | 116 + coverage/opes/ECVcustom.cpp.func.html | 116 + coverage/opes/ECVcustom.cpp.gcov.html | 314 + coverage/opes/ECVlinear.cpp.func-sort-c.html | 112 + coverage/opes/ECVlinear.cpp.func.html | 112 + coverage/opes/ECVlinear.cpp.gcov.html | 344 + .../opes/ECVmultiThermal.cpp.func-sort-c.html | 112 + coverage/opes/ECVmultiThermal.cpp.func.html | 112 + coverage/opes/ECVmultiThermal.cpp.gcov.html | 344 + .../ECVmultiThermalBaric.cpp.func-sort-c.html | 120 + .../opes/ECVmultiThermalBaric.cpp.func.html | 120 + .../opes/ECVmultiThermalBaric.cpp.gcov.html | 606 + .../ECVumbrellasFile.cpp.func-sort-c.html | 112 + coverage/opes/ECVumbrellasFile.cpp.func.html | 112 + coverage/opes/ECVumbrellasFile.cpp.gcov.html | 371 + .../ECVumbrellasLine.cpp.func-sort-c.html | 112 + coverage/opes/ECVumbrellasLine.cpp.func.html | 112 + coverage/opes/ECVumbrellasLine.cpp.gcov.html | 377 + .../opes/ExpansionCVs.cpp.func-sort-c.html | 116 + coverage/opes/ExpansionCVs.cpp.func.html | 116 + coverage/opes/ExpansionCVs.cpp.gcov.html | 302 + coverage/opes/ExpansionCVs.h.func-sort-c.html | 84 + coverage/opes/ExpansionCVs.h.func.html | 84 + coverage/opes/ExpansionCVs.h.gcov.html | 149 + .../opes/OPESexpanded.cpp.func-sort-c.html | 124 + coverage/opes/OPESexpanded.cpp.func.html | 124 + coverage/opes/OPESexpanded.cpp.gcov.html | 1019 + coverage/opes/OPESmetad.cpp.func-sort-c.html | 184 + coverage/opes/OPESmetad.cpp.func.html | 184 + coverage/opes/OPESmetad.cpp.gcov.html | 1828 + coverage/opes/index-sort-f.html | 183 + coverage/opes/index-sort-l.html | 183 + coverage/opes/index.html | 183 + .../pamm/HBPammMatrix.cpp.func-sort-c.html | 100 + coverage/pamm/HBPammMatrix.cpp.func.html | 100 + coverage/pamm/HBPammMatrix.cpp.gcov.html | 334 + coverage/pamm/PAMM.cpp.func-sort-c.html | 84 + coverage/pamm/PAMM.cpp.func.html | 84 + coverage/pamm/PAMM.cpp.gcov.html | 263 + coverage/pamm/index-sort-f.html | 103 + coverage/pamm/index-sort-l.html | 103 + coverage/pamm/index.html | 103 + coverage/piv/PIV.cpp.func-sort-c.html | 92 + coverage/piv/PIV.cpp.func.html | 92 + coverage/piv/PIV.cpp.gcov.html | 1340 + coverage/piv/index-sort-f.html | 93 + coverage/piv/index-sort-l.html | 93 + coverage/piv/index.html | 93 + .../pytorch/PytorchModel.cpp.func-sort-c.html | 92 + coverage/pytorch/PytorchModel.cpp.func.html | 92 + coverage/pytorch/PytorchModel.cpp.gcov.html | 320 + coverage/pytorch/index-sort-f.html | 93 + coverage/pytorch/index-sort-l.html | 93 + coverage/pytorch/index.html | 93 + .../refdist/Difference.cpp.func-sort-c.html | 88 + coverage/refdist/Difference.cpp.func.html | 88 + coverage/refdist/Difference.cpp.gcov.html | 199 + .../refdist/Displacement.cpp.func-sort-c.html | 92 + coverage/refdist/Displacement.cpp.func.html | 92 + coverage/refdist/Displacement.cpp.gcov.html | 174 + .../EuclideanDistance.cpp.func-sort-c.html | 84 + .../refdist/EuclideanDistance.cpp.func.html | 84 + .../refdist/EuclideanDistance.cpp.gcov.html | 157 + coverage/refdist/Kernel.cpp.func-sort-c.html | 88 + coverage/refdist/Kernel.cpp.func.html | 88 + coverage/refdist/Kernel.cpp.gcov.html | 290 + .../MahalanobisDistance.cpp.func-sort-c.html | 84 + .../refdist/MahalanobisDistance.cpp.func.html | 84 + .../refdist/MahalanobisDistance.cpp.gcov.html | 209 + ...MatrixProductDiagonal.cpp.func-sort-c.html | 96 + .../MatrixProductDiagonal.cpp.func.html | 96 + .../MatrixProductDiagonal.cpp.gcov.html | 216 + ...izedEuclideanDistance.cpp.func-sort-c.html | 84 + .../NormalizedEuclideanDistance.cpp.func.html | 84 + .../NormalizedEuclideanDistance.cpp.gcov.html | 166 + coverage/refdist/index-sort-f.html | 153 + coverage/refdist/index-sort-l.html | 153 + coverage/refdist/index.html | 153 + coverage/ruby.png | Bin 0 -> 141 bytes .../s2cm/S2ContactModel.cpp.func-sort-c.html | 104 + coverage/s2cm/S2ContactModel.cpp.func.html | 104 + coverage/s2cm/S2ContactModel.cpp.gcov.html | 402 + coverage/s2cm/index-sort-f.html | 93 + coverage/s2cm/index-sort-l.html | 93 + coverage/s2cm/index.html | 93 + coverage/sasa/index-sort-f.html | 103 + coverage/sasa/index-sort-l.html | 103 + coverage/sasa/index.html | 103 + coverage/sasa/sasa_HASEL.cpp.func-sort-c.html | 124 + coverage/sasa/sasa_HASEL.cpp.func.html | 124 + coverage/sasa/sasa_HASEL.cpp.gcov.html | 1089 + coverage/sasa/sasa_LCPO.cpp.func-sort-c.html | 124 + coverage/sasa/sasa_LCPO.cpp.func.html | 124 + coverage/sasa/sasa_LCPO.cpp.gcov.html | 1157 + .../AlphaRMSD.cpp.func-sort-c.html | 84 + .../AlphaRMSD.cpp.func.html | 84 + .../AlphaRMSD.cpp.gcov.html | 251 + .../AntibetaRMSD.cpp.func-sort-c.html | 84 + .../AntibetaRMSD.cpp.func.html | 84 + .../AntibetaRMSD.cpp.gcov.html | 309 + .../ParabetaRMSD.cpp.func-sort-c.html | 84 + .../ParabetaRMSD.cpp.func.html | 84 + .../ParabetaRMSD.cpp.gcov.html | 355 + ...econdaryStructureRMSD.cpp.func-sort-c.html | 112 + .../SecondaryStructureRMSD.cpp.func.html | 112 + .../SecondaryStructureRMSD.cpp.gcov.html | 405 + .../SecondaryStructureRMSD.h.func-sort-c.html | 76 + .../SecondaryStructureRMSD.h.func.html | 76 + .../SecondaryStructureRMSD.h.gcov.html | 161 + coverage/secondarystructure/index-sort-f.html | 133 + coverage/secondarystructure/index-sort-l.html | 133 + coverage/secondarystructure/index.html | 133 + coverage/setup/Load.cpp.func-sort-c.html | 84 + coverage/setup/Load.cpp.func.html | 84 + coverage/setup/Load.cpp.gcov.html | 222 + coverage/setup/Restart.cpp.func-sort-c.html | 84 + coverage/setup/Restart.cpp.func.html | 84 + coverage/setup/Restart.cpp.gcov.html | 201 + coverage/setup/Units.cpp.func-sort-c.html | 84 + coverage/setup/Units.cpp.func.html | 84 + coverage/setup/Units.cpp.gcov.html | 274 + coverage/setup/index-sort-f.html | 113 + coverage/setup/index-sort-l.html | 113 + coverage/setup/index.html | 113 + coverage/sizeshape/index-sort-f.html | 103 + coverage/sizeshape/index-sort-l.html | 103 + coverage/sizeshape/index.html | 103 + .../sizeshape/mahadist.cpp.func-sort-c.html | 112 + coverage/sizeshape/mahadist.cpp.func.html | 112 + coverage/sizeshape/mahadist.cpp.gcov.html | 525 + .../sizeshape/pos_proj.cpp.func-sort-c.html | 108 + coverage/sizeshape/pos_proj.cpp.func.html | 108 + coverage/sizeshape/pos_proj.cpp.gcov.html | 535 + coverage/small_vector/index-sort-f.html | 93 + coverage/small_vector/index-sort-l.html | 93 + coverage/small_vector/index.html | 93 + .../small_vector.h.func-sort-c.html | 244 + .../small_vector/small_vector.h.func.html | 244 + .../small_vector/small_vector.h.gcov.html | 6559 ++++ coverage/snow.png | Bin 0 -> 141 bytes coverage/sprint/Sprint.cpp.func-sort-c.html | 84 + coverage/sprint/Sprint.cpp.func.html | 84 + coverage/sprint/Sprint.cpp.gcov.html | 219 + coverage/sprint/index-sort-f.html | 93 + coverage/sprint/index-sort-l.html | 93 + coverage/sprint/index.html | 93 + .../symfunc/AngularTetra.cpp.func-sort-c.html | 84 + coverage/symfunc/AngularTetra.cpp.func.html | 84 + coverage/symfunc/AngularTetra.cpp.gcov.html | 161 + .../symfunc/AtomicSMAC.cpp.func-sort-c.html | 84 + coverage/symfunc/AtomicSMAC.cpp.func.html | 84 + coverage/symfunc/AtomicSMAC.cpp.gcov.html | 187 + ...rdShellVectorFunction.cpp.func-sort-c.html | 84 + .../CoordShellVectorFunction.cpp.func.html | 84 + .../CoordShellVectorFunction.cpp.gcov.html | 306 + .../CoordinationNumbers.cpp.func-sort-c.html | 92 + .../symfunc/CoordinationNumbers.cpp.func.html | 92 + .../symfunc/CoordinationNumbers.cpp.gcov.html | 271 + .../CylindricalHarmonic.cpp.func-sort-c.html | 88 + .../symfunc/CylindricalHarmonic.cpp.func.html | 88 + .../symfunc/CylindricalHarmonic.cpp.gcov.html | 173 + coverage/symfunc/Fccubic.cpp.func-sort-c.html | 84 + coverage/symfunc/Fccubic.cpp.func.html | 84 + coverage/symfunc/Fccubic.cpp.gcov.html | 226 + .../HexaticParameter.cpp.func-sort-c.html | 88 + .../symfunc/HexaticParameter.cpp.func.html | 88 + .../symfunc/HexaticParameter.cpp.gcov.html | 206 + .../symfunc/LocalAverage.cpp.func-sort-c.html | 88 + coverage/symfunc/LocalAverage.cpp.func.html | 88 + coverage/symfunc/LocalAverage.cpp.gcov.html | 246 + .../LocalCrystalinity.cpp.func-sort-c.html | 84 + .../symfunc/LocalCrystalinity.cpp.func.html | 84 + .../symfunc/LocalCrystalinity.cpp.gcov.html | 182 + .../LocalSteinhardt.cpp.func-sort-c.html | 92 + .../symfunc/LocalSteinhardt.cpp.func.html | 92 + .../symfunc/LocalSteinhardt.cpp.gcov.html | 521 + .../symfunc/RadialTetra.cpp.func-sort-c.html | 84 + coverage/symfunc/RadialTetra.cpp.func.html | 84 + coverage/symfunc/RadialTetra.cpp.gcov.html | 177 + coverage/symfunc/SMAC.cpp.func-sort-c.html | 84 + coverage/symfunc/SMAC.cpp.func.html | 84 + coverage/symfunc/SMAC.cpp.gcov.html | 199 + .../SphericalHarmonic.cpp.func-sort-c.html | 104 + .../symfunc/SphericalHarmonic.cpp.func.html | 104 + .../symfunc/SphericalHarmonic.cpp.gcov.html | 313 + .../symfunc/Steinhardt.cpp.func-sort-c.html | 92 + coverage/symfunc/Steinhardt.cpp.func.html | 92 + coverage/symfunc/Steinhardt.cpp.gcov.html | 468 + .../ThreeBodyGFunctions.cpp.func-sort-c.html | 100 + .../symfunc/ThreeBodyGFunctions.cpp.func.html | 100 + .../symfunc/ThreeBodyGFunctions.cpp.gcov.html | 263 + coverage/symfunc/index-sort-f.html | 233 + coverage/symfunc/index-sort-l.html | 233 + coverage/symfunc/index.html | 233 + coverage/tools/Angle.cpp.func-sort-c.html | 80 + coverage/tools/Angle.cpp.func.html | 80 + coverage/tools/Angle.cpp.gcov.html | 144 + coverage/tools/AtomNumber.h.func-sort-c.html | 80 + coverage/tools/AtomNumber.h.func.html | 80 + coverage/tools/AtomNumber.h.gcov.html | 228 + .../BiasRepresentation.cpp.func-sort-c.html | 148 + .../tools/BiasRepresentation.cpp.func.html | 148 + .../tools/BiasRepresentation.cpp.gcov.html | 363 + .../Brent1DRootSearch.h.func-sort-c.html | 108 + coverage/tools/Brent1DRootSearch.h.func.html | 108 + coverage/tools/Brent1DRootSearch.h.gcov.html | 196 + .../tools/CheckInRange.cpp.func-sort-c.html | 88 + coverage/tools/CheckInRange.cpp.func.html | 88 + coverage/tools/CheckInRange.cpp.gcov.html | 164 + .../tools/CheckInRange.h.func-sort-c.html | 72 + coverage/tools/CheckInRange.h.func.html | 72 + coverage/tools/CheckInRange.h.gcov.html | 120 + coverage/tools/Citations.cpp.func-sort-c.html | 88 + coverage/tools/Citations.cpp.func.html | 88 + coverage/tools/Citations.cpp.gcov.html | 132 + coverage/tools/Citations.h.func-sort-c.html | 72 + coverage/tools/Citations.h.func.html | 72 + coverage/tools/Citations.h.gcov.html | 150 + .../tools/Communicator.cpp.func-sort-c.html | 216 + coverage/tools/Communicator.cpp.func.html | 216 + coverage/tools/Communicator.cpp.gcov.html | 394 + .../tools/Communicator.h.func-sort-c.html | 312 + coverage/tools/Communicator.h.func.html | 312 + coverage/tools/Communicator.h.gcov.html | 328 + .../ConjugateGradient.h.func-sort-c.html | 84 + coverage/tools/ConjugateGradient.h.func.html | 84 + coverage/tools/ConjugateGradient.h.gcov.html | 142 + coverage/tools/DLLoader.cpp.func-sort-c.html | 104 + coverage/tools/DLLoader.cpp.func.html | 104 + coverage/tools/DLLoader.cpp.gcov.html | 216 + coverage/tools/ERMSD.cpp.func-sort-c.html | 92 + coverage/tools/ERMSD.cpp.func.html | 92 + coverage/tools/ERMSD.cpp.gcov.html | 379 + coverage/tools/ERMSD.h.func-sort-c.html | 72 + coverage/tools/ERMSD.h.func.html | 72 + coverage/tools/ERMSD.h.gcov.html | 149 + coverage/tools/Exception.cpp.func-sort-c.html | 96 + coverage/tools/Exception.cpp.func.html | 96 + coverage/tools/Exception.cpp.gcov.html | 232 + coverage/tools/Exception.h.func-sort-c.html | 628 + coverage/tools/Exception.h.func.html | 628 + coverage/tools/Exception.h.gcov.html | 479 + coverage/tools/FileBase.cpp.func-sort-c.html | 132 + coverage/tools/FileBase.cpp.func.html | 132 + coverage/tools/FileBase.cpp.gcov.html | 251 + coverage/tools/FileBase.h.func-sort-c.html | 72 + coverage/tools/FileBase.h.func.html | 72 + coverage/tools/FileBase.h.gcov.html | 228 + coverage/tools/ForwardDecl.h.func-sort-c.html | 124 + coverage/tools/ForwardDecl.h.func.html | 124 + coverage/tools/ForwardDecl.h.gcov.html | 131 + coverage/tools/Grid.cpp.func-sort-c.html | 712 + coverage/tools/Grid.cpp.func.html | 712 + coverage/tools/Grid.cpp.gcov.html | 1189 + coverage/tools/Grid.h.func-sort-c.html | 172 + coverage/tools/Grid.h.func.html | 172 + coverage/tools/Grid.h.gcov.html | 695 + .../tools/HistogramBead.cpp.func-sort-c.html | 116 + coverage/tools/HistogramBead.cpp.func.html | 116 + coverage/tools/HistogramBead.cpp.gcov.html | 341 + .../tools/HistogramBead.h.func-sort-c.html | 80 + coverage/tools/HistogramBead.h.func.html | 80 + coverage/tools/HistogramBead.h.gcov.html | 190 + coverage/tools/IFile.cpp.func-sort-c.html | 172 + coverage/tools/IFile.cpp.func.html | 172 + coverage/tools/IFile.cpp.gcov.html | 371 + coverage/tools/IFile.h.func-sort-c.html | 72 + coverage/tools/IFile.h.func.html | 72 + coverage/tools/IFile.h.gcov.html | 193 + .../KernelFunctions.cpp.func-sort-c.html | 112 + coverage/tools/KernelFunctions.cpp.func.html | 112 + coverage/tools/KernelFunctions.cpp.gcov.html | 531 + .../tools/KernelFunctions.h.func-sort-c.html | 76 + coverage/tools/KernelFunctions.h.func.html | 76 + coverage/tools/KernelFunctions.h.gcov.html | 173 + coverage/tools/Keywords.cpp.func-sort-c.html | 264 + coverage/tools/Keywords.cpp.func.html | 264 + coverage/tools/Keywords.cpp.gcov.html | 795 + coverage/tools/Keywords.h.func-sort-c.html | 80 + coverage/tools/Keywords.h.func.html | 80 + coverage/tools/Keywords.h.gcov.html | 282 + .../LatticeReduction.cpp.func-sort-c.html | 112 + coverage/tools/LatticeReduction.cpp.func.html | 112 + coverage/tools/LatticeReduction.cpp.gcov.html | 291 + .../tools/LeptonCall.cpp.func-sort-c.html | 84 + coverage/tools/LeptonCall.cpp.func.html | 84 + coverage/tools/LeptonCall.cpp.gcov.html | 167 + coverage/tools/LeptonCall.h.func-sort-c.html | 72 + coverage/tools/LeptonCall.h.func.html | 72 + coverage/tools/LeptonCall.h.gcov.html | 134 + coverage/tools/LinkCells.cpp.func-sort-c.html | 116 + coverage/tools/LinkCells.cpp.func.html | 116 + coverage/tools/LinkCells.cpp.gcov.html | 258 + coverage/tools/LinkCells.h.func-sort-c.html | 72 + coverage/tools/LinkCells.h.func.html | 72 + coverage/tools/LinkCells.h.gcov.html | 177 + .../tools/LoopUnroller.h.func-sort-c.html | 284 + coverage/tools/LoopUnroller.h.func.html | 284 + coverage/tools/LoopUnroller.h.gcov.html | 236 + coverage/tools/Matrix.h.func-sort-c.html | 112 + coverage/tools/Matrix.h.func.html | 112 + coverage/tools/Matrix.h.gcov.html | 490 + ...rixSquareBracketsAccess.h.func-sort-c.html | 144 + .../MatrixSquareBracketsAccess.h.func.html | 144 + .../MatrixSquareBracketsAccess.h.gcov.html | 214 + .../tools/MergeVectorTools.h.func-sort-c.html | 80 + coverage/tools/MergeVectorTools.h.func.html | 80 + coverage/tools/MergeVectorTools.h.gcov.html | 211 + .../tools/Minimise1DBrent.h.func-sort-c.html | 120 + coverage/tools/Minimise1DBrent.h.func.html | 120 + coverage/tools/Minimise1DBrent.h.gcov.html | 271 + .../tools/MinimiseBase.h.func-sort-c.html | 144 + coverage/tools/MinimiseBase.h.func.html | 144 + coverage/tools/MinimiseBase.h.gcov.html | 191 + .../tools/MolDataClass.cpp.func-sort-c.html | 92 + coverage/tools/MolDataClass.cpp.func.html | 92 + coverage/tools/MolDataClass.cpp.gcov.html | 663 + .../tools/MultiValue.cpp.func-sort-c.html | 88 + coverage/tools/MultiValue.cpp.func.html | 88 + coverage/tools/MultiValue.cpp.gcov.html | 176 + coverage/tools/MultiValue.h.func-sort-c.html | 88 + coverage/tools/MultiValue.h.func.html | 88 + coverage/tools/MultiValue.h.gcov.html | 436 + .../tools/NeighborList.cpp.func-sort-c.html | 136 + coverage/tools/NeighborList.cpp.func.html | 136 + coverage/tools/NeighborList.cpp.gcov.html | 370 + .../tools/NeighborList.h.func-sort-c.html | 72 + coverage/tools/NeighborList.h.func.html | 72 + coverage/tools/NeighborList.h.gcov.html | 188 + coverage/tools/OFile.cpp.func-sort-c.html | 192 + coverage/tools/OFile.cpp.func.html | 192 + coverage/tools/OFile.cpp.gcov.html | 512 + coverage/tools/OFile.h.func-sort-c.html | 504 + coverage/tools/OFile.h.func.html | 504 + coverage/tools/OFile.h.gcov.html | 362 + coverage/tools/OpenMP.cpp.func-sort-c.html | 88 + coverage/tools/OpenMP.cpp.func.html | 88 + coverage/tools/OpenMP.cpp.gcov.html | 158 + coverage/tools/OpenMP.h.func-sort-c.html | 84 + coverage/tools/OpenMP.h.func.html | 84 + coverage/tools/OpenMP.h.gcov.html | 148 + coverage/tools/PDB.cpp.func-sort-c.html | 248 + coverage/tools/PDB.cpp.func.html | 248 + coverage/tools/PDB.cpp.gcov.html | 835 + coverage/tools/Pbc.cpp.func-sort-c.html | 124 + coverage/tools/Pbc.cpp.func.html | 124 + coverage/tools/Pbc.cpp.gcov.html | 367 + coverage/tools/Pbc.h.func-sort-c.html | 72 + coverage/tools/Pbc.h.func.html | 72 + coverage/tools/Pbc.h.gcov.html | 224 + .../tools/PlumedHandle.cpp.func-sort-c.html | 104 + coverage/tools/PlumedHandle.cpp.func.html | 104 + coverage/tools/PlumedHandle.cpp.gcov.html | 208 + coverage/tools/RMSD.cpp.func-sort-c.html | 392 + coverage/tools/RMSD.cpp.func.html | 392 + coverage/tools/RMSD.cpp.gcov.html | 1548 + coverage/tools/RMSD.h.func-sort-c.html | 108 + coverage/tools/RMSD.h.func.html | 108 + coverage/tools/RMSD.h.gcov.html | 452 + coverage/tools/Random.cpp.func-sort-c.html | 116 + coverage/tools/Random.cpp.func.html | 116 + coverage/tools/Random.cpp.gcov.html | 245 + coverage/tools/Random.h.func-sort-c.html | 72 + coverage/tools/Random.h.func.html | 72 + coverage/tools/Random.h.gcov.html | 148 + .../tools/RootFindingBase.h.func-sort-c.html | 96 + coverage/tools/RootFindingBase.h.func.html | 96 + coverage/tools/RootFindingBase.h.gcov.html | 153 + coverage/tools/Stopwatch.cpp.func-sort-c.html | 84 + coverage/tools/Stopwatch.cpp.func.html | 84 + coverage/tools/Stopwatch.cpp.gcov.html | 154 + coverage/tools/Stopwatch.h.func-sort-c.html | 116 + coverage/tools/Stopwatch.h.func.html | 116 + coverage/tools/Stopwatch.h.gcov.html | 542 + .../tools/Subprocess.cpp.func-sort-c.html | 136 + coverage/tools/Subprocess.cpp.func.html | 136 + coverage/tools/Subprocess.cpp.gcov.html | 268 + coverage/tools/Subprocess.h.func-sort-c.html | 80 + coverage/tools/Subprocess.h.func.html | 80 + coverage/tools/Subprocess.h.gcov.html | 218 + .../SwitchingFunction.cpp.func-sort-c.html | 496 + .../tools/SwitchingFunction.cpp.func.html | 496 + .../tools/SwitchingFunction.cpp.gcov.html | 1039 + .../SwitchingFunction.h.func-sort-c.html | 72 + coverage/tools/SwitchingFunction.h.func.html | 72 + coverage/tools/SwitchingFunction.h.gcov.html | 194 + coverage/tools/Tensor.cpp.func-sort-c.html | 76 + coverage/tools/Tensor.cpp.func.html | 76 + coverage/tools/Tensor.cpp.gcov.html | 115 + coverage/tools/Tensor.h.func-sort-c.html | 348 + coverage/tools/Tensor.h.func.html | 348 + coverage/tools/Tensor.h.gcov.html | 650 + coverage/tools/Tools.cpp.func-sort-c.html | 300 + coverage/tools/Tools.cpp.func.html | 300 + coverage/tools/Tools.cpp.gcov.html | 596 + coverage/tools/Tools.h.func-sort-c.html | 296 + coverage/tools/Tools.h.func.html | 296 + coverage/tools/Tools.h.gcov.html | 595 + coverage/tools/Torsion.cpp.func-sort-c.html | 80 + coverage/tools/Torsion.cpp.func.html | 80 + coverage/tools/Torsion.cpp.gcov.html | 156 + coverage/tools/Tree.cpp.func-sort-c.html | 84 + coverage/tools/Tree.cpp.func.html | 84 + coverage/tools/Tree.cpp.gcov.html | 200 + coverage/tools/Tree.h.func-sort-c.html | 72 + coverage/tools/Tree.h.func.html | 72 + coverage/tools/Tree.h.gcov.html | 128 + .../tools/TypesafePtr.cpp.func-sort-c.html | 84 + coverage/tools/TypesafePtr.cpp.func.html | 84 + coverage/tools/TypesafePtr.cpp.gcov.html | 133 + coverage/tools/TypesafePtr.h.func-sort-c.html | 312 + coverage/tools/TypesafePtr.h.func.html | 312 + coverage/tools/TypesafePtr.h.gcov.html | 501 + coverage/tools/Units.cpp.func-sort-c.html | 116 + coverage/tools/Units.cpp.func.html | 116 + coverage/tools/Units.cpp.gcov.html | 234 + coverage/tools/Units.h.func-sort-c.html | 72 + coverage/tools/Units.h.func.html | 72 + coverage/tools/Units.h.gcov.html | 243 + coverage/tools/Vector.h.func-sort-c.html | 344 + coverage/tools/Vector.h.func.html | 344 + coverage/tools/Vector.h.gcov.html | 419 + coverage/tools/h36.cpp.func-sort-c.html | 120 + coverage/tools/h36.cpp.func.html | 120 + coverage/tools/h36.cpp.gcov.html | 411 + coverage/tools/index-sort-f.html | 853 + coverage/tools/index-sort-l.html | 853 + coverage/tools/index.html | 853 + coverage/updown.png | Bin 0 -> 117 bytes .../valtools/Concatenate.cpp.func-sort-c.html | 96 + coverage/valtools/Concatenate.cpp.func.html | 96 + coverage/valtools/Concatenate.cpp.gcov.html | 266 + .../valtools/Flatten.cpp.func-sort-c.html | 96 + coverage/valtools/Flatten.cpp.func.html | 96 + coverage/valtools/Flatten.cpp.gcov.html | 171 + .../SelectComponents.cpp.func-sort-c.html | 84 + .../valtools/SelectComponents.cpp.func.html | 84 + .../valtools/SelectComponents.cpp.gcov.html | 166 + .../SelectWithMask.cpp.func-sort-c.html | 108 + .../valtools/SelectWithMask.cpp.func.html | 108 + .../valtools/SelectWithMask.cpp.gcov.html | 281 + coverage/valtools/VStack.cpp.func-sort-c.html | 112 + coverage/valtools/VStack.cpp.func.html | 112 + coverage/valtools/VStack.cpp.gcov.html | 238 + coverage/valtools/index-sort-f.html | 133 + coverage/valtools/index-sort-l.html | 133 + coverage/valtools/index.html | 133 + .../vatom/ArgsToVatom.cpp.func-sort-c.html | 96 + coverage/vatom/ArgsToVatom.cpp.func.html | 96 + coverage/vatom/ArgsToVatom.cpp.gcov.html | 237 + coverage/vatom/Center.cpp.func-sort-c.html | 88 + coverage/vatom/Center.cpp.func.html | 88 + coverage/vatom/Center.cpp.gcov.html | 405 + .../vatom/CenterShortcut.cpp.func-sort-c.html | 84 + coverage/vatom/CenterShortcut.cpp.func.html | 84 + coverage/vatom/CenterShortcut.cpp.gcov.html | 231 + coverage/vatom/FixedAtom.cpp.func-sort-c.html | 88 + coverage/vatom/FixedAtom.cpp.func.html | 88 + coverage/vatom/FixedAtom.cpp.gcov.html | 226 + coverage/vatom/Ghost.cpp.func-sort-c.html | 88 + coverage/vatom/Ghost.cpp.func.html | 88 + coverage/vatom/Ghost.cpp.gcov.html | 286 + coverage/vatom/index-sort-f.html | 133 + coverage/vatom/index-sort-l.html | 133 + coverage/vatom/index.html | 133 + .../ves/BF_Chebyshev.cpp.func-sort-c.html | 88 + coverage/ves/BF_Chebyshev.cpp.func.html | 88 + coverage/ves/BF_Chebyshev.cpp.gcov.html | 232 + coverage/ves/BF_Combined.cpp.func-sort-c.html | 92 + coverage/ves/BF_Combined.cpp.func.html | 92 + coverage/ves/BF_Combined.cpp.gcov.html | 278 + coverage/ves/BF_Cosine.cpp.func-sort-c.html | 92 + coverage/ves/BF_Cosine.cpp.func.html | 92 + coverage/ves/BF_Cosine.cpp.gcov.html | 228 + .../ves/BF_CubicBsplines.cpp.func-sort-c.html | 88 + coverage/ves/BF_CubicBsplines.cpp.func.html | 88 + coverage/ves/BF_CubicBsplines.cpp.gcov.html | 277 + coverage/ves/BF_Custom.cpp.func-sort-c.html | 92 + coverage/ves/BF_Custom.cpp.func.html | 92 + coverage/ves/BF_Custom.cpp.gcov.html | 445 + coverage/ves/BF_Fourier.cpp.func-sort-c.html | 92 + coverage/ves/BF_Fourier.cpp.func.html | 92 + coverage/ves/BF_Fourier.cpp.gcov.html | 232 + .../ves/BF_Gaussians.cpp.func-sort-c.html | 88 + coverage/ves/BF_Gaussians.cpp.func.html | 88 + coverage/ves/BF_Gaussians.cpp.gcov.html | 265 + coverage/ves/BF_Legendre.cpp.func-sort-c.html | 88 + coverage/ves/BF_Legendre.cpp.func.html | 88 + coverage/ves/BF_Legendre.cpp.gcov.html | 248 + coverage/ves/BF_Powers.cpp.func-sort-c.html | 88 + coverage/ves/BF_Powers.cpp.func.html | 88 + coverage/ves/BF_Powers.cpp.gcov.html | 221 + coverage/ves/BF_Sine.cpp.func-sort-c.html | 92 + coverage/ves/BF_Sine.cpp.func.html | 92 + coverage/ves/BF_Sine.cpp.gcov.html | 227 + coverage/ves/BF_Wavelets.cpp.func-sort-c.html | 92 + coverage/ves/BF_Wavelets.cpp.func.html | 92 + coverage/ves/BF_Wavelets.cpp.gcov.html | 494 + .../ves/BasisFunctions.cpp.func-sort-c.html | 156 + coverage/ves/BasisFunctions.cpp.func.html | 156 + coverage/ves/BasisFunctions.cpp.gcov.html | 481 + .../ves/BasisFunctions.h.func-sort-c.html | 104 + coverage/ves/BasisFunctions.h.func.html | 104 + coverage/ves/BasisFunctions.h.gcov.html | 393 + coverage/ves/CoeffsBase.cpp.func-sort-c.html | 200 + coverage/ves/CoeffsBase.cpp.func.html | 200 + coverage/ves/CoeffsBase.cpp.gcov.html | 593 + coverage/ves/CoeffsBase.h.func-sort-c.html | 80 + coverage/ves/CoeffsBase.h.func.html | 80 + coverage/ves/CoeffsBase.h.gcov.html | 335 + .../ves/CoeffsMatrix.cpp.func-sort-c.html | 388 + coverage/ves/CoeffsMatrix.cpp.func.html | 388 + coverage/ves/CoeffsMatrix.cpp.gcov.html | 791 + coverage/ves/CoeffsMatrix.h.func-sort-c.html | 72 + coverage/ves/CoeffsMatrix.h.func.html | 72 + coverage/ves/CoeffsMatrix.h.gcov.html | 287 + .../ves/CoeffsVector.cpp.func-sort-c.html | 468 + coverage/ves/CoeffsVector.cpp.func.html | 468 + coverage/ves/CoeffsVector.cpp.gcov.html | 971 + coverage/ves/CoeffsVector.h.func-sort-c.html | 72 + coverage/ves/CoeffsVector.h.func.html | 72 + coverage/ves/CoeffsVector.h.gcov.html | 316 + ...ermiSwitchingFunction.cpp.func-sort-c.html | 108 + .../ves/FermiSwitchingFunction.cpp.func.html | 108 + .../ves/FermiSwitchingFunction.cpp.gcov.html | 218 + ...ridIntegrationWeights.cpp.func-sort-c.html | 84 + .../ves/GridIntegrationWeights.cpp.func.html | 84 + .../ves/GridIntegrationWeights.cpp.gcov.html | 184 + ...idLinearInterpolation.cpp.func-sort-c.html | 108 + .../ves/GridLinearInterpolation.cpp.func.html | 108 + .../ves/GridLinearInterpolation.cpp.gcov.html | 311 + ...GridLinearInterpolation.h.func-sort-c.html | 76 + .../ves/GridLinearInterpolation.h.func.html | 76 + .../ves/GridLinearInterpolation.h.gcov.html | 158 + .../ves/GridProjWeights.h.func-sort-c.html | 88 + coverage/ves/GridProjWeights.h.func.html | 88 + coverage/ves/GridProjWeights.h.gcov.html | 126 + ...nearBasisSetExpansion.cpp.func-sort-c.html | 216 + .../ves/LinearBasisSetExpansion.cpp.func.html | 216 + .../ves/LinearBasisSetExpansion.cpp.gcov.html | 693 + ...LinearBasisSetExpansion.h.func-sort-c.html | 84 + .../ves/LinearBasisSetExpansion.h.func.html | 84 + .../ves/LinearBasisSetExpansion.h.gcov.html | 326 + ...MD_LinearExpansionPES.cpp.func-sort-c.html | 108 + .../ves/MD_LinearExpansionPES.cpp.func.html | 108 + .../ves/MD_LinearExpansionPES.cpp.gcov.html | 757 + coverage/ves/Opt_Adam.cpp.func-sort-c.html | 88 + coverage/ves/Opt_Adam.cpp.func.html | 88 + coverage/ves/Opt_Adam.cpp.gcov.html | 272 + .../Opt_BachAveragedSGD.cpp.func-sort-c.html | 88 + .../ves/Opt_BachAveragedSGD.cpp.func.html | 88 + .../ves/Opt_BachAveragedSGD.cpp.gcov.html | 378 + coverage/ves/Opt_Dummy.cpp.func-sort-c.html | 88 + coverage/ves/Opt_Dummy.cpp.func.html | 88 + coverage/ves/Opt_Dummy.cpp.gcov.html | 197 + .../Opt_RobbinsMonroSGD.cpp.func-sort-c.html | 88 + .../ves/Opt_RobbinsMonroSGD.cpp.func.html | 88 + .../ves/Opt_RobbinsMonroSGD.cpp.gcov.html | 172 + coverage/ves/Optimizer.cpp.func-sort-c.html | 200 + coverage/ves/Optimizer.cpp.func.html | 200 + coverage/ves/Optimizer.cpp.gcov.html | 1337 + coverage/ves/Optimizer.h.func-sort-c.html | 112 + coverage/ves/Optimizer.h.func.html | 112 + coverage/ves/Optimizer.h.gcov.html | 430 + .../OutputBasisFunctions.cpp.func-sort-c.html | 88 + .../ves/OutputBasisFunctions.cpp.func.html | 88 + .../ves/OutputBasisFunctions.cpp.gcov.html | 312 + .../ves/OutputFesBias.cpp.func-sort-c.html | 92 + coverage/ves/OutputFesBias.cpp.func.html | 92 + coverage/ves/OutputFesBias.cpp.gcov.html | 306 + ...putTargetDistribution.cpp.func-sort-c.html | 88 + .../OutputTargetDistribution.cpp.func.html | 88 + .../OutputTargetDistribution.cpp.gcov.html | 302 + coverage/ves/TD_Chi.cpp.func-sort-c.html | 84 + coverage/ves/TD_Chi.cpp.func.html | 84 + coverage/ves/TD_Chi.cpp.gcov.html | 229 + .../ves/TD_ChiSquared.cpp.func-sort-c.html | 84 + coverage/ves/TD_ChiSquared.cpp.func.html | 84 + coverage/ves/TD_ChiSquared.cpp.gcov.html | 228 + coverage/ves/TD_Custom.cpp.func-sort-c.html | 100 + coverage/ves/TD_Custom.cpp.func.html | 100 + coverage/ves/TD_Custom.cpp.gcov.html | 371 + .../ves/TD_Exponential.cpp.func-sort-c.html | 84 + coverage/ves/TD_Exponential.cpp.func.html | 84 + coverage/ves/TD_Exponential.cpp.gcov.html | 205 + ...iallyModifiedGaussian.cpp.func-sort-c.html | 88 + ...xponentiallyModifiedGaussian.cpp.func.html | 88 + ...xponentiallyModifiedGaussian.cpp.gcov.html | 300 + coverage/ves/TD_Gaussian.cpp.func-sort-c.html | 92 + coverage/ves/TD_Gaussian.cpp.func.html | 92 + coverage/ves/TD_Gaussian.cpp.gcov.html | 391 + ...neralizedExtremeValue.cpp.func-sort-c.html | 88 + .../TD_GeneralizedExtremeValue.cpp.func.html | 88 + .../TD_GeneralizedExtremeValue.cpp.gcov.html | 253 + .../TD_GeneralizedNormal.cpp.func-sort-c.html | 88 + .../ves/TD_GeneralizedNormal.cpp.func.html | 88 + .../ves/TD_GeneralizedNormal.cpp.gcov.html | 303 + coverage/ves/TD_Grid.cpp.func-sort-c.html | 84 + coverage/ves/TD_Grid.cpp.func.html | 84 + coverage/ves/TD_Grid.cpp.gcov.html | 294 + .../TD_LinearCombination.cpp.func-sort-c.html | 112 + .../ves/TD_LinearCombination.cpp.func.html | 112 + .../ves/TD_LinearCombination.cpp.gcov.html | 353 + .../TD_Multicanonical.cpp.func-sort-c.html | 96 + coverage/ves/TD_Multicanonical.cpp.func.html | 96 + coverage/ves/TD_Multicanonical.cpp.gcov.html | 550 + ...ultithermalMultibaric.cpp.func-sort-c.html | 96 + .../TD_MultithermalMultibaric.cpp.func.html | 96 + .../TD_MultithermalMultibaric.cpp.gcov.html | 533 + ...TD_ProductCombination.cpp.func-sort-c.html | 112 + .../ves/TD_ProductCombination.cpp.func.html | 112 + .../ves/TD_ProductCombination.cpp.gcov.html | 340 + ...D_ProductDistribution.cpp.func-sort-c.html | 112 + .../ves/TD_ProductDistribution.cpp.func.html | 112 + .../ves/TD_ProductDistribution.cpp.gcov.html | 301 + coverage/ves/TD_Uniform.cpp.func-sort-c.html | 88 + coverage/ves/TD_Uniform.cpp.func.html | 88 + coverage/ves/TD_Uniform.cpp.gcov.html | 381 + coverage/ves/TD_VonMises.cpp.func-sort-c.html | 92 + coverage/ves/TD_VonMises.cpp.func.html | 92 + coverage/ves/TD_VonMises.cpp.gcov.html | 315 + .../ves/TD_WellTempered.cpp.func-sort-c.html | 96 + coverage/ves/TD_WellTempered.cpp.func.html | 96 + coverage/ves/TD_WellTempered.cpp.gcov.html | 240 + .../ves/TargetDistModifer.h.func-sort-c.html | 76 + coverage/ves/TargetDistModifer.h.func.html | 76 + coverage/ves/TargetDistModifer.h.gcov.html | 129 + .../TargetDistribution.cpp.func-sort-c.html | 176 + coverage/ves/TargetDistribution.cpp.func.html | 176 + coverage/ves/TargetDistribution.cpp.gcov.html | 464 + .../ves/TargetDistribution.h.func-sort-c.html | 96 + coverage/ves/TargetDistribution.h.func.html | 96 + coverage/ves/TargetDistribution.h.gcov.html | 285 + coverage/ves/VesBias.cpp.func-sort-c.html | 252 + coverage/ves/VesBias.cpp.func.html | 252 + coverage/ves/VesBias.cpp.gcov.html | 829 + coverage/ves/VesBias.h.func-sort-c.html | 172 + coverage/ves/VesBias.h.func.html | 172 + coverage/ves/VesBias.h.gcov.html | 491 + coverage/ves/VesDeltaF.cpp.func-sort-c.html | 104 + coverage/ves/VesDeltaF.cpp.func.html | 104 + coverage/ves/VesDeltaF.cpp.gcov.html | 790 + .../VesLinearExpansion.cpp.func-sort-c.html | 156 + coverage/ves/VesLinearExpansion.cpp.func.html | 156 + coverage/ves/VesLinearExpansion.cpp.gcov.html | 633 + coverage/ves/VesTools.cpp.func-sort-c.html | 80 + coverage/ves/VesTools.cpp.func.html | 80 + coverage/ves/VesTools.cpp.gcov.html | 170 + coverage/ves/VesTools.h.func-sort-c.html | 92 + coverage/ves/VesTools.h.func.html | 92 + coverage/ves/VesTools.h.gcov.html | 216 + .../ves/WaveletCoeffs.cpp.func-sort-c.html | 76 + coverage/ves/WaveletCoeffs.cpp.func.html | 76 + coverage/ves/WaveletCoeffs.cpp.gcov.html | 1058 + coverage/ves/WaveletGrid.cpp.func-sort-c.html | 104 + coverage/ves/WaveletGrid.cpp.func.html | 104 + coverage/ves/WaveletGrid.cpp.gcov.html | 330 + coverage/ves/index-sort-f.html | 723 + coverage/ves/index-sort-l.html | 723 + coverage/ves/index.html | 723 + .../volumes/ActionVolume.cpp.func-sort-c.html | 112 + coverage/volumes/ActionVolume.cpp.func.html | 112 + coverage/volumes/ActionVolume.cpp.gcov.html | 214 + .../volumes/ActionVolume.h.func-sort-c.html | 80 + coverage/volumes/ActionVolume.h.func.html | 80 + coverage/volumes/ActionVolume.h.gcov.html | 164 + coverage/volumes/Density.cpp.func-sort-c.html | 84 + coverage/volumes/Density.cpp.func.html | 84 + coverage/volumes/Density.cpp.gcov.html | 140 + .../volumes/VolumeAround.cpp.func-sort-c.html | 92 + coverage/volumes/VolumeAround.cpp.func.html | 92 + coverage/volumes/VolumeAround.cpp.gcov.html | 244 + ...VolumeBetweenContours.cpp.func-sort-c.html | 92 + .../VolumeBetweenContours.cpp.func.html | 92 + .../VolumeBetweenContours.cpp.gcov.html | 238 + .../volumes/VolumeCavity.cpp.func-sort-c.html | 108 + coverage/volumes/VolumeCavity.cpp.func.html | 108 + coverage/volumes/VolumeCavity.cpp.gcov.html | 496 + .../VolumeInCylinder.cpp.func-sort-c.html | 92 + .../volumes/VolumeInCylinder.cpp.func.html | 92 + .../volumes/VolumeInCylinder.cpp.gcov.html | 249 + .../VolumeInSphere.cpp.func-sort-c.html | 92 + coverage/volumes/VolumeInSphere.cpp.func.html | 92 + coverage/volumes/VolumeInSphere.cpp.gcov.html | 213 + .../volumes/VolumeShortcut.h.func-sort-c.html | 120 + coverage/volumes/VolumeShortcut.h.func.html | 120 + coverage/volumes/VolumeShortcut.h.gcov.html | 198 + .../VolumeTetrapore.cpp.func-sort-c.html | 108 + .../volumes/VolumeTetrapore.cpp.func.html | 108 + .../volumes/VolumeTetrapore.cpp.gcov.html | 533 + coverage/volumes/index-sort-f.html | 183 + coverage/volumes/index-sort-l.html | 183 + coverage/volumes/index.html | 183 + coverage/wham/Wham.cpp.func-sort-c.html | 96 + coverage/wham/Wham.cpp.func.html | 96 + coverage/wham/Wham.cpp.gcov.html | 247 + .../wham/WhamHistogram.cpp.func-sort-c.html | 84 + coverage/wham/WhamHistogram.cpp.func.html | 84 + coverage/wham/WhamHistogram.cpp.gcov.html | 211 + .../wham/WhamWeights.cpp.func-sort-c.html | 84 + coverage/wham/WhamWeights.cpp.func.html | 84 + coverage/wham/WhamWeights.cpp.gcov.html | 187 + coverage/wham/index-sort-f.html | 113 + coverage/wham/index-sort-l.html | 113 + coverage/wham/index.html | 113 + coverage/wrapper/Plumed.h.func-sort-c.html | 1224 + coverage/wrapper/Plumed.h.func.html | 1224 + coverage/wrapper/Plumed.h.gcov.html | 4847 +++ coverage/wrapper/index-sort-f.html | 93 + coverage/wrapper/index-sort-l.html | 93 + coverage/wrapper/index.html | 93 + index.html | 14 + 2156 files changed, 515838 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/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/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/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/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/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/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/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/ActionWithMatrix.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithMatrix.cpp.func.html create mode 100644 coverage/core/ActionWithMatrix.cpp.gcov.html create mode 100644 coverage/core/ActionWithMatrix.h.func-sort-c.html create mode 100644 coverage/core/ActionWithMatrix.h.func.html create mode 100644 coverage/core/ActionWithMatrix.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/ModuleMap.cpp.func-sort-c.html create mode 100644 coverage/core/ModuleMap.cpp.func.html create mode 100644 coverage/core/ModuleMap.cpp.gcov.html create mode 100644 coverage/core/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/FunctionOfMatrix.h.func-sort-c.html create mode 100644 coverage/function/FunctionOfMatrix.h.func.html create mode 100644 coverage/function/FunctionOfMatrix.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/Accumulate.cpp.func-sort-c.html create mode 100644 coverage/generic/Accumulate.cpp.func.html create mode 100644 coverage/generic/Accumulate.cpp.gcov.html create mode 100644 coverage/generic/Average.cpp.func-sort-c.html create mode 100644 coverage/generic/Average.cpp.func.html create mode 100644 coverage/generic/Average.cpp.gcov.html create mode 100644 coverage/generic/Collect.cpp.func-sort-c.html create mode 100644 coverage/generic/Collect.cpp.func.html create mode 100644 coverage/generic/Collect.cpp.gcov.html create mode 100644 coverage/generic/Committor.cpp.func-sort-c.html create mode 100644 coverage/generic/Committor.cpp.func.html create mode 100644 coverage/generic/Committor.cpp.gcov.html 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/CreateMask.cpp.func-sort-c.html create mode 100644 coverage/generic/CreateMask.cpp.func.html create mode 100644 coverage/generic/CreateMask.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/GatherReplicas.cpp.func-sort-c.html create mode 100644 coverage/generic/GatherReplicas.cpp.func.html create mode 100644 coverage/generic/GatherReplicas.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/MassChargeInput.cpp.func-sort-c.html create mode 100644 coverage/generic/MassChargeInput.cpp.func.html create mode 100644 coverage/generic/MassChargeInput.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/Histogram.cpp.func-sort-c.html create mode 100644 coverage/gridtools/Histogram.cpp.func.html create mode 100644 coverage/gridtools/Histogram.cpp.gcov.html create mode 100644 coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/InterpolateGrid.cpp.func.html create mode 100644 coverage/gridtools/InterpolateGrid.cpp.gcov.html create mode 100644 coverage/gridtools/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/landmarks/CollectFrames.cpp.func-sort-c.html create mode 100644 coverage/landmarks/CollectFrames.cpp.func.html create mode 100644 coverage/landmarks/CollectFrames.cpp.gcov.html create mode 100644 coverage/landmarks/FarthestPointSampling.cpp.func-sort-c.html create mode 100644 coverage/landmarks/FarthestPointSampling.cpp.func.html create mode 100644 coverage/landmarks/FarthestPointSampling.cpp.gcov.html create mode 100644 coverage/landmarks/LandmarkSelection.cpp.func-sort-c.html create mode 100644 coverage/landmarks/LandmarkSelection.cpp.func.html create mode 100644 coverage/landmarks/LandmarkSelection.cpp.gcov.html create mode 100644 coverage/landmarks/LogSumExp.cpp.func-sort-c.html create mode 100644 coverage/landmarks/LogSumExp.cpp.func.html create mode 100644 coverage/landmarks/LogSumExp.cpp.gcov.html create mode 100644 coverage/landmarks/index-sort-f.html create mode 100644 coverage/landmarks/index-sort-l.html create mode 100644 coverage/landmarks/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/matrixtools/CovarianceMatrix.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/CovarianceMatrix.cpp.func.html create mode 100644 coverage/matrixtools/CovarianceMatrix.cpp.gcov.html create mode 100644 coverage/matrixtools/Determinent.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/Determinent.cpp.func.html create mode 100644 coverage/matrixtools/Determinent.cpp.gcov.html create mode 100644 coverage/matrixtools/DiagonalizeMatrix.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/DiagonalizeMatrix.cpp.func.html create mode 100644 coverage/matrixtools/DiagonalizeMatrix.cpp.gcov.html create mode 100644 coverage/matrixtools/InvertMatrix.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/InvertMatrix.cpp.func.html create mode 100644 coverage/matrixtools/InvertMatrix.cpp.gcov.html create mode 100644 coverage/matrixtools/MatrixOperationBase.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/MatrixOperationBase.cpp.func.html create mode 100644 coverage/matrixtools/MatrixOperationBase.cpp.gcov.html create mode 100644 coverage/matrixtools/MatrixTimesMatrix.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/MatrixTimesMatrix.cpp.func.html create mode 100644 coverage/matrixtools/MatrixTimesMatrix.cpp.gcov.html create mode 100644 coverage/matrixtools/MatrixTimesVector.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/MatrixTimesVector.cpp.func.html create mode 100644 coverage/matrixtools/MatrixTimesVector.cpp.gcov.html create mode 100644 coverage/matrixtools/OuterProduct.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/OuterProduct.cpp.func.html create mode 100644 coverage/matrixtools/OuterProduct.cpp.gcov.html create mode 100644 coverage/matrixtools/TransposeMatrix.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/TransposeMatrix.cpp.func.html create mode 100644 coverage/matrixtools/TransposeMatrix.cpp.gcov.html create mode 100644 coverage/matrixtools/Voronoi.cpp.func-sort-c.html create mode 100644 coverage/matrixtools/Voronoi.cpp.func.html create mode 100644 coverage/matrixtools/Voronoi.cpp.gcov.html create mode 100644 coverage/matrixtools/index-sort-f.html create mode 100644 coverage/matrixtools/index-sort-l.html create mode 100644 coverage/matrixtools/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/metatensor/index-sort-f.html create mode 100644 coverage/metatensor/index-sort-l.html create mode 100644 coverage/metatensor/index.html create mode 100644 coverage/metatensor/metatensor.cpp.func-sort-c.html create mode 100644 coverage/metatensor/metatensor.cpp.func.html create mode 100644 coverage/metatensor/metatensor.cpp.gcov.html create mode 100644 coverage/metatensor/vesin.cpp.func-sort-c.html create mode 100644 coverage/metatensor/vesin.cpp.func.html create mode 100644 coverage/metatensor/vesin.cpp.gcov.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.func.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.gcov.html create mode 100644 coverage/multicolvar/Angles.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Angles.cpp.func.html create mode 100644 coverage/multicolvar/Angles.cpp.gcov.html create mode 100644 coverage/multicolvar/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/sizeshape/index-sort-f.html create mode 100644 coverage/sizeshape/index-sort-l.html create mode 100644 coverage/sizeshape/index.html create mode 100644 coverage/sizeshape/mahadist.cpp.func-sort-c.html create mode 100644 coverage/sizeshape/mahadist.cpp.func.html create mode 100644 coverage/sizeshape/mahadist.cpp.gcov.html create mode 100644 coverage/sizeshape/pos_proj.cpp.func-sort-c.html create mode 100644 coverage/sizeshape/pos_proj.cpp.func.html create mode 100644 coverage/sizeshape/pos_proj.cpp.gcov.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/sprint/Sprint.cpp.func-sort-c.html create mode 100644 coverage/sprint/Sprint.cpp.func.html create mode 100644 coverage/sprint/Sprint.cpp.gcov.html create mode 100644 coverage/sprint/index-sort-f.html create mode 100644 coverage/sprint/index-sort-l.html create mode 100644 coverage/sprint/index.html 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/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/VStack.cpp.func-sort-c.html create mode 100644 coverage/valtools/VStack.cpp.func.html create mode 100644 coverage/valtools/VStack.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/wham/Wham.cpp.func-sort-c.html create mode 100644 coverage/wham/Wham.cpp.func.html create mode 100644 coverage/wham/Wham.cpp.gcov.html create mode 100644 coverage/wham/WhamHistogram.cpp.func-sort-c.html create mode 100644 coverage/wham/WhamHistogram.cpp.func.html create mode 100644 coverage/wham/WhamHistogram.cpp.gcov.html create mode 100644 coverage/wham/WhamWeights.cpp.func-sort-c.html create mode 100644 coverage/wham/WhamWeights.cpp.func.html create mode 100644 coverage/wham/WhamWeights.cpp.gcov.html create mode 100644 coverage/wham/index-sort-f.html create mode 100644 coverage/wham/index-sort-l.html create mode 100644 coverage/wham/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 000000000..e69de29bb diff --git a/README.md b/README.md new file mode 100644 index 000000000..b0b45e794 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Coverage scan for PLUMED v2.10 +----------------------------- + +This repository hosts the coverage scan for [PLUMED](http://www.plumed.org) v2.10, +git revision [9bfe572](https://github.com/plumed/plumed2/commit/9bfe572). + +Coverage scan done on [GiHub actions](http://github.com/plumed/plumed2/actions) on Thu Oct 17 16:45:03 UTC 2024. + +To browse the scan you should go [here](http://plumed.github.io/coverage-v2.10). + +You can also download a full copy of the scan for offline access +at [this link](http://github.com/plumed/coverage-v2.10/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-10-17 16:45:02Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj258
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE315836
+
+
+ + + +
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 000000000..e26a6b742 --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-10-17 16:45:02Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj258
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE315836
+
+
+ + + +
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 000000000..a2acf2bf5 --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-10-17 16:45:02Functions: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         258 : ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept {
+      62         258 :   uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0);
+      63             : 
+      64             :   // Make sure the `archInfoTable` array is correctly indexed.
+      65         258 :   _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         258 :   _type = type;
+      71         258 :   _subType = subType;
+      72         258 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::ArchUtils]
+      76             : // ============================================================================
+      77             : 
+      78      315836 : ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept {
+      79      315836 :   uint32_t typeId = typeIdInOut;
+      80             : 
+      81             :   // Zero the signature so it's clear in case that typeId is not invalid.
+      82      315836 :   regInfo._signature = 0;
+      83             : 
+      84             : #if defined(ASMJIT_BUILD_X86)
+      85      315836 :   if (ArchInfo::isX86Family(archType)) {
+      86             :     // Passed RegType instead of TypeId?
+      87      315836 :     if (typeId <= Reg::kRegMax)
+      88           0 :       typeId = x86OpData.archRegs.regTypeToTypeId[typeId];
+      89             : 
+      90      315836 :     if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId)))
+      91             :       return DebugUtils::errored(kErrorInvalidTypeId);
+      92             : 
+      93             :     // First normalize architecture dependent types.
+      94      315836 :     if (TypeId::isAbstract(typeId)) {
+      95      104966 :       if (typeId == TypeId::kIntPtr)
+      96      104966 :         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      315836 :     if (ASMJIT_UNLIKELY(!size))
+     105             :       return DebugUtils::errored(kErrorInvalidTypeId);
+     106             : 
+     107      315836 :     if (ASMJIT_UNLIKELY(typeId == TypeId::kF80))
+     108             :       return DebugUtils::errored(kErrorInvalidUseOfF80);
+     109             : 
+     110             :     uint32_t regType = 0;
+     111             : 
+     112      315836 :     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      104966 :       case TypeId::kI64:
+     129             :       case TypeId::kU64:
+     130      104966 :         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      210870 :       default:
+     163      210870 :         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      315836 :     typeIdInOut = typeId;
+     173      315836 :     regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature();
+     174      315836 :     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 000000000..6cac4ebf3 --- /dev/null +++ b/coverage-libs/asmjit/arch.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..9ac9a5f6e --- /dev/null +++ b/coverage-libs/asmjit/arch.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..2ffcaf68b --- /dev/null +++ b/coverage-libs/asmjit/arch.h.gcov.html @@ -0,0 +1,304 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-10-17 16:45:02Functions: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      443832 :   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      128284 :   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       31999 :   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      443832 :   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       63998 :   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       31999 :   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 000000000..487cf6fcf --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-10-17 16:45:02Functions: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_10CodeHolderE31999
_ZN4PLMD6asmjit9AssemblerC2Ev31999
_ZN4PLMD6asmjit9AssemblerD2Ev31999
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE63998
_ZN4PLMD6asmjit9Assembler4syncEv63998
_ZN4PLMD6asmjit9Assembler12_emitOpArrayEjPKNS0_8Operand_Em588796
+
+
+ + + +
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 000000000..c1570cf31 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.func.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-10-17 16:45:02Functions: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_Em588796
_ZN4PLMD6asmjit9Assembler13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit9Assembler14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE63998
_ZN4PLMD6asmjit9Assembler4syncEv63998
_ZN4PLMD6asmjit9Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit9Assembler5embedEPKvj0
_ZN4PLMD6asmjit9Assembler7commentEPKcm0
_ZN4PLMD6asmjit9Assembler8_emitLogEjjRKNS0_8Operand_ES4_S4_S4_jjPh0
_ZN4PLMD6asmjit9Assembler8newLabelEv0
_ZN4PLMD6asmjit9Assembler8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit9Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit9Assembler9setOffsetEm0
_ZN4PLMD6asmjit9AssemblerC2Ev31999
_ZN4PLMD6asmjit9AssemblerD0Ev0
_ZN4PLMD6asmjit9AssemblerD2Ev31999
+
+
+ + + +
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 000000000..b1f7b6fad --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.gcov.html @@ -0,0 +1,549 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-10-17 16:45:02Functions: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       31999 : Assembler::Assembler() noexcept
+      49             :   : CodeEmitter(kTypeAssembler),
+      50       31999 :     _section(nullptr),
+      51       31999 :     _bufferData(nullptr),
+      52       31999 :     _bufferEnd(nullptr),
+      53       31999 :     _bufferPtr(nullptr),
+      54       31999 :     _op4(),
+      55       31999 :     _op5() {}
+      56             : 
+      57       31999 : Assembler::~Assembler() noexcept {
+      58       31999 :   if (_code) sync();
+      59       31999 : }
+      60             : 
+      61             : // ============================================================================
+      62             : // [asmjit::Assembler - Events]
+      63             : // ============================================================================
+      64             : 
+      65       31999 : Error Assembler::onAttach(CodeHolder* code) noexcept {
+      66             :   // Attach to the end of the .text section.
+      67       31999 :   _section = code->_sections[0];
+      68       31999 :   uint8_t* p = _section->_buffer._data;
+      69             : 
+      70       31999 :   _bufferData = p;
+      71       31999 :   _bufferEnd  = p + _section->_buffer._capacity;
+      72       31999 :   _bufferPtr  = p + _section->_buffer._length;
+      73             : 
+      74             :   _op4.reset();
+      75             :   _op5.reset();
+      76             : 
+      77       31999 :   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      588796 : Error Assembler::_emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
+     104             :   const Operand_* op = opArray;
+     105      588796 :   switch (opCount) {
+     106       31999 :     case 0: return _emit(instId, _none, _none, _none, _none);
+     107       27026 :     case 1: return _emit(instId, op[0], _none, _none, _none);
+     108      527501 :     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       63998 : 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       63998 :   size_t offset = (size_t)(_bufferPtr - _bufferData);
+     140       63998 :   if (_section->getBuffer().getLength() < offset)
+     141       31999 :     _section->_buffer._length = offset;
+     142       63998 : }
+     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       63998 : Error Assembler::bind(const Label& label) {
+     212       63998 :   if (_lastError) return _lastError;
+     213             :   ASMJIT_ASSERT(_code != nullptr);
+     214             : 
+     215       63998 :   LabelEntry* le = _code->getLabelEntry(label);
+     216       63998 :   if (ASMJIT_UNLIKELY(!le))
+     217           0 :     return setLastError(DebugUtils::errored(kErrorInvalidLabel));
+     218             : 
+     219             :   // Label can be bound only once.
+     220       63998 :   if (ASMJIT_UNLIKELY(le->isBound()))
+     221           0 :     return setLastError(DebugUtils::errored(kErrorLabelAlreadyBound));
+     222             : 
+     223             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     224       63998 :   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       63998 :   LabelLink* link = le->_links;
+     244             :   LabelLink* prev = nullptr;
+     245             : 
+     246       63998 :   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       63998 :   le->_sectionId = _section->getId();
+     280       63998 :   le->_offset = pos;
+     281       63998 :   le->_links = nullptr;
+     282             :   resetInlineComment();
+     283             : 
+     284       63998 :   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 000000000..648486963 --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..b5f6de1b4 --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..0be72b980 --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.gcov.html @@ -0,0 +1,259 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-10-17 16:45:02Functions: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       95997 :   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 000000000..f483735cb --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html @@ -0,0 +1,204 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-10-17 16:45:02Functions: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
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv31999
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE31999
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE31999
_ZN4PLMD6asmjit11CodeBuilderC2Ev31999
_ZN4PLMD6asmjit11CodeBuilderD2Ev31999
_ZN4PLMD6asmjit6CBPassC2EPKc31999
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE63998
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE63998
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE716792
+
+
+ + + +
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 000000000..9fd54f10f --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.func.html @@ -0,0 +1,204 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-10-17 16:45:02Functions: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
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv31999
_ZN4PLMD6asmjit11CodeBuilder13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit11CodeBuilder14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit11CodeBuilder14newCommentNodeEPKcm0
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE63998
_ZN4PLMD6asmjit11CodeBuilder4bindERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder5alignEjj0
_ZN4PLMD6asmjit11CodeBuilder5embedEPKvj0
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE716792
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE31999
_ZN4PLMD6asmjit11CodeBuilder7commentEPKcm0
_ZN4PLMD6asmjit11CodeBuilder8addAfterEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder8newLabelEv0
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit11CodeBuilder8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeBuilder9addBeforeEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE31999
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE63998
_ZN4PLMD6asmjit11CodeBuilderC2Ev31999
_ZN4PLMD6asmjit11CodeBuilderD0Ev0
_ZN4PLMD6asmjit11CodeBuilderD2Ev31999
_ZN4PLMD6asmjit6CBPassC2EPKc31999
_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 000000000..65464a6c8 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.gcov.html @@ -0,0 +1,686 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-10-17 16:45:02Functions: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       31999 : CodeBuilder::CodeBuilder() noexcept
+      50             :   : CodeEmitter(kTypeBuilder),
+      51       31999 :     _cbBaseZone(32768 - Zone::kZoneOverhead),
+      52       31999 :     _cbDataZone(16384 - Zone::kZoneOverhead),
+      53       31999 :     _cbPassZone(32768 - Zone::kZoneOverhead),
+      54       31999 :     _cbHeap(&_cbBaseZone),
+      55             :     _cbPasses(),
+      56             :     _cbLabels(),
+      57       31999 :     _firstNode(nullptr),
+      58       31999 :     _lastNode(nullptr),
+      59       31999 :     _cursor(nullptr),
+      60       31999 :     _position(0),
+      61       31999 :     _nodeFlags(0) {}
+      62       31999 : CodeBuilder::~CodeBuilder() noexcept {}
+      63             : 
+      64             : // ============================================================================
+      65             : // [asmjit::CodeBuilder - Events]
+      66             : // ============================================================================
+      67             : 
+      68       31999 : Error CodeBuilder::onAttach(CodeHolder* code) noexcept {
+      69       31999 :   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       63998 : Error CodeBuilder::registerLabelNode(CBLabel* node) noexcept {
+     119       63998 :   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       63998 :   ASMJIT_PROPAGATE(_code->newLabelId(id));
+     126       63998 :   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       63998 :   ASMJIT_PROPAGATE(_cbLabels.resize(&_cbHeap, index + 1));
+     131             : 
+     132       63998 :   _cbLabels[index] = node;
+     133       63998 :   node->_id = id;
+     134       63998 :   return kErrorOk;
+     135             : }
+     136             : 
+     137       31999 : CBLabel* CodeBuilder::newLabelNode() noexcept {
+     138             :   CBLabel* node = newNodeT<CBLabel>();
+     139       31999 :   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      716792 : CBNode* CodeBuilder::addNode(CBNode* node) noexcept {
+     302             :   ASMJIT_ASSERT(node);
+     303             :   ASMJIT_ASSERT(node->_prev == nullptr);
+     304             :   ASMJIT_ASSERT(node->_next == nullptr);
+     305             : 
+     306      716792 :   if (!_cursor) {
+     307       31999 :     if (!_firstNode) {
+     308       31999 :       _firstNode = node;
+     309       31999 :       _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      684793 :     CBNode* next = _cursor->_next;
+     320             : 
+     321      684793 :     node->_prev = prev;
+     322      684793 :     node->_next = next;
+     323             : 
+     324      684793 :     prev->_next = node;
+     325      684793 :     if (next)
+     326      620795 :       next->_prev = node;
+     327             :     else
+     328       63998 :       _lastNode = node;
+     329             :   }
+     330             : 
+     331      716792 :   _cursor = node;
+     332      716792 :   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       63998 : CBNode* CodeBuilder::setCursor(CBNode* node) noexcept {
+     467       63998 :   CBNode* old = _cursor;
+     468       63998 :   _cursor = node;
+     469       63998 :   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       31999 : ASMJIT_FAVOR_SIZE Error CodeBuilder::addPass(CBPass* pass) noexcept {
+     487       31999 :   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       31999 :   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       31999 :   ASMJIT_PROPAGATE(_cbPasses.append(&_cbHeap, pass));
+     500       31999 :   pass->_cb = this;
+     501       31999 :   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       31999 : Error CodeBuilder::serialize(CodeEmitter* dst) {
+     528             :   Error err = kErrorOk;
+     529             :   CBNode* node_ = getFirstNode();
+     530             : 
+     531             :   do {
+     532             :     dst->setInlineComment(node_->getInlineComment());
+     533             : 
+     534      716792 :     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       63998 :       case CBNode::kNodeFunc:
+     548             :       case CBNode::kNodeLabel: {
+     549             :         CBLabel* node = static_cast<CBLabel*>(node_);
+     550       63998 :         err = dst->bind(node->getLabel());
+     551       63998 :         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      588796 :         err = dst->emitOpArray(node->getInstId(), node->getOpArray(), node->getOpCount());
+     572      588796 :         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      716792 :     if (err) break;
+     586             :     node_ = node_->getNext();
+     587      716792 :   } while (node_);
+     588             : 
+     589       31999 :   return err;
+     590             : }
+     591             : 
+     592             : // ============================================================================
+     593             : // [asmjit::CBPass]
+     594             : // ============================================================================
+     595             : 
+     596       31999 : CBPass::CBPass(const char* name) noexcept
+     597       31999 :   : _cb(nullptr),
+     598       31999 :     _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 000000000..0bd674457 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-10-17 16:45:02Functions: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 000000000..c30280f2c --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-10-17 16:45:02Functions: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 000000000..5f2f6abf3 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.gcov.html @@ -0,0 +1,1020 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-10-17 16:45:02Functions: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       63998 :   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       63998 :   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       31999 :   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       31999 :   ASMJIT_INLINE CBNode* getCursor() const noexcept { return _cursor; }
+     186             :   //! Set the current node without returning the previous node.
+     187      140934 :   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       31999 :   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       31999 :   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       31999 :   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      716792 :   ASMJIT_INLINE CBNode(CodeBuilder* cb, uint32_t type) noexcept {
+     369      716792 :     _prev = nullptr;
+     370      716792 :     _next = nullptr;
+     371      684793 :     _type = static_cast<uint8_t>(type);
+     372      127996 :     _opCount = 0;
+     373      716792 :     _flags = static_cast<uint16_t>(cb->_nodeFlags);
+     374      716792 :     _position = cb->_position;
+     375      716792 :     _inlineComment = nullptr;
+     376      639856 :     _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      981806 :   ASMJIT_INLINE CBNode* getPrev() const noexcept { return _prev; }
+     392             :   //! Get next node in the compiler stream.
+     393     1901199 :   ASMJIT_INLINE CBNode* getNext() const noexcept { return _next; }
+     394             : 
+     395             :   //! Get the node type, see \ref Type.
+     396     3328971 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     397             :   //! Get the node flags.
+     398      413967 :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+     399             : 
+     400             :   //! Get whether the instruction has flag `flag`.
+     401     2903426 :   ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return (static_cast<uint32_t>(_flags) & flag) != 0; }
+     402             :   //! Set node flags to `flags`.
+     403      413967 :   ASMJIT_INLINE void setFlags(uint32_t flags) noexcept { _flags = static_cast<uint16_t>(flags); }
+     404             :   //! Add instruction `flags`.
+     405       31999 :   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      554901 :   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      716792 :   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     1504708 :   ASMJIT_INLINE bool hasPassData() const noexcept { return _passData != nullptr; }
+     452             :   //! Get work-data - data used during processing & transformations.
+     453             :   template<typename T>
+     454     5639273 :   ASMJIT_INLINE T* getPassData() const noexcept { return (T*)_passData; }
+     455             :   //! Set work-data to `data`.
+     456             :   template<typename T>
+     457      554901 :   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      588796 :     : CBNode(cb, kNodeInst) {
+     495             : 
+     496             :     orFlags(kFlagIsRemovable);
+     497      588796 :     _instDetail.instId = static_cast<uint16_t>(instId);
+     498      588796 :     _instDetail.options = options;
+     499             : 
+     500      588796 :     _opCount = static_cast<uint8_t>(opCount);
+     501      588796 :     _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     1002763 :   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     1002245 :   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      588796 :   ASMJIT_INLINE uint32_t getOpCount() const noexcept { return _opCount; }
+     550             :   //! Get operands list.
+     551     1429668 :   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      525857 :   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      174569 :     return static_cast<T*>(&_opArray[_memOpIndex]);
+     570             :   }
+     571             : 
+     572             :   //! Set memory operand index, `0xFF` means no memory operand.
+     573      672169 :   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     1463091 :     for (i = 0; i < opCount; i++)
+     587     1048864 :       if (opArray[i].isMem())
+     588      174569 :         goto Update;
+     589             :     i = 0xFF;
+     590             : 
+     591      588796 : 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       63998 :     : CBNode(cb, kNodeLabel),
+     767       63998 :       _id(id),
+     768       63998 :       _numRefs(0),
+     769       63998 :       _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       63998 :   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 000000000..27b163361 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-10-17 16:45:02Functions: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_E12938
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12938
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12938
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E13456
_ZN4PLMD6asmjit12CodeCompiler6addRetERKNS0_8Operand_ES4_31999
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_31999
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE31999
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv31999
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE31999
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit12CodeCompilerC2Ev31999
_ZN4PLMD6asmjit12CodeCompilerD2Ev31999
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc315836
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc315836
+
+
+ + + +
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 000000000..c87323419 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.func.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-10-17 16:45:02Functions:153641.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E13456
_ZN4PLMD6asmjit10CCFuncCall7_setRetEjRKNS0_8Operand_E12938
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc315836
_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_31999
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_31999
_ZN4PLMD6asmjit12CodeCompiler6renameERNS0_3RegEPKcz0
_ZN4PLMD6asmjit12CodeCompiler6setArgEjRKNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKc0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc315836
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12938
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE31999
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv31999
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12938
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE31999
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit12CodeCompiler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12CodeCompiler9_newConstERNS0_3MemEjPKvm0
_ZN4PLMD6asmjit12CodeCompiler9_newStackERNS0_3MemEjjPKc0
_ZN4PLMD6asmjit12CodeCompilerC2Ev31999
_ZN4PLMD6asmjit12CodeCompilerD0Ev0
_ZN4PLMD6asmjit12CodeCompilerD2Ev31999
_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 000000000..cfbd4c238 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.gcov.html @@ -0,0 +1,675 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-10-17 16:45:02Functions: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       13456 : bool CCFuncCall::_setArg(uint32_t i, const Operand_& op) noexcept {
+      62       13456 :   if ((i & ~kFuncArgHi) >= _funcDetail.getArgCount())
+      63             :     return false;
+      64             : 
+      65       13456 :   _args[i] = op;
+      66       13456 :   return true;
+      67             : }
+      68             : 
+      69       12938 : bool CCFuncCall::_setRet(uint32_t i, const Operand_& op) noexcept {
+      70       12938 :   if (i >= 2)
+      71             :     return false;
+      72             : 
+      73       12938 :   _ret[i] = op;
+      74       12938 :   return true;
+      75             : }
+      76             : 
+      77             : // ============================================================================
+      78             : // [asmjit::CodeCompiler - Construction / Destruction]
+      79             : // ============================================================================
+      80             : 
+      81       31999 : CodeCompiler::CodeCompiler() noexcept
+      82             :   : CodeBuilder(),
+      83       31999 :     _func(nullptr),
+      84       31999 :     _vRegZone(4096 - Zone::kZoneOverhead),
+      85             :     _vRegArray(),
+      86       31999 :     _localConstPool(nullptr),
+      87       31999 :     _globalConstPool(nullptr) {
+      88             : 
+      89       31999 :   _type = kTypeCompiler;
+      90       31999 : }
+      91       31999 : CodeCompiler::~CodeCompiler() noexcept {}
+      92             : 
+      93             : // ============================================================================
+      94             : // [asmjit::CodeCompiler - Events]
+      95             : // ============================================================================
+      96             : 
+      97       31999 : Error CodeCompiler::onAttach(CodeHolder* code) noexcept {
+      98       31999 :   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       31999 : CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept {
+     129             :   Error err;
+     130             : 
+     131             :   CCFunc* func = newNodeT<CCFunc>();
+     132       31999 :   if (!func) goto _NoMemory;
+     133             : 
+     134       31999 :   err = registerLabelNode(func);
+     135       31999 :   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       31999 :   func->_exitNode = newLabelNode();
+     143       31999 :   func->_end = newNodeT<CBSentinel>();
+     144             : 
+     145       31999 :   if (!func->_exitNode || !func->_end)
+     146           0 :     goto _NoMemory;
+     147             : 
+     148             :   // Function prototype.
+     149       31999 :   err = func->getDetail().init(sign);
+     150       31999 :   if (err != kErrorOk) {
+     151           0 :     setLastError(err);
+     152           0 :     return nullptr;
+     153             :   }
+     154             : 
+     155             :   // If the CodeInfo guarantees higher alignment honor it.
+     156       31999 :   if (_codeInfo.getStackAlignment() > func->_funcDetail._callConv.getNaturalStackAlignment())
+     157             :     func->_funcDetail._callConv.setNaturalStackAlignment(_codeInfo.getStackAlignment());
+     158             : 
+     159             :   // Allocate space for function arguments.
+     160       31999 :   func->_args = nullptr;
+     161       31999 :   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       31999 : CCFunc* CodeCompiler::addFunc(CCFunc* func) {
+     176             :   ASMJIT_ASSERT(_func == nullptr);
+     177       31999 :   _func = func;
+     178             : 
+     179       31999 :   addNode(func);                 // Function node.
+     180             :   CBNode* cursor = getCursor();  // {CURSOR}.
+     181       31999 :   addNode(func->getExitNode());  // Function exit label.
+     182       31999 :   addNode(func->getEnd());       // Function end marker.
+     183             : 
+     184             :   _setCursor(cursor);
+     185       31999 :   return func;
+     186             : }
+     187             : 
+     188       31999 : CCFunc* CodeCompiler::addFunc(const FuncSignature& sign) {
+     189       31999 :   CCFunc* func = newFunc(sign);
+     190             : 
+     191       31999 :   if (!func) {
+     192           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     193           0 :     return nullptr;
+     194             :   }
+     195             : 
+     196       31999 :   return addFunc(func);
+     197             : }
+     198             : 
+     199       31999 : CBSentinel* CodeCompiler::endFunc() {
+     200             :   CCFunc* func = getFunc();
+     201       31999 :   if (!func) {
+     202             :     // TODO:
+     203             :     return nullptr;
+     204             :   }
+     205             : 
+     206             :   // Add the local constant pool at the end of the function (if exists).
+     207       31999 :   if (_localConstPool) {
+     208           0 :     setCursor(func->getEnd()->getPrev());
+     209           0 :     addNode(_localConstPool);
+     210           0 :     _localConstPool = nullptr;
+     211             :   }
+     212             : 
+     213             :   // Mark as finished.
+     214       31999 :   func->_isFinished = true;
+     215       31999 :   _func = nullptr;
+     216             : 
+     217             :   CBSentinel* end = func->getEnd();
+     218       31999 :   setCursor(end);
+     219       31999 :   return end;
+     220             : }
+     221             : 
+     222             : // ============================================================================
+     223             : // [asmjit::CodeCompiler - Ret]
+     224             : // ============================================================================
+     225             : 
+     226       31999 : CCFuncRet* CodeCompiler::newRet(const Operand_& o0, const Operand_& o1) noexcept {
+     227       31999 :   CCFuncRet* node = newNodeT<CCFuncRet>(o0, o1);
+     228       31999 :   if (!node) {
+     229           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     230           0 :     return nullptr;
+     231             :   }
+     232             :   return node;
+     233             : }
+     234             : 
+     235       31999 : CCFuncRet* CodeCompiler::addRet(const Operand_& o0, const Operand_& o1) noexcept {
+     236       31999 :   CCFuncRet* node = newRet(o0, o1);
+     237       31999 :   if (!node) return nullptr;
+     238       31999 :   return static_cast<CCFuncRet*>(addNode(node));
+     239             : }
+     240             : 
+     241             : // ============================================================================
+     242             : // [asmjit::CodeCompiler - Call]
+     243             : // ============================================================================
+     244             : 
+     245       12938 : CCFuncCall* CodeCompiler::newCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     246             :   Error err;
+     247             :   uint32_t nArgs;
+     248             : 
+     249       12938 :   CCFuncCall* node = _cbHeap.allocT<CCFuncCall>(sizeof(CCFuncCall) + sizeof(Operand));
+     250       12938 :   Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CCFuncCall));
+     251             : 
+     252       12938 :   if (ASMJIT_UNLIKELY(!node))
+     253           0 :     goto _NoMemory;
+     254             : 
+     255       12938 :   opArray[0].copyFrom(o0);
+     256             :   new (node) CCFuncCall(this, instId, 0, opArray, 1);
+     257             : 
+     258       12938 :   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       12938 :   if ((nArgs = sign.getArgCount()) == 0)
+     265             :     return node;
+     266             : 
+     267       12938 :   node->_args = static_cast<Operand*>(_cbHeap.alloc(nArgs * sizeof(Operand)));
+     268       12938 :   if (!node->_args) goto _NoMemory;
+     269             : 
+     270             :   ::memset(node->_args, 0, nArgs * sizeof(Operand));
+     271       12938 :   return node;
+     272             : 
+     273           0 : _NoMemory:
+     274           0 :   setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     275           0 :   return nullptr;
+     276             : }
+     277             : 
+     278       12938 : CCFuncCall* CodeCompiler::addCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     279       12938 :   CCFuncCall* node = newCall(instId, o0, sign);
+     280       12938 :   if (!node) return nullptr;
+     281       12938 :   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      315836 : VirtReg* CodeCompiler::newVirtReg(uint32_t typeId, uint32_t signature, const char* name) noexcept {
+     322             :   size_t index = _vRegArray.getLength();
+     323      315836 :   if (ASMJIT_UNLIKELY(index > Operand::kPackedIdCount))
+     324             :     return nullptr;
+     325             : 
+     326             :   VirtReg* vreg;
+     327      385719 :   if (_vRegArray.willGrow(&_cbHeap, 1) != kErrorOk || !(vreg = _vRegZone.allocZeroedT<VirtReg>()))
+     328           0 :     return nullptr;
+     329             : 
+     330      315836 :   vreg->_id = Operand::packId(static_cast<uint32_t>(index));
+     331      315836 :   vreg->_regInfo._signature = signature;
+     332      315836 :   vreg->_name = noName;
+     333             : 
+     334             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     335      315836 :   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      315836 :   vreg->_size = TypeId::sizeOf(typeId);
+     340      315836 :   vreg->_typeId = typeId;
+     341      315836 :   vreg->_alignment = static_cast<uint8_t>(std::min<uint32_t>(vreg->_size, 64));
+     342      315836 :   vreg->_priority = 10;
+     343             : 
+     344             :   // The following are only used by `RAPass`.
+     345      315836 :   vreg->_raId = kInvalidValue;
+     346      315836 :   vreg->_state = VirtReg::kStateNone;
+     347      315836 :   vreg->_physId = Globals::kInvalidRegId;
+     348             : 
+     349             :   _vRegArray.appendUnsafe(vreg);
+     350      315836 :   return vreg;
+     351             : }
+     352             : 
+     353      315836 : Error CodeCompiler::_newReg(Reg& out, uint32_t typeId, const char* name) {
+     354             :   RegInfo regInfo;
+     355             : 
+     356      315836 :   Error err = ArchUtils::typeIdToRegInfo(getArchType(), typeId, regInfo);
+     357      315836 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     358             : 
+     359      315836 :   VirtReg* vReg = newVirtReg(typeId, regInfo.getSignature(), name);
+     360      315836 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     361             :     out.reset();
+     362           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     363             :   }
+     364             : 
+     365             :   out._initReg(regInfo.getSignature(), vReg->getId());
+     366      315836 :   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 000000000..682ff1afd --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-10-17 16:45:02Functions: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 000000000..c763b1a04 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-10-17 16:45:02Functions: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 000000000..4877dfea7 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.gcov.html @@ -0,0 +1,843 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-10-17 16:45:02Functions: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      407032 :   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      105792 :   ASMJIT_INLINE uint32_t getTypeId() const noexcept { return _typeId; }
+     110             : 
+     111             :   //! Get virtual-register's size.
+     112      337068 :   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       68050 :   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      327164 :   }
+     131             : 
+     132             :   //! Get register index.
+     133     2353364 :   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       14596 :     _physId = static_cast<uint8_t>(physId);
+     138             :   }
+     139             :   //! Reset register index.
+     140             :   ASMJIT_INLINE void resetPhysId() {
+     141      651413 :     _physId = static_cast<uint8_t>(Globals::kInvalidRegId);
+     142             :   }
+     143             : 
+     144             :   //! Get home registers mask.
+     145      365980 :   ASMJIT_INLINE uint32_t getHomeMask() const { return _homeMask; }
+     146             :   //! Add a home register index to the home registers mask.
+     147       51740 :   ASMJIT_INLINE void addHomeId(uint32_t physId) { _homeMask |= Utils::mask(physId); }
+     148             : 
+     149      367210 :   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      122829 :   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      129404 :   ASMJIT_INLINE bool isModified() const noexcept { return static_cast<bool>(_modified); }
+     159             :   //! Set whether the variable was changed.
+     160     1140320 :   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       91196 :   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       31999 :     : CBLabel(cb),
+     298       31999 :       _funcDetail(),
+     299       31999 :       _frameInfo(),
+     300       31999 :       _exitNode(nullptr),
+     301       31999 :       _end(nullptr),
+     302       31999 :       _args(nullptr),
+     303       31999 :       _isFinished(false) {
+     304             : 
+     305       31999 :     _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      127996 :   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      127996 :   ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
+     322             : 
+     323             :   //! Get function declaration.
+     324       31999 :   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       31999 :   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       31999 :   ASMJIT_INLINE CCFuncRet(CodeBuilder* cb, const Operand_& o0, const Operand_& o1) noexcept : CBNode(cb, kNodeFuncExit) {
+     393             :     orFlags(kFlagIsRet);
+     394       31999 :     _ret[0].copyFrom(o0);
+     395       31999 :     _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       12938 :     : CBInst(cb, instId, options, opArray, opCount),
+     439       12938 :       _funcDetail(),
+     440       12938 :       _args(nullptr) {
+     441             : 
+     442       12938 :     _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       12532 :   ASMJIT_INLINE bool setArg(uint32_t i, const Reg& reg) noexcept { return _setArg(i, reg); }
+     503             :   //! Set argument at `i` to `imm`.
+     504         406 :   ASMJIT_INLINE bool setArg(uint32_t i, const Imm& imm) noexcept { return _setArg(i, imm); }
+     505             : 
+     506             :   //! Set return at `i` to `var`.
+     507       12938 :   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       31999 :   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      166746 :     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     1466781 :     size_t index = Operand::unpackId(id);
+     705             : 
+     706             :     ASMJIT_ASSERT(index < _vRegArray.getLength());
+     707     1633527 :     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 000000000..f210d7e71 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html @@ -0,0 +1,196 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-10-17 16:45:02Functions: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_Ei4600
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El4600
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E14088
_ZN4PLMD6asmjit11CodeEmitter4emitEj31999
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE63998
_ZN4PLMD6asmjit11CodeEmitterC2Ej63998
_ZN4PLMD6asmjit11CodeEmitterD2Ev63998
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_518301
+
+
+ + + +
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 000000000..bb26caf05 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.func.html @@ -0,0 +1,196 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-10-17 16:45:02Functions:93129.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeEmitter12_emitOpArrayEjPKNS0_8Operand_Em0
_ZN4PLMD6asmjit11CodeEmitter12setLastErrorEjPKc0
_ZN4PLMD6asmjit11CodeEmitter14getLabelByNameEPKcmj0
_ZN4PLMD6asmjit11CodeEmitter4emitEj31999
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E14088
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_518301
_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_Ei4600
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El4600
_ZN4PLMD6asmjit11CodeEmitter4emitEji0
_ZN4PLMD6asmjit11CodeEmitter4emitEjl0
_ZN4PLMD6asmjit11CodeEmitter8commentfEPKcz0
_ZN4PLMD6asmjit11CodeEmitter8commentvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit11CodeEmitter8finalizeEv0
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE63998
_ZN4PLMD6asmjit11CodeEmitter8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeEmitterC2Ej63998
_ZN4PLMD6asmjit11CodeEmitterD0Ev0
_ZN4PLMD6asmjit11CodeEmitterD2Ev63998
_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 000000000..246d4e65d --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.gcov.html @@ -0,0 +1,338 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-10-17 16:45:02Functions: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       63998 : CodeEmitter::CodeEmitter(uint32_t type) noexcept
+      56             :   : _codeInfo(),
+      57       63998 :     _code(nullptr),
+      58       63998 :     _nextEmitter(nullptr),
+      59       63998 :     _type(static_cast<uint8_t>(type)),
+      60       63998 :     _destroyed(false),
+      61       63998 :     _finalized(false),
+      62       63998 :     _reserved(false),
+      63       63998 :     _lastError(kErrorNotInitialized),
+      64       63998 :     _privateData(0),
+      65       63998 :     _globalHints(0),
+      66       63998 :     _globalOptions(kOptionMaybeFailureCase),
+      67       63998 :     _options(0),
+      68       63998 :     _extraReg(),
+      69       63998 :     _inlineComment(nullptr),
+      70       63998 :     _none(),
+      71             :     _nativeGpReg(),
+      72       63998 :     _nativeGpArray(nullptr) {}
+      73             : 
+      74       63998 : CodeEmitter::~CodeEmitter() noexcept {
+      75       63998 :   if (_code) {
+      76       63998 :     _destroyed = true;
+      77       63998 :     _code->detach(this);
+      78             :   }
+      79       63998 : }
+      80             : 
+      81             : // ============================================================================
+      82             : // [asmjit::CodeEmitter - Events]
+      83             : // ============================================================================
+      84             : 
+      85       63998 : Error CodeEmitter::onAttach(CodeHolder* code) noexcept {
+      86             :   _codeInfo = code->getCodeInfo();
+      87       63998 :   _lastError = kErrorOk;
+      88             : 
+      89       63998 :   _globalHints = code->getGlobalHints();
+      90       63998 :   _globalOptions = code->getGlobalOptions();
+      91             : 
+      92       63998 :   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       31999 : Error CodeEmitter::emit(uint32_t instId) { return _emit(instId, _none, _none, _none, _none); }
+     232       14088 : Error CodeEmitter::emit(uint32_t instId, OP o0) { return _emit(instId, o0, _none, _none, _none); }
+     233      518301 : 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        4600 : 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        4600 : 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 000000000..e9e641b60 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-10-17 16:45:02Functions: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 000000000..5cd588ce7 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-10-17 16:45:02Functions: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 000000000..997cc99c3 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.gcov.html @@ -0,0 +1,604 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-10-17 16:45:02Functions: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      127996 :   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     1228652 :   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     1164654 :   ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; }
+     336             :   //! Set options of the next instruction.
+     337      588796 :   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     1164654 :   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      575858 :   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      822584 :   ASMJIT_INLINE void setInlineComment(const char* s) noexcept { _inlineComment = s; }
+     362             :   //! Reset annotation of the next instruction to null.
+     363     1228652 :   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      588796 :     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 000000000..5508f6f74 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-10-17 16:45:02Functions: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_10CodeBufferEm31999
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE31999
_ZN4PLMD6asmjit10CodeHolderC2Ev31999
_ZN4PLMD6asmjit10CodeHolderD2Ev31999
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb31999
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm31999
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm31999
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj63998
_ZN4PLMD6asmjit10CodeHolder4syncEv63998
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE63998
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE63998
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv63998
+
+
+ + + +
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 000000000..48d98746f --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-10-17 16:45:02Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CodeHolder10growBufferEPNS0_10CodeBufferEm31999
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj63998
_ZN4PLMD6asmjit10CodeHolder12newLabelLinkEPNS0_10LabelEntryEjml0
_ZN4PLMD6asmjit10CodeHolder13newRelocEntryEPPNS0_10RelocEntryEjj0
_ZN4PLMD6asmjit10CodeHolder13reserveBufferEPNS0_10CodeBufferEm0
_ZN4PLMD6asmjit10CodeHolder15newNamedLabelIdERjPKcmjj0
_ZN4PLMD6asmjit10CodeHolder15setErrorHandlerEPNS0_12ErrorHandlerE0
_ZN4PLMD6asmjit10CodeHolder16getLabelIdByNameEPKcmj0
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE31999
_ZN4PLMD6asmjit10CodeHolder4syncEv63998
_ZN4PLMD6asmjit10CodeHolder5resetEb0
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE63998
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE63998
_ZN4PLMD6asmjit10CodeHolder9setLoggerEPNS0_6LoggerE0
_ZN4PLMD6asmjit10CodeHolderC2Ev31999
_ZN4PLMD6asmjit10CodeHolderD2Ev31999
_ZN4PLMD6asmjit12ErrorHandlerC2Ev0
_ZN4PLMD6asmjit12ErrorHandlerD0Ev0
_ZN4PLMD6asmjit12ErrorHandlerD2Ev0
_ZN4PLMD6asmjit12_GLOBAL__N_1L28CodeHolder_hashNameAndFixLenEPKcRm0
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb31999
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm31999
_ZN4PLMD6asmjitL26CodeHolder_setGlobalOptionEPNS0_10CodeHolderEjj0
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv63998
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm31999
+
+
+ + + +
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 000000000..ed81f618a --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.gcov.html @@ -0,0 +1,799 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-10-17 16:45:02Functions: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       31999 : static void CodeHolder_resetInternal(CodeHolder* self, bool releaseMemory) noexcept {
+      67             :   // Detach all `CodeEmitter`s.
+      68       31999 :   while (self->_emitters)
+      69           0 :     self->detach(self->_emitters);
+      70             : 
+      71             :   // Reset everything into its construction state.
+      72             :   self->_codeInfo.reset();
+      73       31999 :   self->_globalHints = 0;
+      74       31999 :   self->_globalOptions = 0;
+      75       31999 :   self->_logger = nullptr;
+      76       31999 :   self->_errorHandler = nullptr;
+      77             : 
+      78       31999 :   self->_unresolvedLabelsCount = 0;
+      79       31999 :   self->_trampolinesSize = 0;
+      80             : 
+      81             :   // Reset all sections.
+      82             :   size_t numSections = self->_sections.getLength();
+      83       63998 :   for (size_t i = 0; i < numSections; i++) {
+      84       31999 :     SectionEntry* section = self->_sections[i];
+      85       31999 :     if (section->_buffer.hasData() && !section->_buffer.isExternal())
+      86             :       Internal::releaseMemory(section->_buffer._data);
+      87       31999 :     section->_buffer._data = nullptr;
+      88       31999 :     section->_buffer._capacity = 0;
+      89             :   }
+      90             : 
+      91             :   // Reset zone allocator and all containers using it.
+      92       31999 :   ZoneHeap* heap = &self->_baseHeap;
+      93             : 
+      94       31999 :   self->_namedLabels.reset(heap);
+      95             :   self->_relocations.reset();
+      96             :   self->_labels.reset();
+      97             :   self->_sections.reset();
+      98             : 
+      99       31999 :   heap->reset(&self->_baseZone);
+     100       31999 :   self->_baseZone.reset(releaseMemory);
+     101       31999 : }
+     102             : 
+     103             : // ============================================================================
+     104             : // [asmjit::CodeHolder - Construction / Destruction]
+     105             : // ============================================================================
+     106             : 
+     107       31999 : CodeHolder::CodeHolder() noexcept
+     108             :   : _codeInfo(),
+     109       31999 :     _globalHints(0),
+     110       31999 :     _globalOptions(0),
+     111       31999 :     _emitters(nullptr),
+     112       31999 :     _cgAsm(nullptr),
+     113       31999 :     _logger(nullptr),
+     114       31999 :     _errorHandler(nullptr),
+     115       31999 :     _unresolvedLabelsCount(0),
+     116       31999 :     _trampolinesSize(0),
+     117       31999 :     _baseZone(16384 - Zone::kZoneOverhead),
+     118       31999 :     _dataZone(16384 - Zone::kZoneOverhead),
+     119       31999 :     _baseHeap(&_baseZone),
+     120       31999 :     _namedLabels(&_baseHeap) {}
+     121             : 
+     122       31999 : CodeHolder::~CodeHolder() noexcept {
+     123       31999 :   CodeHolder_resetInternal(this, true);
+     124       31999 : }
+     125             : 
+     126             : // ============================================================================
+     127             : // [asmjit::CodeHolder - Init / Reset]
+     128             : // ============================================================================
+     129             : 
+     130       31999 : Error CodeHolder::init(const CodeInfo& info) noexcept {
+     131             :   // Cannot reinitialize if it's locked or there is one or more CodeEmitter
+     132             :   // attached.
+     133       31999 :   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       31999 :   Error err = _sections.willGrow(&_baseHeap);
+     141       31999 :   if (err == kErrorOk) {
+     142       31999 :     SectionEntry* se = _baseZone.allocZeroedT<SectionEntry>();
+     143       31999 :     if (ASMJIT_LIKELY(se)) {
+     144       31999 :       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       31999 :   if (ASMJIT_UNLIKELY(err)) {
+     154           0 :     _baseZone.reset(false);
+     155           0 :     return err;
+     156             :   }
+     157             :   else {
+     158             :     _codeInfo = info;
+     159       31999 :     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       63998 : Error CodeHolder::attach(CodeEmitter* emitter) noexcept {
+     172             :   // Catch a possible misuse of the API.
+     173       63998 :   if (!emitter)
+     174             :     return DebugUtils::errored(kErrorInvalidArgument);
+     175             : 
+     176             :   uint32_t type = emitter->getType();
+     177       63998 :   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       63998 :   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       63998 :   if (type == CodeEmitter::kTypeAssembler) {
+     189       31999 :     if (_cgAsm)
+     190             :       return DebugUtils::errored(kErrorSlotOccupied);
+     191       31999 :     pSlot = reinterpret_cast<CodeEmitter**>(&_cgAsm);
+     192             :   }
+     193             : 
+     194       63998 :   Error err = emitter->onAttach(this);
+     195       63998 :   if (err != kErrorOk) return err;
+     196             : 
+     197             :   // Add to a single-linked list of `CodeEmitter`s.
+     198       63998 :   emitter->_nextEmitter = _emitters;
+     199       63998 :   _emitters = emitter;
+     200       63998 :   if (pSlot) *pSlot = emitter;
+     201             : 
+     202             :   // Establish the connection.
+     203       63998 :   emitter->_code = this;
+     204       63998 :   return kErrorOk;
+     205             : }
+     206             : 
+     207       63998 : Error CodeHolder::detach(CodeEmitter* emitter) noexcept {
+     208       63998 :   if (!emitter)
+     209             :     return DebugUtils::errored(kErrorInvalidArgument);
+     210             : 
+     211       63998 :   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       63998 :   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       63998 :   if (type == CodeEmitter::kTypeAssembler)
+     228       31999 :     _cgAsm = nullptr;
+     229             : 
+     230             :   // Remove from a single-linked list of `CodeEmitter`s.
+     231       63998 :   CodeEmitter** pPrev = &_emitters;
+     232             :   for (;;) {
+     233             :     ASMJIT_ASSERT(*pPrev != nullptr);
+     234       63998 :     CodeEmitter* cur = *pPrev;
+     235             : 
+     236       63998 :     if (cur == emitter) {
+     237       63998 :       *pPrev = emitter->_nextEmitter;
+     238             :       break;
+     239             :     }
+     240             : 
+     241           0 :     pPrev = &cur->_nextEmitter;
+     242           0 :   }
+     243             : 
+     244       63998 :   emitter->_code = nullptr;
+     245       63998 :   emitter->_nextEmitter = nullptr;
+     246             : 
+     247       63998 :   return err;
+     248             : }
+     249             : 
+     250             : // ============================================================================
+     251             : // [asmjit::CodeHolder - Sync]
+     252             : // ============================================================================
+     253             : 
+     254       63998 : void CodeHolder::sync() noexcept {
+     255       63998 :   if (_cgAsm) _cgAsm->sync();
+     256       63998 : }
+     257             : 
+     258             : // ============================================================================
+     259             : // [asmjit::CodeHolder - Result Information]
+     260             : // ============================================================================
+     261             : 
+     262       63998 : size_t CodeHolder::getCodeSize() const noexcept {
+     263             :   // Reflect all changes first.
+     264       63998 :   const_cast<CodeHolder*>(this)->sync();
+     265             : 
+     266             :   // TODO: Support sections.
+     267       63998 :   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       31999 : static Error CodeHolder_reserveInternal(CodeHolder* self, CodeBuffer* cb, size_t n) noexcept {
+     294       31999 :   uint8_t* oldData = cb->_data;
+     295             :   uint8_t* newData;
+     296             : 
+     297       31999 :   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       31999 :   if (ASMJIT_UNLIKELY(!newData))
+     303             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     304             : 
+     305       31999 :   cb->_data = newData;
+     306       31999 :   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       31999 :   Assembler* a = self->_cgAsm;
+     312       31999 :   if (a && &a->_section->_buffer == cb) {
+     313             :     size_t offset = a->getOffset();
+     314             : 
+     315       31999 :     a->_bufferData = newData;
+     316       31999 :     a->_bufferEnd  = newData + n;
+     317       31999 :     a->_bufferPtr  = newData + offset;
+     318             :   }
+     319             : 
+     320             :   return kErrorOk;
+     321             : }
+     322             : 
+     323       31999 : 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       31999 :   if (_cgAsm) _cgAsm->sync();
+     329             : 
+     330             :   // Now the length of the section must be valid.
+     331             :   size_t length = cb->getLength();
+     332       31999 :   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       31999 :   size_t required = cb->getLength() + n;
+     339       31999 :   if (ASMJIT_UNLIKELY(required <= capacity)) return kErrorOk;
+     340             : 
+     341       31999 :   if (cb->isFixedSize())
+     342             :     return DebugUtils::errored(kErrorCodeTooLarge);
+     343             : 
+     344       31999 :   if (capacity < 8096)
+     345             :     capacity = 8096;
+     346             :   else
+     347           0 :     capacity += Globals::kAllocOverhead;
+     348             : 
+     349             :   do {
+     350             :     size_t old = capacity;
+     351       31999 :     if (capacity < Globals::kAllocThreshold)
+     352       31999 :       capacity *= 2;
+     353             :     else
+     354           0 :       capacity += Globals::kAllocThreshold;
+     355             : 
+     356       31999 :     if (capacity < Globals::kAllocThreshold)
+     357       31999 :       capacity *= 2;
+     358             :     else
+     359           0 :       capacity += Globals::kAllocThreshold;
+     360             : 
+     361             :     // Overflow.
+     362       31999 :     if (ASMJIT_UNLIKELY(old > capacity))
+     363             :       return DebugUtils::errored(kErrorNoHeapMemory);
+     364       31999 :   } while (capacity - Globals::kAllocOverhead < required);
+     365             : 
+     366       31999 :   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       63998 : Error CodeHolder::newLabelId(uint32_t& idOut) noexcept {
+     450       63998 :   idOut = 0;
+     451             : 
+     452             :   size_t index = _labels.getLength();
+     453       63998 :   if (ASMJIT_LIKELY(index >= Operand::kPackedIdCount))
+     454             :     return DebugUtils::errored(kErrorLabelIndexOverflow);
+     455             : 
+     456       95997 :   ASMJIT_PROPAGATE(_labels.willGrow(&_baseHeap));
+     457       63998 :   LabelEntry* le = _baseHeap.allocZeroedT<LabelEntry>();
+     458             : 
+     459       63998 :   if (ASMJIT_UNLIKELY(!le))
+     460             :     return DebugUtils::errored(kErrorNoHeapMemory);;
+     461             : 
+     462       63998 :   uint32_t id = Operand::packId(static_cast<uint32_t>(index));
+     463             :   le->_setId(id);
+     464       63998 :   le->_parentId = 0;
+     465       63998 :   le->_sectionId = SectionEntry::kInvalidId;
+     466       63998 :   le->_offset = 0;
+     467             : 
+     468             :   _labels.appendUnsafe(le);
+     469       63998 :   idOut = id;
+     470       63998 :   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       31999 : size_t CodeHolder::relocate(void* _dst, uint64_t baseAddress) const noexcept {
+     588       31999 :   SectionEntry* section = _sections[0];
+     589             :   ASMJIT_ASSERT(section != nullptr);
+     590             : 
+     591             :   uint8_t* dst = static_cast<uint8_t*>(_dst);
+     592       31999 :   if (baseAddress == Globals::kNoBaseAddress)
+     593       31999 :     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       31999 :   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       31999 :   ::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       31999 :   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 000000000..837d6b3e4 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..2f367b9be --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..96719a21f --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.gcov.html @@ -0,0 +1,853 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-10-17 16:45:02Functions: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      128026 :     : _archInfo(),
+     137      128026 :       _stackAlignment(0),
+     138      128026 :       _cdeclCallConv(CallConv::kIdNone),
+     139      128026 :       _stdCallConv(CallConv::kIdNone),
+     140      128026 :       _fastCallConv(CallConv::kIdNone),
+     141      128026 :       _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       31999 :     return _archInfo._type != ArchInfo::kTypeNone;
+     155             :   }
+     156             : 
+     157             :   ASMJIT_INLINE void init(const CodeInfo& other) noexcept {
+     158       95997 :     _archInfo = other._archInfo;
+     159       95997 :     _packedMiscInfo = other._packedMiscInfo;
+     160       95997 :     _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       31999 :     _stackAlignment = 0;
+     172       31999 :     _cdeclCallConv = CallConv::kIdNone;
+     173       31999 :     _stdCallConv = CallConv::kIdNone;
+     174       31999 :     _fastCallConv = CallConv::kIdNone;
+     175       31999 :     _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       31999 :   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       31999 :   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       95997 :   ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     263       31999 :   ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
+     264             : 
+     265       31999 :   ASMJIT_INLINE bool isExternal() const noexcept { return _isExternal; }
+     266       31999 :   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       63998 :   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       31999 :     _nameAsU32[0] = Utils::pack32_4x8(c0, c1, c2, c3);
+     310       31999 :     _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       63998 :   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       63998 :   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       63998 :   ASMJIT_INLINE uint32_t getGlobalHints() const noexcept { return _globalHints; }
+     575             :   //! Get global options, internally propagated to all `CodeEmitter`s attached.
+     576       63998 :   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       63998 :   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       31999 :   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       63998 :     size_t index = static_cast<size_t>(Operand::unpackId(id));
+     700       63998 :     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 000000000..1e8a15b91 --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..f859ea92c --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..3745e84af --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.gcov.html @@ -0,0 +1,613 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..8d9aa78a7 --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0310.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..675ed285d --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0310.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..deeef4215 --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.gcov.html @@ -0,0 +1,362 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0310.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..94fe40b8d --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13714991.9 %
Date:2024-10-17 16:45:02Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv258
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE258
_ZN4PLMD6asmjit7CpuInfo7getHostEv32029
+
+
+ + + +
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 000000000..7e5b7e588 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13714991.9 %
Date:2024-10-17 16:45:02Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE31999
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE44937
_ZN4PLMD6asmjit8CallConv4initEj44937
+
+
+ + + +
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 000000000..fddd75149 --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-10-17 16:45:02Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE44937
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE31999
_ZN4PLMD6asmjit8CallConv4initEj44937
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31999
_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 000000000..9715e3473 --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.gcov.html @@ -0,0 +1,288 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-10-17 16:45:02Functions: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       44937 : ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId) noexcept {
+      57             :   reset();
+      58             : 
+      59             : #if defined(ASMJIT_BUILD_X86)
+      60       44937 :   if (CallConv::isX86Family(ccId))
+      61       44937 :     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       44937 : ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) {
+      77             :   uint32_t ccId = sign.getCallConv();
+      78       44937 :   CallConv& cc = _callConv;
+      79             : 
+      80             :   uint32_t argCount = sign.getArgCount();
+      81       44937 :   if (ASMJIT_UNLIKELY(argCount > kFuncArgCount))
+      82             :     return DebugUtils::errored(kErrorInvalidArgument);
+      83             : 
+      84       44937 :   ASMJIT_PROPAGATE(cc.init(ccId));
+      85             : 
+      86       44937 :   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       58393 :   for (uint32_t i = 0; i < argCount; i++) {
+      91             :     Value& arg = _args[i];
+      92       13456 :     arg.initTypeId(TypeId::deabstract(args[i], deabstractDelta));
+      93             :   }
+      94       44937 :   _argCount = static_cast<uint8_t>(argCount);
+      95             : 
+      96             :   uint32_t ret = sign.getRet();
+      97       44937 :   if (ret != TypeId::kVoid) {
+      98             :     _rets[0].initTypeId(TypeId::deabstract(ret, deabstractDelta));
+      99       44937 :     _retCount = 1;
+     100             :   }
+     101             : 
+     102             : #if defined(ASMJIT_BUILD_X86)
+     103       44937 :   if (CallConv::isX86Family(ccId))
+     104       44937 :     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       31999 : 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       31999 :   if (CallConv::isX86Family(ccId))
+     126       31999 :     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       31999 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitProlog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     165             : #if defined(ASMJIT_BUILD_X86)
+     166       31999 :   if (emitter->getArchInfo().isX86Family())
+     167       31999 :     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       31999 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitEpilog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     179             : #if defined(ASMJIT_BUILD_X86)
+     180       31999 :   if (emitter->getArchInfo().isX86Family())
+     181       31999 :     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 000000000..f3eae6f8c --- /dev/null +++ b/coverage-libs/asmjit/func.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-10-17 16:45:02Functions: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 000000000..cff0aec4e --- /dev/null +++ b/coverage-libs/asmjit/func.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-10-17 16:45:02Functions: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 000000000..df6045865 --- /dev/null +++ b/coverage-libs/asmjit/func.h.gcov.html @@ -0,0 +1,1403 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-10-17 16:45:02Functions: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       44937 :   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       44937 :     ::memset(_passedOrder, 0xFF, sizeof(_passedOrder));
+     263             :   }
+     264             : 
+     265             :   // --------------------------------------------------------------------------
+     266             :   // [Accessors]
+     267             :   // --------------------------------------------------------------------------
+     268             : 
+     269             :   //! Get calling convention id, see \ref Id.
+     270       31999 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     271             :   //! Set calling convention id, see \ref Id.
+     272       44937 :   ASMJIT_INLINE void setId(uint32_t id) noexcept { _id = static_cast<uint8_t>(id); }
+     273             : 
+     274             :   //! Get architecture type.
+     275       76936 :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archType; }
+     276             :   //! Set architecture type.
+     277       44937 :   ASMJIT_INLINE void setArchType(uint32_t archType) noexcept { _archType = static_cast<uint8_t>(archType); }
+     278             : 
+     279             :   //! Get calling convention algorithm, see \ref Algorithm.
+     280       44937 :   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       57581 :   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       95997 :   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       44937 :     _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       31999 :   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       44937 :   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      172933 :     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       44937 :     _passedOrder[kind].packed[0] = p0;
+     334       44937 :     _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      140934 :     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       44937 :   }
+     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       44937 :     _callConv = static_cast<uint8_t>(ccId);
+     443       44937 :     _argCount = static_cast<uint8_t>(argCount);
+     444       44937 :     _vaIndex = kNoVarArgs;
+     445       44937 :     _ret = ret;
+     446       44937 :     _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       44937 :   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       57875 :   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       44937 :   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       44937 :   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       31999 :   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       12420 :   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         518 :   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       58393 :     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       12644 :       _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         812 :       _value |= (regType << kRegTypeShift) | (regId << kRegIdShift) | kIsByReg;
+     732       44937 :     }
+     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       51458 :     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       59205 :     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       70519 :     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       71331 :     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       44937 :   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       44937 :   ASMJIT_INLINE uint32_t getRetCount() const noexcept { return _retCount; }
+     795             :   //! Get the number of function arguments.
+     796      148267 :   ASMJIT_INLINE uint32_t getArgCount() const noexcept { return _argCount; }
+     797             : 
+     798             :   //! Get whether the function has a return value.
+     799       31999 :   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       57875 :     return _usedRegs[kind];
+     853             :   }
+     854             : 
+     855             :   ASMJIT_INLINE void addUsedRegs(uint32_t kind, uint32_t regs) noexcept {
+     856             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     857       13456 :     _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       31999 :   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       31999 :     _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       95997 :   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       27399 :   ASMJIT_INLINE bool hasCalls() const noexcept { return (_attributes & kAttrHasCalls) != 0; }
+     952             :   //! Set `kFlagHasCalls` to true.
+     953       12938 :   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       31999 :   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       31999 :   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       31999 :   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      127996 :     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       31999 :     _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       31999 :   ASMJIT_INLINE uint32_t getStackFrameAlignment() const noexcept { return _stackFrameAlignment; }
+    1015             :   //! Get minimum call-frame alignment required by the function.
+    1016       31999 :   ASMJIT_INLINE uint32_t getCallFrameAlignment() const noexcept { return _callFrameAlignment; }
+    1017             : 
+    1018       31999 :   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       31999 :     _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       12938 :   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       31999 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1048       31999 :   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      127996 :   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       95997 :   ASMJIT_INLINE bool hasDynamicAlignment() const noexcept { return static_cast<bool>(_dynamicAlignment); }
+    1096             : 
+    1097       31999 :   ASMJIT_INLINE bool hasMmxCleanup() const noexcept { return static_cast<bool>(_mmxCleanup); }
+    1098       31999 :   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      127996 :     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       31999 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1122           0 :   ASMJIT_INLINE uint32_t getStackArgsOffset() const noexcept { return _stackArgsOffset; }
+    1123             : 
+    1124       63998 :   ASMJIT_INLINE bool hasStackAdjustment() const noexcept { return _stackAdjustment != 0; }
+    1125             :   ASMJIT_INLINE uint32_t getStackAdjustment() const noexcept { return _stackAdjustment; }
+    1126             : 
+    1127       31999 :   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 000000000..3469ff9dc --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:090.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..3475e86f4 --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:090.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..4add06a30 --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:090.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..68962b283 --- /dev/null +++ b/coverage-libs/asmjit/globals.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2366.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..ac3e91c0e --- /dev/null +++ b/coverage-libs/asmjit/globals.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2366.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..e8c243c70 --- /dev/null +++ b/coverage-libs/asmjit/globals.h.gcov.html @@ -0,0 +1,446 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2366.7 %
Date:2024-10-17 16:45:02Functions: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      194842 : 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      194674 : 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 000000000..d711b28e0 --- /dev/null +++ b/coverage-libs/asmjit/index-sort-f.html @@ -0,0 +1,603 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2260712431.7 %
Date:2024-10-17 16:45:02Functions:14035239.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
inst.cpp +
0.0%
+
0.0 %0 / 60.0 %0 / 2
x86compiler.h +
66.7%66.7%
+
66.7 %4 / 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
func.cpp +
77.4%77.4%
+
77.4 %24 / 3171.4 %5 / 7
x86compiler.cpp +
31.8%31.8%
+
31.8 %48 / 15171.4 %5 / 7
runtime.cpp +
73.7%73.7%
+
73.7 %28 / 3875.0 %9 / 12
osutils.cpp +
81.8%81.8%
+
81.8 %18 / 2280.0 %4 / 5
func.h +
70.1%70.1%
+
70.1 %68 / 97-0 / 0
x86regalloc_p.h +
69.4%69.4%
+
69.4 %34 / 49-0 / 0
arch.h +
75.0%75.0%
+
75.0 %6 / 8-0 / 0
logging.h +
0.0%
+
0.0 %0 / 5-0 / 0
assembler.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
moved_string.h +
22.2%22.2%
+
22.2 %6 / 27-0 / 0
regalloc_p.h +
66.7%66.7%
+
66.7 %36 / 54-0 / 0
utils.h +
48.9%48.9%
+
48.9 %22 / 45-0 / 0
x86misc.h +
59.5%59.5%
+
59.5 %22 / 37-0 / 0
codecompiler.h +
64.1%64.1%
+
64.1 %41 / 64-0 / 0
x86inst.h +
66.7%66.7%
+
66.7 %10 / 15-0 / 0
inst.h +
40.0%40.0%
+
40.0 %2 / 5-0 / 0
codeholder.h +
78.0%78.0%
+
78.0 %32 / 41-0 / 0
runtime.h +
100.0%
+
100.0 %3 / 3-0 / 0
cpuinfo.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
globals.h +
66.7%66.7%
+
66.7 %2 / 3-0 / 0
operand.h +
54.4%54.4%
+
54.4 %49 / 90-0 / 0
codebuilder.h +
53.2%53.2%
+
53.2 %50 / 94-0 / 0
codeemitter.h +
81.8%81.8%
+
81.8 %9 / 11-0 / 0
osutils.h +
100.0%
+
100.0 %5 / 5-0 / 0
x86assembler.h +
100.0%
+
100.0 %2 / 2-0 / 0
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
constpool.h +
0.0%
+
0.0 %0 / 31-0 / 0
x86emitter.h +
63.0%63.0%
+
63.0 %17 / 27-0 / 0
arch.cpp +
62.5%62.5%
+
62.5 %25 / 40100.0 %2 / 2
zone.h +
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 000000000..ff172c8dc --- /dev/null +++ b/coverage-libs/asmjit/index-sort-l.html @@ -0,0 +1,603 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2260712431.7 %
Date:2024-10-17 16:45:02Functions: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
cpuinfo.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
x86misc.h +
59.5%59.5%
+
59.5 %22 / 37-0 / 0
arch.cpp +
62.5%62.5%
+
62.5 %25 / 40100.0 %2 / 2
x86emitter.h +
63.0%63.0%
+
63.0 %17 / 27-0 / 0
codecompiler.h +
64.1%64.1%
+
64.1 %41 / 64-0 / 0
globals.h +
66.7%66.7%
+
66.7 %2 / 3-0 / 0
x86compiler.h +
66.7%66.7%
+
66.7 %4 / 60.0 %0 / 2
x86inst.h +
66.7%66.7%
+
66.7 %10 / 15-0 / 0
regalloc_p.h +
66.7%66.7%
+
66.7 %36 / 54-0 / 0
x86regalloc_p.h +
69.4%69.4%
+
69.4 %34 / 49-0 / 0
func.h +
70.1%70.1%
+
70.1 %68 / 97-0 / 0
runtime.cpp +
73.7%73.7%
+
73.7 %28 / 3875.0 %9 / 12
arch.h +
75.0%75.0%
+
75.0 %6 / 8-0 / 0
func.cpp +
77.4%77.4%
+
77.4 %24 / 3171.4 %5 / 7
codeholder.h +
78.0%78.0%
+
78.0 %32 / 41-0 / 0
zone.h +
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 000000000..ecc2ea881 --- /dev/null +++ b/coverage-libs/asmjit/index.html @@ -0,0 +1,603 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2260712431.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..87d2b9687 --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:060.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..25f7cb673 --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:060.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..6404c210e --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:060.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..1629eb8bd --- /dev/null +++ b/coverage-libs/asmjit/inst.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2540.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..88b69af87 --- /dev/null +++ b/coverage-libs/asmjit/inst.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2540.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..10e0c0116 --- /dev/null +++ b/coverage-libs/asmjit/inst.h.gcov.html @@ -0,0 +1,213 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2540.0 %
Date:2024-10-17 16:45:02Functions: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      588796 :       : instId(0),
+      78             :         options(0),
+      79      588796 :         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 000000000..f36260e3f --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01470.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..cc80ab9ee --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01470.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..70a7634a7 --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.gcov.html @@ -0,0 +1,600 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01470.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..76932b8bc --- /dev/null +++ b/coverage-libs/asmjit/logging.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:050.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..5a593a7d5 --- /dev/null +++ b/coverage-libs/asmjit/logging.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:050.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..b3c96ac42 --- /dev/null +++ b/coverage-libs/asmjit/logging.h.gcov.html @@ -0,0 +1,393 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:050.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..503b80736 --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/moved_string.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - moved_string.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:62722.2 %
Date:2024-10-17 16:45:02Functions: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 000000000..6219d8504 --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/moved_string.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - moved_string.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:62722.2 %
Date:2024-10-17 16:45:02Functions: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 000000000..e5fdfbf8e --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.gcov.html @@ -0,0 +1,394 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/moved_string.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - moved_string.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:62722.2 %
Date:2024-10-17 16:45:02Functions: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       31999 :   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       31999 :   ASMJIT_INLINE StringBuilderTmp() noexcept : StringBuilder(NoInit) {
+     289       31999 :     _data = _embeddedData;
+     290       31999 :     _data[0] = 0;
+     291             : 
+     292       31999 :     _length = 0;
+     293       31999 :     _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 000000000..ef4dd36f3 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-10-17 16:45:02Functions: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 000000000..f2793c005 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-10-17 16:45:02Functions: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 000000000..d58bb5767 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.gcov.html @@ -0,0 +1,1675 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-10-17 16:45:02Functions: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     1582319 :   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      379834 :   static ASMJIT_INLINE uint32_t packId(uint32_t id) noexcept { return id + kPackedIdMin; }
+     164             :   //! Convert a packed-id back to real-id.
+     165      211369 :   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     1075900 :   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         812 :   ASMJIT_INLINE void setSignature(uint32_t signature) noexcept { _signature = signature; }
+     270             : 
+     271      515884 :   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     3695625 :   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       91196 :     _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     1912804 :   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      694968 :   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      339678 :   ASMJIT_INLINE Operand() noexcept { reset(); }
+     445             :   //! Create a reference to `other` operand.
+     446       64810 :   ASMJIT_INLINE Operand(const Operand& other) noexcept { _init(other); }
+     447             :   //! Create a reference to `other` operand.
+     448      105792 :   explicit ASMJIT_INLINE Operand(const Operand_& other) noexcept { _init(other); }
+     449             :   //! Create a completely uninitialized operand (dangerous).
+     450       11470 :   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     1027932 :     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     2351959 :     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       31999 :   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      297612 :   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       14900 :   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     1753450 :     _signature = signature;
+     827     1753450 :     _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      827934 :   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      588796 :   ASMJIT_INLINE uint32_t getSignature() const noexcept { return _signature; }
+     852             :   //! Get register id or 0.
+     853      588796 :   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       91196 :     uint32_t signature = (baseType  << kSignatureMemBaseTypeShift ) |
+     943             :                          (indexType << kSignatureMemIndexTypeShift) |
+     944           0 :                          (size      << kSignatureSizeShift        ) ;
+     945             : 
+     946       91196 :     _init_packed_d0_d1(kOpMem | signature | flags, indexId);
+     947       91196 :     _mem.base = baseId;
+     948       91196 :     _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       91196 :   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      166746 :   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      166746 :   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      257942 :   ASMJIT_INLINE uint32_t getBaseId() const noexcept { return _mem.base; }
+    1019             :   //! Get id of the INDEX register.
+    1020      174569 :   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       91196 :     _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       91196 :   }
+    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      174569 :   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       91196 :     _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      116842 :     _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      117248 :   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      105372 : 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      315836 :   static ASMJIT_INLINE bool isValid(uint32_t typeId) noexcept { return typeId >= _kIntStart && typeId <= _kVec512End; }
+    1461       58393 :   static ASMJIT_INLINE bool isAbstract(uint32_t typeId) noexcept { return typeId >= kIntPtr && typeId <= kUIntPtr; }
+    1462       13456 :   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       12644 :   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      105792 :   static ASMJIT_INLINE bool isVec32(uint32_t typeId) noexcept { return typeId >= _kVec32Start && typeId <= _kVec32End; }
+    1473      105792 :   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      631672 :     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      105792 :     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       58393 :     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 000000000..3c84fb77e --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-10-17 16:45:02Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj31999
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm31999
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv32029
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv64028
+
+
+ + + +
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 000000000..d3f7543bc --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-10-17 16:45:02Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj31999
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv32029
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm31999
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv64028
+
+
+ + + +
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 000000000..d297cbe95 --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.gcov.html @@ -0,0 +1,330 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-10-17 16:45:02Functions: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       64028 : static const VMemInfo& OSUtils_GetVMemInfo() noexcept {
+     140             :   static VMemInfo vmi;
+     141       64028 :   if (ASMJIT_UNLIKELY(!vmi.pageSize)) {
+     142         258 :     size_t pageSize = ::getpagesize();
+     143         258 :     vmi.pageSize = pageSize;
+     144         516 :     vmi.pageGranularity = std::max<size_t>(pageSize, 65536);
+     145             :   }
+     146       64028 :   return vmi;
+     147             : };
+     148             : 
+     149       32029 : VMemInfo OSUtils::getVirtualMemoryInfo() noexcept { return OSUtils_GetVMemInfo(); }
+     150             : 
+     151       31999 : void* OSUtils::allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept {
+     152       31999 :   const VMemInfo& vmi = OSUtils_GetVMemInfo();
+     153             : 
+     154       31999 :   size_t alignedSize = Utils::alignTo<size_t>(size, vmi.pageSize);
+     155             :   int protection = PROT_READ;
+     156             : 
+     157       31999 :   if (flags & kVMWritable  ) protection |= PROT_WRITE;
+     158       31999 :   if (flags & kVMExecutable) protection |= PROT_EXEC;
+     159             : 
+     160       31999 :   void* mbase = ::mmap(nullptr, alignedSize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+     161       31999 :   if (ASMJIT_UNLIKELY(mbase == MAP_FAILED)) return nullptr;
+     162             : 
+     163       31999 :   if (allocated) *allocated = alignedSize;
+     164             :   return mbase;
+     165             : }
+     166             : 
+     167       31999 : Error OSUtils::releaseVirtualMemory(void* p, size_t size) noexcept {
+     168       31999 :   if (ASMJIT_UNLIKELY(::munmap(p, size) != 0))
+     169             :     return DebugUtils::errored(kErrorInvalidState);
+     170             : 
+     171       31999 :   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 000000000..df4adbc9c --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..f309c5724 --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..fdbc5f80f --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.gcov.html @@ -0,0 +1,283 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-10-17 16:45:02Functions: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       32029 :   ASMJIT_INLINE Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
+     153             :   //! Destroy the `Lock` instance.
+     154       32029 :   ASMJIT_INLINE ~Lock() noexcept { pthread_mutex_destroy(&_handle); }
+     155             : 
+     156             :   //! Lock.
+     157       31999 :   ASMJIT_INLINE void lock() noexcept { pthread_mutex_lock(&_handle); }
+     158             :   //! Unlock.
+     159       31999 :   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       31999 :   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 000000000..485a0a8c8 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-10-17 16:45:02Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv31999
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv31999
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv31999
_ZN4PLMD6asmjit6RAPass7cleanupEv31999
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE31999
_ZN4PLMD6asmjit6RAPassC2Ev31999
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE39456
+
+
+ + + +
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 000000000..4b6f929f1 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-10-17 16:45:02Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE39456
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv31999
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv31999
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv31999
_ZN4PLMD6asmjit6RAPass7cleanupEv31999
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE31999
_ZN4PLMD6asmjit6RAPassC2Ev31999
_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 000000000..254cd251b --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.gcov.html @@ -0,0 +1,696 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-10-17 16:45:02Functions: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       31999 : RAPass::RAPass() noexcept :
+      51             :   CBPass("RA"),
+      52       31999 :   _varMapToVaListOffset(0) {}
+      53           0 : RAPass::~RAPass() noexcept {}
+      54             : 
+      55             : // ============================================================================
+      56             : // [asmjit::RAPass - Interface]
+      57             : // ============================================================================
+      58             : 
+      59       31999 : Error RAPass::process(Zone* zone) noexcept {
+      60       31999 :   _zone = zone;
+      61       31999 :   _heap.reset(zone);
+      62       31999 :   _emitComments = (cb()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) != 0;
+      63             : 
+      64             :   Error err = kErrorOk;
+      65             :   CBNode* node = cc()->getFirstNode();
+      66       31999 :   if (!node) return err;
+      67             : 
+      68             :   do {
+      69       31999 :     if (node->getType() == CBNode::kNodeFunc) {
+      70             :       CCFunc* func = static_cast<CCFunc*>(node);
+      71             :       node = func->getEnd();
+      72             : 
+      73       31999 :       err = compile(func);
+      74       31999 :       if (err) break;
+      75             :     }
+      76             : 
+      77             :     // Find a function by skipping all nodes that are not `kNodeFunc`.
+      78             :     do {
+      79             :       node = node->getNext();
+      80       31999 :     } while (node && node->getType() != CBNode::kNodeFunc);
+      81       31999 :   } while (node);
+      82             : 
+      83       31999 :   _heap.reset(nullptr);
+      84       31999 :   _zone = nullptr;
+      85       31999 :   return err;
+      86             : }
+      87             : 
+      88       31999 : Error RAPass::compile(CCFunc* func) noexcept {
+      89       31999 :   ASMJIT_PROPAGATE(prepare(func));
+      90             : 
+      91             :   Error err;
+      92             :   do {
+      93       31999 :     err = fetch();
+      94       31999 :     if (err) break;
+      95             : 
+      96       31999 :     err = removeUnreachableCode();
+      97       31999 :     if (err) break;
+      98             : 
+      99       31999 :     err = livenessAnalysis();
+     100       31999 :     if (err) break;
+     101             : 
+     102             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     103       31999 :     if (cc()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) {
+     104           0 :       err = annotate();
+     105           0 :       if (err) break;
+     106             :     }
+     107             : #endif // !ASMJIT_DISABLE_LOGGING
+     108             : 
+     109       31999 :     err = translate();
+     110             :   } while (false);
+     111             : 
+     112       31999 :   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       31999 :   return err;
+     119             : }
+     120             : 
+     121       31999 : Error RAPass::prepare(CCFunc* func) noexcept {
+     122             :   CBNode* end = func->getEnd();
+     123             : 
+     124       31999 :   _func = func;
+     125       31999 :   _stop = end->getNext();
+     126             : 
+     127             :   _unreachableList.reset();
+     128             :   _returningList.reset();
+     129             :   _jccList.reset();
+     130             :   _contextVd.reset();
+     131             : 
+     132       31999 :   _memVarCells = nullptr;
+     133       31999 :   _memStackCells = nullptr;
+     134             : 
+     135       31999 :   _mem1ByteVarsUsed = 0;
+     136       31999 :   _mem2ByteVarsUsed = 0;
+     137       31999 :   _mem4ByteVarsUsed = 0;
+     138       31999 :   _mem8ByteVarsUsed = 0;
+     139       31999 :   _mem16ByteVarsUsed = 0;
+     140       31999 :   _mem32ByteVarsUsed = 0;
+     141       31999 :   _mem64ByteVarsUsed = 0;
+     142       31999 :   _memStackCellsUsed = 0;
+     143             : 
+     144       31999 :   _memMaxAlign = 0;
+     145       31999 :   _memVarTotal = 0;
+     146       31999 :   _memStackTotal = 0;
+     147       31999 :   _memAllTotal = 0;
+     148       31999 :   _annotationLength = 12;
+     149             : 
+     150       31999 :   return kErrorOk;
+     151             : }
+     152             : 
+     153       31999 : void RAPass::cleanup() noexcept {
+     154             :   VirtReg** virtArray = _contextVd.getData();
+     155             :   size_t virtCount = _contextVd.getLength();
+     156             : 
+     157      347835 :   for (size_t i = 0; i < virtCount; i++) {
+     158      315836 :     VirtReg* vreg = virtArray[i];
+     159      315836 :     vreg->_raId = kInvalidValue;
+     160             :     vreg->resetPhysId();
+     161             :   }
+     162             : 
+     163             :   _contextVd.reset();
+     164       31999 : }
+     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       39456 : RACell* RAPass::_newVarCell(VirtReg* vreg) {
+     188             :   ASMJIT_ASSERT(vreg->_memCell == nullptr);
+     189             : 
+     190             :   RACell* cell;
+     191       39456 :   uint32_t size = vreg->getSize();
+     192             : 
+     193       39456 :   if (vreg->isStack()) {
+     194           0 :     cell = _newStackCell(size, vreg->getAlignment());
+     195           0 :     if (ASMJIT_UNLIKELY(!cell)) return nullptr;
+     196             :   }
+     197             :   else {
+     198       39456 :     cell = static_cast<RACell*>(_zone->alloc(sizeof(RACell)));
+     199       39456 :     if (!cell) goto _NoMemory;
+     200             : 
+     201       39456 :     cell->next = _memVarCells;
+     202       39456 :     cell->offset = 0;
+     203       39456 :     cell->size = size;
+     204       39456 :     cell->alignment = size;
+     205             : 
+     206       39456 :     _memVarCells = cell;
+     207       39456 :     _memMaxAlign = std::max<uint32_t>(_memMaxAlign, size);
+     208       39456 :     _memVarTotal += size;
+     209             : 
+     210       39456 :     switch (size) {
+     211           0 :       case  1: _mem1ByteVarsUsed++ ; break;
+     212           0 :       case  2: _mem2ByteVarsUsed++ ; break;
+     213           0 :       case  4: _mem4ByteVarsUsed++ ; break;
+     214       39456 :       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       39456 :   vreg->_memCell = cell;
+     225       39456 :   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       31999 : Error RAPass::resolveCellOffsets() {
+     271       31999 :   RACell* varCell = _memVarCells;
+     272       31999 :   RACell* stackCell = _memStackCells;
+     273             : 
+     274             :   uint32_t pos64 = 0;
+     275       31999 :   uint32_t pos32 = pos64 + _mem64ByteVarsUsed * 64;
+     276       31999 :   uint32_t pos16 = pos32 + _mem32ByteVarsUsed * 32;
+     277       31999 :   uint32_t pos8  = pos16 + _mem16ByteVarsUsed * 16;
+     278       31999 :   uint32_t pos4  = pos8  + _mem8ByteVarsUsed  * 8 ;
+     279       31999 :   uint32_t pos2  = pos4  + _mem4ByteVarsUsed  * 4 ;
+     280       31999 :   uint32_t pos1  = pos2  + _mem2ByteVarsUsed  * 2 ;
+     281             : 
+     282             :   // Assign home slots.
+     283       71455 :   while (varCell) {
+     284       39456 :     uint32_t size = varCell->size;
+     285             :     uint32_t offset = 0;
+     286             : 
+     287       39456 :     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       39456 :       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       39456 :     varCell->offset = static_cast<int32_t>(offset);
+     301       39456 :     varCell = varCell->next;
+     302             :   }
+     303             : 
+     304             :   // Assign stack slots.
+     305       31999 :   uint32_t stackPos = pos1 + _mem1ByteVarsUsed;
+     306       31999 :   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       31999 :   _memAllTotal = stackPos;
+     319       31999 :   return kErrorOk;
+     320             : }
+     321             : 
+     322             : // ============================================================================
+     323             : // [asmjit::RAPass - RemoveUnreachableCode]
+     324             : // ============================================================================
+     325             : 
+     326       31999 : Error RAPass::removeUnreachableCode() {
+     327             :   ZoneList<CBNode*>::Link* link = _unreachableList.getFirst();
+     328             :   CBNode* stop = getStop();
+     329             : 
+     330       63998 :   while (link) {
+     331             :     CBNode* node = link->getValue();
+     332       31999 :     if (node && node->getPrev() && node != stop) {
+     333             :       // Locate all unreachable nodes.
+     334             :       CBNode* first = node;
+     335             :       do {
+     336       31999 :         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       31999 :       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       31999 :   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       31999 : Error RAPass::livenessAnalysis() {
+     385             :   uint32_t bLen = static_cast<uint32_t>(
+     386       31999 :     ((_contextVd.getLength() + RABits::kEntityBits - 1) / RABits::kEntityBits));
+     387             : 
+     388             :   // No variables.
+     389       31999 :   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       31999 :   size_t varMapToVaListOffset = _varMapToVaListOffset;
+     405             :   RABits* bCur = newBits(bLen);
+     406       31999 :   if (ASMJIT_UNLIKELY(!bCur)) goto NoMem;
+     407             : 
+     408             :   // Allocate bits for code visited first time.
+     409      490903 : Visit:
+     410             :   for (;;) {
+     411             :     wd = node->getPassData<RAData>();
+     412      490903 :     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      490903 :     if (!bTmp) goto NoMem;
+     421             : 
+     422             :     wd = node->getPassData<RAData>();
+     423      490903 :     wd->liveness = bTmp;
+     424             : 
+     425      490903 :     uint32_t tiedTotal = wd->tiedTotal;
+     426             :     TiedReg* tiedArray = reinterpret_cast<TiedReg*>(((uint8_t*)wd) + varMapToVaListOffset);
+     427             : 
+     428     1279104 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+     429      788201 :       TiedReg* tied = &tiedArray[i];
+     430      788201 :       VirtReg* vreg = tied->vreg;
+     431             : 
+     432      788201 :       uint32_t flags = tied->flags;
+     433      788201 :       uint32_t raId = vreg->_raId;
+     434             : 
+     435      788201 :       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      490903 :     if (node->getType() == CBNode::kNodeLabel)
+     448           0 :       goto Target;
+     449             : 
+     450      490903 :     if (node == func)
+     451       31999 :       goto Done;
+     452             : 
+     453             :     ASMJIT_ASSERT(node->getPrev());
+     454             :     node = node->getPrev();
+     455      458904 :   }
+     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       31999 :   if (ltCur) {
+     540           0 :     node = ltCur->node;
+     541           0 :     from = ltCur->from;
+     542             : 
+     543           0 :     goto JumpNext;
+     544             :   }
+     545             : 
+     546             :   retPtr = retPtr->getNext();
+     547       31999 :   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 000000000..0f3796fda --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..42953cef9 --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..c751f448b --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.gcov.html @@ -0,0 +1,673 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-10-17 16:45:02Functions: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      788201 :     this->vreg = vreg;
+     101      788201 :     this->flags = flags;
+     102      788201 :     this->refCount = 0;
+     103      788201 :     this->inPhysId = Globals::kInvalidRegId;
+     104      788201 :     this->outPhysId = Globals::kInvalidRegId;
+     105      788201 :     this->reserved = 0;
+     106      788201 :     this->inRegs = inRegs;
+     107       12938 :     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       63082 :   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      365980 :   ASMJIT_INLINE uint32_t hasOutPhysId() const { return outPhysId != Globals::kInvalidRegId; }
+     118             : 
+     119             :   //! Set the input register index.
+     120      472365 :   ASMJIT_INLINE void setInPhysId(uint32_t index) { inPhysId = static_cast<uint8_t>(index); }
+     121             :   //! Set the output register index.
+     122      315836 :   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     2956209 :     return (data[index / kEntityBits] >> (index % kEntityBits)) & 1;
+     210             :   }
+     211             : 
+     212             :   ASMJIT_INLINE void setBit(uint32_t index) noexcept {
+     213      788201 :     data[index / kEntityBits] |= static_cast<uintptr_t>(1) << (index % kEntityBits);
+     214      472365 :   }
+     215             : 
+     216             :   ASMJIT_INLINE void delBit(uint32_t index) noexcept {
+     217      315836 :     data[index / kEntityBits] &= ~(static_cast<uintptr_t>(1) << (index % kEntityBits));
+     218      315836 :   }
+     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      554901 :     : liveness(nullptr),
+     323      554901 :       state(nullptr),
+     324      554901 :       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       63998 :   ASMJIT_INLINE CodeCompiler* cc() const noexcept { return static_cast<CodeCompiler*>(_cb); }
+     382             : 
+     383             :   //! Get function.
+     384       63998 :   ASMJIT_INLINE CCFunc* getFunc() const noexcept { return _func; }
+     385             :   //! Get stop node.
+     386       95997 :   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      788201 :     if (ASMJIT_LIKELY(vreg->_raId != kInvalidValue)) return kErrorOk;
+     416             : 
+     417      315836 :     uint32_t raId = static_cast<uint32_t>(_contextVd.getLength());
+     418      315836 :     ASMJIT_PROPAGATE(_contextVd.append(&_heap, vreg));
+     419             : 
+     420      315836 :     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       91196 :     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       31999 :       _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      490903 :       _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       31999 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     470       31999 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     471             : 
+     472             :     link->setValue(node);
+     473             :     _unreachableList.append(link);
+     474             : 
+     475       31999 :     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       31999 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     489       31999 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     490             : 
+     491             :     link->setValue(node);
+     492             :     _returningList.append(link);
+     493             : 
+     494       31999 :     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 000000000..daca511bc --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-10-17 16:45:02Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm31999
_ZN4PLMD6asmjit10JitRuntimeC2Ev32029
_ZN4PLMD6asmjit10JitRuntimeD0Ev32029
_ZN4PLMD6asmjit10JitRuntimeD2Ev32029
_ZN4PLMD6asmjit11HostRuntimeC2Ev32029
_ZN4PLMD6asmjit11HostRuntimeD2Ev32029
_ZN4PLMD6asmjit7RuntimeC2Ev32029
_ZN4PLMD6asmjit7RuntimeD2Ev32029
+
+
+ + + +
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 000000000..829c3fc23 --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-10-17 16:45:02Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit10JitRuntimeC2Ev32029
_ZN4PLMD6asmjit10JitRuntimeD0Ev32029
_ZN4PLMD6asmjit10JitRuntimeD2Ev32029
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm31999
_ZN4PLMD6asmjit11HostRuntimeC2Ev32029
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit11HostRuntimeD2Ev32029
_ZN4PLMD6asmjit7RuntimeC2Ev32029
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD2Ev32029
+
+
+ + + +
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 000000000..957e1226a --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.gcov.html @@ -0,0 +1,249 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-10-17 16:45:02Functions: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       32029 : Runtime::Runtime() noexcept
+      93             :   : _codeInfo(),
+      94       32029 :     _runtimeType(kRuntimeNone),
+      95       32029 :     _allocType(VMemMgr::kAllocFreeable) {}
+      96       32029 : Runtime::~Runtime() noexcept {}
+      97             : 
+      98             : // ============================================================================
+      99             : // [asmjit::HostRuntime - Construction / Destruction]
+     100             : // ============================================================================
+     101             : 
+     102       32029 : HostRuntime::HostRuntime() noexcept {
+     103       32029 :   _runtimeType = kRuntimeJit;
+     104             : 
+     105             :   // Setup the CodeInfo of this Runtime.
+     106       32029 :   _codeInfo._archInfo       = CpuInfo::getHost().getArchInfo();
+     107       32029 :   _codeInfo._stackAlignment = static_cast<uint8_t>(hostDetectNaturalStackAlignment());
+     108       32029 :   _codeInfo._cdeclCallConv  = CallConv::kIdHostCDecl;
+     109       32029 :   _codeInfo._stdCallConv    = CallConv::kIdHostStdCall;
+     110       32029 :   _codeInfo._fastCallConv   = CallConv::kIdHostFastCall;
+     111       32029 : }
+     112       32029 : HostRuntime::~HostRuntime() noexcept {}
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::HostRuntime - Interface]
+     116             : // ============================================================================
+     117             : 
+     118       31999 : void HostRuntime::flush(const void* p, size_t size) noexcept {
+     119             :   hostFlushInstructionCache(p, size);
+     120       31999 : }
+     121             : 
+     122             : // ============================================================================
+     123             : // [asmjit::JitRuntime - Construction / Destruction]
+     124             : // ============================================================================
+     125             : 
+     126       32029 : JitRuntime::JitRuntime() noexcept {}
+     127       64058 : JitRuntime::~JitRuntime() noexcept {}
+     128             : 
+     129             : // ============================================================================
+     130             : // [asmjit::JitRuntime - Interface]
+     131             : // ============================================================================
+     132             : 
+     133       31999 : Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
+     134       31999 :   size_t codeSize = code->getCodeSize();
+     135       31999 :   if (ASMJIT_UNLIKELY(codeSize == 0)) {
+     136           0 :     *dst = nullptr;
+     137           0 :     return DebugUtils::errored(kErrorNoCodeGenerated);
+     138             :   }
+     139             : 
+     140       31999 :   void* p = _memMgr.alloc(codeSize, getAllocType());
+     141       31999 :   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       31999 :   size_t relocSize = code->relocate(p);
+     148       31999 :   if (ASMJIT_UNLIKELY(relocSize == 0)) {
+     149           0 :     *dst = nullptr;
+     150           0 :     _memMgr.release(p);
+     151           0 :     return DebugUtils::errored(kErrorInvalidState);
+     152             :   }
+     153             : 
+     154       31999 :   if (relocSize < codeSize)
+     155           0 :     _memMgr.shrink(p, relocSize);
+     156             : 
+     157       31999 :   flush(p, relocSize);
+     158       31999 :   *dst = p;
+     159             : 
+     160       31999 :   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 000000000..b7c7904ce --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..3dac46b92 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..d4717a9f5 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.gcov.html @@ -0,0 +1,303 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-10-17 16:45:02Functions: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       31999 :   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       31999 :     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       31999 :   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 000000000..a7c5693f5 --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/string.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - string.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01380.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..8f17c212b --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/string.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - string.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01380.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..39638ef9a --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.gcov.html @@ -0,0 +1,455 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/string.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - string.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01380.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..0bd07bd0d --- /dev/null +++ b/coverage-libs/asmjit/utils.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/utils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - utils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:224548.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..86db71e14 --- /dev/null +++ b/coverage-libs/asmjit/utils.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/utils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - utils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:224548.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..0c1cad41a --- /dev/null +++ b/coverage-libs/asmjit/utils.h.gcov.html @@ -0,0 +1,1463 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/utils.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - utils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:224548.9 %
Date:2024-10-17 16:45:02Functions: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      490903 :     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      620739 :     return ASMJIT_ARCH_LE ? (static_cast<uint64_t>(u1) << 32) + u0
+     146      379834 :                           : (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     1576402 :       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      229112 :     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        4600 :     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      115790 :       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      365980 :     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     2025202 :     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       76936 :     uint32_t overflow = static_cast<uint32_t>(
+     402       76936 :       -static_cast<int32_t>(x >= sizeof(uint32_t) * 8));
+     403             : 
+     404       76936 :     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       31999 :     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      417543 :     if (mask)
+     507      417543 :       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     2337894 :     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        6994 :     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      159014 :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     961             :     if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) {
+     962      159014 :       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     1090741 :       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      961209 :       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      923931 :       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 000000000..fd2bfd3c0 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9731830.5 %
Date:2024-10-17 16:45:02Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjit7VMemMgr5allocEmj31999
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm31999
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE31999
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm31999
_ZN4PLMD6asmjit7VMemMgrC2Ev32029
_ZN4PLMD6asmjit7VMemMgrD2Ev32029
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb32029
_ZN4PLMD6asmjitL8_SetBitsEPmmm63998
+
+
+ + + +
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 000000000..bd3c69329 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9731830.5 %
Date:2024-10-17 16:45:02Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit12X86AssemblerD2Ev31999
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_588796
+
+
+ + + +
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 000000000..9893210c6 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:186170510.9 %
Date:2024-10-17 16:45:02Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_588796
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86AssemblerD2Ev31999
+
+
+ + + +
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 000000000..af52a52a8 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.gcov.html @@ -0,0 +1,4721 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:186170510.9 %
Date:2024-10-17 16:45:02Functions: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      588796 :   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      588796 :   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       31999 : X86Assembler::X86Assembler(CodeHolder* code) noexcept : Assembler() {
+     382       31999 :   if (code)
+     383       31999 :     code->attach(this);
+     384       31999 : }
+     385       31999 : X86Assembler::~X86Assembler() noexcept {}
+     386             : 
+     387             : // ============================================================================
+     388             : // [asmjit::X86Assembler - Events]
+     389             : // ============================================================================
+     390             : 
+     391       31999 : Error X86Assembler::onAttach(CodeHolder* code) noexcept {
+     392             :   uint32_t archType = code->getArchType();
+     393       31999 :   if (!ArchInfo::isX86Family(archType))
+     394             :     return DebugUtils::errored(kErrorInvalidArch);
+     395             : 
+     396       31999 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+     397             : 
+     398       31999 :   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       31999 :     _nativeGpArray = x86OpData.gpq;
+     408             :   }
+     409             : 
+     410       31999 :   _nativeGpReg = _nativeGpArray[0];
+     411       31999 :   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      588796 : 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      588796 :   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      588796 :   uint8_t* cursor = _bufferPtr;
+     550      588796 :   uint32_t options = static_cast<uint32_t>(instId >= X86Inst::_kIdCount)       |
+     551      588796 :                      static_cast<uint32_t>((size_t)(_bufferEnd - cursor) < 16) |
+     552      588796 :                      getGlobalOptions() | getOptions();
+     553             : 
+     554      588796 :   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      588796 :   uint32_t isign3 = o0.getOp() + (o1.getOp() << 3) + (o2.getOp() << 6);
+     569             : 
+     570      588796 :   if (ASMJIT_UNLIKELY(options & kErrorsAndSpecialCases)) {
+     571             :     // Don't do anything if we are in error state.
+     572       31999 :     if (_lastError) return _lastError;
+     573             : 
+     574       31999 :     if (options & CodeEmitter::kOptionMaybeFailureCase) {
+     575             :       // Unknown instruction.
+     576       31999 :       if (ASMJIT_UNLIKELY(instId >= X86Inst::_kIdCount))
+     577           0 :         goto InvalidArgument;
+     578             : 
+     579             :       // Grow request, happens rarely.
+     580       31999 :       if ((size_t)(_bufferEnd - cursor) < 16) {
+     581       31999 :         err = _code->growBuffer(&_section->_buffer, 16);
+     582       31999 :         if (ASMJIT_UNLIKELY(err)) goto Failed;
+     583             : 
+     584       31999 :         cursor = _bufferPtr;
+     585       31999 :         options &= ~1;
+     586             :       }
+     587             :     }
+     588             : 
+     589             :     // Strict validation.
+     590             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     591       31999 :     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       31999 :     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       31999 :     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      588796 :   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        9200 :     case X86Inst::kEncodingX86Arith:
+     877        9200 :       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        9200 :       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        9200 :       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        9200 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+     944        9200 :         uint32_t size = o0.getSize();
+     945             : 
+     946             :         rbReg = o0.getId();
+     947             :         imVal = static_cast<const Imm&>(o1).getInt64();
+     948             : 
+     949        9200 :         if (size == 1) {
+     950           0 :           FIXUP_GPB(o0, rbReg);
+     951             :           imLen = 1;
+     952             :         }
+     953             :         else {
+     954        9200 :           if (size == 2) {
+     955             :             ADD_66H_P(1);
+     956             :           }
+     957        9200 :           else if (size == 4) {
+     958             :             // Sign extend so isInt8 returns the right result.
+     959             :             imVal = x86SignExtend32To64(imVal);
+     960             :           }
+     961        9200 :           else if (size == 8) {
+     962             :             // In 64-bit mode it's not possible to use 64-bit immediate.
+     963        9200 :             if (Utils::isUInt32(imVal)) {
+     964             :               // Zero-extend `and` by using a 32-bit GPD destination instead of a 64-bit GPQ.
+     965        9200 :               if (instId == X86Inst::kIdAnd)
+     966           0 :                 size = 4;
+     967        9200 :               else if (!Utils::isInt32(imVal))
+     968           0 :                 goto InvalidImmediate;
+     969             :             }
+     970        9200 :             ADD_REX_W_BY_SIZE(size);
+     971             :           }
+     972             : 
+     973       18400 :           imLen = std::min<uint32_t>(size, 4);
+     974        9200 :           if (Utils::isInt8(imVal) && !(options & X86Inst::kOptionLongForm))
+     975             :             imLen = 1;
+     976             :         }
+     977             : 
+     978             :         // Alternate Form - AL, AX, EAX, RAX.
+     979        9200 :         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        9200 :         opCode += size != 1 ? (imLen != 1 ? 1 : 3) : 0;
+     987        9200 :         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       12938 :     case X86Inst::kEncodingX86Call:
+    1063       12938 :       if (isign3 == ENC_OPS1(Reg)) {
+    1064             :         rbReg = o0.getId();
+    1065       12938 :         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      105778 :     case X86Inst::kEncodingX86Mov:
+    1399             :       // Reg <- Reg
+    1400      105778 :       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      105778 :       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      105778 :       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      105778 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1587             :         opReg = o0.getId();
+    1588      105778 :         imLen = o0.getSize();
+    1589             : 
+    1590      105778 :         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      105778 :           if (imLen == 8 && !(options & X86Inst::kOptionLongForm)) {
+    1603      105778 :             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      105778 :             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      105778 :           ADD_PREFIX_BY_SIZE(imLen);
+    1621      105778 :           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        7044 :     case X86Inst::kEncodingX86Push:
+    1710        7044 :       if (isign3 == ENC_OPS1(Reg)) {
+    1711        7044 :         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        7044 :           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        7044 :       if (isign3 == ENC_OPS1(Reg)) {
+    1741        7044 :         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       14088 : 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       14088 :           if (ASMJIT_UNLIKELY(o0.getSize() < 2))
+    1758           0 :             goto InvalidInstruction;
+    1759             : 
+    1760             :           opCode = commonData->getAltOpCode();
+    1761             :           opReg = o0.getId();
+    1762             : 
+    1763       14088 :           ADD_66H_P_BY_SIZE(o0.getSize());
+    1764       14088 :           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       31999 :     case X86Inst::kEncodingX86Ret:
+    1782       31999 :       if (isign3 == 0) {
+    1783             :         // 'ret' without immediate, change C2 to C3.
+    1784       31999 :         opCode++;
+    1785       31999 :         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      296240 :     case X86Inst::kEncodingExtMov:
+    2349             :       // GP|MMX|XMM <- GP|MMX|XMM
+    2350      296240 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2351             :         opReg = o0.getId();
+    2352             :         rbReg = o1.getId();
+    2353             : 
+    2354      121671 :         if (!(options & X86Inst::kOptionModMR) || !commonData->hasAltOpCode())
+    2355      121671 :           goto EmitX86R;
+    2356             : 
+    2357             :         opCode = commonData->getAltOpCode();
+    2358             :         Utils::swap(opReg, rbReg);
+    2359           0 :         goto EmitX86R;
+    2360             :       }
+    2361             : 
+    2362             :       // GP|MMX|XMM <- Mem
+    2363      174569 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2364             :         opReg = o0.getId();
+    2365             :         rmRel = &o1;
+    2366      134595 :         goto EmitX86M;
+    2367             :       }
+    2368             : 
+    2369             :       // The following instruction uses opCode[1].
+    2370             :       opCode = commonData->getAltOpCode();
+    2371             : 
+    2372             :       // Mem <- GP|MMX|XMM
+    2373       39974 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2374             :         opReg = o1.getId();
+    2375             :         rmRel = &o0;
+    2376       39974 :         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      116283 : CaseExtRm:
+    2551      116283 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2552             :         opReg = o0.getId();
+    2553             :         rbReg = o1.getId();
+    2554      116283 :         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       31999 :   EMIT_PP(opCode);
+    3575             : 
+    3576             :   // Emit REX prefix (64-bit only).
+    3577             :   {
+    3578             :     uint32_t rex = x86ExtractREX(opCode, options);
+    3579       31999 :     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       31999 :   EMIT_MM_OP(opCode);
+    3588             : 
+    3589       31999 :   if (imLen != 0)
+    3590           0 :     goto EmitImm;
+    3591             :   else
+    3592       31999 :     goto EmitDone;
+    3593             : 
+    3594      119866 : EmitX86OpReg:
+    3595             :   // Emit mandatory instruction prefix.
+    3596      119866 :   EMIT_PP(opCode);
+    3597             : 
+    3598             :   // Emit REX prefix (64-bit only).
+    3599             :   {
+    3600             :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3601      119866 :                    (opReg >> 3); // Rex.B (0x01).
+    3602      119866 :     if (rex) {
+    3603      105778 :       EMIT_BYTE(rex | kX86ByteRex);
+    3604      105778 :       if (options & X86Inst::_kOptionInvalidRex)
+    3605           0 :         goto InvalidRexPrefix;
+    3606      105778 :       opReg &= 0x7;
+    3607             :     }
+    3608             :   }
+    3609             : 
+    3610             :   // Emit instruction opcodes.
+    3611      119866 :   opCode += opReg;
+    3612      119866 :   EMIT_MM_OP(opCode);
+    3613             : 
+    3614      119866 :   if (imLen != 0)
+    3615      105778 :     goto EmitImm;
+    3616             :   else
+    3617       14088 :     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      262362 : EmitX86R:
+    3655             :   // Mandatory instruction prefix.
+    3656      262362 :   EMIT_PP(opCode);
+    3657             : 
+    3658             :   // Rex prefix (64-bit only).
+    3659             :   {
+    3660      262362 :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3661      262362 :                    ((opReg & 0x08) >> 1) | // REX.R (0x04).
+    3662      262362 :                    ((rbReg       ) >> 3) ; // REX.B (0x01).
+    3663      262362 :     if (rex) {
+    3664       23958 :       if (options & X86Inst::_kOptionInvalidRex)
+    3665           0 :         goto InvalidRexPrefix;
+    3666       23958 :       EMIT_BYTE(rex | kX86ByteRex);
+    3667       23958 :       opReg &= 0x07;
+    3668       23958 :       rbReg &= 0x07;
+    3669             :     }
+    3670             :   }
+    3671             : 
+    3672             :   // Instruction opcodes.
+    3673      262362 :   EMIT_MM_OP(opCode);
+    3674             :   // ModR.
+    3675      262362 :   EMIT_BYTE(x86EncodeMod(3, opReg, rbReg));
+    3676             : 
+    3677      262362 :   if (imLen != 0)
+    3678       11470 :     goto EmitImm;
+    3679             :   else
+    3680      250892 :     goto EmitDone;
+    3681             : 
+    3682      174569 : EmitX86M:
+    3683             :   ASMJIT_ASSERT(rmRel != nullptr);
+    3684             :   ASMJIT_ASSERT(rmRel->getOp() == Operand::kOpMem);
+    3685      174569 :   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      174569 :   if (rmRel->as<X86Mem>().hasSegment())
+    3692           0 :     EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]);
+    3693             : 
+    3694             :   // Address-override prefix.
+    3695      174569 :   if (rmInfo & _getAddressOverrideMask())
+    3696           0 :     EMIT_BYTE(0x67);
+    3697             : 
+    3698             :   // Mandatory instruction prefix.
+    3699      174569 :   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      174569 :     rex  = (rbReg >> 3) & 0x01; // REX.B (0x01).
+    3709      174569 :     rex |= (rxReg >> 2) & 0x02; // REX.X (0x02).
+    3710      174569 :     rex |= (opReg >> 1) & 0x04; // REX.R (0x04).
+    3711             : 
+    3712      174569 :     rex &= rmInfo;
+    3713      174569 :     rex |= x86ExtractREX(opCode, options);
+    3714             : 
+    3715      174569 :     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      174569 :   EMIT_MM_OP(opCode);
+    3725             :   // ... Fall through ...
+    3726             : 
+    3727             :   // --------------------------------------------------------------------------
+    3728             :   // [Emit - MOD/SIB]
+    3729             :   // --------------------------------------------------------------------------
+    3730             : 
+    3731      174569 : EmitModSib:
+    3732      174569 :   if (!(rmInfo & (kX86MemInfo_Index | kX86MemInfo_67H_X86))) {
+    3733             :     // ==========|> [BASE + DISP8|DISP32].
+    3734      174569 :     if (rmInfo & kX86MemInfo_BaseGp) {
+    3735      174569 :       rbReg &= 0x7;
+    3736             :       relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3737             : 
+    3738             :       uint32_t mod = x86EncodeMod(0, opReg, rbReg);
+    3739      174569 :       if (rbReg == X86Gp::kIdSp) {
+    3740             :         // [XSP|R12].
+    3741       91196 :         if (relOffset == 0) {
+    3742        9200 :           EMIT_BYTE(mod);
+    3743        9200 :           EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3744             :         }
+    3745             :         // [XSP|R12 + DISP8|DISP32].
+    3746             :         else {
+    3747       81996 :           uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3748       81996 :           int32_t cdOffset = relOffset >> cdShift;
+    3749             : 
+    3750       81996 :           if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3751       36936 :             EMIT_BYTE(mod + 0x40); // <- MOD(1, opReg, rbReg).
+    3752       36936 :             EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3753       36936 :             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       83373 :       else if (rbReg != X86Gp::kIdBp && relOffset == 0) {
+    3763             :         // [BASE].
+    3764       60435 :         EMIT_BYTE(mod);
+    3765             :       }
+    3766             :       else {
+    3767             :         // [BASE + DISP8|DISP32].
+    3768       22938 :         uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3769       22938 :         int32_t cdOffset = relOffset >> cdShift;
+    3770             : 
+    3771       22938 :         if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3772       14762 :           EMIT_BYTE(mod + 0x40);
+    3773       14762 :           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      174569 :   if (imLen != 0)
+    4013           0 :     goto EmitImm;
+    4014             :   else
+    4015      174569 :     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      117248 :     uint32_t i = imLen;
+    4476      117248 :     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      117248 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4484      106810 :     imm >>= 8;
+    4485      106810 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4486      106810 :     imm >>= 8;
+    4487      106810 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4488      106810 :     imm >>= 8;
+    4489      106810 :     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      105778 :     imm >>= 8;
+    4496      105778 :     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      588796 : EmitDone:
+    4507             : #if !defined(ASMJIT_DISABLE_LOGGING)
+    4508             :   // Logging is a performance hit anyway, so make it the unlikely case.
+    4509      588796 :   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      588796 :   _bufferPtr = cursor;
+    4518      588796 :   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 000000000..a26ca02f6 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..bd794c6f6 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..adfbab906 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.gcov.html @@ -0,0 +1,201 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-10-17 16:45:02Functions: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      174569 :   ASMJIT_INLINE uint32_t _getAddressOverrideMask() const noexcept { return _privateData; }
+      94       31999 :   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 000000000..66648b426 --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86builder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86builder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0150.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..c40268f3e --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86builder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86builder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0150.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..ed7d98c80 --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86builder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86builder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0150.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..7b9780525 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-10-17 16:45:02Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv31999
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit11X86CompilerD2Ev31999
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_575858
+
+
+ + + +
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 000000000..032889dcd --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-10-17 16:45:02Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_575858
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv31999
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE31999
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86CompilerD2Ev31999
+
+
+ + + +
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 000000000..60b87c90b --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.gcov.html @@ -0,0 +1,478 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-10-17 16:45:02Functions: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       31999 : X86Compiler::X86Compiler(CodeHolder* code) noexcept : CodeCompiler() {
+      52       31999 :   if (code)
+      53       31999 :     code->attach(this);
+      54       31999 : }
+      55       31999 : X86Compiler::~X86Compiler() noexcept {}
+      56             : 
+      57             : // ============================================================================
+      58             : // [asmjit::X86Compiler - Events]
+      59             : // ============================================================================
+      60             : 
+      61       31999 : Error X86Compiler::onAttach(CodeHolder* code) noexcept {
+      62             :   uint32_t archType = code->getArchType();
+      63       31999 :   if (!ArchInfo::isX86Family(archType))
+      64             :     return DebugUtils::errored(kErrorInvalidArch);
+      65             : 
+      66       63998 :   ASMJIT_PROPAGATE(_cbPasses.willGrow(&_cbHeap, 1));
+      67       31999 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+      68             : 
+      69       31999 :   if (archType == ArchInfo::kTypeX86)
+      70           0 :     _nativeGpArray = x86OpData.gpd;
+      71             :   else
+      72       31999 :     _nativeGpArray = x86OpData.gpq;
+      73       31999 :   _nativeGpReg = _nativeGpArray[0];
+      74             : 
+      75       63998 :   return addPassT<X86RAPass>();
+      76             : }
+      77             : 
+      78             : // ============================================================================
+      79             : // [asmjit::X86Compiler - Finalize]
+      80             : // ============================================================================
+      81             : 
+      82       31999 : Error X86Compiler::finalize() {
+      83       31999 :   if (_lastError) return _lastError;
+      84             : 
+      85             :   // Flush the global constant pool.
+      86       31999 :   if (_globalConstPool) {
+      87           0 :     addNode(_globalConstPool);
+      88           0 :     _globalConstPool = nullptr;
+      89             :   }
+      90             : 
+      91             :   Error err = kErrorOk;
+      92             :   ZoneVector<CBPass*>& passes = _cbPasses;
+      93             : 
+      94       63998 :   for (size_t i = 0, len = passes.getLength(); i < len; i++) {
+      95       31999 :     CBPass* pass = passes[i];
+      96       31999 :     err = pass->process(&_cbPassZone);
+      97       31999 :     _cbPassZone.reset();
+      98       31999 :     if (err) break;
+      99             :   }
+     100             : 
+     101       31999 :   _cbPassZone.reset();
+     102       31999 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     103             : 
+     104             :   // TODO: There must be possibility to attach more assemblers, this is not so nice.
+     105       31999 :   if (_code->_cgAsm) {
+     106           0 :     return serialize(_code->_cgAsm);
+     107             :   }
+     108             :   else {
+     109       31999 :     X86Assembler a(_code);
+     110       31999 :     return serialize(&a);
+     111       31999 :   }
+     112             : }
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::X86Compiler - Inst]
+     116             : // ============================================================================
+     117             : 
+     118             : static ASMJIT_INLINE bool isJumpInst(uint32_t instId) noexcept {
+     119      575858 :   return (instId >= X86Inst::kIdJa   && instId <= X86Inst::kIdJz    ) ||
+     120      575858 :          (instId >= X86Inst::kIdLoop && instId <= X86Inst::kIdLoopne) ;
+     121             : }
+     122             : 
+     123      575858 : Error X86Compiler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     124      575858 :   uint32_t options = getOptions() | getGlobalOptions();
+     125             :   const char* inlineComment = getInlineComment();
+     126             : 
+     127      575858 :   uint32_t opCount = static_cast<uint32_t>(!o0.isNone()) +
+     128      575858 :                      static_cast<uint32_t>(!o1.isNone()) +
+     129      575858 :                      static_cast<uint32_t>(!o2.isNone()) +
+     130      575858 :                      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      575858 :   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      575858 :   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      575858 :     CBInst* node = _cbHeap.allocT<CBInst>(sizeof(CBInst) + opCount * sizeof(Operand));
+     229      575858 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBInst));
+     230             : 
+     231      575858 :     if (ASMJIT_UNLIKELY(!node))
+     232           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     233             : 
+     234      575858 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     235      575858 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     236      575858 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     237      575858 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     238             : 
+     239             :     node = new(node) CBInst(this, instId, options, opArray, opCount);
+     240      575858 :     node->_instDetail.extraReg = _extraReg;
+     241             :     _extraReg.reset();
+     242             : 
+     243      575858 :     if (inlineComment) {
+     244           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     245             :       node->setInlineComment(inlineComment);
+     246             :     }
+     247             : 
+     248      575858 :     addNode(node);
+     249      575858 :     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 000000000..9574fe26a --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..96f3bc447 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..3ddade6d2 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.gcov.html @@ -0,0 +1,398 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-10-17 16:45:02Functions: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      104966 :   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      210870 :   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       12938 :   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       31999 :   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 000000000..5f5434a98 --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..a7bd9ad10 --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..ba4817e90 --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.gcov.html @@ -0,0 +1,5225 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-10-17 16:45:02Functions: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       95997 :     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        4600 :   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      104966 :   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        7044 :   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        7044 :   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        4600 :   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       25998 :   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       14802 :   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      107075 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Xmm)                                // SSE2
+    1166       82855 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Mem)                                // SSE2
+    1167         518 :   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       57457 :   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        2716 :   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        7552 :   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        5286 :   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 000000000..dfd62c094 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0240.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..5df1ab015 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0240.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..0f889c7fb --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.gcov.html @@ -0,0 +1,3829 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0240.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..ed0155002 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..acff32d12 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-10-17 16:45:02Functions: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 000000000..d9b69aa41 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.gcov.html @@ -0,0 +1,2623 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-10-17 16:45:02Functions: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      413449 :     ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+    2157             :     //! Get if the instruction has a `flag`, see \ref X86Inst::Flags.
+    2158      949114 :     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      413449 :     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      297612 :     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       82855 :     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      588796 :   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      588796 :   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     1034762 : ASMJIT_INLINE const X86Inst::CommonData& X86Inst::getCommonData() const noexcept { return X86InstDB::commonData[_commonDataIndex]; }
+    2522       82855 : 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       54062 : 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 000000000..b7528a4ce --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86instimpl.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86instimpl.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01700.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..00fa37954 --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86instimpl.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86instimpl.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01700.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..06fc3d490 --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.gcov.html @@ -0,0 +1,833 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86instimpl.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86instimpl.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01700.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..b9ad69b03 --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86internal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86internal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11339428.7 %
Date:2024-10-17 16:45:02Functions: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_15FuncFrameLayoutE31999
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE31999
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj44937
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj44937
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc105792
+
+
+ + + +
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 000000000..8b94eb1d9 --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86internal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86internal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11339428.7 %
Date:2024-10-17 16:45:02Functions:61442.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Internal10emitEpilogEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjit11X86Internal11emitArgMoveEPNS0_10X86EmitterERKNS0_6X86RegEjRKNS0_8Operand_EjbPKc0
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc105792
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj44937
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj44937
_ZN4PLMD6asmjit11X86Internal15argsToFrameInfoERKNS0_14FuncArgsMapperERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE31999
_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 000000000..b3e9d4445 --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.gcov.html @@ -0,0 +1,1458 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86internal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86internal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11339428.7 %
Date:2024-10-17 16:45:02Functions: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       12644 :   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       44937 : 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       44937 :   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       44937 :   return kErrorOk;
+     414             : }
+     415             : 
+     416             : // ============================================================================
+     417             : // [asmjit::X86Internal - FuncDetail]
+     418             : // ============================================================================
+     419             : 
+     420       44937 : 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       44937 :   if (func.getRetCount() != 0) {
+     428             :     uint32_t typeId = func._rets[0].getTypeId();
+     429       44937 :     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       44937 :       case TypeId::kF32:
+     459             :       case TypeId::kF64: {
+     460       44937 :         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       44937 :   uint32_t stackBase = gpSize;
+     490       44937 :   uint32_t stackOffset = stackBase + cc._spillZoneSize;
+     491             : 
+     492       44937 :   if (cc.getAlgorithm() == CallConv::kAlgorithmDefault) {
+     493             :     uint32_t gpzPos = 0;
+     494             :     uint32_t vecPos = 0;
+     495             : 
+     496       58393 :     for (i = 0; i < argCount; i++) {
+     497             :       FuncDetail::Value& arg = func._args[i];
+     498             :       uint32_t typeId = arg.getTypeId();
+     499             : 
+     500       13456 :       if (TypeId::isInt(typeId)) {
+     501         812 :         uint32_t regId = gpzPos < CallConv::kNumRegArgsPerKind ? cc._passedOrder[X86Reg::kKindGp].id[gpzPos] : Globals::kInvalidRegId;
+     502         812 :         if (regId != Globals::kInvalidRegId) {
+     503             :           uint32_t regType = (typeId <= TypeId::kU32)
+     504         812 :             ? X86Reg::kRegGpd
+     505             :             : X86Reg::kRegGpq;
+     506             :           arg.assignToReg(regType, regId);
+     507             :           func.addUsedRegs(X86Reg::kKindGp, Utils::mask(regId));
+     508         812 :           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         812 :         continue;
+     516         812 :       }
+     517             : 
+     518       12644 :       if (TypeId::isFloat(typeId) || TypeId::isVec(typeId)) {
+     519       12644 :         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       12644 :         if (TypeId::isFloat(typeId) && !cc.hasFlag(CallConv::kFlagPassFloatsByVec))
+     523             :           regId = Globals::kInvalidRegId;
+     524             : 
+     525       12644 :         if (regId != Globals::kInvalidRegId) {
+     526             :           arg.initReg(typeId, x86VecTypeIdToRegType(typeId), regId);
+     527             :           func.addUsedRegs(X86Reg::kKindVec, Utils::mask(regId));
+     528       12644 :           vecPos++;
+     529             :         }
+     530             :         else {
+     531             :           int32_t size = TypeId::sizeOf(typeId);
+     532             :           arg.assignToStack(stackOffset);
+     533           0 :           stackOffset += size;
+     534             :         }
+     535       12644 :         continue;
+     536       12644 :       }
+     537             :     }
+     538             :   }
+     539             : 
+     540       44937 :   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       44937 :   func._argStackSize = stackOffset - stackBase;
+     583       44937 :   return kErrorOk;
+     584             : }
+     585             : 
+     586             : // ============================================================================
+     587             : // [asmjit::X86Internal - FrameLayout]
+     588             : // ============================================================================
+     589             : 
+     590       31999 : ASMJIT_FAVOR_SIZE Error X86Internal::initFrameLayout(FuncFrameLayout& layout, const FuncDetail& func, const FuncFrameInfo& ffi) noexcept {
+     591             :   layout.reset();
+     592             : 
+     593             :   uint32_t kind;
+     594       31999 :   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      159995 :   for (kind = 0; kind < Globals::kMaxVRegKinds; kind++)
+     598      127996 :     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       31999 :   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       31999 :   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       31999 :         ffi.getStackFrameAlignment(),
+     614       31999 :         ffi.getCallFrameAlignment()),
+     615       31999 :       func.getCallConv().getNaturalStackAlignment());
+     616       31999 :   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       31999 :   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       31999 :   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       31999 :   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       31999 :   if (dsa && stackArgsRegId == X86Gp::kIdSp)
+     637             :     stackArgsRegId = X86Gp::kIdBp;
+     638             : 
+     639       31999 :   if (stackArgsRegId != X86Gp::kIdSp)
+     640           0 :     layout._savedRegs[X86Reg::kKindGp] |= Utils::mask(stackArgsRegId) & func.getPreservedRegs(X86Gp::kKindGp);
+     641             : 
+     642       31999 :   layout._stackBaseRegId = X86Gp::kIdSp;
+     643       31999 :   layout._stackArgsRegId = static_cast<uint8_t>(stackArgsRegId);
+     644             : 
+     645             :   // Setup stack size used to save preserved registers.
+     646       31999 :   layout._gpStackSize  = Utils::bitCount(layout.getSavedRegs(X86Reg::kKindGp )) * gpSize;
+     647       31999 :   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       31999 :   v += ffi._callFrameSize;               // Count '_callFrameSize'  <- This is used to call functions.
+     652             :   v  = Utils::alignTo(v, stackAlignment);// Align to function's SA
+     653             : 
+     654       31999 :   layout._stackBaseOffset = v;           // Store '_stackBaseOffset'<- Function's own stack starts here..
+     655       31999 :   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       31999 :   if (stackAlignment >= 16 && layout._vecStackSize) {
+     662             :     v = Utils::alignTo(v, 16);           // Align '_vecStackOffset'.
+     663           0 :     layout._alignedVecSR = true;
+     664             :   }
+     665             : 
+     666       31999 :   layout._vecStackOffset = v;            // Store '_vecStackOffset' <- Functions VEC Save|Restore starts here.
+     667       31999 :   v += layout._vecStackSize;             // Count '_vecStackSize'   <- Functions VEC Save|Restore ends here.
+     668             : 
+     669       31999 :   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       31999 :   if (v || ffi.hasCalls())
+     684        6994 :     v += Utils::alignDiff(v + layout._gpStackSize + gpSize, stackAlignment);
+     685             : 
+     686       31999 :   layout._stackAdjustment = v;           // Store '_stackAdjustment'<- SA used by 'add zsp, SA' and 'sub zsp, SA'.
+     687       31999 :   layout._gpStackOffset = v;             // Store '_gpStackOffset'  <- Functions GP Save|Restore starts here.
+     688       31999 :   v += layout._gpStackSize;              // Count '_gpStackSize'    <- Functions GP Save|Restore ends here.
+     689             : 
+     690       31999 :   v += gpSize;                           // Count 'ReturnAddress'.
+     691       31999 :   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       31999 :   if (stackArgsRegId != X86Gp::kIdSp) {
+     699           0 :     if (ffi.hasPreservedFP())
+     700             :       stackArgsOffset = gpSize;
+     701             :     else
+     702             :       stackArgsOffset = layout._gpStackSize;
+     703             :   }
+     704       31999 :   layout._stackArgsOffset = stackArgsOffset;
+     705             : 
+     706             :   // If the function does dynamic stack adjustment then the stack-adjustment
+     707             :   // must be aligned.
+     708       31999 :   if (dsa)
+     709           0 :     layout._stackAdjustment = Utils::alignTo(layout._stackAdjustment, stackAlignment);
+     710             : 
+     711             :   // Initialize variables based on CallConv flags.
+     712       31999 :   if (func.hasFlag(CallConv::kFlagCalleePopsStack))
+     713           0 :     layout._calleeStackCleanup = static_cast<uint16_t>(func.getArgStackSize());
+     714             : 
+     715             :   // Initialize variables based on FFI flags.
+     716       31999 :   layout._mmxCleanup = ffi.hasMmxCleanup();
+     717       31999 :   layout._avxEnabled = ffi.isAvxEnabled();
+     718       31999 :   layout._avxCleanup = ffi.hasAvxCleanup();
+     719             : 
+     720       31999 :   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      105792 : 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      105792 :   if (dst.isMem()) { memFlags |= kDstMem; dst.as<X86Mem>().setSize(src.getSize()); }
+     765      105792 :   if (src.isMem()) { memFlags |= kSrcMem; src.as<X86Mem>().setSize(dst.getSize()); }
+     766             : 
+     767      105792 :   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      105792 :       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      105792 :       if (TypeId::isVec64(typeId) && memFlags) {
+     812       91196 :         if (elementTypeId == TypeId::kF64)
+     813       91196 :           instId = avxEnabled ? X86Inst::kIdVmovsd : X86Inst::kIdMovsd;
+     814             :         else
+     815           0 :           instId = avxEnabled ? X86Inst::kIdVmovq : X86Inst::kIdMovq;
+     816             :         break;
+     817             :       }
+     818             : 
+     819       14596 :       if (elementTypeId == TypeId::kF32)
+     820           0 :         instId = avxEnabled ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps;
+     821       14596 :       else if (elementTypeId == TypeId::kF64)
+     822       14596 :         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      105792 :   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       31999 : 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       31999 :   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       31999 :   if (gpSaved) {
+    1067       34986 :     for (uint32_t i = gpSaved, regId = 0; i; i >>= 1, regId++) {
+    1068       28020 :       if (!(i & 0x1)) continue;
+    1069             :       gpReg.setId(regId);
+    1070        7044 :       ASMJIT_PROPAGATE(emitter->push(gpReg));
+    1071             :     }
+    1072             :   }
+    1073             : 
+    1074             :   // Emit: 'mov saReg, zsp'.
+    1075             :   uint32_t stackArgsRegId = layout.getStackArgsRegId();
+    1076       31999 :   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       31999 :   if (layout.hasDynamicAlignment())
+    1084           0 :     ASMJIT_PROPAGATE(emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment())));
+    1085             : 
+    1086             :   // Emit: 'sub zsp, StackAdjustment'.
+    1087       31999 :   if (layout.hasStackAdjustment())
+    1088        4600 :     ASMJIT_PROPAGATE(emitter->sub(zsp, layout.getStackAdjustment()));
+    1089             : 
+    1090             :   // Emit: 'mov [zsp + dsaSlot], saReg'.
+    1091       31999 :   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       31999 :   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       31999 : 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       31999 :   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       31999 :   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       31999 :   if (layout.hasMmxCleanup()) ASMJIT_PROPAGATE(emitter->emms());
+    1149       31999 :   if (layout.hasAvxCleanup()) ASMJIT_PROPAGATE(emitter->vzeroupper());
+    1150             : 
+    1151       31999 :   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       31999 :     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       31999 :     else if (layout.hasStackAdjustment()) {
+    1166             :       // Emit 'add zsp, StackAdjustment'.
+    1167        4600 :       ASMJIT_PROPAGATE(emitter->add(zsp, static_cast<int32_t>(layout.getStackAdjustment())));
+    1168             :     }
+    1169             :   }
+    1170             : 
+    1171             :   // Emit 'pop gp' sequence.
+    1172       31999 :   if (gpSaved) {
+    1173             :     i = gpSaved;
+    1174             :     regId = 16;
+    1175             : 
+    1176             :     do {
+    1177      111456 :       regId--;
+    1178      111456 :       if (i & 0x8000) {
+    1179             :         gpReg.setId(regId);
+    1180        7044 :         ASMJIT_PROPAGATE(emitter->pop(gpReg));
+    1181             :       }
+    1182      111456 :       i <<= 1;
+    1183      111456 :     } while (regId != 0);
+    1184             :   }
+    1185             : 
+    1186             :   // Emit 'pop zbp'.
+    1187       31999 :   if (layout.hasPreservedFP()) ASMJIT_PROPAGATE(emitter->pop(zbp));
+    1188             : 
+    1189             :   // Emit 'ret' or 'ret x'.
+    1190       31999 :   if (layout.hasCalleeStackCleanup())
+    1191           0 :     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdRet, static_cast<int>(layout.getCalleeStackCleanup())));
+    1192             :   else
+    1193       31999 :     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 000000000..d0b36a2e6 --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:02030.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..fff9b1e5b --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:02030.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..d66db9794 --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.gcov.html @@ -0,0 +1,786 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86logging.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:02030.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..6dc823247 --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86misc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86misc.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:223759.5 %
Date:2024-10-17 16:45:02Functions: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 000000000..0ce7b557c --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86misc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86misc.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:223759.5 %
Date:2024-10-17 16:45:02Functions: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 000000000..baad81666 --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.gcov.html @@ -0,0 +1,493 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86misc.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86misc.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:223759.5 %
Date:2024-10-17 16:45:02Functions: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     1536707 :   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     8244675 :     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     1576402 :     _packed += n << shift;
+     132      788201 :   }
+     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      490903 :     uint32_t x = static_cast<uint32_t>(count._regs[0]);
+     150      490903 :     uint32_t y = static_cast<uint32_t>(count._regs[1]) + x;
+     151      490903 :     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      717682 :     switch (kind) {
+     231     1264194 :       case X86Reg::kKindGp : return _gp;
+     232     3429383 :       case X86Reg::kKindVec: return _vec;
+     233      510656 :       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      214215 :       case X86Reg::kKindGp : _gp  = static_cast<uint16_t>(mask); break;
+     278       25876 :       case X86Reg::kKindMm : _mm  = static_cast<uint8_t >(mask); break;
+     279       12938 :       case X86Reg::kKindK  : _k   = static_cast<uint8_t >(mask); break;
+     280      379814 :       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      104966 :       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      254329 :       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      445966 :   }
+     344             : 
+     345             :   ASMJIT_INLINE void or_(uint32_t kind, uint32_t mask) noexcept {
+     346             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     347       31999 :     switch (kind) {
+     348      209932 :       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      554606 :       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       66336 :       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 000000000..66d13e6f6 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-10-17 16:45:02Functions: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 000000000..ed711a1ef --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-10-17 16:45:02Functions: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 000000000..9f7cdb3e1 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.gcov.html @@ -0,0 +1,1209 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-10-17 16:45:02Functions: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       83373 :     uint32_t signature = (base.getType()   << kSignatureMemBaseTypeShift ) |
+     126             :                          (size             << kSignatureSizeShift        ) ;
+     127             : 
+     128       83373 :     _init_packed_d0_d1(kOpMem | signature | flags, 0);
+     129       83373 :     _mem.base = base.getId();
+     130       83373 :     _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       31999 :   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      210870 : 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 000000000..9ff2cd8cd --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html @@ -0,0 +1,188 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-10-17 16:45:02Functions: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_3ImmE812
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE5286
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE12938
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc14596
_ZN4PLMD6asmjit9X86RAPass5fetchEv31999
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE31999
_ZN4PLMD6asmjit9X86RAPass9translateEv31999
_ZN4PLMD6asmjit9X86RAPassC2Ev31999
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE31999
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE31999
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc39456
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc51740
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej426905
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE477965
+
+
+ + + +
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 000000000..62f379512 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.func.html @@ -0,0 +1,188 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-10-17 16:45:02Functions:172958.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE477965
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE12938
_ZN4PLMD6asmjit9X86RAPass10emitSwapGpEPNS0_7VirtRegES3_jjPKc0
_ZN4PLMD6asmjit9X86RAPass11_checkStateEv0
_ZN4PLMD6asmjit9X86RAPass11switchStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE812
_ZN4PLMD6asmjit9X86RAPass14emitImmToStackEjPKNS0_6X86MemEPKNS0_3ImmE0
_ZN4PLMD6asmjit9X86RAPass14emitRegToStackEjPKNS0_6X86MemEjj0
_ZN4PLMD6asmjit9X86RAPass15intersectStatesEPNS0_7RAStateES3_0
_ZN4PLMD6asmjit9X86RAPass5fetchEv31999
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE31999
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE31999
_ZN4PLMD6asmjit9X86RAPass8annotateEv0
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc51740
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc14596
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc39456
_ZN4PLMD6asmjit9X86RAPass9loadStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass9saveStateEv0
_ZN4PLMD6asmjit9X86RAPass9translateEv31999
_ZN4PLMD6asmjit9X86RAPassC2Ev31999
_ZN4PLMD6asmjit9X86RAPassD0Ev0
_ZN4PLMD6asmjit9X86RAPassD2Ev0
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE31999
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE31999
_ZN4PLMD6asmjitL23X86RAPass_translateJumpEPNS0_9X86RAPassEPNS0_6CBJumpEPNS0_7CBLabelE0
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE31999
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej426905
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE31999
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE5286
+
+
+ + + +
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 000000000..ab0e7b24f --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html @@ -0,0 +1,4164 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-10-17 16:45:02Functions: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       31999 : X86RAPass::X86RAPass() noexcept : RAPass() {
+     200       31999 :   _state = &_x86State;
+     201       31999 :   _varMapToVaListOffset = ASMJIT_OFFSET_OF(X86RAData, tiedArray);
+     202       31999 : }
+     203           0 : X86RAPass::~X86RAPass() noexcept {}
+     204             : 
+     205             : // ============================================================================
+     206             : // [asmjit::X86RAPass - Interface]
+     207             : // ============================================================================
+     208             : 
+     209       31999 : Error X86RAPass::process(Zone* zone) noexcept {
+     210       31999 :   return Base::process(zone);
+     211             : }
+     212             : 
+     213       31999 : Error X86RAPass::prepare(CCFunc* func) noexcept {
+     214       31999 :   ASMJIT_PROPAGATE(Base::prepare(func));
+     215             : 
+     216             :   uint32_t archType = cc()->getArchType();
+     217       31999 :   _regCount._gp  = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     218       31999 :   _regCount._mm  = 8;
+     219       31999 :   _regCount._k   = 8;
+     220       31999 :   _regCount._vec = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     221             :   _zsp = cc()->zsp();
+     222             :   _zbp = cc()->zbp();
+     223             : 
+     224       31999 :   _gaRegs[X86Reg::kKindGp ] = Utils::bits(_regCount.getGp()) & ~Utils::mask(X86Gp::kIdSp);
+     225       31999 :   _gaRegs[X86Reg::kKindMm ] = Utils::bits(_regCount.getMm());
+     226       31999 :   _gaRegs[X86Reg::kKindK  ] = Utils::bits(_regCount.getK());
+     227       31999 :   _gaRegs[X86Reg::kKindVec] = Utils::bits(_regCount.getVec());
+     228             : 
+     229       31999 :   _x86State.reset(0);
+     230             :   _clobberedRegs.reset();
+     231             : 
+     232       31999 :   _avxEnabled = false;
+     233             : 
+     234       31999 :   _varBaseRegId = Globals::kInvalidRegId; // Used by patcher.
+     235       31999 :   _varBaseOffset = 0;                     // Used by patcher.
+     236             : 
+     237       31999 :   return kErrorOk;
+     238             : }
+     239             : 
+     240             : // ============================================================================
+     241             : // [asmjit::X86RAPass - Emit]
+     242             : // ============================================================================
+     243             : 
+     244       14596 : Error X86RAPass::emitMove(VirtReg* vReg, uint32_t dstId, uint32_t srcId, const char* reason) {
+     245             :   const char* comment = nullptr;
+     246       14596 :   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       14596 :   return X86Internal::emitRegMove(reinterpret_cast<X86Emitter*>(cc()), dst, src, vReg->getTypeId(), _avxEnabled, comment);
+     254             : }
+     255             : 
+     256       51740 : Error X86RAPass::emitLoad(VirtReg* vReg, uint32_t id, const char* reason) {
+     257             :   const char* comment = nullptr;
+     258       51740 :   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       51740 :   return X86Internal::emitRegMove(reinterpret_cast<X86Emitter*>(cc()), dst, src, vReg->getTypeId(), _avxEnabled, comment);
+     266             : }
+     267             : 
+     268       39456 : Error X86RAPass::emitSave(VirtReg* vReg, uint32_t id, const char* reason) {
+     269             :   const char* comment = nullptr;
+     270       39456 :   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       39456 :   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         812 : 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         812 :   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         812 :       if (imm.isUInt32())
+     327           0 :         goto Mov32Truncate;
+     328             : 
+     329             :       r0.setX86RegT<X86Reg::kRegGpq>(dstPhysId);
+     330         812 :       cc()->emit(X86Inst::kIdMov, r0, imm);
+     331         812 :       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         812 :   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        5286 : static void X86RAPass_prepareSingleVarInst(uint32_t instId, TiedReg* tr) {
+    1027        5286 :   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        5286 :     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        5286 :       tr->flags &= ~TiedReg::kRReg;
+    1041        5286 :       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        5286 : }
+    1053             : 
+    1054             : // ============================================================================
+    1055             : // [asmjit::X86RAPass - Helpers]
+    1056             : // ============================================================================
+    1057             : 
+    1058       31999 : 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       31999 :   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       31999 :     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       31999 :     uint32_t regs = passed & ~used;
+    1084             : 
+    1085             :     // Pick any other register if that didn't work out.
+    1086       31999 :     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       31999 : }
+    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       31999 : 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     2591919 :   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       31999 :   uint32_t* gaRegs = _gaRegs;
+    1275             : 
+    1276       31999 :   if (func->getFrameInfo().hasPreservedFP())
+    1277           0 :     gaRegs[X86Reg::kKindGp] &= ~Utils::mask(X86Gp::kIdBp);
+    1278             : 
+    1279             :   // Allowed index registers (GP/XMM/YMM).
+    1280       31999 :   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      458904 : _Do:
+    1381      490903 :     while (node_->hasPassData()) {
+    1382           0 : _NextGroup:
+    1383       31999 :       if (!jLink)
+    1384             :         jLink = _jccList.getFirst();
+    1385             :       else
+    1386             :         jLink = jLink->getNext();
+    1387             : 
+    1388       31999 :       if (!jLink) goto _Done;
+    1389             :       node_ = X86RAPass_getOppositeJccFlow(static_cast<CBJump*>(jLink->getValue()));
+    1390             :     }
+    1391             : 
+    1392      490903 :     position++;
+    1393             : 
+    1394             :     next = node_->getNext();
+    1395             :     node_->setPosition(position);
+    1396             : 
+    1397      490903 :     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      413967 :       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      413967 :         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      413967 :           if (commonData.isFpu())
+    1523             :             flags |= CBNode::kFlagIsFp;
+    1524             : 
+    1525      413967 :           if (commonData.hasFixedRM() && (special = X86SpecialInst_get(instId, opArray, opCount)) != nullptr)
+    1526           0 :             flags |= CBNode::kFlagIsSpecial;
+    1527             : 
+    1528     1244171 :           for (uint32_t i = 0; i < opCount; i++) {
+    1529      830204 :             Operand* op = &opArray[i];
+    1530             :             VirtReg* vreg;
+    1531             :             TiedReg* tied;
+    1532             : 
+    1533             :             if (op->isVirtReg()) {
+    1534             :               vreg = cc()->getVirtRegById(op->getId());
+    1535      639595 :               if (vreg->isFixed()) continue;
+    1536             : 
+    1537     1576802 :               RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1538      639595 :               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      639595 :               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      639595 :                 if (i == 0) {
+    1594             :                   // Read/Write is usually the combination of the first operand.
+    1595             :                   combinedFlags = inFlags | outFlags;
+    1596             : 
+    1597      413449 :                   if (node->getOptions() & CodeEmitter::kOptionOverwrite) {
+    1598             :                     // Manually forcing write-only.
+    1599             :                     combinedFlags = outFlags;
+    1600             :                   }
+    1601      413449 :                   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      297612 :                     if (opArray[1].isMem() && inst.getOperationData().isMovSsSd())
+    1609             :                       movSize = 16;
+    1610             : 
+    1611      297612 :                     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      104966 :                       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      104966 :                       if (movSize >= 4 || movSize >= regSize)
+    1624             :                         combinedFlags = outFlags;
+    1625             :                     }
+    1626      192646 :                     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      115837 :                   else if (commonData.isUseR()) {
+    1634             :                     // Comparison/Test instructions don't modify any operand.
+    1635             :                     combinedFlags = inFlags;
+    1636             :                   }
+    1637      115837 :                   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      226146 :                   if (commonData.isUseXX() || (instId == X86Inst::kIdImul && opCount == 3 && i == 1))
+    1651             :                     combinedFlags = inFlags | outFlags;
+    1652             :                 }
+    1653      639595 :                 tied->flags |= combinedFlags;
+    1654             :               }
+    1655             :             }
+    1656      190609 :             else if (op->isMem()) {
+    1657             :               X86Mem* m = static_cast<X86Mem*>(op);
+    1658             :               node->setMemOpIndex(i);
+    1659             : 
+    1660       83373 :               uint32_t specBase = special ? uint32_t(special[i].inReg) : uint32_t(Globals::kInvalidRegId);
+    1661             : 
+    1662       83373 :               if (m->hasBaseReg()) {
+    1663             :                 uint32_t id = m->getBaseId();
+    1664       83373 :                 if (cc()->isVirtRegValid(id)) {
+    1665             :                   vreg = cc()->getVirtRegById(id);
+    1666       83373 :                   if (!vreg->isStack() && !vreg->isFixed()) {
+    1667      166746 :                     RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1668       83373 :                     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       83373 :                       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       83373 :                         tied->flags |= TiedReg::kRReg;
+    1714             :                       }
+    1715             :                     }
+    1716             :                   }
+    1717             :                 }
+    1718             :               }
+    1719             : 
+    1720       83373 :               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      413967 :           if (tiedTotal) {
+    1738             :             // Handle instructions which result in zeros/ones or nop if used with the
+    1739             :             // same destination and source operand.
+    1740      419253 :             if (tiedTotal == 1 && opCount >= 2 && opArray[0].isVirtReg() && opArray[1].isVirtReg() && !node->hasMemOp())
+    1741        5286 :               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      413967 :           if (tiedCount.getVec() && commonData.hasFlag(X86Inst::kFlagVex | X86Inst::kFlagEvex))
+    1746           0 :             _avxEnabled = true;
+    1747             :         }
+    1748             : 
+    1749             :         const RegOnly& extraReg = node->getExtraReg();
+    1750      413967 :         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     1131649 :         RA_FINALIZE(node_);
+    1768             : 
+    1769             :         // Handle conditional/unconditional jump.
+    1770      413967 :         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       31999 :       case CBNode::kNodeFunc: {
+    1826             :         ASMJIT_ASSERT(node_ == func);
+    1827       31999 :         X86RAPass_assignStackArgsRegId(this, func);
+    1828             : 
+    1829             :         FuncDetail& fd = func->getDetail();
+    1830             :         TiedReg* tied;
+    1831             : 
+    1832             :         RA_DECLARE();
+    1833       31999 :         cc()->setCursor(node_);
+    1834             : 
+    1835             :         X86Gp saReg;
+    1836             :         uint32_t argCount = fd.getArgCount();
+    1837             : 
+    1838       31999 :         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       31999 :         if (!saReg.isValid())
+    1901             :           func->getFrameInfo().setStackArgsRegId(Globals::kInvalidRegId);
+    1902             : 
+    1903       31999 :         RA_FINALIZE(node_);
+    1904             :         next = node_->getNext();
+    1905       31999 :         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       31999 :       case CBNode::kNodeFuncExit: {
+    1923             :         CCFuncRet* node = static_cast<CCFuncRet*>(node_);
+    1924       31999 :         ASMJIT_PROPAGATE(addReturningNode(node));
+    1925             : 
+    1926             :         FuncDetail& fd = func->getDetail();
+    1927             :         RA_DECLARE();
+    1928             : 
+    1929       31999 :         if (fd.hasRet()) {
+    1930             :           const FuncDetail::Value& ret = fd.getRet(0);
+    1931             :           uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    1932             : 
+    1933       95997 :           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       63998 :               RA_MERGE(vreg, tied, 0, 0);
+    1939             : 
+    1940       31999 :               if (retKind == vreg->getKind()) {
+    1941       31999 :                 tied->flags |= TiedReg::kRReg;
+    1942       31999 :                 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       63998 :         RA_FINALIZE(node_);
+    1957             : 
+    1958       31999 :         if (!next->hasPassData())
+    1959       31999 :           ASMJIT_PROPAGATE(addUnreachableNode(next));
+    1960       31999 :         goto _NextGroup;
+    1961             :       }
+    1962             : 
+    1963             :       // ----------------------------------------------------------------------
+    1964             :       // [Func-Call]
+    1965             :       // ----------------------------------------------------------------------
+    1966             : 
+    1967       12938 :       case CBNode::kNodeFuncCall: {
+    1968             :         CCFuncCall* node = static_cast<CCFuncCall*>(node_);
+    1969             :         FuncDetail& fd = node->getDetail();
+    1970             : 
+    1971       12938 :         Operand_* target = node->_opArray;
+    1972       12938 :         Operand_* args = node->_args;
+    1973       12938 :         Operand_* rets = node->_ret;
+    1974             : 
+    1975             :         func->getFrameInfo().enableCalls();
+    1976       12938 :         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       12938 :         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       12938 :           RA_MERGE(vreg, tied, 0, 0);
+    1994             : 
+    1995       12938 :           tied->flags |= TiedReg::kRReg | TiedReg::kRCall;
+    1996       12938 :           if (tied->inRegs == 0)
+    1997       12938 :             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       26394 :         for (i = 0; i < argCount; i++) {
+    2030       13456 :           Operand_* op = &args[i];
+    2031         812 :           if (!op->isVirtReg()) continue;
+    2032             : 
+    2033             :           vreg = cc()->getVirtRegById(op->getId());
+    2034             :           const FuncDetail::Value& arg = fd.getArg(i);
+    2035             : 
+    2036       12644 :           if (arg.byReg()) {
+    2037       25288 :             RA_MERGE(vreg, tied, 0, 0);
+    2038             : 
+    2039             :             uint32_t argClass = X86Reg::kindOf(arg.getRegType());
+    2040             : 
+    2041       12644 :             if (vreg->getKind() == argClass) {
+    2042       12644 :               tied->inRegs |= Utils::mask(arg.getRegId());
+    2043       12644 :               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       38814 :         for (i = 0; i < 2; i++) {
+    2063       25876 :           Operand_* op = &rets[i];
+    2064       12938 :           if (!op->isVirtReg()) continue;
+    2065             : 
+    2066             :           const FuncDetail::Value& ret = fd.getRet(i);
+    2067       12938 :           if (ret.byReg()) {
+    2068             :             uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    2069             : 
+    2070             :             vreg = cc()->getVirtRegById(op->getId());
+    2071       38814 :             RA_MERGE(vreg, tied, 0, 0);
+    2072             : 
+    2073       12938 :             if (vreg->getKind() == retKind) {
+    2074             :               tied->setOutPhysId(ret.getRegId());
+    2075       12938 :               tied->flags |= TiedReg::kWReg | TiedReg::kWFunc;
+    2076             :             }
+    2077             :             else {
+    2078             :               // TODO: Function-call return value conversion.
+    2079             :             }
+    2080             :           }
+    2081             :         }
+    2082             : 
+    2083             :         // Init clobbered.
+    2084       12938 :         clobberedRegs.set(X86Reg::kKindGp , Utils::bits(_regCount.getGp())  & (fd.getPassedRegs(X86Reg::kKindGp ) | ~fd.getPreservedRegs(X86Reg::kKindGp )));
+    2085       12938 :         clobberedRegs.set(X86Reg::kKindMm , Utils::bits(_regCount.getMm())  & (fd.getPassedRegs(X86Reg::kKindMm ) | ~fd.getPreservedRegs(X86Reg::kKindMm )));
+    2086       12938 :         clobberedRegs.set(X86Reg::kKindK  , Utils::bits(_regCount.getK())   & (fd.getPassedRegs(X86Reg::kKindK  ) | ~fd.getPreservedRegs(X86Reg::kKindK  )));
+    2087       12938 :         clobberedRegs.set(X86Reg::kKindVec, Utils::bits(_regCount.getVec()) & (fd.getPassedRegs(X86Reg::kKindVec) | ~fd.getPreservedRegs(X86Reg::kKindVec)));
+    2088             : 
+    2089       51458 :         RA_FINALIZE(node_);
+    2090             :         break;
+    2091             :       }
+    2092             :     }
+    2093             : 
+    2094             :     node_ = next;
+    2095      458904 :   } while (node_ != stop);
+    2096             : 
+    2097       31999 : _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       31999 :   if (!node_->hasPassData()) {
+    2102             :     CBLabel* fExit = func->getExitNode();
+    2103       31999 :     RA_POPULATE(fExit);
+    2104       31999 :     fExit->setPosition(++position);
+    2105             : 
+    2106       31999 :     RA_POPULATE(node_);
+    2107       31999 :     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       31999 :   ASMJIT_INLINE X86BaseAlloc(X86RAPass* context) {
+    2171       31999 :     _context = context;
+    2172       31999 :     _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       93654 :   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     4439210 :   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      338164 :   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      490903 :   _node = node;
+    2262      490903 :   _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      490903 :   _cc->_setCursor(node->getPrev());
+    2268             : 
+    2269             :   // Setup the lists of variables.
+    2270             :   {
+    2271             :     TiedReg* tied = raData->getTiedArray();
+    2272      490903 :     _tiedArray[X86Reg::kKindGp ] = tied;
+    2273      490903 :     _tiedArray[X86Reg::kKindMm ] = tied + raData->getTiedStart(X86Reg::kKindMm );
+    2274      490903 :     _tiedArray[X86Reg::kKindK  ] = tied + raData->getTiedStart(X86Reg::kKindK  );
+    2275      490903 :     _tiedArray[X86Reg::kKindVec] = tied + raData->getTiedStart(X86Reg::kKindVec);
+    2276             :   }
+    2277             : 
+    2278             :   // Setup counters.
+    2279      490903 :   _tiedTotal = raData->tiedTotal;
+    2280      490903 :   _tiedCount = raData->tiedCount;
+    2281             :   _tiedDone.reset();
+    2282             : 
+    2283             :   // Connect VREG->TIED.
+    2284     1279104 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2285      788201 :     TiedReg* tied = &_tiedArray[0][i];
+    2286      788201 :     VirtReg* vreg = tied->vreg;
+    2287      788201 :     vreg->_tied = tied;
+    2288             :   }
+    2289             : }
+    2290             : 
+    2291             : ASMJIT_INLINE void X86BaseAlloc::cleanup() {
+    2292             :   // Disconnect VREG->TIED.
+    2293     1247105 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2294      788201 :     TiedReg* tied = &_tiedArray[0][i];
+    2295      788201 :     VirtReg* vreg = tied->vreg;
+    2296      788201 :     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     1195647 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2315      749681 :     TiedReg* tied = &tiedArray[i];
+    2316      749681 :     if ((tied->flags & checkFlags) == TiedReg::kWReg)
+    2317      302898 :       _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     1247105 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2327      788201 :     TiedReg* tied = &tiedArray[i];
+    2328      788201 :     if (tied->flags & TiedReg::kUnuse)
+    2329      283837 :       _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       31999 :   ASMJIT_INLINE X86VarAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2346       31999 :   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      477965 : 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      477965 :   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      445966 :     if (node_->getType() == CBNode::kNodeInst) {
+    2445             :       CBInst* node = static_cast<CBInst*>(node_);
+    2446      413967 :       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      413967 :       ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    2452             :     }
+    2453       31999 :     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      445966 :     _context->_clobberedRegs.or_(_willAlloc);
+    2505             :   }
+    2506             : 
+    2507             :   // Update clobbered mask.
+    2508      477965 :   _context->_clobberedRegs.or_(raData->clobberedRegs);
+    2509             : 
+    2510             :   // Unuse.
+    2511      477965 :   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      477965 :   _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      634305 :   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     1279020 :   for (i = 0; i < tiedCount; i++) {
+    2557      749681 :     TiedReg* tied = &tiedArray[i];
+    2558      749681 :     VirtReg* vreg = tied->vreg;
+    2559             : 
+    2560      749681 :     uint32_t vaFlags = tied->flags;
+    2561             :     uint32_t physId = vreg->getPhysId();
+    2562      749681 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    2563             : 
+    2564      749681 :     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      749681 :       uint32_t mandatoryRegs = tied->inRegs;
+    2573      749681 :       uint32_t allocableRegs = tied->allocableRegs;
+    2574             : 
+    2575      749681 :       if (regMask != 0) {
+    2576             :         // Special path for planning output-only registers.
+    2577      396075 :         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      396075 :           if ((mandatoryRegs | allocableRegs) & regMask) {
+    2601             :             tied->setInPhysId(physId);
+    2602      383701 :             tied->flags |= TiedReg::kRDone;
+    2603             : 
+    2604      383701 :             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      364076 :               tied->inRegs |= regMask;
+    2611      364076 :               willAlloc |= regMask;
+    2612             :             }
+    2613             : 
+    2614             :             addTiedDone(C);
+    2615      383701 :             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      365980 :       willFree |= regMask;
+    2632      365980 :       continue;
+    2633      365980 :     }
+    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      529339 :   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     1279020 :   for (i = 0; i < tiedCount; i++) {
+    2655      749681 :     TiedReg* tied = &tiedArray[i];
+    2656      749681 :     VirtReg* vreg = tied->vreg;
+    2657      749681 :     uint32_t vaFlags = tied->flags;
+    2658             : 
+    2659      749681 :     if ((vaFlags & TiedReg::kXReg) != 0) {
+    2660      749681 :       if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2661      302898 :         if (vaFlags & TiedReg::kWDone)
+    2662           0 :           continue;
+    2663             : 
+    2664             :         // Skip all registers that have assigned outPhysId. Spill if occupied.
+    2665      302898 :         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      446783 :         if (vaFlags & TiedReg::kRDone)
+    2673      383701 :           continue;
+    2674             : 
+    2675             :         // We skip all registers that have assigned inPhysId, indicates that
+    2676             :         // the register to allocate in is known.
+    2677       63082 :         if (tied->hasInPhysId()) {
+    2678           0 :           uint32_t inRegs = tied->inRegs;
+    2679           0 :           willSpill |= occupied & inRegs;
+    2680           0 :           continue;
+    2681           0 :         }
+    2682             :       }
+    2683             : 
+    2684      365980 :       uint32_t m = tied->inRegs;
+    2685      365980 :       if (tied->hasOutPhysId())
+    2686           0 :         m |= Utils::mask(tied->outPhysId);
+    2687             : 
+    2688      365980 :       m = tied->allocableRegs & ~(willAlloc ^ m);
+    2689             :       m = guessAlloc<C>(vreg, m);
+    2690             :       ASMJIT_ASSERT(m != 0);
+    2691             : 
+    2692      365980 :       uint32_t candidateRegs = m & ~occupied;
+    2693             :       uint32_t homeMask = vreg->getHomeMask();
+    2694             : 
+    2695             :       uint32_t physId;
+    2696             :       uint32_t regMask;
+    2697             : 
+    2698      365980 :       if (candidateRegs == 0) {
+    2699       15478 :         candidateRegs = m & occupied & ~state->_modified.get(C);
+    2700       15478 :         if (candidateRegs == 0)
+    2701             :           candidateRegs = m;
+    2702             :       }
+    2703      365980 :       if (candidateRegs & homeMask) candidateRegs &= homeMask;
+    2704             : 
+    2705             :       physId = Utils::findFirstBit(candidateRegs);
+    2706             :       regMask = Utils::mask(physId);
+    2707             : 
+    2708      365980 :       if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2709             :         tied->setOutPhysId(physId);
+    2710             :       }
+    2711             :       else {
+    2712             :         tied->setInPhysId(physId);
+    2713       63082 :         tied->inRegs = regMask;
+    2714             :       }
+    2715             : 
+    2716      365980 :       willAlloc |= regMask;
+    2717      365980 :       willSpill |= regMask & occupied;
+    2718             :       willFree  &=~regMask;
+    2719      365980 :       occupied  |= regMask;
+    2720             : 
+    2721      365980 :       continue;
+    2722      365980 :     }
+    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      445966 :   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      550932 :   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      407720 :   do {
+    2793             :     didWork = false;
+    2794     1005137 :     for (i = 0; i < tiedCount; i++) {
+    2795      597417 :       TiedReg* aTied = &tiedArray[i];
+    2796      597417 :       VirtReg* aVReg = aTied->vreg;
+    2797             : 
+    2798      597417 :       if ((aTied->flags & (TiedReg::kRReg | TiedReg::kRDone)) != TiedReg::kRReg)
+    2799      534335 :         continue;
+    2800             : 
+    2801             :       uint32_t aPhysId = aVReg->getPhysId();
+    2802       63082 :       uint32_t bPhysId = aTied->inPhysId;
+    2803             : 
+    2804             :       // Shouldn't be the same.
+    2805             :       ASMJIT_ASSERT(aPhysId != bPhysId);
+    2806             : 
+    2807       63082 :       VirtReg* bVReg = getState()->getListByKind(C)[bPhysId];
+    2808       63082 :       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       63082 :       else if (aPhysId != Globals::kInvalidRegId) {
+    2831             :         _context->move<C>(aVReg, bPhysId);
+    2832             : 
+    2833       12374 :         aTied->flags |= TiedReg::kRDone;
+    2834             :         addTiedDone(C);
+    2835             : 
+    2836             :         didWork = true;
+    2837       12374 :         continue;
+    2838             :       }
+    2839             :       else {
+    2840             :         _context->alloc<C>(aVReg, bPhysId);
+    2841             : 
+    2842       50708 :         aTied->flags |= TiedReg::kRDone;
+    2843             :         addTiedDone(C);
+    2844             : 
+    2845             :         didWork = true;
+    2846       50708 :         continue;
+    2847             :       }
+    2848             :     }
+    2849             :   } while (didWork);
+    2850             : 
+    2851             :   // Alloc 'out' regs.
+    2852      828349 :   for (i = 0; i < tiedCount; i++) {
+    2853      483711 :     TiedReg* tied = &tiedArray[i];
+    2854      483711 :     VirtReg* vreg = tied->vreg;
+    2855             : 
+    2856      483711 :     if ((tied->flags & (TiedReg::kXReg | TiedReg::kWDone)) != TiedReg::kWReg)
+    2857      180813 :       continue;
+    2858             : 
+    2859      302898 :     uint32_t physId = tied->outPhysId;
+    2860             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    2861             : 
+    2862      302898 :     if (vreg->getPhysId() != physId) {
+    2863             :       ASMJIT_ASSERT(getState()->getListByKind(C)[physId] == nullptr);
+    2864      302898 :       _context->attach<C>(vreg, physId, false);
+    2865             :     }
+    2866             : 
+    2867      302898 :     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      353606 :   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      353606 :   CBNode* node = _node;
+    2891     2203827 :   for (i = 0; i < maxLookAhead; i++) {
+    2892             :     X86RAData* raData = node->getPassData<X86RAData>();
+    2893     2200007 :     RABits* liveness = raData ? raData->liveness : static_cast<RABits*>(nullptr);
+    2894             : 
+    2895             :     // If the variable becomes dead it doesn't make sense to continue.
+    2896     2200007 :     if (liveness && !liveness->getBit(raId)) break;
+    2897             : 
+    2898             :     // Stop on `CBSentinel` and `CCFuncRet`.
+    2899     1934558 :     if (node->hasFlag(CBNode::kFlagIsRet)) break;
+    2900             : 
+    2901             :     // Stop on conditional jump, we don't follow them.
+    2902     1934558 :     if (node->hasFlag(CBNode::kFlagIsJcc)) break;
+    2903             : 
+    2904             :     // Advance on non-conditional jump.
+    2905     1934558 :     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     1934558 :     if (raData) {
+    2916             :       TiedReg* tied = raData->findTiedByKind(C, vreg);
+    2917             :       uint32_t mask;
+    2918             : 
+    2919     1934558 :       if (tied) {
+    2920             :         // If the variable is overwritten it doesn't make sense to continue.
+    2921      403557 :         if ((tied->flags & TiedReg::kRAll) == 0)
+    2922             :           break;
+    2923             : 
+    2924      403557 :         mask = tied->allocableRegs;
+    2925      403557 :         if (mask != 0) {
+    2926      403557 :           allocableRegs &= mask;
+    2927      403557 :           if (allocableRegs == 0) break;
+    2928             :           safeRegs = allocableRegs;
+    2929             :         }
+    2930             : 
+    2931      388961 :         mask = tied->inRegs;
+    2932      388961 :         if (mask != 0) {
+    2933       26597 :           allocableRegs &= mask;
+    2934       26597 :           if (allocableRegs == 0) break;
+    2935             :           safeRegs = allocableRegs;
+    2936       26597 :           break;
+    2937             :         }
+    2938             : 
+    2939      362364 :         allocableRegs &= ~(raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2940      362364 :         if (allocableRegs == 0) break;
+    2941             :       }
+    2942             :       else {
+    2943     1531001 :         allocableRegs &= ~(raData->inRegs.get(C) | raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2944     1531001 :         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     1195647 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2971      749681 :     TiedReg* tied = &tiedArray[i];
+    2972             : 
+    2973      749681 :     if (tied->flags & TiedReg::kWReg) {
+    2974      413449 :       VirtReg* vreg = tied->vreg;
+    2975             : 
+    2976             :       uint32_t physId = vreg->getPhysId();
+    2977             :       uint32_t regMask = Utils::mask(physId);
+    2978             : 
+    2979             :       vreg->setModified(true);
+    2980      413449 :       _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       31999 :   ASMJIT_INLINE X86CallAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2998       31999 :   ASMJIT_INLINE ~X86CallAlloc() {}
+    2999             : 
+    3000             :   // --------------------------------------------------------------------------
+    3001             :   // [Accessors]
+    3002             :   // --------------------------------------------------------------------------
+    3003             : 
+    3004             :   //! Get the node.
+    3005       12938 :   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       12938 : 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       12938 :   ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    3129             : 
+    3130             :   // To emit instructions after call.
+    3131       12938 :   _cc->_setCursor(node);
+    3132             : 
+    3133             :   // If the callee pops stack it has to be manually adjusted back.
+    3134             :   FuncDetail& fd = node->getDetail();
+    3135       12938 :   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       38814 :   uint32_t clobbered = _raData->clobberedRegs.get(C);
+    3185             : 
+    3186             :   uint32_t willAlloc = _willAlloc.get(C);
+    3187       38814 :   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       77334 :   for (i = 0; i < tiedCount; i++) {
+    3196       38520 :     TiedReg* tied = &tiedArray[i];
+    3197       38520 :     VirtReg* vreg = tied->vreg;
+    3198             : 
+    3199       38520 :     uint32_t vaFlags = tied->flags;
+    3200             :     uint32_t physId = vreg->getPhysId();
+    3201       38520 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    3202             : 
+    3203       38520 :     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       25582 :       uint32_t inRegs = tied->inRegs;
+    3209             : 
+    3210       25582 :       if (inRegs == 0) {
+    3211       12938 :         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       25582 :       if ((regMask & inRegs) != 0 || ((regMask & ~clobbered) != 0 && (vaFlags & TiedReg::kUnuse) == 0)) {
+    3218             :         tied->setInPhysId(physId);
+    3219       22328 :         tied->flags |= TiedReg::kRDone;
+    3220             :         addTiedDone(C);
+    3221             :       }
+    3222             :       else {
+    3223        3254 :         willFree |= regMask;
+    3224             :       }
+    3225             :     }
+    3226             :     else {
+    3227             :       // Memory access - if variable is allocated it has to be freed.
+    3228       12938 :       if (regMask != 0) {
+    3229           0 :         willFree |= regMask;
+    3230             :       }
+    3231             :       else {
+    3232       12938 :         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       38814 :   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       77334 :   for (i = 0; i < tiedCount; i++) {
+    3247       38520 :     TiedReg* tied = &tiedArray[i];
+    3248       12938 :     VirtReg* vreg = tied->vreg;
+    3249             : 
+    3250       38520 :     uint32_t vaFlags = tied->flags;
+    3251       38520 :     if ((vaFlags & TiedReg::kRDone) != 0 || (vaFlags & TiedReg::kRReg) == 0)
+    3252       35266 :       continue;
+    3253             : 
+    3254             :     // All registers except Gp used by call itself must have inPhysId.
+    3255        3254 :     uint32_t m = tied->inRegs;
+    3256           0 :     if (C != X86Reg::kKindGp || m) {
+    3257             :       ASMJIT_ASSERT(m != 0);
+    3258             :       tied->setInPhysId(Utils::findFirstBit(m));
+    3259        3254 :       willSpill |= occupied & m;
+    3260        3254 :       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       12938 :   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         832 :     uint32_t bitIndex = Utils::findFirstBit(m) + 1;
+    3313             : 
+    3314         832 :     i += bitIndex;
+    3315         832 :     m >>= bitIndex;
+    3316             : 
+    3317         832 :     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         832 :     _context->spill<C>(vreg);
+    3333         832 :   } while (m != 0);
+    3334             : }
+    3335             : 
+    3336             : template<int C>
+    3337             : ASMJIT_INLINE void X86CallAlloc::alloc() {
+    3338       12938 :   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        6504 :   do {
+    3347             :     didWork = false;
+    3348       19572 :     for (i = 0; i < tiedCount; i++) {
+    3349       13068 :       TiedReg* aTied = &tiedArray[i];
+    3350       13068 :       VirtReg* aVReg = aTied->vreg;
+    3351       13068 :       if ((aTied->flags & (TiedReg::kRReg | TiedReg::kRDone)) != TiedReg::kRReg) continue;
+    3352             : 
+    3353             :       uint32_t sPhysId = aVReg->getPhysId();
+    3354        3258 :       uint32_t bPhysId = aTied->inPhysId;
+    3355             : 
+    3356             :       // Shouldn't be the same.
+    3357             :       ASMJIT_ASSERT(sPhysId != bPhysId);
+    3358             : 
+    3359        3258 :       VirtReg* bVReg = getState()->getListByKind(C)[bPhysId];
+    3360        3258 :       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        3254 :       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        1032 :         _context->_clobberedRegs.or_(C, Utils::mask(bPhysId));
+    3396             : 
+    3397        1032 :         aTied->flags |= TiedReg::kRDone;
+    3398             :         addTiedDone(C);
+    3399             : 
+    3400             :         didWork = true;
+    3401        1032 :         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       12938 :   Operand_* args = node->_args;
+    3417             : 
+    3418       26394 :   for (uint32_t i = 0; i < argCount; i++) {
+    3419       13456 :     Operand_& op = args[i];
+    3420       13456 :     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         812 :     if (arg.byReg()) {
+    3427         812 :       _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       51458 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    3446       38520 :     TiedReg* tied = &tiedArray[i];
+    3447       38520 :     if ((tied->flags & TiedReg::kRReg) == 0) continue;
+    3448             : 
+    3449       25582 :     uint32_t inRegs = tied->inRegs;
+    3450       25582 :     if (!inRegs) continue;
+    3451             : 
+    3452       12644 :     VirtReg* vreg = tied->vreg;
+    3453             :     uint32_t physId = vreg->getPhysId();
+    3454             : 
+    3455             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    3456             : 
+    3457       12644 :     inRegs &= ~Utils::mask(physId);
+    3458       12644 :     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       38814 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C);
+    3551             : 
+    3552       55272 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3553       42334 :     if (affected & 0x1) {
+    3554       34026 :       VirtReg* vreg = sVars[i];
+    3555             :       ASMJIT_ASSERT(vreg != nullptr);
+    3556             :       ASMJIT_ASSERT(vreg->isModified());
+    3557             : 
+    3558       34026 :       TiedReg* tied = vreg->_tied;
+    3559       34026 :       if (!tied || (tied->flags & (TiedReg::kWReg | TiedReg::kUnuse)) == 0)
+    3560       23718 :         _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       38814 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C);
+    3576             : 
+    3577       74744 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3578       61806 :     if (affected & 0x1) {
+    3579       46758 :       VirtReg* vreg = sVars[i];
+    3580             :       ASMJIT_ASSERT(vreg != nullptr);
+    3581             : 
+    3582       46758 :       TiedReg* tied = vreg->_tied;
+    3583             :       uint32_t vdState = VirtReg::kStateNone;
+    3584             : 
+    3585       46758 :       if (!vreg->isModified() || (tied && (tied->flags & (TiedReg::kWAll | TiedReg::kUnuse)) != 0))
+    3586             :         vdState = VirtReg::kStateMem;
+    3587       46758 :       _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       12938 :   Operand_* rets = node->_ret;
+    3600             : 
+    3601       38814 :   for (uint32_t i = 0; i < 2; i++) {
+    3602       25876 :     const FuncDetail::Value& ret = fd.getRet(i);
+    3603       25876 :     Operand_* op = &rets[i];
+    3604             : 
+    3605       25876 :     if (!ret.byReg() || !op->isVirtReg())
+    3606       12938 :       continue;
+    3607             : 
+    3608       12938 :     VirtReg* vreg = _cc->getVirtRegById(op->getId());
+    3609             :     uint32_t regId = ret.getRegId();
+    3610             : 
+    3611       12938 :     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       12938 :         if (X86Reg::kindOf(ret.getRegType()) == X86Reg::kKindVec) {
+    3624       12938 :           _context->unuse<X86Reg::kKindVec>(vreg);
+    3625       12938 :           _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      426905 : static Error X86RAPass_translateOperands(X86RAPass* self, Operand_* opArray, uint32_t opCount) {
+    3648             :   X86Compiler* cc = self->cc();
+    3649             : 
+    3650             :   // Translate variables into registers.
+    3651     1270047 :   for (uint32_t i = 0; i < opCount; i++) {
+    3652      843142 :     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      652533 :       op->_reg.id = vreg->getPhysId();
+    3658             :     }
+    3659      190609 :     else if (op->isMem()) {
+    3660             :       X86Mem* m = static_cast<X86Mem*>(op);
+    3661             : 
+    3662       83373 :       if (m->hasBaseReg() && cc->isVirtRegValid(m->getBaseId())) {
+    3663             :         VirtReg* vreg = cc->getVirtRegById(m->getBaseId());
+    3664             : 
+    3665       83373 :         if (m->isRegHome()) {
+    3666           0 :           self->getVarCell(vreg);
+    3667             :         }
+    3668             :         else {
+    3669             :           ASMJIT_ASSERT(vreg->getPhysId() != Globals::kInvalidRegId);
+    3670       83373 :           op->_mem.base = vreg->getPhysId();
+    3671             :         }
+    3672             :       }
+    3673             : 
+    3674       83373 :       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      426905 :   return kErrorOk;
+    3682             : }
+    3683             : 
+    3684             : // ============================================================================
+    3685             : // [asmjit::X86RAPass - TranslatePrologEpilog]
+    3686             : // ============================================================================
+    3687             : 
+    3688             : //! \internal
+    3689       31999 : 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       31999 :   ffi.setStackFrameSize(self->_memAllTotal);
+    3702       31999 :   ffi.setStackFrameAlignment(self->_memMaxAlign);
+    3703             : 
+    3704       31999 :   return kErrorOk;
+    3705             : }
+    3706             : 
+    3707             : //! \internal
+    3708       31999 : 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      661505 :     if (node->getType() == CBNode::kNodeInst) {
+    3714             :       CBInst* iNode = static_cast<CBInst*>(node);
+    3715             : 
+    3716      520571 :       if (iNode->hasMemOp()) {
+    3717             :         X86Mem* m = iNode->getMemOp<X86Mem>();
+    3718             : 
+    3719      174569 :         if (m->isArgHome()) {
+    3720             :           m->addOffsetLo32(layout.getStackArgsOffset());
+    3721             :           m->clearArgHome();
+    3722             :         }
+    3723             : 
+    3724      174569 :         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       91196 :           m->_setBase(cc->_nativeGpReg.getType(), self->_varBaseRegId);
+    3732       91196 :           m->addOffsetLo32(self->_varBaseOffset + cell->offset);
+    3733             :           m->clearRegHome();
+    3734             :         }
+    3735             :       }
+    3736             :     }
+    3737             : 
+    3738             :     node = node->getNext();
+    3739      661505 :   } while (node != stop);
+    3740             : 
+    3741       31999 :   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       31999 : 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       31999 :   if (raData) {
+    3793       31999 :     TiedReg* tiedArray = raData->tiedArray;
+    3794       31999 :     uint32_t tiedTotal = raData->tiedTotal;
+    3795             : 
+    3796       63998 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+    3797       31999 :       TiedReg* tied = &tiedArray[i];
+    3798       31999 :       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       31999 :   while (node) {
+    3814       31999 :     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       31999 :       case CBNode::kNodeLabel:
+    3818       31999 :         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       31999 : 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      490903 :     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       31999 :       if (!jLink) {
+    3884       31999 :         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      490903 :     node_->_flags |= CBNode::kFlagIsTranslated;
+    3910             : 
+    3911      490903 :     if (node_->hasPassData()) {
+    3912      490903 :       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      458904 :           if (!node_->isJcc()) {
+    3945             :             X86RAData* raData = node_->getPassData<X86RAData>();
+    3946             :             RABits* liveness;
+    3947             : 
+    3948      458904 :             if (raData && next && next->hasPassData() && (liveness = next->getPassData<RAData>()->liveness)) {
+    3949      458904 :               TiedReg* tiedArray = raData->tiedArray;
+    3950      458904 :               uint32_t tiedTotal = raData->tiedTotal;
+    3951             : 
+    3952     1215106 :               for (uint32_t i = 0; i < tiedTotal; i++) {
+    3953      756202 :                 TiedReg* tied = &tiedArray[i];
+    3954      756202 :                 VirtReg* vreg = tied->vreg;
+    3955             : 
+    3956      756202 :                 if (!liveness->getBit(vreg->_raId) && !vreg->isFixed())
+    3957      283837 :                   tied->flags |= TiedReg::kUnuse;
+    3958             :               }
+    3959             :             }
+    3960             :           }
+    3961             : 
+    3962      458904 :           if (node_->getType() == CBNode::kNodeFuncCall) {
+    3963       12938 :             ASMJIT_PROPAGATE(cAlloc.run(static_cast<CCFuncCall*>(node_)));
+    3964             :             break;
+    3965             :           }
+    3966             :           ASMJIT_FALLTHROUGH;
+    3967             : 
+    3968             :         case CBNode::kNodeHint:
+    3969             :         case CBNode::kNodeFuncExit: {
+    3970      477965 :           ASMJIT_PROPAGATE(vAlloc.run(node_));
+    3971             : 
+    3972             :           // Handle conditional/unconditional jump.
+    3973      477965 :           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      477965 :           else if (node_->isRet()) {
+    4031       31999 :             ASMJIT_PROPAGATE(
+    4032             :               X86RAPass_translateRet(this, static_cast<CCFuncRet*>(node_), func->getExitNode()));
+    4033       31999 :             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      458904 :     if (next == stop)
+    4052           0 :       goto _NextGroup;
+    4053             :     node_ = next;
+    4054             :   }
+    4055             : 
+    4056             : _Done:
+    4057             :   {
+    4058       31999 :     ASMJIT_PROPAGATE(resolveCellOffsets());
+    4059       31999 :     ASMJIT_PROPAGATE(X86RAPass_prepareFuncFrame(this, func));
+    4060             : 
+    4061             :     FuncFrameLayout layout;
+    4062       31999 :     ASMJIT_PROPAGATE(layout.init(func->getDetail(), func->getFrameInfo()));
+    4063             : 
+    4064       31999 :     _varBaseRegId = layout._stackBaseRegId;
+    4065       31999 :     _varBaseOffset = layout._stackBaseOffset;
+    4066             : 
+    4067       31999 :     ASMJIT_PROPAGATE(X86RAPass_patchFuncMem(this, func, stop, layout));
+    4068             : 
+    4069             :     cc->_setCursor(func);
+    4070       31999 :     ASMJIT_PROPAGATE(FuncUtils::emitProlog(this->cc(), layout));
+    4071             : 
+    4072             :     cc->_setCursor(func->getExitNode());
+    4073       31999 :     ASMJIT_PROPAGATE(FuncUtils::emitEpilog(this->cc(), layout));
+    4074             :   }
+    4075             : 
+    4076       31999 :   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 000000000..97b2ca64b --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-10-17 16:45:02Functions: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 000000000..7fff2e4a1 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-10-17 16:45:02Functions: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 000000000..1a38884fc --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.gcov.html @@ -0,0 +1,810 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-10-17 16:45:02Functions: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     1109802 :   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      490903 :     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     1934558 :     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      788201 :     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     4243888 :     for (uint32_t i = 0; i < tiedCount; i++)
+     131     2712887 :       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       25876 :       case X86Reg::kKindGp : return _listGp;
+     237       25876 :       case X86Reg::kKindMm : return _listMm;
+     238      108242 :       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     1582988 :   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      554901 :     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      315836 :     _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      315836 :   }
+     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      335577 :     _x86State.getListByKind(C)[physId] = nullptr;
+     415             :     _x86State._occupied.andNot(C, regMask);
+     416             :     _x86State._modified.andNot(C, regMask);
+     417             : 
+     418             :     ASMJIT_X86_CHECK_STATE
+     419      335577 :   }
+     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       14596 :     uint32_t bothRegMask = newRegMask ^ oldRegMask;
+     437             : 
+     438             :     vreg->setPhysId(newPhysId);
+     439             : 
+     440       14596 :     _x86State.getListByKind(C)[oldPhysId] = nullptr;
+     441       14596 :     _x86State.getListByKind(C)[newPhysId] = vreg;
+     442             : 
+     443             :     _x86State._occupied.xor_(C, bothRegMask);
+     444       14596 :     _x86State._modified.xor_(C, bothRegMask & -static_cast<int32_t>(vreg->isModified()));
+     445             : 
+     446             :     ASMJIT_X86_CHECK_STATE
+     447       14596 :   }
+     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       23718 :     emitSave(vreg, physId, "Save");
+     483             :     vreg->setModified(false);
+     484             :     _x86State._modified.andNot(C, regMask);
+     485             : 
+     486             :     ASMJIT_X86_CHECK_STATE
+     487       23718 :   }
+     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       14596 :     if (newPhysId != oldPhysId) {
+     505       14596 :       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       51740 :     if (oldState != VirtReg::kStateReg) {
+     560       51740 :       if (oldState == VirtReg::kStateMem)
+     561       51740 :         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       51740 :     _x86State.getListByKind(C)[physId] = vreg;
+     580             :     _x86State._occupied.xor_(C, regMask);
+     581       51740 :     _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       16310 :     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       16310 :     if (vreg->isModified())
+     603       15738 :       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      646431 :     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       91196 :     (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 000000000..28ca90b5d --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.func-sort-c.html @@ -0,0 +1,160 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:15529852.0 %
Date:2024-10-17 16:45:02Functions: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_8ZoneHeapE63998
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm63998
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm63998
_ZN4PLMD6asmjit4Zone6_allocEm129564
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE159995
_ZN4PLMD6asmjit4ZoneC2Ejj191994
_ZN4PLMD6asmjit4ZoneD2Ev191994
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm267762
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm267762
_ZN4PLMD6asmjit4Zone5resetEb287991
_ZN4PLMD6asmjit4Zone11allocZeroedEm379834
_ZN4PLMD6asmjit4Zone3dupEPKvmb490903
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm1061490
+
+
+ + + +
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 000000000..58b953749 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.func.html @@ -0,0 +1,160 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:15529852.0 %
Date:2024-10-17 16:45:02Functions:142263.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12ZoneHashBase4_delEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase4_putEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE63998
_ZN4PLMD6asmjit12ZoneHashBase7_rehashEj0
_ZN4PLMD6asmjit13ZoneBitVector4fillEmmb0
_ZN4PLMD6asmjit13ZoneBitVector7_appendEPNS0_8ZoneHeapEb0
_ZN4PLMD6asmjit13ZoneBitVector7_resizeEPNS0_8ZoneHeapEmmb0
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm267762
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm63998
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm267762
_ZN4PLMD6asmjit4Zone11allocZeroedEm379834
_ZN4PLMD6asmjit4Zone3dupEPKvmb490903
_ZN4PLMD6asmjit4Zone5resetEb287991
_ZN4PLMD6asmjit4Zone6_allocEm129564
_ZN4PLMD6asmjit4Zone7sformatEPKcz0
_ZN4PLMD6asmjit4ZoneC2Ejj191994
_ZN4PLMD6asmjit4ZoneD2Ev191994
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm63998
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm168
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE159995
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm1061490
_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 000000000..6800c0a86 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.gcov.html @@ -0,0 +1,935 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:15529852.0 %
Date:2024-10-17 16:45:02Functions: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      191994 :   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      191994 : Zone::Zone(uint32_t blockSize, uint32_t blockAlignment) noexcept
+      64      191994 :   : _ptr(nullptr),
+      65      191994 :     _end(nullptr),
+      66      191994 :     _block(const_cast<Zone::Block*>(&Zone_zeroBlock)),
+      67      191994 :     _blockSize(blockSize),
+      68      191994 :     _blockAlignmentShift(Zone_getAlignmentOffsetFromAlignment(blockAlignment)) {}
+      69             : 
+      70      191994 : Zone::~Zone() noexcept {
+      71      191994 :   reset(true);
+      72      191994 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::Zone - Reset]
+      76             : // ============================================================================
+      77             : 
+      78      287991 : void Zone::reset(bool releaseMemory) noexcept {
+      79      287991 :   Block* cur = _block;
+      80             : 
+      81             :   // Can't be altered.
+      82      287991 :   if (cur == &Zone_zeroBlock)
+      83             :     return;
+      84             : 
+      85      191994 :   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      127996 :     Block* next = cur->next;
+      89             :     do {
+      90      129240 :       Block* prev = cur->prev;
+      91             :       Internal::releaseMemory(cur);
+      92             :       cur = prev;
+      93      129240 :     } while (cur);
+      94             : 
+      95             :     cur = next;
+      96      128320 :     while (cur) {
+      97         324 :       next = cur->next;
+      98             :       Internal::releaseMemory(cur);
+      99             :       cur = next;
+     100             :     }
+     101             : 
+     102      127996 :     _ptr = nullptr;
+     103      127996 :     _end = nullptr;
+     104      127996 :     _block = const_cast<Zone::Block*>(&Zone_zeroBlock);
+     105             :   }
+     106             :   else {
+     107       64322 :     while (cur->prev)
+     108             :       cur = cur->prev;
+     109             : 
+     110       63998 :     _ptr = cur->data;
+     111       63998 :     _end = _ptr + cur->size;
+     112       63998 :     _block = cur;
+     113             :   }
+     114             : }
+     115             : 
+     116             : // ============================================================================
+     117             : // [asmjit::Zone - Alloc]
+     118             : // ============================================================================
+     119             : 
+     120      129564 : void* Zone::_alloc(size_t size) noexcept {
+     121      129564 :   Block* curBlock = _block;
+     122             :   uint8_t* p;
+     123             : 
+     124      129564 :   size_t blockSize = std::max<size_t>(_blockSize, size);
+     125      129564 :   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      129564 :   Block* next = curBlock->next;
+     136      129564 :   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      129564 :   if (ASMJIT_UNLIKELY(blockSize > (~static_cast<size_t>(0) - sizeof(Block) - blockAlignment)))
+     148             :     return nullptr;
+     149             : 
+     150      129564 :   blockSize += blockAlignment;
+     151      129564 :   Block* newBlock = static_cast<Block*>(Internal::allocMemory(sizeof(Block) + blockSize));
+     152             : 
+     153      129564 :   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      129564 :   p = Utils::alignTo(newBlock->data, blockAlignment);
+     160      129564 :   newBlock->prev = nullptr;
+     161      129564 :   newBlock->next = nullptr;
+     162      129564 :   newBlock->size = blockSize;
+     163             : 
+     164      129564 :   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      129564 :   _block = newBlock;
+     178      129564 :   _ptr = p + size;
+     179      129564 :   _end = newBlock->data + blockSize;
+     180             : 
+     181      129564 :   return static_cast<void*>(p);
+     182             : }
+     183             : 
+     184      379834 : void* Zone::allocZeroed(size_t size) noexcept {
+     185             :   void* p = alloc(size);
+     186      379834 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     187      379834 :   return ::memset(p, 0, size);
+     188             : }
+     189             : 
+     190      490903 : void* Zone::dup(const void* data, size_t size, bool nullTerminate) noexcept {
+     191      490903 :   if (ASMJIT_UNLIKELY(!data || !size)) return nullptr;
+     192             : 
+     193             :   ASMJIT_ASSERT(size != IntTraits<size_t>::maxValue());
+     194      490903 :   uint8_t* m = allocT<uint8_t>(size + nullTerminate);
+     195      490903 :   if (ASMJIT_UNLIKELY(!m)) return nullptr;
+     196             : 
+     197             :   ::memcpy(m, data, size);
+     198      490903 :   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      159995 : void ZoneHeap::reset(Zone* zone) noexcept {
+     238             :   // Free dynamic blocks.
+     239      159995 :   DynamicBlock* block = _dynamicBlocks;
+     240      161107 :   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      159995 :   _zone = zone;
+     249      159995 : }
+     250             : 
+     251             : // ============================================================================
+     252             : // [asmjit::ZoneHeap - Alloc / Release]
+     253             : // ============================================================================
+     254             : 
+     255     1061490 : 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     1060210 :     uint8_t* p = reinterpret_cast<uint8_t*>(_slots[slot]);
+     263     1060210 :     size = allocatedSize;
+     264             : 
+     265     1060210 :     if (p) {
+     266        9367 :       _slots[slot] = reinterpret_cast<Slot*>(p)->next;
+     267             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     268        9367 :       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     1050843 :     Zone* zone = _zone;
+     275             :     p = Utils::alignTo(zone->getCursor(), kBlockAlignment);
+     276     1050843 :     size_t remain = (p <= zone->getEnd()) ? (size_t)(zone->getEnd() - p) : size_t(0);
+     277             : 
+     278     1050843 :     if (ASMJIT_LIKELY(remain >= size)) {
+     279      986389 :       zone->setCursor(p + size);
+     280             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     281      986389 :       return p;
+     282             :     }
+     283             :     else {
+     284             :       // Distribute the remaining memory to suitable slots.
+     285       64454 :       if (remain >= kLoGranularity) {
+     286             :         do {
+     287         371 :           size_t distSize = std::min<size_t>(remain, kLoMaxSize);
+     288         371 :           uint32_t distSlot = static_cast<uint32_t>((distSize - kLoGranularity) / kLoGranularity);
+     289             :           ASMJIT_ASSERT(distSlot < kLoCount);
+     290             : 
+     291         371 :           reinterpret_cast<Slot*>(p)->next = _slots[distSlot];
+     292         371 :           _slots[distSlot] = reinterpret_cast<Slot*>(p);
+     293             : 
+     294         371 :           p += distSize;
+     295         371 :           remain -= distSize;
+     296         371 :         } while (remain >= kLoGranularity);
+     297             :         zone->setCursor(p);
+     298             :       }
+     299             : 
+     300       64454 :       p = static_cast<uint8_t*>(zone->_alloc(size));
+     301       64454 :       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       63998 : void* ZoneHeap::_allocZeroed(size_t size, size_t& allocatedSize) noexcept {
+     347             :   ASMJIT_ASSERT(isInitialized());
+     348             : 
+     349       63998 :   void* p = _alloc(size, allocatedSize);
+     350       63998 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     351       63998 :   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      267762 : Error ZoneVectorBase::_grow(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     382      267762 :   size_t threshold = Globals::kAllocThreshold / sizeOfT;
+     383      267762 :   size_t capacity = _capacity;
+     384      267762 :   size_t after = _length;
+     385             : 
+     386      267762 :   if (ASMJIT_UNLIKELY(IntTraits<size_t>::maxValue() - n < after))
+     387             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     388             : 
+     389      267762 :   after += n;
+     390      267762 :   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      267762 :   if (capacity < 4)
+     398             :     capacity = 4;
+     399       75768 :   else if (capacity < 8)
+     400             :     capacity = 8;
+     401       23760 :   else if (capacity < 16)
+     402             :     capacity = 16;
+     403        5688 :   else if (capacity < 64)
+     404             :     capacity = 64;
+     405             :   else if (capacity < 256)
+     406             :     capacity = 256;
+     407             : 
+     408      267930 :   while (capacity < after) {
+     409         168 :     if (capacity < threshold)
+     410         168 :       capacity *= 2;
+     411             :     else
+     412           0 :       capacity += threshold;
+     413             :   }
+     414             : 
+     415      267762 :   return _reserve(heap, sizeOfT, capacity);
+     416             : }
+     417             : 
+     418      267762 : Error ZoneVectorBase::_reserve(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     419      267762 :   size_t oldCapacity = _capacity;
+     420      267762 :   if (oldCapacity >= n) return kErrorOk;
+     421             : 
+     422      267762 :   size_t nBytes = n * sizeOfT;
+     423      267762 :   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      267762 :   if (ASMJIT_UNLIKELY(!newData))
+     430             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     431             : 
+     432      267762 :   void* oldData = _data;
+     433      267762 :   if (_length)
+     434       75768 :     ::memcpy(newData, oldData, _length * sizeOfT);
+     435             : 
+     436      267762 :   if (oldData)
+     437       75768 :     heap->release(oldData, oldCapacity * sizeOfT);
+     438             : 
+     439      267762 :   _capacity = allocatedBytes / sizeOfT;
+     440             :   ASMJIT_ASSERT(_capacity >= n);
+     441             : 
+     442      267762 :   _data = newData;
+     443      267762 :   return kErrorOk;
+     444             : }
+     445             : 
+     446       63998 : Error ZoneVectorBase::_resize(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     447       63998 :   size_t length = _length;
+     448       63998 :   if (_capacity < n) {
+     449       31999 :     ASMJIT_PROPAGATE(_grow(heap, sizeOfT, n - length));
+     450             :     ASMJIT_ASSERT(_capacity >= n);
+     451             :   }
+     452             : 
+     453       63998 :   if (length < n)
+     454       63998 :     ::memset(static_cast<uint8_t*>(_data) + length * sizeOfT, 0, (n - length) * sizeOfT);
+     455             : 
+     456       63998 :   _length = n;
+     457       63998 :   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       63998 : void ZoneHashBase::reset(ZoneHeap* heap) noexcept {
+     678       63998 :   ZoneHashNode** oldData = _data;
+     679       63998 :   if (oldData != _embedded)
+     680           0 :     _heap->release(oldData, _bucketsCount * sizeof(ZoneHashNode*));
+     681             : 
+     682       63998 :   _heap = heap;
+     683       63998 :   _size = 0;
+     684       63998 :   _bucketsCount = 1;
+     685       63998 :   _bucketsGrow = 1;
+     686       63998 :   _data = _embedded;
+     687       63998 :   _embedded[0] = nullptr;
+     688       63998 : }
+     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 000000000..e417ecb59 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:759380.6 %
Date:2024-10-17 16:45:02Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_31999
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_315836
+
+
+ + + +
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 000000000..8ca902ed1 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:759380.6 %
Date:2024-10-17 16:45:02Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_31999
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_315836
+
+
+ + + +
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 000000000..e7eebad64 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.gcov.html @@ -0,0 +1,1233 @@ + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:759380.6 %
Date:2024-10-17 16:45:02Functions: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      129564 :   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     1050843 :   ASMJIT_INLINE uint8_t* getCursor() noexcept { return _ptr; }
+     125             :   //! Get the end of the current zone block, only useful if you use `getCursor()`.
+     126     1050843 :   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      986389 :     _ptr = p;
+     134         363 :   }
+     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     1561091 :     uint8_t* ptr = _ptr;
+     174     1561091 :     size_t remainingBytes = (size_t)(_end - ptr);
+     175             : 
+     176     1561091 :     if (ASMJIT_UNLIKELY(remainingBytes < size))
+     177       65110 :       return _alloc(size);
+     178             : 
+     179     1495981 :     _ptr += size;
+     180             :     ASMJIT_ASSERT(_ptr <= _end);
+     181             : 
+     182     1495981 :     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      347835 :     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       31999 :   ASMJIT_INLINE ZoneHeap() noexcept {
+     326             :     ::memset(this, 0, sizeof(*this));
+     327             :   }
+     328             :   //! Create a new `ZoneHeap` initialized to use `zone`.
+     329       63998 :   explicit ASMJIT_INLINE ZoneHeap(Zone* zone) noexcept {
+     330             :     ::memset(this, 0, sizeof(*this));
+     331       63998 :     _zone = zone;
+     332             :   }
+     333             :   //! Destroy the `ZoneHeap`.
+     334       63998 :   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       75768 :     if (size > kHiMaxSize)
+     372             :       return false;
+     373             : 
+     374       75600 :     if (size <= kLoMaxSize)
+     375       74488 :       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     1061490 :     if (size > kHiMaxSize)
+     386             :       return false;
+     387             : 
+     388     1060210 :     if (size <= kLoMaxSize) {
+     389     1010865 :       slot = static_cast<uint32_t>((size - 1) / kLoGranularity);
+     390     1010865 :       allocatedSize = Utils::alignTo(size, kLoGranularity);
+     391             :     }
+     392             :     else {
+     393       49345 :       slot = static_cast<uint32_t>((size - kLoMaxSize - 1) / kHiGranularity) + kLoCount;
+     394       49345 :       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      729730 :     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      267762 :     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       63998 :     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       75600 :       static_cast<Slot*>(p)->next = static_cast<Slot*>(_slots[slot]);
+     465       75600 :       _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       63998 :     ASMJIT_INLINE Link* getNext() const noexcept { return _next; }
+     499             :     //! Get value.
+     500       31999 :     ASMJIT_INLINE T getValue() const noexcept { return _value; }
+     501             :     //! Set value to `value`.
+     502       63998 :     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       31999 :   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      127996 :   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       31999 :     _first = nullptr;
+     555       31999 :     _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       63998 :     link->_next = nullptr;
+     566       63998 :     if (!_first)
+     567       63998 :       _first = link;
+     568             :     else
+     569           0 :       _last->_next = link;
+     570       63998 :     _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      127996 :     : _data(nullptr),
+     598      127996 :       _length(0),
+     599      127996 :       _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     1022411 :   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       95997 :     _data = nullptr;
+     622       95997 :     _length = 0;
+     623       95997 :     _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      191994 :   ASMJIT_INLINE T* getData() noexcept { return static_cast<T*>(_data); }
+     686             :   //! \overload
+     687     1761523 :   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      347835 :   Error append(ZoneHeap* heap, const T& item) noexcept {
+     722      347835 :     if (ASMJIT_UNLIKELY(_length == _capacity))
+     723       69883 :       ASMJIT_PROPAGATE(grow(heap, 1));
+     724             : 
+     725      347835 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     726             : 
+     727      347835 :     _length++;
+     728      347835 :     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      411833 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     767      379834 :     _length++;
+     768       31999 :   }
+     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      127996 :     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     1697525 :     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      235763 :   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       63998 :   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      443832 :     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       31999 :   ASMJIT_INLINE ZoneHashBase(ZoneHeap* heap) noexcept {
+    1068       31999 :     _heap = heap;
+    1069       31999 :     _size = 0;
+    1070       31999 :     _bucketsCount = 1;
+    1071       31999 :     _bucketsGrow = 1;
+    1072       31999 :     _data = _embedded;
+    1073       31999 :     _embedded[0] = nullptr;
+    1074             :   }
+    1075       31999 :   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       31999 :   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 000000000..0f9194445 --- /dev/null +++ b/coverage-libs/blas/blas.cpp.func-sort-c.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-10-17 16:45:02Functions: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
_ZN4PLMD4blas6dtrmm_EPKcS2_S2_S2_PiS3_PdS4_S3_S4_S3_411
_ZN4PLMD4blas6dgemm_EPKcS2_PiS3_S3_PdS4_S3_S4_S3_S4_S4_S3_504
_ZN4PLMD4blas5drot_EPiPdS1_S2_S1_S2_S2_1800
_ZN4PLMD4blas6dswap_EPiPdS1_S2_S1_8490
_ZN4PLMD4blas7idamax_EPiPdS1_33025
_ZN4PLMD4blas6dtrmv_EPKcS2_S2_PiPdS3_S4_S3_36253
_ZN4PLMD4blas6dsyr2_EPKcPiPdS4_S3_S4_S3_S4_S3_1248709
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1249222
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1249223
_ZN4PLMD4blas6dnrm2_EPiPdS1_1262812
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1275614
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1287182
_ZN4PLMD4blas6daxpy_EPiPdS2_S1_S2_S1_1535898
_ZN4PLMD4blas6dscal_EPiPdS2_S1_2137688
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4471174
+
+
+ + + +
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 000000000..0eef8e7c6 --- /dev/null +++ b/coverage-libs/blas/blas.cpp.func.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-10-17 16:45:02Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1249223
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1275614
_ZN4PLMD4blas5drot_EPiPdS1_S2_S1_S2_S2_1800
_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_1535898
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4471174
_ZN4PLMD4blas6dgemm_EPKcS2_PiS3_S3_PdS4_S3_S4_S3_S4_S4_S3_504
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1287182
_ZN4PLMD4blas6dnrm2_EPiPdS1_1262812
_ZN4PLMD4blas6dscal_EPiPdS2_S1_2137688
_ZN4PLMD4blas6dswap_EPiPdS1_S2_S1_8490
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1249222
_ZN4PLMD4blas6dsyr2_EPKcPiPdS4_S3_S4_S3_S4_S3_1248709
_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 000000000..63b99ad42 --- /dev/null +++ b/coverage-libs/blas/blas.cpp.gcov.html @@ -0,0 +1,3766 @@ + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-10-17 16:45:02Functions: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     1535898 : 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     1535898 :   int n=*n_arg;
+      97     1535898 :   double da=*da_arg;
+      98     1535898 :   int incx = *incx_arg;
+      99     1535898 :   int incy = *incy_arg;
+     100             : 
+     101     1535898 :   if (n<=0)
+     102             :     return;
+     103             : 
+     104     1535898 :   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     8627988 :     for(i=0;i<(n-4);i+=4) {
+     122     7092090 :       dy[i]   += da*dx[i];
+     123     7092090 :       dy[i+1] += da*dx[i+1];
+     124     7092090 :       dy[i+2] += da*dx[i+2];
+     125     7092090 :       dy[i+3] += da*dx[i+3];
+     126             :     }
+     127             :     /* continue with current value of i */
+     128     5384756 :     for(;i<n;i++)
+     129     3848858 :       dy[i]   += da*dx[i];
+     130             :   }
+     131             : }
+     132             : }
+     133             : }
+     134             : #include "blas.h"
+     135             : 
+     136             : namespace PLMD{
+     137             : namespace blas{
+     138             : void
+     139     4471174 : 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     4471174 :     int n= *n__;
+     148     4471174 :     int incx = *incx__;
+     149     4471174 :     int incy = *incy__;
+     150             :     
+     151             : 
+     152     4471174 :     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     4572411 :         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    18533861 :         for(;i<n;i++)
+     181    14068571 :             dy[i] = dx[i];
+     182             :     }
+     183             : }
+     184             : }
+     185             : }
+     186             : #include "blas.h"
+     187             : 
+     188             : namespace PLMD{
+     189             : namespace blas{
+     190             : double
+     191     1249223 : 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     1249223 :     int n=*n_arg;
+     199     1249223 :     int incx = *incx_arg;
+     200     1249223 :     int incy = *incy_arg;
+     201             :     double t1;
+     202             :     
+     203     1249223 :     if(n<=0)
+     204             :         return 0.0;
+     205             :     
+     206             :     t1 = 0.0;
+     207             :     
+     208     1249223 :     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     1249223 :         m = n%5;
+     224             :         
+     225     4371031 :         for(i=0;i<m;i++)
+     226     3121808 :             t1 += dx[i] * dy[i];
+     227             :         
+     228             :         /* unroll */
+     229     1285544 :         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     1287182 : 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     1287182 :   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     1287182 :   int m = *m__;
+     401     1287182 :   int n = *n__;
+     402     1287182 :   double alpha = *alpha__;
+     403     1287182 :   double beta = *beta__;
+     404     1287182 :   int incx = *incx__;
+     405     1287182 :   int incy = *incy__;
+     406     1287182 :   int lda = *lda__;
+     407             :   
+     408     1287182 :   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     1286990 :   if(ch=='N') {
+     412             :     lenx = n;
+     413             :     leny = m;
+     414             :   } else {
+     415             :     lenx = m;
+     416             :     leny = n;
+     417             :   }
+     418             :   
+     419     1286990 :    if(incx>0)
+     420             :     kx = 1;
+     421             :   else
+     422           0 :     kx = 1 - (lenx -1)*(incx);
+     423             : 
+     424     1286990 :   if(incy>0)
+     425             :     ky = 1;
+     426             :   else
+     427           0 :     ky = 1 - (leny -1)*(incy);
+     428             :  
+     429     1286990 :   if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     430     1265500 :     if(incy==1) {
+     431     1265500 :       if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+     432     3333508 :         for(i=0;i<leny;i++)
+     433     2068008 :           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     1286990 :   if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     450             :     return;
+     451             :   
+     452     1286990 :   if(ch=='N') {
+     453             :     jx = kx;
+     454       27222 :     if(incy==1) {
+     455      511632 :       for(j=1;j<=n;j++,jx+=incx) 
+     456      484794 :         if(std::abs(x[jx-1])>PLUMED_GMX_DOUBLE_MIN) {
+     457      484794 :           temp = alpha * x[jx-1];
+     458    63100049 :           for(i=1;i<=m;i++)
+     459    62615255 :             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     1259768 :     if(incx==1) {
+     475     3230172 :       for(j=1;j<=n;j++,jy+=incy) {
+     476             :         temp = 0.0;
+     477    62212273 :         for(i=1;i<=m;i++)
+     478    60241113 :           temp += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     479     1971160 :         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     1275614 : 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     1275614 :     int m = *m__;
+     521     1275614 :     int n = *n__;
+     522     1275614 :     int incx = *incx__;
+     523     1275614 :     int incy = *incy__;
+     524     1275614 :     int lda = *lda__;
+     525     1275614 :     double alpha = *alpha__;
+     526             :     
+     527     1275614 :     if(m<=0 || n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     528             :         return;
+     529             :     
+     530     1275614 :     if(incy>0)
+     531             :         jy = 0;
+     532             :     else
+     533           0 :         jy = incy * (1 - n);
+     534             :     
+     535     1275614 :     if(incx==1) {
+     536     3021858 :         for(j=0;j<n;j++,jy+=incy)
+     537     1746244 :             if(std::abs(y[jy])>PLUMED_GMX_DOUBLE_MIN) {
+     538     1746234 :                 temp = alpha * y[jy];
+     539     8618460 :                 for(i=0;i<m;i++)
+     540     6872226 :                     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     1262812 : 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     1262812 :     int n = *n__;
+     578     1262812 :     int incx = *incx__;
+     579             :     
+     580     1262812 :     if(n<1 || incx<1)
+     581             :         return 0;
+     582     1262812 :     else if (n==1) {
+     583      625509 :         t = x[0];
+     584      625509 :         if(t>=0)
+     585             :             return t;
+     586             :         else 
+     587      464697 :             return -t;
+     588             :     }
+     589             :     
+     590             :     scale = 0.0;
+     591             :     ssq   = 1.0;
+     592             :     
+     593      637303 :     max_ix = 1+(n-1)*(incx);
+     594     3211597 :     for(ix=1;ix<=max_ix;ix+=incx) {
+     595     2574294 :         t = x[ix-1];
+     596     2574294 :         if(std::abs(t)>PLUMED_GMX_DOUBLE_MIN) {
+     597     2572105 :             absxi = (t>=0) ? t : (-t);
+     598     2572105 :             if(scale<absxi) {
+     599      922099 :                 t = scale/absxi;
+     600      922099 :                 t = t*t;
+     601      922099 :                 ssq = ssq*t + 1.0;
+     602             :                 scale = absxi;
+     603             :             } else {
+     604     1650006 :                 t = absxi/scale;
+     605     1650006 :                 ssq += t*t;
+     606             :             }
+     607             :         }
+     608             :     }
+     609      637303 :     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        1800 : 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        1800 :   int n = *n__;
+     634        1800 :   int incx = *incx__;
+     635        1800 :   int incy = *incy__;
+     636        1800 :   double c = *c__;
+     637        1800 :   double s = *s__;
+     638             :   
+     639        1800 :   if(incx!=1 || incy!=1) {
+     640             :     ix = 0;
+     641             :     iy = 0;
+     642         900 :     if(incx<0)
+     643           0 :       ix = (1-n)*(incx);
+     644         900 :     if(incy<0)
+     645           0 :       iy = (1-n)*(incy);
+     646             :     
+     647        6016 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+     648        5116 :       dtemp  = (c) * dx[ix] + (s) * dy[iy];
+     649        5116 :       dy[iy] = (c) * dy[iy] - (s) * dx[ix];
+     650        5116 :       dx[ix] = dtemp;
+     651             :     }
+     652             : 
+     653             :     return;
+     654             : 
+     655             :   } else {
+     656             : 
+     657             :     /* unit increments */   
+     658        5955 :     for(i=0;i<n;i++) {
+     659        5055 :       dtemp = (c) * dx[i] + (s) * dy[i];
+     660        5055 :       dy[i] = (c) * dy[i] - (s) * dx[i];
+     661        5055 :       dx[i] = dtemp;      
+     662             :     }
+     663             : 
+     664             :   }
+     665             : }
+     666             : }
+     667             : }
+     668             : #include "blas.h"
+     669             : 
+     670             : namespace PLMD{
+     671             : namespace blas{
+     672             : void 
+     673     2137688 : PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(int  *    n__,
+     674             :                       double *   fact__,
+     675             :                       double *   dx,
+     676             :                       int    *   incx__)
+     677             : {
+     678             :     int nincx,i;
+     679             : 
+     680     2137688 :     int n = *n__;
+     681     2137688 :     double fact = *fact__;
+     682     2137688 :     int incx = *incx__;
+     683             :     
+     684     2137688 :     if(n<=0 || incx<=0)
+     685             :         return;
+     686             :     
+     687     2121177 :     if(incx==1) {
+     688             :         /* Unrool factor 5 */
+     689     2303046 :         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     7302624 :         for(;i<n;i++)
+     698     5185482 :             dx[i]   *= fact;
+     699             :         
+     700             :         return;
+     701             :     } else {
+     702             :         /* inc != 1 */
+     703        4035 :         nincx = n * (incx);
+     704      162438 :         for (i=0;i<nincx;i+=incx)
+     705      158403 :             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        8490 : 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        8490 :   int n = *n__;
+     728        8490 :   int incx = *incx__;
+     729        8490 :   int incy = *incy__;
+     730             :   
+     731        8490 :   if(n<=0)
+     732             :     return;
+     733             : 
+     734        8490 :   if(incx==1 && incy==1) {
+     735       77201 :     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       14349 :     for(;i<n;i++) {
+     748        9925 :       d1      = dx[i];
+     749        9925 :       dx[i]   = dy[i];
+     750        9925 :       dy[i]   = d1;
+     751             :     }
+     752             : 
+     753             :   } else {
+     754             :     ix = 0;
+     755             :     iy = 0;
+     756        4066 :     if(incx<0)
+     757           0 :       ix = incx * (1 - n);
+     758        4066 :     if(incy<0)
+     759           0 :       iy = incy * (1 - n);
+     760             : 
+     761      200881 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+     762      196815 :       d1     = dx[ix];
+     763      196815 :       dx[ix] = dy[iy];
+     764      196815 :       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     1249222 : 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     1249222 :     const char ch=std::toupper(*uplo);
+     793             :     int kx,ky,i,j,ix,iy,jx,jy;
+     794             :     double temp1,temp2;
+     795             :     
+     796     1249222 :     int n = *n__;
+     797     1249222 :     int lda = *lda__;
+     798     1249222 :     int incx = *incx__;
+     799     1249222 :     int incy = *incy__;
+     800     1249222 :     double alpha = *alpha__;
+     801     1249222 :     double beta  = *beta__;
+     802             :     
+     803     1249222 :     if(n<=0 || incx==0 || incy==0)
+     804             :         return;
+     805             :     
+     806     1249222 :     if(incx>0)
+     807             :         kx = 1;
+     808             :     else
+     809           0 :         kx = 1 - (n -1)*(incx);
+     810             :     
+     811     1249222 :     if(incy>0)
+     812             :         ky = 1;
+     813             :     else
+     814           0 :         ky = 1 - (n -1)*(incy);
+     815             :     
+     816     1249222 :     if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     817     1249222 :         if(incy==1) {
+     818     1249222 :             if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+     819     4552630 :                 for(i=1;i<=n;i++)
+     820     3303408 :                     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     1249222 :         if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN) 
+     841             :             return;
+     842             :         
+     843     1249222 :         if(ch=='U') {
+     844     1249222 :             if(incx==1 && incy==1) {
+     845     4552630 :                 for(j=1;j<=n;j++) {
+     846     3303408 :                     temp1 = alpha * x[j-1];
+     847             :                     temp2 = 0.0;
+     848    29831600 :                     for(i=1;i<j;i++) {
+     849    26528192 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+     850    26528192 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     851             :                     }
+     852     3303408 :                     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     1248709 : 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     1248709 :     const char ch=std::toupper(*uplo);
+     936             :     
+     937     1248709 :     int n = *n__;
+     938     1248709 :     int lda = *lda__;
+     939     1248709 :     int incx = *incx__;
+     940     1248709 :     int incy = *incy__;
+     941     1248709 :     float alpha = *alpha__;
+     942             :     
+     943             :     
+     944     1248709 :     if(n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN || incx==0 || incy==0 ||
+     945     1248709 :        (ch != 'U' && ch != 'L'))
+     946             :         return;
+     947             :     
+     948             :     jx = jy = kx = ky = 0;
+     949             :     
+     950             :     /* init start points for non-unit increments */
+     951     1248709 :     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     1248709 :     if(ch == 'U') {
+     966             :         /* Data in upper part of A */
+     967     1248709 :         if(incx==1 && incy==1) {
+     968             :             /* Unit increments for both x and y */
+     969     4410178 :             for(j=1;j<=n;j++) {
+     970     3161469 :                 if( std::abs(x[j-1])>PLUMED_GMX_DOUBLE_MIN  || std::abs(y[j-1])>PLUMED_GMX_DOUBLE_MIN ) {
+     971     3161467 :                     temp1 = alpha * y[j-1];
+     972     3161467 :                     temp2 = alpha * x[j-1];
+     973    10111771 :                     for(i=1;i<=j;i++)
+     974     6950304 :                         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 000000000..e463bd9b7 --- /dev/null +++ b/coverage-libs/blas/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..e45dccf26 --- /dev/null +++ b/coverage-libs/blas/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..fc23246f4 --- /dev/null +++ b/coverage-libs/blas/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..0fcdff13c --- /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 000000000..94c522159 --- /dev/null +++ b/coverage-libs/index-sort-f.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:95482901432.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..f56a415c6 --- /dev/null +++ b/coverage-libs/index-sort-l.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:95482901432.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..1e339dcdc --- /dev/null +++ b/coverage-libs/index.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:95482901432.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..67aaaea20 --- /dev/null +++ b/coverage-libs/lapack/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..2d19b4654 --- /dev/null +++ b/coverage-libs/lapack/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..8a4da0779 --- /dev/null +++ b/coverage-libs/lapack/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..eea9d1cc7 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func-sort-c.html @@ -0,0 +1,796 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-10-17 16:45:02Functions: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
_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
_ZN4PLMD6lapack7dlascl_EPKcPiS3_PdS4_S3_S3_S4_S3_S3_264
_ZN4PLMD6lapack7dorm2r_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_799
_ZN4PLMD6lapack7dorml2_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_803
_ZN4PLMD6lapack7dbdsdc_EPKcS2_PiPdS4_S4_S3_S4_S3_S4_S3_S4_S3_S3_816
_ZN4PLMD6lapack7dgebd2_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_816
_ZN4PLMD6lapack7dgebrd_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_S1_816
_ZN4PLMD6lapack7dlange_EPKcPiS3_PdS3_S4_816
_ZN4PLMD6lapack7dormlq_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_816
_ZN4PLMD6lapack7dormqr_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_816
_ZN4PLMD6lapack7dbdsqr_EPKcPiS3_S3_S3_PdS4_S4_S3_S4_S3_S4_S3_S4_S3_875
_ZN4PLMD6lapack7dlasdq_EPKcPiS3_S3_S3_S3_PdS4_S4_S3_S4_S3_S4_S3_S4_S3_875
_ZN4PLMD6lapack7dlasv2_EPdS1_S1_S1_S1_S1_S1_S1_S1_900
_ZN4PLMD6lapack7dlaed6_EPiS1_PdS2_S2_S2_S2_S1_1387
_ZN4PLMD6lapack7dgesdd_EPKcPiS3_PdS3_S4_S4_S3_S4_S3_S4_S3_S3_S3_1632
_ZN4PLMD6lapack7dormbr_EPKcS2_S2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_1632
_ZN4PLMD6lapack7dlasd4_EPiS1_PdS2_S2_S2_S2_S2_S1_3251
_ZN4PLMD6lapack6dlas2_EPdS1_S1_S1_S1_4552
_ZN4PLMD6lapack6dlasr_EPKcS2_S2_PiS3_PdS4_S4_S3_12262
_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_96279
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_624304
_ZN4PLMD6lapack7dorm2l_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_637226
_ZN4PLMD6lapack7dlasq2_EPiPdS1_637235
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_637236
_ZN4PLMD6lapack7dormql_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_637236
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_637236
_ZN4PLMD6lapack7dstegr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_637236
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_637236
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_637236
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_637236
_ZN4PLMD6lapack8dlarrvx_EPiPdS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_637236
_ZN4PLMD6lapack7dlanst_EPKcPiPdS4_637265
_ZN4PLMD6lapack8dlarrbx_EPiPdS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_637311
_ZN4PLMD6lapack7dlaset_EPKcPiS3_PdS4_S4_S3_640634
_ZN4PLMD6lapack7dsyevr_EPKcS2_S2_PiPdS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_651875
_ZN4PLMD6lapack8dlar1vx_EPiS1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_831186
_ZN4PLMD6lapack7dlapy2_EPdS1_1256210
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1895119
_ZN4PLMD6lapack6dlarf_EPKcPiS3_PdS3_S4_S4_S3_S4_1899581
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_14066784
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_14066793
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_14690906
+
+
+ + + +
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 000000000..61456032c --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func.html @@ -0,0 +1,796 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-10-17 16:45:02Functions: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_1899581
_ZN4PLMD6lapack6dlas2_EPdS1_S1_S1_S1_4552
_ZN4PLMD6lapack6dlasr_EPKcS2_S2_PiS3_PdS4_S4_S3_12262
_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_816
_ZN4PLMD6lapack7dbdsqr_EPKcPiS3_S3_S3_PdS4_S4_S3_S4_S3_S4_S3_S4_S3_875
_ZN4PLMD6lapack7dgebd2_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_816
_ZN4PLMD6lapack7dgebrd_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_S1_816
_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_1632
_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_816
_ZN4PLMD6lapack7dlanst_EPKcPiPdS4_637265
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_637236
_ZN4PLMD6lapack7dlapy2_EPdS1_1256210
_ZN4PLMD6lapack7dlarfb_EPKcS2_S2_S2_PiS3_S3_PdS3_S4_S3_S4_S3_S4_S3_137
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1895119
_ZN4PLMD6lapack7dlarft_EPKcS2_PiS3_PdS3_S4_S4_S3_137
_ZN4PLMD6lapack7dlarnv_EPiS1_S1_Pd0
_ZN4PLMD6lapack7dlartg_EPdS1_S1_S1_S1_96279
_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_875
_ZN4PLMD6lapack7dlasdt_EPiS1_S1_S1_S1_S1_S1_29
_ZN4PLMD6lapack7dlaset_EPKcPiS3_PdS4_S4_S3_640634
_ZN4PLMD6lapack7dlasq1_EPiPdS2_S2_S1_0
_ZN4PLMD6lapack7dlasq2_EPiPdS1_637235
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_14690906
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_14066784
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_14066793
_ZN4PLMD6lapack7dlasq6_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_624304
_ZN4PLMD6lapack7dlassq_EPiPdS1_S2_S2_0
_ZN4PLMD6lapack7dlasv2_EPdS1_S1_S1_S1_S1_S1_S1_S1_900
_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_637226
_ZN4PLMD6lapack7dorm2r_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_799
_ZN4PLMD6lapack7dormbr_EPKcS2_S2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_1632
_ZN4PLMD6lapack7dorml2_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_803
_ZN4PLMD6lapack7dormlq_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_816
_ZN4PLMD6lapack7dormql_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_637236
_ZN4PLMD6lapack7dormqr_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_816
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_637236
_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_637236
_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_651875
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_637236
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_637236
_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_831186
_ZN4PLMD6lapack8dlarrbx_EPiPdS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_637311
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_637236
_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_637236
_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 000000000..342a2d147 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.gcov.html @@ -0,0 +1,31099 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-10-17 16:45:02Functions: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         816 : 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         816 :     double zero = 0.0;
+      69         816 :     double one = 1.0;
+      70         816 :     int c_0 = 0;
+      71         816 :     int c_1 = 1;
+      72             : 
+      73         816 :     --d__;
+      74         816 :     --e;
+      75         816 :     u_dim1 = *ldu;
+      76         816 :     u_offset = 1 + u_dim1;
+      77         816 :     u -= u_offset;
+      78         816 :     vt_dim1 = *ldvt;
+      79         816 :     vt_offset = 1 + vt_dim1;
+      80         816 :     vt -= vt_offset;
+      81         816 :     --q;
+      82         816 :     --iq;
+      83         816 :     --work;
+      84             :     --iwork;
+      85             : 
+      86             :     k = iu = z__ = ic = is = ivt = difl = difr = perm = 0;
+      87             :     poles = givnum = givptr = givcol = 0;
+      88             :     
+      89         816 :     smlsiz = DBDSDC_SMALLSIZE;
+      90         816 :     *info = 0;
+      91             : 
+      92         816 :     iuplo = (*uplo=='U' || *uplo=='u') ? 1 : 2;
+      93             : 
+      94         816 :     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         816 :     case 'i':
+     104             :     case 'I':
+     105         816 :       icompq = 2;
+     106         816 :       break;
+     107             :     default:
+     108             :       return;
+     109             :     }
+     110             : 
+     111         816 :     if (*n <= 0) 
+     112             :         return;
+     113             :     
+     114         816 :     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         816 :     nm1 = *n - 1;
+     126             :     wstart = 1;
+     127             :     qstart = 3;
+     128         816 :     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         816 :     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         816 :     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         816 :     if (*n <= smlsiz) {
+     157         787 :         if (icompq == 2) {
+     158         787 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+     159         787 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+     160         787 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U",&c_0,n,n,n,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+     161         787 :                     &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         787 :         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         816 : L40:
+     264         816 :     i__1 = *n;
+     265        4704 :     for (ii = 2; ii <= i__1; ++ii) {
+     266        3888 :         i__ = ii - 1;
+     267             :         kk = i__;
+     268        3888 :         p = d__[i__];
+     269        3888 :         i__2 = *n;
+     270      155641 :         for (j = ii; j <= i__2; ++j) {
+     271      151753 :             if (d__[j] > p) {
+     272             :                 kk = j;
+     273             :                 p = d__[j];
+     274             :             }
+     275             :         }
+     276        3888 :         if (kk != i__) {
+     277        1983 :             d__[kk] = d__[i__];
+     278        1983 :             d__[i__] = p;
+     279        1983 :             if (icompq == 1) {
+     280           0 :                 iq[i__] = kk;
+     281        1983 :             } else if (icompq == 2) {
+     282        1983 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &u[i__ * u_dim1 + 1],&c_1,&u[kk*u_dim1+1],&c_1);
+     283        1983 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &vt[i__ + vt_dim1], ldvt, &vt[kk + vt_dim1], ldvt);
+     284             :             }
+     285        1905 :         } else if (icompq == 1) {
+     286           0 :             iq[i__] = i__;
+     287             :         }
+     288             :     }
+     289         816 :     if (icompq == 1) {
+     290           0 :         if (iuplo == 1) {
+     291           0 :             iq[*n] = 1;
+     292             :         } else {
+     293           0 :             iq[*n] = 0;
+     294             :         }
+     295             :     }
+     296         816 :     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         875 : 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         875 :     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         875 :     int c__1 = 1;
+     340             :     double c_b49 = 1.f;
+     341         875 :     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         875 :     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         875 :     --d__;
+     370         875 :     --e;
+     371         875 :     vt_dim1 = *ldvt;
+     372         875 :     vt_offset = 1 + vt_dim1;
+     373         875 :     vt -= vt_offset;
+     374         875 :     u_dim1 = *ldu;
+     375         875 :     u_offset = 1 + u_dim1;
+     376         875 :     u -= u_offset;
+     377         875 :     c_dim1 = *ldc;
+     378         875 :     c_offset = 1 + c_dim1;
+     379         875 :     c__ -= c_offset;
+     380         875 :     --work;
+     381             : 
+     382         875 :     *info = 0;
+     383             :     
+     384         875 :     itmp1 = (*n > 1) ? *n : 1;
+     385         875 :     itmp2 = (*nru > 1) ? *nru : 1;
+     386             :     
+     387             :     lower = (xuplo == 'L');
+     388         875 :     if ( (xuplo!='U') && !lower) {
+     389           0 :         *info = -1;
+     390         875 :     } else if (*n < 0) {
+     391           0 :         *info = -2;
+     392         875 :     } else if (*ncvt < 0) {
+     393           0 :         *info = -3;
+     394         875 :     } else if (*nru < 0) {
+     395           0 :         *info = -4;
+     396         875 :     } else if (*ncc < 0) {
+     397           0 :         *info = -5;
+     398         875 :     } else if ( ((*ncvt == 0) && (*ldvt < 1)) || ((*ncvt > 0) && (*ldvt < itmp1)) ) {
+     399           0 :         *info = -9;
+     400         875 :     } else if (*ldu < itmp2) {
+     401           0 :         *info = -11;
+     402         875 :     } else if ( ((*ncc == 0) && (*ldc < 1)) || ((*ncc > 0) && (*ldc < itmp1))) {
+     403           0 :         *info = -13;
+     404             :     }
+     405         875 :     if (*info != 0) {
+     406             :         return;
+     407             :     }
+     408         875 :     if (*n == 0) {
+     409             :         return;
+     410             :     }
+     411         875 :     if (*n == 1) {
+     412           0 :         goto L160;
+     413             :     }
+     414             : 
+     415         875 :     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         875 :     nm1 = *n - 1;
+     423         875 :     nm12 = nm1 + nm1;
+     424         875 :     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         875 :     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         875 :     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         875 :     i__1 = *n;
+     457        5515 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     458        4640 :         r__2 = smax, r__3 = (r__1 = d__[i__], std::abs(r__1));
+     459        4640 :         smax = (r__2>r__3) ? r__2 : r__3;
+     460             :     }
+     461         875 :     i__1 = *n - 1;
+     462        4640 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     463        3765 :         r__2 = smax, r__3 = (r__1 = e[i__], std::abs(r__1));
+     464        3765 :         smax = (r__2>r__3) ? r__2 : r__3;
+     465             :     }
+     466             :     sminl = 0.f;
+     467             :     if (tol >= 0.f) {
+     468         875 :         sminoa = std::abs(d__[1]);
+     469         875 :         if (sminoa == 0.f) {
+     470           0 :             goto L50;
+     471             :         }
+     472             :         mu = sminoa;
+     473         875 :         i__1 = *n;
+     474        4640 :         for (i__ = 2; i__ <= i__1; ++i__) {
+     475        3765 :             mu = (r__2 = d__[i__], std::abs(r__2)) * (mu / (mu + (r__1 = e[i__ - 
+     476        3765 :                     1], std::abs(r__1))));
+     477        3765 :             sminoa = (sminoa<mu) ? sminoa : mu;
+     478        3765 :             if (sminoa == 0.f) {
+     479           0 :                 goto L50;
+     480             :             }
+     481             :         }
+     482         875 : L50:
+     483         875 :         sminoa /=  std::sqrt((double) (*n));
+     484         875 :         r__1 = tol * sminoa, r__2 = *n * 6 * *n * unfl;
+     485         875 :         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       11321 : L60:
+     497             : 
+     498       12196 :     if (m <= 1) {
+     499         875 :         goto L160;
+     500             :     }
+     501       11321 :     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       11321 :     smax = (r__1 = d__[m], std::abs(r__1));
+     509             :     smin = smax;
+     510       11321 :     i__1 = m - 1;
+     511       71473 :     for (lll = 1; lll <= i__1; ++lll) {
+     512       63100 :         ll = m - lll;
+     513       63100 :         abss = (r__1 = d__[ll], std::abs(r__1));
+     514       63100 :         abse = (r__1 = e[ll], std::abs(r__1));
+     515             :         if (tol < 0.f && abss <= thresh) {
+     516             :             d__[ll] = 0.f;
+     517             :         }
+     518       63100 :         if (abse <= thresh) {
+     519        2948 :             goto L80;
+     520             :         }
+     521       60152 :         smin = (smin<abss) ? smin : abss;
+     522       60152 :         r__1 = (smax>abss) ? smax : abss;
+     523       60152 :         smax = (r__1>abse) ? r__1 : abse;
+     524             :     }
+     525             :     ll = 0;
+     526        8373 :     goto L90;
+     527             : L80:
+     528        2948 :     e[ll] = 0.f;
+     529        2948 :     if (ll == m - 1) {
+     530             :         --m;
+     531        2839 :         goto L60;
+     532             :     }
+     533         109 : L90:
+     534        8482 :     ++ll;
+     535        8482 :     if (ll == m - 1) {
+     536         900 :         PLUMED_BLAS_F77_FUNC(dlasv2,DLASV2)(&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr,
+     537             :                  &sinl, &cosl);
+     538         900 :         d__[m - 1] = sigmx;
+     539         900 :         e[m - 1] = 0.f;
+     540         900 :         d__[m] = sigmn;
+     541         900 :         if (*ncvt > 0) {
+     542         900 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(ncvt, &vt[m - 1 + vt_dim1], ldvt, &vt[m + vt_dim1], ldvt, &
+     543             :                     cosr, &sinr);
+     544             :         }
+     545         900 :         if (*nru > 0) {
+     546         900 :             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         900 :         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         900 :         m += -2;
+     554         900 :         goto L60;
+     555             :     }
+     556        7582 :     if (ll > oldm || m < oldll) {
+     557         902 :         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        6680 :     if (idir == 1) {
+     564             : 
+     565        7549 :         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        6377 :             mu = (r__1 = d__[ll], std::abs(r__1));
+     572             :             sminl = mu;
+     573             :             i__1 = m - 1;
+     574       54062 :             for (lll = ll; lll <= i__1; ++lll) {
+     575       48023 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+     576         338 :                     e[lll] = 0.f;
+     577         338 :                     goto L60;
+     578             :                 }
+     579       47685 :                 mu = (r__2 = d__[lll + 1], std::abs(r__2)) * (mu / (mu + (r__1 = 
+     580             :                         e[lll], std::abs(r__1))));
+     581       47685 :                 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        6072 :     r__1 = eps, r__2 = tol * .01f;
+     609        6072 :     if (tol >= 0.f && *n * tol * (sminl / smax) <= ((r__1>r__2) ? r__1 : r__2)) {
+     610        1520 :         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        6072 :     iter = iter + m - ll;
+     627        6072 :     if (shift == 0.f) {
+     628        1520 :         if (idir == 1) {
+     629        1520 :             cs = 1.f;
+     630        1520 :             oldcs = 1.f;
+     631        1520 :             i__1 = m - 1;
+     632        5666 :             for (i__ = ll; i__ <= i__1; ++i__) {
+     633        4146 :                 r__1 = d__[i__] * cs;
+     634        4146 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&r__1, &e[i__], &cs, &sn, &r__);
+     635        4146 :                 if (i__ > ll) {
+     636        2626 :                     e[i__ - 1] = oldsn * r__;
+     637             :                 }
+     638        4146 :                 r__1 = oldcs * r__;
+     639        4146 :                 r__2 = d__[i__ + 1] * sn;
+     640        4146 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+     641        4146 :                 work[i__ - ll + 1] = cs;
+     642        4146 :                 work[i__ - ll + 1 + nm1] = sn;
+     643        4146 :                 work[i__ - ll + 1 + nm12] = oldcs;
+     644        4146 :                 work[i__ - ll + 1 + nm13] = oldsn;
+     645             :             }
+     646        1520 :             h__ = d__[m] * cs;
+     647        1520 :             d__[m] = h__ * oldcs;
+     648        1520 :             e[m - 1] = h__ * oldsn;
+     649        1520 :             if (*ncvt > 0) {
+     650        1520 :                 i__1 = m - ll + 1;
+     651        1520 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+     652        1520 :                         ll + vt_dim1], ldvt);
+     653             :             }
+     654        1520 :             if (*nru > 0) {
+     655        1520 :                 i__1 = m - ll + 1;
+     656        1520 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+     657        1520 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+     658             :             }
+     659        1520 :             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        1520 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+     665         507 :                 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        6072 :     goto L60;
+     806             : 
+     807         875 : L160:
+     808         875 :     i__1 = *n;
+     809        5515 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     810        4640 :         if (d__[i__] < 0.f) {
+     811         963 :             d__[i__] = -d__[i__];
+     812             : 
+     813         963 :             if (*ncvt > 0) {
+     814         963 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(ncvt, &c_b72, &vt[i__ + vt_dim1], ldvt);
+     815             :             }
+     816             :         }
+     817             :     }
+     818             : 
+     819         875 :     i__1 = *n - 1;
+     820        4640 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     821             : 
+     822             :         isub = 1;
+     823        3765 :         smin = d__[1];
+     824        3765 :         i__2 = *n + 1 - i__;
+     825       25722 :         for (j = 2; j <= i__2; ++j) {
+     826       21957 :             if (d__[j] <= smin) {
+     827             :                 isub = j;
+     828             :                 smin = d__[j];
+     829             :             }
+     830             :         }
+     831        3765 :         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         875 :     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         816 : 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         816 :     *info = 0;
+     887             : 
+     888         816 :   if(*m>=*n) {
+     889             :     /* reduce to upper bidiag. form */
+     890        5136 :     for(i=0;i<*n;i++) {
+     891        4320 :       i1 = *m - i;
+     892        4320 :       i2 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+     893        4320 :       i3 = 1;
+     894        4320 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+     895        4320 :       d[i] = a[i*(*lda)+i];
+     896        4320 :       a[i*(*lda)+i] = 1.0;
+     897        4320 :       i2 = *n - i - 1;
+     898        4320 :       PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i]),lda,work);
+     899        4320 :       a[i*(*lda)+i] = d[i];
+     900             : 
+     901        4320 :       if(i<(*n-1)) {
+     902             : 
+     903        3504 :         i1 = *n - i -1;
+     904        3504 :         i2 = ( (i+2) < (*n-1)) ? (i+2) : (*n-1); 
+     905        3504 :         PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i1,&(a[(i+1)*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+     906             : 
+     907        3504 :         e[i] = a[(i+1)*(*lda)+i];
+     908        3504 :         a[(i+1)*(*lda)+i] = 1.0;
+     909             : 
+     910        3504 :         i1 = *m - i - 1;
+     911        3504 :         i2 = *n - i - 1;
+     912        3504 :         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        3504 :         a[(i+1)*(*lda)+i] = e[i];
+     914             :       } else
+     915         816 :         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         816 :   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         816 : 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         816 :     double one = 1.0;
+     985         816 :     double minusone = -1.0;
+     986             : 
+     987         816 :     a_dim1 = *lda;
+     988         816 :     a_offset = 1 + a_dim1;
+     989         816 :     a -= a_offset;
+     990         816 :     --d__;
+     991         816 :     --e;
+     992         816 :     --tauq;
+     993         816 :     --taup;
+     994         816 :     --work;
+     995             : 
+     996         816 :     nb = DGEBRD_BLOCKSIZE;
+     997         816 :     *info = 0;
+     998         816 :     if (*lwork==-1) {
+     999           0 :       work[1] = (double) ( (*m + *n) * nb);
+    1000           0 :       return;
+    1001             :     }
+    1002         816 :     minmn = (*m < *n) ? *m : *n;
+    1003         816 :     if (minmn == 0) {
+    1004           0 :       work[1] = 1.;
+    1005           0 :       return;
+    1006             :     }
+    1007             : 
+    1008         816 :     ws = (*m > *n) ? *m : *n;
+    1009         816 :     ldwrkx = *m;
+    1010         816 :     ldwrky = *n;
+    1011             : 
+    1012         816 :     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         816 :     i_1 = minmn - nx;
+    1031         816 :     i_2 = nb;
+    1032         828 :     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         816 :     i_2 = *m - i_ + 1;
+    1067         816 :     i_1 = *n - i_ + 1;
+    1068         816 :     PLUMED_BLAS_F77_FUNC(dgebd2,DGEBD2)(&i_2, &i_1, &a[i_ + i_ * a_dim1], lda, &d__[i_], &e[i_], &
+    1069         816 :             tauq[i_], &taup[i_], &work[1], &iinfo);
+    1070         816 :     work[1] = ws;
+    1071         816 :     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        1632 : 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        1632 :     int c__0 = 0;
+    1435        1632 :     int c__1 = 1;
+    1436        1632 :     double zero = 0.0;
+    1437        1632 :     double one = 1.0;
+    1438             : 
+    1439             : 
+    1440        1632 :     a_dim1 = *lda;
+    1441        1632 :     a_offset = 1 + a_dim1;
+    1442        1632 :     a -= a_offset;
+    1443             :     --s;
+    1444        1632 :     u_dim1 = *ldu;
+    1445        1632 :     u_offset = 1 + u_dim1;
+    1446        1632 :     u -= u_offset;
+    1447        1632 :     vt_dim1 = *ldvt;
+    1448        1632 :     vt_offset = 1 + vt_dim1;
+    1449        1632 :     vt -= vt_offset;
+    1450        1632 :     --work;
+    1451             :     --iwork;
+    1452             : 
+    1453        1632 :     *info = 0;
+    1454        1632 :     minmn = (*m < *n) ? *m : *n;
+    1455        1632 :     mnthr = (int) (minmn * 11. / 6.);
+    1456        1632 :     wntqn = (*jobz=='o' || *jobz=='O');
+    1457             : 
+    1458             :     maxwrk = 1;
+    1459        1632 :     lquery = *lwork == -1;
+    1460             : 
+    1461        1632 :     if (*info == 0 && *m > 0 && *n > 0) {
+    1462        1632 :         if (*m >= *n) {
+    1463             : 
+    1464        1632 :             if (wntqn) {
+    1465           0 :                 bdspac = *n * 7;
+    1466             :             } else {
+    1467        1632 :                 bdspac = *n * 3 * *n + (*n << 2);
+    1468             :             }
+    1469        1632 :             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        1630 :                 wrkbl = *n * 3 + (*m + *n*32);
+    1487        1630 :                 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        1630 :                     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        1632 :         work[1] = (double) maxwrk;
+    1530             :     }
+    1531             : 
+    1532             :     
+    1533        1632 :     if( lquery != 0)
+    1534             :     {
+    1535             :         return;
+    1536             :     }
+    1537             :     
+    1538             : 
+    1539         816 :     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         816 :     smlnum =  std::sqrt(safemin) / eps;
+    1549             : 
+    1550             : 
+    1551         816 :     bignum = 1. / smlnum;
+    1552             : 
+    1553             : 
+    1554         816 :     anrm = PLUMED_BLAS_F77_FUNC(dlange,DLANGE)("M", m, n, &a[a_offset], lda, dum);
+    1555             :     iscl = 0;
+    1556         816 :     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         816 :     } 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         816 :     if (*m >= *n) {
+    1565         816 :         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         815 :             itauq = ie + *n;
+    1645         815 :             itaup = itauq + *n;
+    1646         815 :             nwork = itaup + *n;
+    1647             : 
+    1648         815 :             i__1 = *lwork - nwork + 1;
+    1649         815 :             PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+    1650         815 :                     work[itaup], &work[nwork], &i__1, &ierr);
+    1651         815 :             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         815 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("F", m, m, &zero, &zero, &u[u_offset], ldu);
+    1658         815 :                 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         815 :                 i__1 = *m - *n;
+    1663         815 :                 i__2 = *m - *n;
+    1664         815 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("F", &i__1, &i__2, &zero, &one, &u[*n + 1 + (*n + 
+    1665         815 :                         1) * u_dim1], ldu);
+    1666             : 
+    1667         815 :                 i__1 = *lwork - nwork + 1;
+    1668         815 :                 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         815 :                 i__1 = *lwork - nwork + 1;
+    1671         815 :                 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         816 :     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         816 :     work[1] = (double) maxwrk;
+    1806             : 
+    1807         816 :     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         816 : 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         816 :   const char ch=std::toupper(*norm);
+    3556             :   double dtemp,sum,max,val,scale;
+    3557             :   int i,j;
+    3558             : 
+    3559         816 :   switch(ch) {
+    3560             :   case 'M':
+    3561             :     max = 0.0;
+    3562        5520 :     for(j=0;j<*n;j++)
+    3563      312916 :       for(i=0;i<*m;i++) {
+    3564      308212 :         dtemp = std::abs(a[j*(*lda)+i]);
+    3565      308212 :         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         816 :   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      637265 : PLUMED_BLAS_F77_FUNC(dlanst,DLANST)(const char *norm,
+    3626             :         int *n,
+    3627             :         double *d,
+    3628             :         double *e)
+    3629             : {
+    3630      637265 :   const char ch=std::toupper(*norm);
+    3631             :   double dtemp,max,val,scale,sum;
+    3632             :   int i,j;
+    3633             : 
+    3634             : 
+    3635      637265 :   if(*n<=0)
+    3636             :     return 0.0;
+    3637             :   
+    3638      637265 :   switch(ch) {
+    3639      637265 :   case 'M':
+    3640      637265 :     max = std::abs(d[*n-1]);
+    3641     2525185 :       for(i=0;i<(*n-1);i++) {
+    3642     1887920 :         dtemp = std::abs(d[i]);
+    3643     1887920 :         if(dtemp>max)
+    3644             :           max = dtemp;
+    3645     1887920 :         dtemp = std::abs(e[i]);
+    3646     1887920 :         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      637236 : 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      637236 :     int c__1 = 1;
+    3711             : 
+    3712             :     /* Local variables */
+    3713             :     int i__, j;
+    3714             :     double sum, absa, scale;
+    3715             :     double value =0.0;
+    3716             : 
+    3717      637236 :     a_dim1 = *lda;
+    3718      637236 :     a_offset = 1 + a_dim1;
+    3719      637236 :     a -= a_offset;
+    3720      637236 :     --work;
+    3721             : 
+    3722      637236 :     if (*n == 0) {
+    3723             :         value = 0.;
+    3724      637236 :     } else if (*norm=='M' || *norm=='m') {
+    3725             : 
+    3726             :         value = 0.;
+    3727      637236 :         if (*uplo=='U' || *uplo=='u') {
+    3728      637236 :             i__1 = *n;
+    3729     3160997 :             for (j = 1; j <= i__1; ++j) {
+    3730             :                 i__2 = j;
+    3731     8989436 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+    3732             :                   d__2 = value;
+    3733     6465675 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+    3734     6465675 :                   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      637236 :     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     1256210 : PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(double * x, double * y)
+    3827             : {
+    3828             :   double xabs,yabs;
+    3829             :   double w,z;
+    3830             : 
+    3831     1256210 :   xabs = std::abs(*x);
+    3832     1256210 :   yabs = std::abs(*y);
+    3833             :   
+    3834     1256210 :   if(xabs>yabs) {
+    3835             :     w = xabs;
+    3836             :     z = yabs;
+    3837             :   } else {
+    3838             :     w = yabs;
+    3839             :     z = xabs;
+    3840             :   }
+    3841             : 
+    3842     1256210 :   if( std::abs(z)<PLUMED_GMX_DOUBLE_MIN) 
+    3843             :     return w;
+    3844             :   else {
+    3845     1256210 :     z = z/w;
+    3846     1256210 :     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      831186 : 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      831186 :     --work;
+    3894             :     --isuppz;
+    3895      831186 :     --z__;
+    3896      831186 :     --gersch;
+    3897      831186 :     --lld;
+    3898      831186 :     --ld;
+    3899      831186 :     --l;
+    3900      831186 :     --d__;
+    3901             : 
+    3902             :     /* Function Body */
+    3903             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    3904      831186 :     if (*r__ == 0) {
+    3905             : 
+    3906      829720 :         r1 = *b1;
+    3907      829720 :         r2 = *bn;
+    3908             :         i__1 = *bn;
+    3909     1878520 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+    3910     1878520 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3911             :                 r1 = i__;
+    3912      829720 :                 goto L20;
+    3913             :             }
+    3914             :         }
+    3915           0 :         goto L40;
+    3916             : L20:
+    3917             :         i__1 = *b1;
+    3918     2017280 :         for (i__ = *bn; i__ >= i__1; --i__) {
+    3919     2017280 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3920             :                 r2 = i__;
+    3921      829720 :                 goto L40;
+    3922             :             }
+    3923             :         }
+    3924             :     } else {
+    3925             :         r1 = *r__;
+    3926             :         r2 = *r__;
+    3927             :     }
+    3928             : 
+    3929      831186 : L40:
+    3930      831186 :     indumn = *n;
+    3931      831186 :     inds = (*n << 1) + 1;
+    3932      831186 :     indp = *n * 3 + 1;
+    3933             :     sawnan = 0;
+    3934             : 
+    3935      831186 :     if (*b1 == 1) {
+    3936      831186 :         work[inds] = 0.;
+    3937             :     } else {
+    3938           0 :         work[inds] = lld[*b1 - 1];
+    3939             :     }
+    3940      831186 :     s = work[inds] - *sigma;
+    3941             :     i__1 = r2 - 1;
+    3942     2502792 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+    3943     1671606 :         dplus = d__[i__] + s;
+    3944     1671606 :         work[i__] = ld[i__] / dplus;
+    3945     1671606 :         work[inds + i__] = s * work[i__] * l[i__];
+    3946     1671606 :         s = work[inds + i__] - *sigma;
+    3947             :     }
+    3948             : 
+    3949      831186 :     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      831186 :     work[indp + *bn - 1] = d__[*bn] - *sigma;
+    3974             :     i__1 = r1;
+    3975     2761131 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+    3976     1929945 :         dminus = lld[i__] + work[indp + i__];
+    3977     1929945 :         tmp = d__[i__] / dminus;
+    3978     1929945 :         work[indumn + i__] = l[i__] * tmp;
+    3979     1929945 :         work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+    3980             :     }
+    3981      831186 :     tmp = work[indp + r1 - 1];
+    3982      831186 :     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      831186 :     *mingma = work[inds + r1 - 1] + work[indp + r1 - 1];
+    4006      831186 :     if (std::abs(*mingma)<PLUMED_GMX_DOUBLE_MIN) {
+    4007       72847 :         *mingma = eps * work[inds + r1 - 1];
+    4008             :     }
+    4009      831186 :     *r__ = r1;
+    4010             :     i__1 = r2 - 1;
+    4011     1360262 :     for (i__ = r1; i__ <= i__1; ++i__) {
+    4012      529076 :         tmp = work[inds + i__] + work[indp + i__];
+    4013      529076 :         if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4014       38530 :             tmp = eps * work[inds + i__];
+    4015             :         }
+    4016      529076 :         if (std::abs(tmp) < std::abs(*mingma)) {
+    4017      110921 :             *mingma = tmp;
+    4018      110921 :             *r__ = i__ + 1;
+    4019             :         }
+    4020             :     }
+    4021             : 
+    4022      831186 :     isuppz[1] = *b1;
+    4023      831186 :     isuppz[2] = *bn;
+    4024      831186 :     z__[*r__] = 1.;
+    4025      831186 :     *ztz = 1.;
+    4026      831186 :     if (! sawnan) {
+    4027      831186 :         from = *r__ - 1;
+    4028      831186 :         i__1 = *r__ - 32;
+    4029      831186 :         to = (i__1>(*b1)) ? i__1 : (*b1);
+    4030             : L120:
+    4031     1540215 :         if (from >= *b1) {
+    4032             :             i__1 = to;
+    4033     1862612 :             for (i__ = from; i__ >= i__1; --i__) {
+    4034     1152386 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+    4035     1152386 :                 *ztz += z__[i__] * z__[i__];
+    4036             :             }
+    4037      710226 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+    4038        1197 :                 isuppz[1] = to + 2;
+    4039             :             } else {
+    4040      709029 :                 from = to - 1;
+    4041      709029 :                 i__1 = to - 32;
+    4042      709029 :                 to = (i__1>*b1) ? i__1 : *b1;
+    4043      709029 :                 goto L120;
+    4044             :             }
+    4045             :         }
+    4046      831186 :         from = *r__ + 1;
+    4047      831186 :         i__1 = *r__ + 32;
+    4048      831186 :         to = (i__1<*bn) ? i__1 : *bn;
+    4049             : L140:
+    4050     1587384 :         if (from <= *bn) {
+    4051             :             i__1 = to;
+    4052     2534602 :             for (i__ = from; i__ <= i__1; ++i__) {
+    4053     1778349 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+    4054     1778349 :                 *ztz += z__[i__] * z__[i__];
+    4055             :             }
+    4056      756253 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to - 1]) <= eps) {
+    4057          55 :                 isuppz[2] = to - 2;
+    4058             :             } else {
+    4059      756198 :                 from = to + 1;
+    4060      756198 :                 i__1 = to + 32;
+    4061      756198 :                 to = (i__1<*bn) ? i__1 : *bn;
+    4062      756198 :                 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      831186 :     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     1899581 : 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     1899581 :   const char ch=std::toupper(*side);
+    4126     1899581 :   double one = 1.0;
+    4127     1899581 :   double zero = 0.0;
+    4128     1899581 :   double minustau = -(*tau);
+    4129     1899581 :   int i1 = 1;
+    4130             : 
+    4131             : 
+    4132     1899581 :   if(ch=='L') {
+    4133     1893120 :     if(std::abs(*tau)>PLUMED_GMX_DOUBLE_MIN) {
+    4134     1254258 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+    4135     1254258 :       PLUMED_BLAS_F77_FUNC(dger,DGER)(m,n,&minustau,v,incv,work,&i1,c,ldc);
+    4136             :     }
+    4137             :   } else {
+    4138        6461 :     if(std::abs(*tau)>PLUMED_GMX_DOUBLE_MIN) {
+    4139        4842 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+    4140        4842 :       PLUMED_BLAS_F77_FUNC(dger,DGER)(m,n,&minustau,work,&i1,v,incv,c,ldc);
+    4141             :     }
+    4142             :   }
+    4143     1899581 :   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     1895119 : 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     1895119 :   if(*n<=1) {
+    4573      638868 :     *tau = 0;
+    4574      638868 :     return;
+    4575             :   }
+    4576             : 
+    4577     1256251 :   ti1 = *n-1;
+    4578             : 
+    4579     1256251 :   xnorm = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(&ti1,x,incx);
+    4580             : 
+    4581     1256251 :   if(std::abs(xnorm)<PLUMED_GMX_DOUBLE_MIN) {
+    4582          68 :     *tau = 0.0;
+    4583             :   } else {
+    4584             : 
+    4585     1256183 :     t = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(alpha,&xnorm);
+    4586             : 
+    4587     1256183 :     if(*alpha<0)
+    4588             :       beta = t;
+    4589             :     else
+    4590      511233 :       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     1256183 :     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     1256183 :       *tau = (beta-*alpha)/beta;
+    4631     1256183 :       ti1= *n-1;
+    4632     1256183 :       t = 1.0/(*alpha-beta);
+    4633     1256183 :       PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&t,x,incx);
+    4634     1256183 :       *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      637311 : 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      637311 :     --iwork;
+    4881      637311 :     --work;
+    4882      637311 :     --werr;
+    4883      637311 :     --wgap;
+    4884      637311 :     --w;
+    4885      637311 :     --lld;
+    4886             :     --ld;
+    4887             :     --l;
+    4888      637311 :     --d__;
+    4889             : 
+    4890      637311 :     *info = 0;
+    4891      637311 :     i__1 = *n << 1;
+    4892     5740591 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    4893     5103280 :         iwork[i__] = 0;
+    4894             :     }
+    4895      637311 :     i1 = *ifirst;
+    4896             :     i2 = *ifirst;
+    4897             :     prev = 0;
+    4898      637311 :     i__1 = *ilast;
+    4899     1275494 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    4900      638183 :         k = i__ << 1;
+    4901      638183 :         iwork[k - 1] = 1;
+    4902             :         i2 = i__;
+    4903             :     }
+    4904             : 
+    4905             :     i__ = i1;
+    4906             :     nint = 0;
+    4907     1275494 : L30:
+    4908     1275494 :     if (i__ <= i2) {
+    4909      638183 :         ii = i__ - *offset;
+    4910      638183 :         if (iwork[(i__ << 1) - 1] == 1) {
+    4911             :             fac = 1.;
+    4912      638183 :             left = w[ii] - werr[ii];
+    4913             : 
+    4914             : 
+    4915      638290 : L40:
+    4916      638290 :             if (i__ > i1 && left <= right) {
+    4917             :                 left = right;
+    4918           0 :                 cnt = i__ - 1;
+    4919             :             } else {
+    4920      638290 :                 s = -left;
+    4921             :                 cnt = 0;
+    4922      638290 :                 i__1 = *n - 1;
+    4923     2958372 :                 for (j = 1; j <= i__1; ++j) {
+    4924     2320082 :                     dplus = d__[j] + s;
+    4925     2320082 :                     s = s * lld[j] / dplus - left;
+    4926     2320082 :                     if (dplus < 0.) {
+    4927      222332 :                         ++cnt;
+    4928             :                     }
+    4929             :                 }
+    4930      638290 :                 dplus = d__[*n] + s;
+    4931      638290 :                 if (dplus < 0.) {
+    4932         105 :                     ++cnt;
+    4933             :                 }
+    4934      638290 :         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      638290 :                 if (cnt > i__ - 1) {
+    4957         107 :                     left -= werr[ii] * fac;
+    4958         107 :                     fac *= 2.;
+    4959         107 :                     goto L40;
+    4960             :                 }
+    4961             :             }
+    4962      638183 :             nleft = cnt + 1;
+    4963             :             i1 = (i1<nleft) ? i1 : nleft;
+    4964             :             fac = 1.;
+    4965      638183 :             right = w[ii] + werr[ii];
+    4966      638217 : L60:
+    4967      638217 :             s = -right;
+    4968             :             cnt = 0;
+    4969      638217 :             i__1 = *n - 1;
+    4970     2926386 :             for (j = 1; j <= i__1; ++j) {
+    4971     2288169 :                 dplus = d__[j] + s;
+    4972     2288169 :                 s = s * lld[j] / dplus - right;
+    4973     2288169 :                 if (dplus < 0.) {
+    4974     2085783 :                     ++cnt;
+    4975             :                 }
+    4976             :             }
+    4977      638217 :             dplus = d__[*n] + s;
+    4978      638217 :             if (dplus < 0.) {
+    4979      638179 :                 ++cnt;
+    4980             :             }
+    4981      638217 :             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      638217 :             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      638183 :             ++nint;
+    5010      638183 :             k = nleft << 1;
+    5011      638183 :             work[k - 1] = left;
+    5012      638183 :             work[k] = right;
+    5013      638183 :             i__ = cnt + 1;
+    5014      638183 :             iwork[k - 1] = i__;
+    5015      638183 :             iwork[k] = cnt;
+    5016      638183 :             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      638183 :         goto L30;
+    5028             :     }
+    5029      637311 :     if (i__ <= *n && iwork[(i__ << 1) - 1] != -1) {
+    5030      541066 :         work[(i__ << 1) - 1] = work[prev * 2];
+    5031             :     }
+    5032             : 
+    5033       96245 : L80:
+    5034    32788917 :     prev = i1 - 1;
+    5035             :     olnint = nint;
+    5036             :     i__ = i1;
+    5037             :     i__1 = olnint;
+    5038    65579442 :     for (p = 1; p <= i__1; ++p) {
+    5039    32790525 :         k = i__ << 1;
+    5040    32790525 :         left = work[k - 1];
+    5041    32790525 :         right = work[k];
+    5042    32790525 :         next = iwork[k - 1];
+    5043    32790525 :         nright = iwork[k];
+    5044    32790525 :         mid = (left + right) * .5;
+    5045    32790525 :         width = right - mid;
+    5046             :         d__1 = std::abs(left);
+    5047             :         d__2 = std::abs(right);
+    5048    32790525 :         tmp = (d__1>d__2) ? d__1 : d__2;
+    5049             : 
+    5050             :         gap = 0.;
+    5051    32790525 :         if (i__ == nright) {
+    5052    32498982 :             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    32496443 :             } else if (prev > 0) {
+    5056     4905953 :                 gap = left - work[k - 2];
+    5057    27590490 :             } else if (next <= *n) {
+    5058    27590490 :                 gap = work[k + 1] - right;
+    5059             :             }
+    5060             :         }
+    5061    32790525 :         d__1 = *rtol1 * gap, d__2 = *rtol2 * tmp;
+    5062    36916752 :         if (width < ((d__1>d__2) ? d__1 : d__2)) {
+    5063      638183 :             --nint;
+    5064      638183 :             iwork[k - 1] = 0;
+    5065             :             kk = k;
+    5066             :             i__2 = nright;
+    5067      638183 :             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      638183 :             if (i1 == i__) {
+    5075             :                 i1 = next;
+    5076             :             } else {
+    5077         835 :                 iwork[(prev << 1) - 1] = next;
+    5078             :             }
+    5079             :             i__ = next;
+    5080      638183 :             continue;
+    5081             :         }
+    5082             :         prev = i__;
+    5083             : 
+    5084    32152342 :         s = -mid;
+    5085             :         cnt = 0;
+    5086    32152342 :         i__2 = *n - 1;
+    5087   127913934 :         for (j = 1; j <= i__2; ++j) {
+    5088    95761592 :             dplus = d__[j] + s;
+    5089    95761592 :             s = s * lld[j] / dplus - mid;
+    5090    95761592 :             if (dplus < 0.) {
+    5091    18139439 :                 ++cnt;
+    5092             :             }
+    5093             :         }
+    5094    32152342 :         dplus = d__[*n] + s;
+    5095    32152342 :         if (dplus < 0.) {
+    5096    14122006 :             ++cnt;
+    5097             :         }
+    5098    32152342 :         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    32152342 :         i__2 = i__ - 1, i__3 = (nright<cnt) ? nright : cnt;
+    5120             :         cnt = (i__2>i__3) ? i__2 : i__3;
+    5121    32152342 :         if (cnt == i__ - 1) {
+    5122    15500889 :             work[k - 1] = mid;
+    5123    16651453 :         } else if (cnt == nright) {
+    5124    16401349 :             work[k] = mid;
+    5125             :         } else {
+    5126      250104 :             iwork[k] = cnt;
+    5127      250104 :             ++cnt;
+    5128      250104 :             iwork[k - 1] = cnt;
+    5129      250104 :             kk = cnt << 1;
+    5130      250104 :             iwork[kk - 1] = next;
+    5131      250104 :             iwork[kk] = nright;
+    5132      250104 :             work[k] = mid;
+    5133      250104 :             work[kk - 1] = mid;
+    5134      250104 :             work[kk] = right;
+    5135             :             prev = cnt;
+    5136      250104 :             if (cnt - 1 > i__) {
+    5137       38391 :                 work[kk - 2] = mid;
+    5138             :             }
+    5139      250104 :             if (cnt > *ifirst && cnt <= *ilast) {
+    5140           0 :                 ++nint;
+    5141      250104 :             } else if (cnt <= *ifirst) {
+    5142             :                 i1 = cnt;
+    5143             :             }
+    5144             :         }
+    5145             :         i__ = next;
+    5146             :     }
+    5147    32788917 :     if (nint > 0) {
+    5148    32151606 :         goto L80;
+    5149             :     }
+    5150      637311 :     i__1 = *ilast;
+    5151     1275494 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    5152      638183 :         k = i__ << 1;
+    5153      638183 :         ii = i__ - *offset;
+    5154      638183 :         if (iwork[k - 1] != -1) {
+    5155      638183 :             w[ii] = (work[k - 1] + work[k]) * .5;
+    5156      638183 :             werr[ii] = work[k] - w[ii];
+    5157      638183 :             if (i__ != *ilast) {
+    5158         872 :                 wgap[ii] = work[k + 1] - work[k];
+    5159             :             }
+    5160             :         }
+    5161             :     }
+    5162             : 
+    5163      637311 :     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      637236 : 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      637236 :     int c__1 = 1;
+    5207      637236 :     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      637236 :     --iwork;
+    5224      637236 :     --work;
+    5225      637236 :     --gersch;
+    5226      637236 :     --indexw;
+    5227      637236 :     --iblock;
+    5228      637236 :     --w;
+    5229      637236 :     --isplit;
+    5230      637236 :     --e;
+    5231      637236 :     --d__;
+    5232             : 
+    5233             :     sigma = 0;
+    5234             :     irange = 0;
+    5235             :     sgndef = 0;
+    5236             :     maxcnt = 0;
+    5237             : 
+    5238      637236 :     *info = 0;
+    5239             : 
+    5240      637236 :     if (*range=='A' || *range=='a')
+    5241             :         irange = 1;
+    5242      577999 :     else if (*range=='V' || *range=='v')
+    5243             :         irange = 2;
+    5244      577999 :     else if (*range=='I' || *range=='i')
+    5245             :         irange = 3;
+    5246             :     
+    5247             : 
+    5248      637236 :     *m = 0;
+    5249             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5250             : 
+    5251      637236 :     *nsplit = 1;
+    5252      637236 :     i__1 = *n - 1;
+    5253     2523761 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5254     1886525 :         if (std::abs(e[i__]) <= *tol) {
+    5255         468 :             isplit[*nsplit] = i__;
+    5256         468 :             ++(*nsplit);
+    5257             :         }
+    5258             :     }
+    5259      637236 :     isplit[*nsplit] = *n;
+    5260             : 
+    5261             :     ibegin = 1;
+    5262      637236 :     i__1 = *nsplit;
+    5263     1274940 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5264      637704 :         iend = isplit[jblk];
+    5265      637704 :         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      637235 :         in = iend - ibegin + 1;
+    5275             : 
+    5276      637235 :         gl = d__[ibegin] - std::abs(e[ibegin]);
+    5277      637235 :         gu = d__[ibegin] + std::abs(e[ibegin]);
+    5278      637235 :         gersch[(ibegin << 1) - 1] = gl;
+    5279      637235 :         gersch[ibegin * 2] = gu;
+    5280      637235 :         gersch[(iend << 1) - 1] = d__[iend] - std::abs(e[iend - 1]);
+    5281      637235 :         gersch[iend * 2] = d__[iend] + std::abs(e[iend - 1]);
+    5282      637235 :         d__1 = gersch[(iend << 1) - 1];
+    5283      637235 :         gl = (d__1<gl) ? d__1 : gl;
+    5284             :         d__1 = gersch[iend * 2];
+    5285      637235 :         gu = (d__1>gu) ? d__1 : gu;
+    5286      637235 :         i__2 = iend - 1;
+    5287     1886057 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5288     1248822 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+    5289     1248822 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+    5290             :             d__1 = gersch[(i__ << 1) - 1];
+    5291     1248822 :             gl = (d__1<gl) ? d__1 : gl;
+    5292     1248822 :             gersch[i__ * 2] = d__[i__] + offd;
+    5293             :             d__1 = gersch[i__ * 2];
+    5294     1248822 :             gu = (d__1>gu) ? d__1 : gu;
+    5295             :         }
+    5296             :         d__1 = std::abs(gl), d__2 = std::abs(gu);
+    5297      637235 :         nrm = (d__1>d__2) ? d__1 : d__2;
+    5298             : 
+    5299      637235 :         width = gu - gl;
+    5300             :         i__2 = iend - 1;
+    5301     2523292 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5302     1886057 :             work[i__] = e[i__] * e[i__];
+    5303             :         }
+    5304     1911705 :         for (j = 1; j <= 2; ++j) {
+    5305     1274470 :             if (j == 1) {
+    5306      637235 :                 tau = gl + width * .25;
+    5307             :             } else {
+    5308      637235 :                 tau = gu - width * .25;
+    5309             :             }
+    5310     1274470 :             tmp = d__[ibegin] - tau;
+    5311     1274470 :             if (tmp < 0.) {
+    5312      673445 :                 cnt = 1;
+    5313             :             } else {
+    5314      601025 :                 cnt = 0;
+    5315             :             }
+    5316     1274470 :             i__2 = iend;
+    5317     5046584 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5318     3772114 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+    5319     3772114 :                 if (tmp < 0.) {
+    5320     1764266 :                     ++cnt;
+    5321             :                 }
+    5322             :             }
+    5323     1274470 :             if (cnt == 0) {
+    5324             :                 gl = tau;
+    5325     1274470 :             } else if (cnt == in) {
+    5326             :                 gu = tau;
+    5327             :             }
+    5328     1274470 :             if (j == 1) {
+    5329             :                 maxcnt = cnt;
+    5330             :                 sigma = gl;
+    5331             :                 sgndef = 1.;
+    5332             :             } else {
+    5333      637235 :                 if (in - cnt > maxcnt) {
+    5334             :                     sigma = gu;
+    5335             :                     sgndef = -1.;
+    5336             :                 }
+    5337             :             }
+    5338             :         }
+    5339             : 
+    5340      637235 :         work[in * 3] = 1.;
+    5341             :         delta = eps;
+    5342      637235 :         tau = sgndef * nrm;
+    5343      637235 : L60:
+    5344      637235 :         sigma -= delta * tau;
+    5345      637235 :         work[1] = d__[ibegin] - sigma;
+    5346             :         j = ibegin;
+    5347      637235 :         i__2 = in - 1;
+    5348     2523292 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5349     1886057 :             work[(in << 1) + i__] = 1. / work[i__];
+    5350     1886057 :             tmp = e[j] * work[(in << 1) + i__];
+    5351     1886057 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+    5352     1886057 :             work[in + i__] = tmp;
+    5353     1886057 :             ++j;
+    5354             :         }
+    5355     3160527 :         for (i__ = in; i__ >= 1; --i__) {
+    5356     2523292 :             tmp = sgndef * work[i__];
+    5357     2523292 :         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      637235 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5364      637235 :         i__2 = in - 1;
+    5365      637235 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5366      637235 :         i__2 = in - 1;
+    5367     2523292 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5368     1886057 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+    5369     1886057 :             work[(in << 2) + i__] = work[in * 3 + i__] * work[in + i__];
+    5370             :         }
+    5371      637235 :         if (sgndef > 0.) {
+    5372      540990 :             cnt = 1;
+    5373      540990 :             work[1] = (gl + gu) / 2. - sigma;
+    5374      540990 :             work[in + 1] = 0.;
+    5375      540990 :             work[(in << 1) + 1] = (gu - gl) / 2.;
+    5376             :         } else {
+    5377       96245 :             cnt = in;
+    5378       96245 :             work[in] = (gl + gu) / 2. - sigma;
+    5379       96245 :             work[in * 2] = 0.;
+    5380       96245 :             work[in * 3] = (gu - gl) / 2.;
+    5381             :         }
+    5382      637235 :         rtol = eps * 4.;
+    5383      637235 :         PLUMED_BLAS_F77_FUNC(dlarrbx,DLARRBX)(&in, &d__[ibegin], &e[ibegin], &work[in * 3 + 1], &work[(in <<
+    5384      637235 :                  2) + 1], &cnt, &cnt, &rtol, &rtol, &c__0, &work[1], &work[in 
+    5385      637235 :                 + 1], &work[(in << 1) + 1], &work[in * 5 + 1], &iwork[1], &
+    5386             :                 iinfo);
+    5387      637235 :         if (sgndef > 0.) {
+    5388      540990 :             tau = work[1] - work[(in << 1) + 1];
+    5389             :         } else {
+    5390       96245 :             tau = work[in] + work[in * 3];
+    5391             :         }
+    5392             : 
+    5393      637235 :         work[in * 3] = 1.;
+    5394             :         delta = eps * 2.;
+    5395      637235 : L100:
+    5396      637235 :         tau *= 1. - delta;
+    5397             : 
+    5398      637235 :         s = -tau;
+    5399             :         j = ibegin;
+    5400      637235 :         i__2 = in - 1;
+    5401     2523292 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5402     1886057 :             work[i__] = d__[j] + s;
+    5403     1886057 :             work[(in << 1) + i__] = 1. / work[i__];
+    5404     1886057 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+    5405     1886057 :             s = s * work[in + i__] * e[j] - tau;
+    5406     1886057 :             ++j;
+    5407             :         }
+    5408      637235 :         work[in] = d__[iend] + s;
+    5409             : 
+    5410     3160527 :         for (i__ = in; i__ >= 1; --i__) {
+    5411     2523292 :             tmp = sgndef * work[i__];
+    5412     2523292 :             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      637235 :         sigma += tau;
+    5419      637235 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5420      637235 :         i__2 = in - 1;
+    5421      637235 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5422      637235 :         e[iend] = sigma;
+    5423      637235 :         tmp = (double) in * 4. * eps * (std::abs(sigma) + std::abs(tau));
+    5424             :         i__2 = iend;
+    5425     3160527 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5426     2523292 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+    5427     2523292 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+    5428             :         }
+    5429             : 
+    5430             :         j = ibegin;
+    5431      637235 :         i__2 = in - 1;
+    5432     2523292 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5433     1886057 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+    5434     1886057 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+    5435     1886057 :             ++j;
+    5436             :         }
+    5437      637235 :         work[(in << 1) - 1] = std::abs(d__[iend]);
+    5438             : 
+    5439      637235 :         PLUMED_BLAS_F77_FUNC(dlasq2,DLASQ2)(&in, &work[1], info);
+    5440      637235 :         if (*info != 0) {
+    5441             :             return;
+    5442             :         }
+    5443             : 
+    5444      637235 :         if (sgndef > 0.) {
+    5445      540990 :             i__2 = in;
+    5446     2679542 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5447     2138552 :                 ++(*m);
+    5448     2138552 :                 w[*m] = work[in - i__ + 1];
+    5449     2138552 :                 iblock[*m] = jblk;
+    5450     2138552 :                 indexw[*m] = i__;
+    5451             :             }
+    5452             :         } else {
+    5453       96245 :             i__2 = in;
+    5454      480985 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5455      384740 :                 ++(*m);
+    5456      384740 :                 w[*m] = -work[i__];
+    5457      384740 :                 iblock[*m] = jblk;
+    5458      384740 :                 indexw[*m] = i__;
+    5459             :             }
+    5460             :         }
+    5461      637235 :         ibegin = iend + 1;
+    5462      637704 : L170:
+    5463             :         ;
+    5464             :     }
+    5465      637236 :     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      637236 :     } else if (irange == 3) {
+    5485      577999 :         *m = *iu - *il + 1;
+    5486      577999 :         if (*nsplit == 1) {
+    5487             :             i__1 = *m;
+    5488     1171179 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5489      593189 :                 w[i__] = w[*il + i__ - 1];
+    5490      593189 :                 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      637236 : 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      637236 :     double c_b5 = 0.;
+    5696      637236 :     int c__1 = 1;
+    5697      637236 :     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      637236 :     --d__;
+    5732      637236 :     --l;
+    5733             :     --isplit;
+    5734      637236 :     --w;
+    5735      637236 :     --iblock;
+    5736      637236 :     --indexw;
+    5737             :     --gersch;
+    5738      637236 :     z_dim1 = *ldz;
+    5739      637236 :     z_offset = 1 + z_dim1;
+    5740      637236 :     z__ -= z_offset;
+    5741      637236 :     --isuppz;
+    5742      637236 :     --work;
+    5743      637236 :     --iwork;
+    5744             : 
+    5745      637236 :     inderr = *n;
+    5746      637236 :     indld = *n << 1;
+    5747      637236 :     indlld = *n * 3;
+    5748      637236 :     indgap = *n << 2;
+    5749      637236 :     indwrk = *n * 5 + 1;
+    5750             : 
+    5751             :     iindr = *n;
+    5752             :     iindc1 = *n << 1;
+    5753             :     iindc2 = *n * 3;
+    5754      637236 :     iindwk = (*n << 2) + 1;
+    5755             : 
+    5756             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5757             : 
+    5758             :     i__1 = *n << 1;
+    5759     5684758 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5760     5047522 :         iwork[i__] = 0;
+    5761             :     }
+    5762      637236 :     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      637236 :     i__1 = iblock[*m];
+    5768     1274938 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5769      637702 :         iend = isplit[jblk];
+    5770             : 
+    5771      637702 :         wend = wbegin - 1;
+    5772     1467891 : L171:
+    5773     1467891 :         if (wend < *m) {
+    5774      830655 :             if (iblock[wend + 1] == jblk) {
+    5775      830189 :                 ++wend;
+    5776      830189 :                 goto L171;
+    5777             :             }
+    5778             :         }
+    5779      637702 :         if (wend < wbegin) {
+    5780           0 :             ibegin = iend + 1;
+    5781           0 :             continue;
+    5782             :         }
+    5783             : 
+    5784      637702 :         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      637233 :         oldien = ibegin - 1;
+    5793      637233 :         in = iend - oldien;
+    5794      637233 :         d__1 = .001, d__2 = 1. / (double) in;
+    5795      637233 :         reltol = (d__1<d__2) ? d__1 : d__2;
+    5796      637233 :         im = wend - wbegin + 1;
+    5797      637233 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
+    5798      637233 :         i__2 = im - 1;
+    5799      829720 :         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      637233 :         work[inderr + im] = eps * std::abs(work[im]);
+    5804      637233 :         d__2 = std::abs(work[im]);
+    5805      637233 :         work[indgap + im] = (d__2>eps) ? d__2 : eps;
+    5806             :         ndone = 0;
+    5807             : 
+    5808             :         ndepth = 0;
+    5809             :         parity = 1;
+    5810             :         nclus = 1;
+    5811      637233 :         iwork[iindc1 + 1] = 1;
+    5812      637233 :         iwork[iindc1 + 2] = im;
+    5813             : 
+    5814     1274477 : L40:
+    5815     1274477 :         if (ndone < im) {
+    5816             :             oldncl = nclus;
+    5817             :             nclus = 0;
+    5818      637244 :             parity = 1 - parity;
+    5819      637244 :             if (parity == 0) {
+    5820             :                 oldcls = iindc1;
+    5821             :                 newcls = iindc2;
+    5822             :             } else {
+    5823             :                 oldcls = iindc2;
+    5824             :                 newcls = iindc1;
+    5825             :             }
+    5826             :             i__2 = oldncl;
+    5827     1274553 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5828             : 
+    5829      637309 :                 j = oldcls + (i__ << 1);
+    5830      637309 :                 oldfst = iwork[j - 1];
+    5831      637309 :                 oldlst = iwork[j];
+    5832      637309 :                 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      637309 :                 i__3 = in - 1;
+    5844     2551636 :                 for (j = 1; j <= i__3; ++j) {
+    5845     1914327 :                     tmp = d__[k] * l[k];
+    5846     1914327 :                     work[indld + j] = tmp;
+    5847     1914327 :                     work[indlld + j] = tmp * l[k];
+    5848     1914327 :                     ++k;
+    5849             :                 }
+    5850      637309 :                 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      637309 :                 newfrs = oldfst;
+    5862      637309 :                 i__3 = oldlst;
+    5863     1467977 :                 for (j = oldfst; j <= i__3; ++j) {
+    5864      830668 :                     if (j == oldlst || work[indgap + j] >= 
+    5865      193359 :                         reltol * std::abs(work[j])) {
+    5866      829796 :                         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      829796 :                     newsiz = newlst - newfrs + 1;
+    5878      829796 :                     newftt = wbegin + newfrs - 1;
+    5879      829796 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+    5880      829796 :                     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     1659440 :                         for (k = newfrs; k <= i__4; ++k) {
+    5935             :                             iter = 0;
+    5936      831186 : L90:
+    5937      831186 :                             lambda = work[k];
+    5938             : 
+    5939      831186 :                             PLUMED_BLAS_F77_FUNC(dlar1vx,DLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
+    5940      831186 :                                     l[ibegin], &work[indld + 1], &work[indlld 
+    5941      831186 :                                     + 1], &w[wbegin + k - 1], &gersch[(oldien 
+    5942      831186 :                                     << 1) + 1], &z__[ibegin + ktot * z_dim1], 
+    5943      831186 :                                     &ztz, &mingma, &iwork[iindr + ktot], &
+    5944      831186 :                                     isuppz[(ktot << 1) - 1], &work[indwrk]);
+    5945      831186 :                             tmp = 1. / ztz;
+    5946      831186 :                             nrminv =  std::sqrt(tmp);
+    5947      831186 :                             resid = std::abs(mingma) * nrminv;
+    5948      831186 :                             rqcorr = mingma * tmp;
+    5949      831186 :                             if (k == in) {
+    5950       72739 :                                 gap = work[indgap + k - 1];
+    5951      758447 :                             } else if (k == 1) {
+    5952      637768 :                                 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      831186 :                             ++iter;
+    5959      831186 :                             if (resid > *tol * gap && std::abs(rqcorr) > eps * 4. *
+    5960       44161 :                                      std::abs(lambda)) {
+    5961        1483 :                                 work[k] = lambda + rqcorr;
+    5962        1483 :                                 if (iter < 8) {
+    5963        1466 :                                     goto L90;
+    5964             :                                 }
+    5965             :                             }
+    5966      829720 :                             iwork[ktot] = 1;
+    5967      829720 :                             if (newsiz == 1) {
+    5968      829720 :                                 ++ndone;
+    5969             :                             }
+    5970      829720 :                             zfrom = isuppz[(ktot << 1) - 1];
+    5971      829720 :                             zto = isuppz[ktot * 2];
+    5972      829720 :                             i__5 = zto - zfrom + 1;
+    5973      829720 :                             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+    5974      829720 :                                     ktot * z_dim1], &c__1);
+    5975      829720 :                             ++ktot;
+    5976             :                         }
+    5977      829720 :                         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      829796 :                     newfrs = j + 1;
+    6010             :                 }
+    6011             :             }
+    6012      637244 :             ++ndepth;
+    6013      637244 :             goto L40;
+    6014             :         }
+    6015      637233 :         j = wbegin << 1;
+    6016             :         i__2 = wend;
+    6017     1466953 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+    6018      829720 :             isuppz[j - 1] += oldien;
+    6019      829720 :             isuppz[j] += oldien;
+    6020      829720 :             j += 2;
+    6021             : 
+    6022             :         }
+    6023      637233 :         ibegin = iend + 1;
+    6024      637233 :         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       96279 : 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       96279 :   if(std::abs(*g)<PLUMED_GMX_DOUBLE_MIN) {
+    6062           0 :     *cs = 1.0;
+    6063           0 :     *sn = 0.0;
+    6064           0 :     *r = *f;
+    6065       96279 :   } 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       96278 :     scale = (f1a > g1a) ? f1a : g1a;
+    6075       96278 :     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       96278 :     } 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       96278 :       *r =  std::sqrt(f1*f1 + g1*g1);
+    6107       96278 :       *cs = f1 / *r;
+    6108       96278 :       *sn = g1 / *r;
+    6109             :     }
+    6110       96278 :     if(std::abs(*f)>std::abs(*g) && *cs<0.0) {
+    6111       19937 :       *cs *= -1.0;
+    6112       19937 :       *sn *= -1.0;
+    6113       19937 :       *r  *= -1.0;
+    6114             :     }
+    6115             :   }
+    6116       96279 :   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         875 : 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         875 :     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         875 :     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         875 :     --d__;
+    8877         875 :     --e;
+    8878         875 :     vt_dim1 = *ldvt;
+    8879         875 :     vt_offset = 1 + vt_dim1;
+    8880         875 :     vt -= vt_offset;
+    8881         875 :     u_dim1 = *ldu;
+    8882         875 :     u_offset = 1 + u_dim1;
+    8883         875 :     u -= u_offset;
+    8884         875 :     c_dim1 = *ldc;
+    8885         875 :     c_offset = 1 + c_dim1;
+    8886         875 :     c__ -= c_offset;
+    8887         875 :     --work;
+    8888             : 
+    8889         875 :     *info = 0;
+    8890             :     iuplo = 0;
+    8891         875 :     if (xuplo == 'U') {
+    8892             :         iuplo = 1;
+    8893             :     }
+    8894         875 :     if (xuplo == 'L') {
+    8895             :         iuplo = 2;
+    8896             :     }
+    8897             :     
+    8898         875 :     itmp1 = (*n > 1) ? *n : 1;
+    8899         875 :     itmp2 = (*nru > 1) ? *nru : 1;
+    8900         875 :     if (iuplo == 0) {
+    8901           0 :         *info = -1;
+    8902         875 :     } else if (*sqre < 0 || *sqre > 1) {
+    8903           0 :         *info = -2;
+    8904         875 :     } else if (*n < 0) {
+    8905           0 :         *info = -3;
+    8906         875 :     } else if (*ncvt < 0) {
+    8907           0 :         *info = -4;
+    8908         875 :     } else if (*nru < 0) {
+    8909           0 :         *info = -5;
+    8910         875 :     } else if (*ncc < 0) {
+    8911           0 :         *info = -6;
+    8912         875 :     } else if ((*ncvt == 0 && *ldvt < 1) || (*ncvt > 0 && *ldvt < itmp1)) {
+    8913           0 :         *info = -10;
+    8914         875 :     } else if (*ldu < itmp2) {
+    8915           0 :         *info = -12;
+    8916         875 :     } else if ((*ncc == 0 && *ldc < 1) || (*ncc > 0 && *ldc < itmp1)) {
+    8917           0 :         *info = -14;
+    8918             :     }
+    8919         875 :     if (*info != 0) {
+    8920             :         return;
+    8921             :     }
+    8922         875 :     if (*n == 0) {
+    8923             :         return;
+    8924             :     }
+    8925             : 
+    8926         875 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+    8927         875 :     np1 = *n + 1;
+    8928         875 :     sqre1 = *sqre;
+    8929             : 
+    8930         875 :     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         816 :     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         875 :     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         875 :     i__1 = *n;
+    9002        5515 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    9003             : 
+    9004             :         isub = i__;
+    9005        4640 :         smin = d__[i__];
+    9006        4640 :         i__2 = *n;
+    9007       26597 :         for (j = i__ + 1; j <= i__2; ++j) {
+    9008       21957 :             if (d__[j] < smin) {
+    9009             :                 isub = j;
+    9010             :                 smin = d__[j];
+    9011             :             }
+    9012             :         }
+    9013        4640 :         if (isub != i__) {
+    9014        1901 :             d__[isub] = d__[i__];
+    9015        1901 :             d__[i__] = smin;
+    9016        1901 :             if (*ncvt > 0) {
+    9017        1901 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[i__ + vt_dim1], 
+    9018             :                         ldvt);
+    9019             :             }
+    9020        1901 :             if (*nru > 0) {
+    9021        1901 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[i__ * u_dim1 + 1]
+    9022             :                         , &c__1);
+    9023             :             }
+    9024        1901 :             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      640634 : 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      640634 :   const char ch=std::toupper(*uplo);
+    9107             : 
+    9108      640634 :   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      640634 :   } 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     1485143 :     for(j=0;j<*n;j++) {
+    9122     5462526 :       for(i=0;i<*m;i++)
+    9123     4618016 :         a[j*(*lda)+i] = *alpha;
+    9124             :     }    
+    9125             :   }
+    9126             : 
+    9127      640634 :   k = (*m < *n) ? *m : *n;
+    9128     1485145 :   for(i=0;i<k;i++)
+    9129      844511 :     a[i*(*lda)+i] = *beta;
+    9130      640634 : }
+    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      637235 : 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      637235 :     --z__;
+    9265             : 
+    9266      637235 :     *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      637235 :     if (*n < 0) {
+    9277           0 :         *info = -1;
+    9278           0 :         return;
+    9279      637235 :     } else if (*n == 0) {
+    9280             :         return;
+    9281      637235 :     } else if (*n == 1) {
+    9282             : 
+    9283           0 :         if (z__[1] < 0.) {
+    9284           0 :             *info = -201;
+    9285             :         }
+    9286           0 :         return;
+    9287      637235 :     } 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      623869 :     z__[*n * 2] = 0.;
+    9315      623869 :     emin = z__[2];
+    9316      623869 :     qmax = 0.;
+    9317             :     zmax = 0.;
+    9318             :     d__ = 0.;
+    9319             :     e = 0.;
+    9320             : 
+    9321      623869 :     i__1 = 2*(*n - 1);
+    9322     2496560 :     for (k = 1; k <= i__1; k += 2) {
+    9323     1872691 :         if (z__[k] < 0.) {
+    9324           0 :             *info = -(k + 200);
+    9325           0 :             return;
+    9326     1872691 :         } else if (z__[k + 1] < 0.) {
+    9327           0 :             *info = -(k + 201);
+    9328           0 :             return;
+    9329             :         }
+    9330     1872691 :         d__ += z__[k];
+    9331     1872691 :         e += z__[k + 1];
+    9332     1872691 :         d__1 = qmax, d__2 = z__[k];
+    9333     1872691 :         qmax = (d__1>d__2) ? d__1 : d__2;
+    9334             :         d__1 = emin, d__2 = z__[k + 1];
+    9335     1872691 :         emin = (d__1<d__2) ? d__1 : d__2;
+    9336     1872691 :         d__1 = (qmax>zmax) ? qmax : zmax;
+    9337             :         d__2 = z__[k + 1];
+    9338     1872691 :         zmax = (d__1>d__2) ? d__1 : d__2;
+    9339             :     }
+    9340      623869 :     if (z__[(*n << 1) - 1] < 0.) {
+    9341           0 :         *info = -((*n << 1) + 199);
+    9342           0 :         return;
+    9343             :     }
+    9344      623869 :     d__ += z__[(*n << 1) - 1];
+    9345      623869 :     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
+    9346      623913 :     qmax = (d__1>d__2) ? d__1 : d__2;
+    9347             : 
+    9348      623869 :     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      623869 :     trace = d__ + e;
+    9359             : 
+    9360      623869 :     if (std::abs(trace)<PLUMED_GMX_DOUBLE_MIN) {
+    9361           0 :         z__[(*n << 1) - 1] = 0.;
+    9362           0 :         return;
+    9363             :     }
+    9364             : 
+    9365      623869 :     ieee = 1;
+    9366      623869 :     posinf = one/zero;
+    9367      623869 :     if(posinf<=1.0)
+    9368           0 :       ieee = 0;
+    9369             :     neginf = -one/zero;
+    9370      623869 :     if(neginf>=0.0)
+    9371           0 :       ieee = 0;
+    9372      623869 :     negzro = one/(neginf+one);
+    9373      623869 :     if(std::abs(negzro)>PLUMED_GMX_DOUBLE_MIN)
+    9374           0 :       ieee = 0;
+    9375      623869 :     neginf = one/negzro;
+    9376      623869 :     if(neginf>=0)
+    9377           0 :       ieee = 0;
+    9378      623869 :     newzro = negzro + zero;
+    9379      623869 :     if(std::abs(newzro-zero)>PLUMED_GMX_DOUBLE_MIN)
+    9380           0 :       ieee = 0;
+    9381      623869 :     posinf = one /newzro;
+    9382      623869 :     if(posinf<=one)
+    9383           0 :       ieee = 0;
+    9384      623869 :     neginf = neginf*posinf;
+    9385      623869 :     if(neginf>=zero)
+    9386           0 :       ieee = 0;
+    9387      623869 :     posinf = posinf*posinf;
+    9388      623869 :     if(posinf<=1.0)
+    9389           0 :       ieee = 0;
+    9390             : 
+    9391     3120429 :     for (k = *n << 1; k >= 2; k += -2) {
+    9392     2496560 :         z__[k * 2] = 0.;
+    9393     2496560 :         z__[(k << 1) - 1] = z__[k];
+    9394     2496560 :         z__[(k << 1) - 2] = 0.;
+    9395     2496560 :         z__[(k << 1) - 3] = z__[k - 1];
+    9396             :     }
+    9397             : 
+    9398      623869 :     i0 = 1;
+    9399      623869 :     n0 = *n;
+    9400             : 
+    9401      623869 :     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      623869 :     pp = 0;
+    9415             : 
+    9416     1871607 :     for (k = 1; k <= 2; ++k) {
+    9417             : 
+    9418     1247738 :         d__ = z__[(n0 << 2) + pp - 3];
+    9419     1247738 :         i__1 = (i0 << 2) + pp;
+    9420     4993120 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+    9421     3745382 :             if (z__[i4 - 1] <= tol2 * d__) {
+    9422          33 :                 z__[i4 - 1] = -0.;
+    9423          33 :                 d__ = z__[i4 - 3];
+    9424             :             } else {
+    9425     3745349 :                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
+    9426             :             }
+    9427             :         }
+    9428             : 
+    9429     1247738 :         emin = z__[(i0 << 2) + pp + 1];
+    9430     1247738 :         d__ = z__[(i0 << 2) + pp - 3];
+    9431             :         i__1 = 4*(n0 - 1) + pp;
+    9432     4993120 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+    9433     3745382 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+    9434     3745382 :             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     3745258 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+    9440     3745258 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+    9441     3745258 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+    9442     3745258 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+    9443     3745258 :                 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     3745382 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+    9450     3745382 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9451             :         }
+    9452     1247738 :         z__[(n0 << 2) - pp - 2] = d__;
+    9453             : 
+    9454             : 
+    9455     1247738 :         qmax = z__[(i0 << 2) - pp - 2];
+    9456     1247738 :         i__1 = (n0 << 2) - pp - 2;
+    9457     4993120 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+    9458     3745382 :             d__1 = qmax, d__2 = z__[i4];
+    9459     4994212 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9460             :         }
+    9461             : 
+    9462     1247738 :         pp = 1 - pp;
+    9463             :     }
+    9464             : 
+    9465      623869 :     iter = 2;
+    9466      623869 :     nfail = 0;
+    9467      623869 :     ndiv = 2*(n0 - i0);
+    9468             : 
+    9469      623869 :     i__1 = *n + 1;
+    9470     1247991 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+    9471     1247991 :         if (n0 < 1) {
+    9472      623869 :             goto L170;
+    9473             :         }
+    9474             : 
+    9475      624122 :         desig = 0.;
+    9476      624122 :         if (n0 == *n) {
+    9477      623869 :             sigma = 0.;
+    9478             :         } else {
+    9479         253 :             sigma = -z__[(n0 << 2) - 1];
+    9480             :         }
+    9481      624122 :         if (sigma < 0.) {
+    9482           0 :             *info = 1;
+    9483           0 :             return;
+    9484             :         }
+    9485             : 
+    9486             :         emax = 0.;
+    9487      624122 :         if (n0 > i0) {
+    9488      623869 :             emin = std::abs(z__[(n0 << 2) - 5]);
+    9489             :         } else {
+    9490             :             emin = 0.;
+    9491             :         }
+    9492      624122 :         qmin = z__[(n0 << 2) - 3];
+    9493      624122 :         qmax = qmin;
+    9494     2501880 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+    9495     1877942 :             if (z__[i4 - 5] <= 0.) {
+    9496         184 :                 goto L100;
+    9497             :             }
+    9498     1877758 :             if (qmin >= emax * 4.) {
+    9499     1250826 :                 d__1 = qmin, d__2 = z__[i4 - 3];
+    9500     1250826 :                 qmin = (d__1<d__2) ? d__1 : d__2;
+    9501             :                 d__1 = emax, d__2 = z__[i4 - 5];
+    9502     1250826 :                 emax = (d__1>d__2) ? d__1 : d__2;
+    9503             :             }
+    9504     1877758 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+    9505     1877758 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9506             :             d__1 = emin, d__2 = z__[i4 - 5];
+    9507     1877758 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9508             :         }
+    9509             :         i4 = 4;
+    9510             : 
+    9511      624122 : L100:
+    9512      624122 :         i0 = i4 / 4;
+    9513      624122 :         pp = 0;
+    9514             : 
+    9515      624122 :         if (n0 - i0 > 1) {
+    9516      623984 :             dee = z__[(i0 << 2) - 3];
+    9517             :             deemin = dee;
+    9518             :             kmin = i0;
+    9519      623984 :             i__2 = (n0 << 2) - 3;
+    9520     3125721 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+    9521     2501737 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+    9522     2501737 :                 if (dee <= deemin) {
+    9523             :                     deemin = dee;
+    9524     1363417 :                     kmin = (i4 + 3) / 4;
+    9525             :                 }
+    9526             :             }
+    9527      623984 :             if (2*(kmin - i0) < n0 - kmin && deemin <= z__[(n0 << 2) - 3] * 
+    9528             :                     .5) {
+    9529        8615 :                 ipn4 = 4*(i0 + n0);
+    9530        8615 :                 pp = 2;
+    9531        8615 :                 i__2 = 2*(i0 + n0 - 1);
+    9532       27675 :                 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
+    9533       19060 :                     temp = z__[i4 - 3];
+    9534       19060 :                     z__[i4 - 3] = z__[ipn4 - i4 - 3];
+    9535       19060 :                     z__[ipn4 - i4 - 3] = temp;
+    9536       19060 :                     temp = z__[i4 - 2];
+    9537       19060 :                     z__[i4 - 2] = z__[ipn4 - i4 - 2];
+    9538       19060 :                     z__[ipn4 - i4 - 2] = temp;
+    9539       19060 :                     temp = z__[i4 - 1];
+    9540       19060 :                     z__[i4 - 1] = z__[ipn4 - i4 - 5];
+    9541       19060 :                     z__[ipn4 - i4 - 5] = temp;
+    9542       19060 :                     temp = z__[i4];
+    9543       19060 :                     z__[i4] = z__[ipn4 - i4 - 4];
+    9544       19060 :                     z__[ipn4 - i4 - 4] = temp;
+    9545             :                 }
+    9546             :             }
+    9547             :         }
+    9548             : 
+    9549             : 
+    9550      624122 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+    9551      624122 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+    9552             : 
+    9553      624122 :         nbig = (n0 - i0 + 1) * 30;
+    9554             :         i__2 = nbig;
+    9555    15315028 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+    9556    15315028 :             if (i0 > n0) {
+    9557      624122 :                 goto L150;
+    9558             :             }
+    9559             : 
+    9560    14690906 :             PLUMED_BLAS_F77_FUNC(dlasq3,DLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+    9561             :                     nfail, &iter, &ndiv, &ieee);
+    9562             : 
+    9563    14690906 :             pp = 1 - pp;
+    9564             : 
+    9565    14690906 :             if (pp == 0 && n0 - i0 >= 3) {
+    9566      186283 :                 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      623869 :     i__1 = *n;
+    9611     2496560 :     for (k = 2; k <= i__1; ++k) {
+    9612     1872691 :         z__[k] = z__[(k << 2) - 3];
+    9613             :     }
+    9614             : 
+    9615      623869 :     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("D", n, &z__[1], &iinfo);
+    9616             : 
+    9617             :     e = 0.;
+    9618     3120429 :     for (k = *n; k >= 1; --k) {
+    9619     2496560 :         e += z__[k];
+    9620             :     }
+    9621             : 
+    9622             : 
+    9623      623869 :     z__[(*n << 1) + 1] = trace;
+    9624      623869 :     z__[(*n << 1) + 2] = e;
+    9625      623869 :     z__[(*n << 1) + 3] = (double) iter;
+    9626      623869 :     i__1 = *n;
+    9627      623869 :     z__[(*n << 1) + 4] = (double) ndiv / (double) (i__1 * i__1);
+    9628      623869 :     z__[(*n << 1) + 5] = nfail * 100. / (double) iter;
+    9629             : 
+    9630      623869 :     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    14690906 : 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    14690906 :     int ttype = 0;
+    9664    14690906 :     double dmin1 = 0.;
+    9665    14690906 :     double dmin2 = 0.;
+    9666    14690906 :     double dn = 0.;
+    9667    14690906 :     double dn1 = 0.;
+    9668    14690906 :     double dn2 = 0.;
+    9669    14690906 :     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    14690906 :     --z__;
+    9679             : 
+    9680    14690906 :     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     1872405 : L10:
+    9688             : 
+    9689    16563311 :     if (*n0 < *i0) {
+    9690             :         return;
+    9691             :     }
+    9692    15939189 :     if (*n0 == *i0) {
+    9693         214 :         goto L20;
+    9694             :     }
+    9695    15938975 :     nn = (*n0 << 2) + *pp;
+    9696    15938975 :     if (*n0 == *i0 + 1) {
+    9697      623908 :         goto L40;
+    9698             :     }
+    9699             : 
+    9700    15315067 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+    9701    14067031 :             4] > tol2 * z__[nn - 7]) {
+    9702    14067031 :         goto L30;
+    9703             :     }
+    9704             : 
+    9705     1248036 : L20:
+    9706             : 
+    9707     1248250 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+    9708     1248250 :     --(*n0);
+    9709     1248250 :     goto L10;
+    9710             : 
+    9711             : L30:
+    9712             : 
+    9713    14067031 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+    9714    14066784 :             nn - 11]) {
+    9715    14066784 :         goto L50;
+    9716             :     }
+    9717             : 
+    9718         247 : L40:
+    9719             : 
+    9720      624155 :     if (z__[nn - 3] > z__[nn - 7]) {
+    9721             :         s = z__[nn - 3];
+    9722       23216 :         z__[nn - 3] = z__[nn - 7];
+    9723       23216 :         z__[nn - 7] = s;
+    9724             :     }
+    9725      624155 :     if (z__[nn - 5] > z__[nn - 3] * tol2) {
+    9726      624153 :         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
+    9727      624153 :         s = z__[nn - 3] * (z__[nn - 5] / t);
+    9728      624153 :         if (s <= t) {
+    9729      604118 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+    9730             :         } else {
+    9731       20035 :             s = z__[nn - 3] * (z__[nn - 5] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+    9732             :         }
+    9733      624153 :         t = z__[nn - 7] + (s + z__[nn - 5]);
+    9734      624153 :         z__[nn - 3] *= z__[nn - 7] / t;
+    9735      624153 :         z__[nn - 7] = t;
+    9736             :     }
+    9737      624155 :     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
+    9738      624155 :     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
+    9739      624155 :     *n0 += -2;
+    9740      624155 :     goto L10;
+    9741             : 
+    9742             : L50:
+    9743    14066784 :     if (*pp == 2) {
+    9744        8615 :         *pp = 0;
+    9745             :     }
+    9746             : 
+    9747    14066784 :     if (*dmin__ <= 0. || *n0 < n0in) {
+    9748     1248270 :         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
+    9749      321732 :             ipn4 = 4*(*i0 + *n0);
+    9750      321732 :             i__1 = 2*(*i0 + *n0 - 1);
+    9751      653982 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+    9752      332250 :                 temp = z__[j4 - 3];
+    9753      332250 :                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
+    9754      332250 :                 z__[ipn4 - j4 - 3] = temp;
+    9755      332250 :                 temp = z__[j4 - 2];
+    9756      332250 :                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
+    9757      332250 :                 z__[ipn4 - j4 - 2] = temp;
+    9758      332250 :                 temp = z__[j4 - 1];
+    9759      332250 :                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
+    9760      332250 :                 z__[ipn4 - j4 - 5] = temp;
+    9761      332250 :                 temp = z__[j4];
+    9762      332250 :                 z__[j4] = z__[ipn4 - j4 - 4];
+    9763      332250 :                 z__[ipn4 - j4 - 4] = temp;
+    9764             :             }
+    9765      321732 :             if (*n0 - *i0 <= 4) {
+    9766      321635 :                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
+    9767      321635 :                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
+    9768             :             }
+    9769      321732 :             d__1 = dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
+    9770      321732 :             dmin2 = ((d__1<d__2) ? d__1 : d__2);
+    9771      321732 :             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
+    9772      321732 :                     , d__1 = ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
+    9773      321732 :             z__[(*n0 << 2) + *pp - 1] = ((d__1<d__2) ? d__1 : d__2);
+    9774      321732 :             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
+    9775      321732 :                      ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
+    9776      321732 :             z__[(*n0 << 2) - *pp] = ((d__1<d__2) ? d__1 : d__2);
+    9777      321732 :             d__1 = *qmax;
+    9778      321732 :             d__2 = z__[(*i0 << 2) + *pp - 3];
+    9779      321732 :             d__1 = (d__1>d__2) ? d__1 : d__2;
+    9780      321732 :             d__2 = z__[(*i0 << 2) + *pp + 1];
+    9781      321732 :             *qmax = ((d__1>d__2) ? d__1 : d__2);
+    9782      321732 :             *dmin__ = -0.;
+    9783             :         }
+    9784             :     }
+    9785             : 
+    9786             : 
+    9787    14066784 :     PLUMED_BLAS_F77_FUNC(dlasq4,DLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9788             :             dn2, &tau, &ttype);
+    9789             : 
+    9790    14066793 : L70:
+    9791             : 
+    9792    14066793 :     PLUMED_BLAS_F77_FUNC(dlasq5,DLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9793             :             dn2, ieee);
+    9794             : 
+    9795    14066793 :     *ndiv += *n0 - *i0 + 2;
+    9796    14066793 :     ++(*iter);
+    9797             : 
+    9798    14066793 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+    9799             : 
+    9800    14066784 :         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    14066784 : L90:
+    9837    14066784 :     if (tau < *sigma) {
+    9838    12195945 :         *desig += tau;
+    9839    12195945 :         t = *sigma + *desig;
+    9840    12195945 :         *desig -= t - *sigma;
+    9841             :     } else {
+    9842     1870839 :         t = *sigma + tau;
+    9843     1870839 :         *desig = *sigma - (t - tau) + *desig;
+    9844             :     }
+    9845    14066784 :     *sigma = t;
+    9846             : 
+    9847    14066784 :     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    14066784 : 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    14066784 :     if (*dmin__ <= 0.) {
+    9885      937127 :         *tau = -(*dmin__);
+    9886      937127 :         *ttype = -1;
+    9887      937127 :         return;
+    9888             :     }
+    9889             : 
+    9890             :     s = 0.0;
+    9891             : 
+    9892    13129657 :     nn = (*n0 << 2) + *pp;
+    9893    13129657 :     if (*n0in == *n0) {
+    9894             : 
+    9895    12818514 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn) ||
+    9896    12818514 :          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    12818514 :         } 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    12818514 :             if (*ttype == -6) {
+   10023             :                 g += (1. - g) * .333;
+   10024    12818514 :             } else if (*ttype == -18) {
+   10025             :                 g = .083250000000000005;
+   10026             :             } else {
+   10027             :                 g = .25;
+   10028             :             }
+   10029    12818514 :             s = g * *dmin__;
+   10030    12818514 :             *ttype = -6;
+   10031             :         }
+   10032             : 
+   10033      311143 :     } else if (*n0in == *n0 + 1) {
+   10034             : 
+   10035      310988 :         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      310988 :             s = *dmin1 * .25;
+   10076      310988 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin1 + *dn1)) {
+   10077           0 :                 s = *dmin1 * .5;
+   10078             :             }
+   10079      310988 :             *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    13129657 :     *tau = s;
+   10131    13129657 :     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    14066793 : 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    14066793 :     --z__;
+   10167             : 
+   10168    14066793 :     if (*n0 - *i0 - 1 <= 0) {
+   10169             :         return;
+   10170             :     }
+   10171             : 
+   10172    14066793 :     j4 = (*i0 << 2) + *pp - 3;
+   10173    14066793 :     emin = z__[j4 + 4];
+   10174    14066793 :     d__ = z__[j4] - *tau;
+   10175    14066793 :     *dmin__ = d__;
+   10176    14066793 :     *dmin1 = -z__[j4];
+   10177             : 
+   10178    14066793 :     if (*ieee) {
+   10179             : 
+   10180    14066793 :         if (*pp == 0) {
+   10181     7196790 :             i__1 = 4*(*n0 - 3);
+   10182     8557440 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10183     1360650 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   10184     1360650 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   10185     1360650 :                 d__ = d__ * temp - *tau;
+   10186     1360650 :                 if(d__<*dmin__)
+   10187      365511 :                   *dmin__ = d__;
+   10188     1360650 :                 z__[j4] = z__[j4 - 1] * temp;
+   10189             :                 d__1 = z__[j4];
+   10190     1360650 :                 if(d__1<emin)
+   10191             :                   emin = d__1;
+   10192             :             }
+   10193             :         } else {
+   10194     6870003 :             i__1 = 4*(*n0 - 3);
+   10195     7785001 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10196      914998 :                 z__[j4 - 3] = d__ + z__[j4];
+   10197      914998 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   10198      914998 :                 d__ = d__ * temp - *tau;
+   10199      914998 :                 if(d__<*dmin__)
+   10200      259894 :                   *dmin__ = d__;
+   10201      914998 :                 z__[j4 - 1] = z__[j4] * temp;
+   10202             :                 d__1 = z__[j4 - 1];
+   10203      914998 :                 if(d__1<emin)
+   10204             :                   emin = d__1;
+   10205             :             }
+   10206             :         }
+   10207             : 
+   10208    14066793 :         *dnm2 = d__;
+   10209    14066793 :         *dmin2 = *dmin__;
+   10210    14066793 :         j4 = 4*(*n0 - 2) - *pp;
+   10211    14066793 :         j4p2 = j4 + (*pp << 1) - 1;
+   10212    14066793 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   10213    14066793 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10214    14066793 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   10215    14066793 :         if(*dnm1<*dmin__)
+   10216    11189671 :           *dmin__ = *dnm1;
+   10217             : 
+   10218    14066793 :         *dmin1 = *dmin__;
+   10219    14066793 :         j4 += 4;
+   10220    14066793 :         j4p2 = j4 + (*pp << 1) - 1;
+   10221    14066793 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   10222    14066793 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10223    14066793 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   10224    14066793 :         if(*dn<*dmin__)
+   10225    13444049 :           *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    14066793 :     z__[j4 + 2] = *dn;
+   10291    14066793 :     z__[(*n0 << 2) - *pp] = emin;
+   10292    14066793 :     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       12262 : 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       12262 :     --c__;
+   10469       12262 :     --s;
+   10470       12262 :     a_dim1 = *lda;
+   10471       12262 :     a_offset = 1 + a_dim1;
+   10472       12262 :     a -= a_offset;
+   10473             : 
+   10474             :     /* Function Body */
+   10475             : 
+   10476       12262 :     if (*m == 0 || *n == 0) {
+   10477             :         return;
+   10478             :     }
+   10479       12262 :     if (*side=='L' || *side=='l') {
+   10480             : 
+   10481        6131 :         if (*pivot=='V' || *pivot=='v') {
+   10482        6131 :             if (*direct=='F' || *direct=='f') {
+   10483             :                 i__1 = *m - 1;
+   10484       53995 :                 for (j = 1; j <= i__1; ++j) {
+   10485       47897 :                     ctemp = c__[j];
+   10486       47897 :                     stemp = s[j];
+   10487       47897 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10488       47897 :                         i__2 = *n;
+   10489      872545 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10490      824648 :                             temp = a[j + 1 + i__ * a_dim1];
+   10491      824648 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   10492      824648 :                                     a[j + i__ * a_dim1];
+   10493      824648 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   10494      824648 :                                     + 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        6131 :     } else if (*side=='R' || *side=='r') {
+   10582             : 
+   10583        6131 :         if (*pivot=='V' || *pivot=='v') {
+   10584        6131 :             if (*direct=='F' || *direct=='f') {
+   10585             :                 i__1 = *n - 1;
+   10586       53936 :                 for (j = 1; j <= i__1; ++j) {
+   10587       47838 :                     ctemp = c__[j];
+   10588       47838 :                     stemp = s[j];
+   10589       47838 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10590       47838 :                         i__2 = *m;
+   10591      854728 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10592      806890 :                             temp = a[i__ + (j + 1) * a_dim1];
+   10593      806890 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   10594      806890 :                                      a[i__ + j * a_dim1];
+   10595      806890 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   10596      806890 :                                     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      624304 : 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      624304 :     --d__;
+   10717             : 
+   10718      624304 :     *info = 0;
+   10719             :     dir = -1;
+   10720      624304 :     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      624304 :     } else if (*n < 0) {
+   10728           0 :         *info = -2;
+   10729             :     }
+   10730      624304 :     if (*info != 0) {
+   10731             :         return;
+   10732             :     }
+   10733      624304 :     if (*n <= 1) {
+   10734             :         return;
+   10735             :     }
+   10736             : 
+   10737             :     stkpnt = 1;
+   10738      623879 :     stack[0] = 1;
+   10739      623879 :     stack[1] = *n;
+   10740      623997 : L10:
+   10741      623997 :     start = stack[(stkpnt << 1) - 2];
+   10742      623997 :     endd = stack[(stkpnt << 1) - 1];
+   10743      623997 :     --stkpnt;
+   10744      623997 :     if (endd - start <= 20 && endd - start > 0) {
+   10745             : 
+   10746             : 
+   10747      623938 :         if (dir == 0) {
+   10748             : 
+   10749             :             i__1 = endd;
+   10750     2496560 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10751             :                 i__2 = start + 1;
+   10752     1872635 :                 for (j = i__; j >= i__2; --j) {
+   10753     1872635 :                     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     1872635 :                         goto L30;
+   10759             :                     }
+   10760             :                 }
+   10761     1872635 : 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      623997 :     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         900 : 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         900 :     ft = *f;
+   11169             :     fa = std::abs(ft);
+   11170         900 :     ht = *h__;
+   11171             :     ha = std::abs(*h__);
+   11172             : 
+   11173             :     pmax = 1;
+   11174             :     swap = ha > fa;
+   11175         900 :     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         900 :     gt = *g;
+   11186             :     ga = std::abs(gt);
+   11187         900 :     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         900 :         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         900 :         if (gasmal) {
+   11215             : 
+   11216         900 :             d__ = fa - ha;
+   11217         900 :             if ( std::abs( fa - d__ )<PLUMED_GMX_DOUBLE_EPS*std::abs( fa + d__ )) {
+   11218             :                 l = 1.;
+   11219             :             } else {
+   11220         900 :                 l = d__ / fa;
+   11221             :             }
+   11222             : 
+   11223         900 :             m = gt / ft;
+   11224         900 :             t = 2. - l;
+   11225             : 
+   11226         900 :             mm = m * m;
+   11227         900 :             tt = t * t;
+   11228         900 :             s =  std::sqrt(tt + mm);
+   11229             : 
+   11230         900 :             if ( std::abs(l)<PLUMED_GMX_DOUBLE_MIN) {
+   11231             :                 r__ = std::abs(m);
+   11232             :             } else {
+   11233         900 :                 r__ =  std::sqrt(l * l + mm);
+   11234             :             }
+   11235         900 :             a = (s + r__) * .5;
+   11236             : 
+   11237         900 :             *ssmin = ha / a;
+   11238         900 :             *ssmax = fa * a;
+   11239         900 :             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         900 :                 t = (m / (s + t) + m / (r__ + l)) * (a + 1.);
+   11248             :             }
+   11249         900 :             l =  std::sqrt(t * t + 4.);
+   11250         900 :             crt = 2. / l;
+   11251         900 :             srt = t / l;
+   11252         900 :             clt = (crt + srt * m) / a;
+   11253         900 :             slt = ht / ft * srt / a;
+   11254             :         }
+   11255             :     }
+   11256         900 :     if (swap) {
+   11257          12 :         *csl = srt;
+   11258          12 :         *snl = crt;
+   11259          12 :         *csr = slt;
+   11260          12 :         *snr = clt;
+   11261             :     } else {
+   11262         888 :         *csl = clt;
+   11263         888 :         *snl = slt;
+   11264         888 :         *csr = crt;
+   11265         888 :         *snr = srt;
+   11266             :     }
+   11267             : 
+   11268         900 :     if (pmax == 1) {
+   11269         907 :         tsign = ( (*csr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*f>0) ? 1.0 : -1.0);
+   11270             :     }
+   11271         900 :     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         900 :     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         900 :     if(tsign<0)
+   11278          25 :       *ssmax *= -1.0;
+   11279         925 :     d__1 = tsign * ( (*f>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   11280         900 :     if(d__1<0)
+   11281          65 :       *ssmin *= -1.0;
+   11282         900 :     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      637226 : 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      637226 :     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      637226 :     a_dim1 = *lda;
+   12074      637226 :     a_offset = 1 + a_dim1;
+   12075      637226 :     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      637226 :     *info = 0;
+   12084      637226 :     left = (*side=='L' || *side=='l');
+   12085      637226 :     notran = (*trans=='N' || *trans=='n');
+   12086             : 
+   12087      637226 :     if (left) {
+   12088      637226 :         nq = *m;
+   12089             :     } else {
+   12090           0 :         nq = *n;
+   12091             :     }
+   12092             :     if (*info != 0) {
+   12093             :         return;
+   12094             :     }
+   12095             : 
+   12096      637226 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12097             :         return;
+   12098             :     }
+   12099             : 
+   12100      637226 :     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      637226 :     if (left) {
+   12111      637226 :         ni = *n;
+   12112             :     } else {
+   12113           0 :         mi = *m;
+   12114             :     }
+   12115             : 
+   12116             :     i__1 = i2;
+   12117             :     i__2 = i3;
+   12118     2522395 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12119     1885169 :         if (left) {
+   12120             : 
+   12121     1885169 :             mi = *m - *k + i__;
+   12122             :         } else {
+   12123             : 
+   12124           0 :             ni = *n - *k + i__;
+   12125             :         }
+   12126             : 
+   12127     1885169 :         aii = a[nq - *k + i__ + i__ * a_dim1];
+   12128     1885169 :         a[nq - *k + i__ + i__ * a_dim1] = 1.;
+   12129     1885169 :         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     1885169 :         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         799 : 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         799 :     int c__1 = 1;
+   12164             : 
+   12165         799 :     a_dim1 = *lda;
+   12166         799 :     a_offset = 1 + a_dim1;
+   12167         799 :     a -= a_offset;
+   12168             :     --tau;
+   12169         799 :     c_dim1 = *ldc;
+   12170         799 :     c_offset = 1 + c_dim1;
+   12171         799 :     c__ -= c_offset;
+   12172             :     --work;
+   12173         799 :     *info = 0;
+   12174         799 :     left = (*side=='L' || *side=='l');
+   12175         799 :     notran = (*trans=='N' || *trans=='n');
+   12176             : 
+   12177             :     ic = jc = 0;
+   12178             : 
+   12179         799 :     if (*m <= 0 || *n <= 0 || *k <= 0) {
+   12180             :         return;
+   12181             :     }
+   12182             : 
+   12183         799 :     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         799 :     if (left) {
+   12194         799 :         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        4427 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12204        3628 :         if (left) {
+   12205             : 
+   12206        3628 :             mi = *m - i__ + 1;
+   12207             :             ic = i__;
+   12208             :         } else {
+   12209             : 
+   12210           0 :             ni = *n - i__ + 1;
+   12211             :             jc = i__;
+   12212             :         }
+   12213             : 
+   12214             : 
+   12215        3628 :         aii = a[i__ + i__ * a_dim1];
+   12216        3628 :         a[i__ + i__ * a_dim1] = 1.;
+   12217        3628 :         PLUMED_BLAS_F77_FUNC(dlarf,DLARF)(side, &mi, &ni, &a[i__ + i__ * a_dim1], &c__1, &tau[i__], &c__[
+   12218        3628 :                 ic + jc * c_dim1], ldc, &work[1]);
+   12219        3628 :         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        1632 : 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        1632 :     a_dim1 = *lda;
+   12262        1632 :     a_offset = 1 + a_dim1;
+   12263        1632 :     a -= a_offset;
+   12264             :     --tau;
+   12265        1632 :     c_dim1 = *ldc;
+   12266        1632 :     c_offset = 1 + c_dim1;
+   12267        1632 :     c__ -= c_offset;
+   12268             :     --work;
+   12269        1632 :     *info = 0;
+   12270        1632 :     applyq = (*vect=='Q' || *vect=='q');
+   12271        1632 :     left = (*side=='L' || *side=='l');
+   12272        1632 :     notran = (*trans=='N' || *trans=='n');
+   12273        1632 :     lquery = *lwork == -1;
+   12274             : 
+   12275        1632 :     if (left) {
+   12276         816 :         nq = *m;
+   12277         816 :         nw = *n;
+   12278             :     } else {
+   12279         816 :         nq = *n;
+   12280         816 :         nw = *m;
+   12281             :     }
+   12282             : 
+   12283             :     nb = DORMQR_BLOCKSIZE;
+   12284        1632 :     lwkopt = nw * nb;
+   12285        1632 :     work[1] = (double) lwkopt;
+   12286             :     
+   12287        1632 :     if (*info != 0) {
+   12288             :         i__1 = -(*info);
+   12289             :         return;
+   12290        1632 :     } else if (lquery) {
+   12291             :         return;
+   12292             :     }
+   12293             : 
+   12294        1632 :     work[1] = 1.;
+   12295        1632 :     if (*m == 0 || *n == 0) {
+   12296             :         return;
+   12297             :     }
+   12298             : 
+   12299        1632 :     if (applyq) {
+   12300             : 
+   12301         816 :         if (nq >= *k) {
+   12302             : 
+   12303         816 :             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         816 :         if (notran) {
+   12325           0 :             *(unsigned char *)transt = 'T';
+   12326             :         } else {
+   12327         816 :             *(unsigned char *)transt = 'N';
+   12328             :         }
+   12329         816 :         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         816 :         } else if (nq > 1) {
+   12334             : 
+   12335         816 :             if (left) {
+   12336           0 :                 mi = *m - 1;
+   12337           0 :                 ni = *n;
+   12338             :                 i1 = 2;
+   12339             :                 i2 = 1;
+   12340             :             } else {
+   12341         816 :                 mi = *m;
+   12342         816 :                 ni = *n - 1;
+   12343             :                 i1 = 1;
+   12344             :                 i2 = 2;
+   12345             :             }
+   12346         816 :             i__1 = nq - 1;
+   12347         816 :             PLUMED_BLAS_F77_FUNC(dormlq,DORMLQ)(side, transt, &mi, &ni, &i__1, &a[(a_dim1 << 1) + 1], lda,
+   12348         816 :                      &tau[1], &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &
+   12349             :                     iinfo);
+   12350             :         }
+   12351             :     }
+   12352        1632 :     work[1] = (double) lwkopt;
+   12353        1632 :     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         803 : 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         803 :   const char xside=std::toupper(*side);
+   12384         803 :   const char xtrans=std::toupper(*trans);
+   12385             :   int i,i1,i2,i3,ni,mi,ic,jc;
+   12386             :   double aii;
+   12387             : 
+   12388         803 :   if(*m<=0 || *n<=0 || *k<=0)
+   12389             :     return;
+   12390             : 
+   12391             :   ic = jc = 0;
+   12392             : 
+   12393         803 :   if((xside=='L' && xtrans=='N') || (xside!='L' && xtrans!='N')) {
+   12394             :     i1 = 0;
+   12395             :     i2 = *k;
+   12396             :     i3 = 1;
+   12397             :   } else {
+   12398         803 :     i1 = *k-1;
+   12399             :     i2 = -1;
+   12400             :     i3 = -1;
+   12401             :   }
+   12402             :   
+   12403         803 :   if(xside=='L') {
+   12404           0 :     ni = *n;
+   12405             :     jc = 0;
+   12406             :   } else {
+   12407         803 :     mi = *m;
+   12408             :     ic = 0;
+   12409             :   }
+   12410             : 
+   12411        3760 :   for(i=i1;i!=i2;i+=i3) {
+   12412        2957 :     if(xside=='L') {
+   12413           0 :       mi = *m - i;
+   12414             :       ic = i;
+   12415             :     } else {
+   12416        2957 :       ni = *n - i;
+   12417             :       jc = i;
+   12418             :     }
+   12419        2957 :     aii = a[i*(*lda)+i];
+   12420        2957 :     a[i*(*lda)+i] = 1.0;
+   12421        2957 :     PLUMED_BLAS_F77_FUNC(dlarf,DLARF)(side,&mi,&ni,&(a[i*(*lda)+i]),lda,tau+i,
+   12422        2957 :            &(c[jc*(*ldc)+ic]),ldc,work);
+   12423        2957 :     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         816 : 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         816 :     int ldt = 65;
+   12468             : 
+   12469         816 :     a_dim1 = *lda;
+   12470         816 :     a_offset = 1 + a_dim1;
+   12471         816 :     a -= a_offset;
+   12472             :     --tau;
+   12473         816 :     c_dim1 = *ldc;
+   12474         816 :     c_offset = 1 + c_dim1;
+   12475         816 :     c__ -= c_offset;
+   12476             :     --work;
+   12477             : 
+   12478             :     ic = jc = 0;
+   12479             : 
+   12480         816 :     *info = 0;
+   12481         816 :     left = (*side=='L' || *side=='l');
+   12482         816 :     notran = (*trans=='N' || *trans=='n');
+   12483         816 :     lquery = *lwork == -1;
+   12484             : 
+   12485         816 :     if (left) {
+   12486           0 :         nq = *m;
+   12487           0 :         nw = *n;
+   12488             :     } else {
+   12489         816 :         nq = *n;
+   12490         816 :         nw = *m;
+   12491             :     }
+   12492             : 
+   12493             :     nb = DORMLQ_BLOCKSIZE;
+   12494         816 :     lwkopt = nw * nb;
+   12495         816 :     work[1] = (double) lwkopt;
+   12496             :     
+   12497         816 :     if (*info != 0) {
+   12498             :         return;
+   12499         816 :     } else if (lquery) {
+   12500             :         return;
+   12501             :     }
+   12502             : 
+   12503         816 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12504           0 :         work[1] = 1.;
+   12505           0 :         return;
+   12506             :     }
+   12507             : 
+   12508             :     nbmin = 2;
+   12509         816 :     ldwork = nw;
+   12510         816 :     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         816 :     if (nb < nbmin || nb >= *k) {
+   12519             : 
+   12520             : 
+   12521         803 :         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         816 :     work[1] = (double) lwkopt;
+   12574         816 :     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      637236 : 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      637236 :     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      637236 :     a_dim1 = *lda;
+   12607      637236 :     a_offset = 1 + a_dim1;
+   12608      637236 :     a -= a_offset;
+   12609             :     --tau;
+   12610             :     c_dim1 = *ldc;
+   12611             :     c_offset = 1 + c_dim1;
+   12612             :     c__ -= c_offset;
+   12613             :     --work;
+   12614             : 
+   12615      637236 :     *info = 0;
+   12616      637236 :     left = (*side=='L' || *side=='l');
+   12617      637236 :     notran = (*trans=='N' || *trans=='n');
+   12618      637236 :     lquery = *lwork == -1;
+   12619             : 
+   12620      637236 :     if (left) {
+   12621      637236 :         nq = *m;
+   12622      637236 :         nw = *n;
+   12623             :     } else {
+   12624           0 :         nq = *n;
+   12625           0 :         nw = *m;
+   12626             :     }
+   12627             : 
+   12628             :     nb = DORMQL_BLOCKSIZE;
+   12629      637236 :     lwkopt = nw * nb;
+   12630      637236 :     work[1] = (double) lwkopt;
+   12631             :     
+   12632      637236 :     if (*info != 0) {
+   12633             :         return;
+   12634      637236 :     } else if (lquery) {
+   12635             :         return;
+   12636             :     }
+   12637             : 
+   12638      637236 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12639           0 :         work[1] = 1.;
+   12640           0 :         return;
+   12641             :     }
+   12642             : 
+   12643             :     nbmin = 2;
+   12644      637236 :     ldwork = nw;
+   12645      637236 :     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      637236 :     if (nb < nbmin || nb >= *k) {
+   12654             : 
+   12655      637226 :         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      637236 :     work[1] = (double) lwkopt;
+   12698      637236 :     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         816 : 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         816 :     int ldt = 65;
+   12738             : 
+   12739         816 :     a_dim1 = *lda;
+   12740         816 :     a_offset = 1 + a_dim1;
+   12741         816 :     a -= a_offset;
+   12742             :     --tau;
+   12743         816 :     c_dim1 = *ldc;
+   12744         816 :     c_offset = 1 + c_dim1;
+   12745         816 :     c__ -= c_offset;
+   12746             :     --work;
+   12747             : 
+   12748         816 :     *info = 0;
+   12749         816 :     left = (*side=='L' || *side=='l');
+   12750         816 :     notran = (*trans=='N' || *trans=='n');
+   12751         816 :     lquery = *lwork == -1;
+   12752             : 
+   12753         816 :     if (left) {
+   12754         816 :         nq = *m;
+   12755         816 :         nw = *n;
+   12756             :     } else {
+   12757           0 :         nq = *n;
+   12758           0 :         nw = *m;
+   12759             :     }
+   12760             : 
+   12761             :      ic = jc = 0;
+   12762             :      nb = DORMQR_BLOCKSIZE;
+   12763         816 :      lwkopt = nw * nb;
+   12764         816 :      work[1] = (double) lwkopt;
+   12765             : 
+   12766         816 :     if (*info != 0) {
+   12767             :         return;
+   12768         816 :     } else if (lquery) {
+   12769             :       return;
+   12770             :     }
+   12771             : 
+   12772         816 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12773           0 :         work[1] = 1.;
+   12774           0 :         return;
+   12775             :     }
+   12776             : 
+   12777             :     nbmin = 2;
+   12778         816 :     ldwork = nw;
+   12779         816 :     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         816 :     if (nb < nbmin || nb >= *k) {
+   12788             : 
+   12789         799 :         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         816 :     work[1] = (double) lwkopt;
+   12835         816 :     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      637236 : 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      637236 :     a_dim1 = *lda;
+   12877      637236 :     a_offset = 1 + a_dim1;
+   12878      637236 :     a -= a_offset;
+   12879             :     --tau;
+   12880      637236 :     c_dim1 = *ldc;
+   12881      637236 :     c_offset = 1 + c_dim1;
+   12882      637236 :     c__ -= c_offset;
+   12883             :     --work;
+   12884             : 
+   12885      637236 :     *info = 0;
+   12886      637236 :     left = (*side=='L' || *side=='l');
+   12887      637236 :     upper = (*uplo=='U' || *uplo=='u');
+   12888      637236 :     lquery = *lwork == -1;
+   12889             : 
+   12890      637236 :     if (left) {
+   12891      637236 :         nq = *m;
+   12892      637236 :         nw = *n;
+   12893             :     } else {
+   12894           0 :         nq = *n;
+   12895           0 :         nw = *m;
+   12896             :     }
+   12897             : 
+   12898             : 
+   12899             :     nb = DORMQL_BLOCKSIZE;
+   12900      637236 :     lwkopt = nw * nb;
+   12901      637236 :     work[1] = (double) lwkopt;
+   12902             :     
+   12903      637236 :     if (*info != 0) {
+   12904             :         i__2 = -(*info);
+   12905             :         return;
+   12906      637236 :     } else if (lquery) {
+   12907             :         return;
+   12908             :     }
+   12909             : 
+   12910      637236 :     if (*m == 0 || *n == 0 || nq == 1) {
+   12911           0 :         work[1] = 1.;
+   12912           0 :         return;
+   12913             :     }
+   12914             : 
+   12915      637236 :     if (left) {
+   12916      637236 :         mi = *m - 1;
+   12917      637236 :         ni = *n;
+   12918             :     } else {
+   12919           0 :         mi = *m;
+   12920           0 :         ni = *n - 1;
+   12921             :     }
+   12922             : 
+   12923      637236 :     if (upper) {
+   12924      637236 :         i__2 = nq - 1;
+   12925      637236 :         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      637236 :     work[1] = (double) lwkopt;
+   12940      637236 :     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      637236 : 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      637236 :     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      637236 :     --w;
+   13492      637236 :     z_dim1 = *ldz;
+   13493      637236 :     z_offset = 1 + z_dim1;
+   13494      637236 :     z__ -= z_offset;
+   13495      637236 :     --isuppz;
+   13496      637236 :     --work;
+   13497      637236 :     --iwork;
+   13498             : 
+   13499      637236 :     wantz = (*jobz=='V' || *jobz=='v');
+   13500      637236 :     alleig = (*range=='A' || *range=='a');
+   13501      637236 :     valeig = (*range=='V' || *range=='v');
+   13502      637236 :     indeig = (*range=='I' || *range=='i');
+   13503             : 
+   13504      637236 :     lquery = *lwork == -1 || *liwork == -1;
+   13505      637236 :     lwmin = *n * 17;
+   13506      637236 :     liwmin = *n * 10;
+   13507             : 
+   13508      637236 :     *info = 0;
+   13509      637236 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   13510           0 :         *info = -1;
+   13511      637236 :     } else if (! (alleig || valeig || indeig)) {
+   13512           0 :         *info = -2;
+   13513      637236 :     } else if (*n < 0) {
+   13514           0 :         *info = -3;
+   13515      637236 :     } else if (valeig && *n > 0 && *vu <= *vl) {
+   13516           0 :         *info = -7;
+   13517      637236 :     } else if (indeig && (*il < 1 || *il > *n)) {
+   13518           0 :         *info = -8;
+   13519      637236 :     } else if (indeig && (*iu < *il || *iu > *n)) {
+   13520           0 :         *info = -9;
+   13521      637236 :     } else if (*ldz < 1 || (wantz && *ldz < *n)) {
+   13522           0 :         *info = -14;
+   13523      637236 :     } else if (*lwork < lwmin && ! lquery) {
+   13524           0 :         *info = -17;
+   13525      637236 :     } else if (*liwork < liwmin && ! lquery) {
+   13526           0 :         *info = -19;
+   13527             :     }
+   13528      637236 :     if (*info == 0) {
+   13529      637236 :         work[1] = (double) lwmin;
+   13530      637236 :         iwork[1] = liwmin;
+   13531             :     }
+   13532             : 
+   13533      637236 :     if (*info != 0) {
+   13534             :         i__1 = -(*info);
+   13535             :         return;
+   13536      637236 :     } else if (lquery) {
+   13537             :         return;
+   13538             :     }
+   13539             : 
+   13540      637236 :     *m = 0;
+   13541      637236 :     if (*n == 0) {
+   13542             :         return;
+   13543             :     }
+   13544             : 
+   13545      637236 :     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      637236 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   13568             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   13569      637236 :     scale = 1.;
+   13570      637236 :     tnrm = PLUMED_BLAS_F77_FUNC(dlanst,DLANST)("M", n, &d__[1], &e[1]);
+   13571      637236 :     if (tnrm > 0. && tnrm < rmin) {
+   13572           0 :         scale = rmin / tnrm;
+   13573      637236 :     } else if (tnrm > rmax) {
+   13574           0 :         scale = rmax / tnrm;
+   13575             :     }
+   13576      637236 :     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      637236 :     indwrk = (*n << 1) + 1;
+   13584             : 
+   13585             :     iinspl = 1;
+   13586      637236 :     iindbl = *n + 1;
+   13587             :     iindw = (*n << 1) + 1;
+   13588      637236 :     iindwk = *n * 3 + 1;
+   13589             : 
+   13590      637236 :     thresh = eps * tnrm;
+   13591      637236 :     PLUMED_BLAS_F77_FUNC(dlarrex,DLARREX)(range, n, vl, vu, il, iu, &d__[1], &e[1], &thresh, &nsplit, &
+   13592      637236 :             iwork[iinspl], m, &w[1], &iwork[iindbl], &iwork[iindw], &work[
+   13593      637236 :             indgrs], &work[indwrk], &iwork[iindwk], &iinfo);
+   13594             :     
+   13595      637236 :     if (iinfo != 0) {
+   13596           0 :         *info = 1;
+   13597           0 :         return;
+   13598             :     }
+   13599             : 
+   13600      637236 :     if (wantz) {
+   13601      637236 :         d__1 = *abstol, d__2 = (double) (*n) * eps;
+   13602      637236 :         tol = (d__1>d__2) ? d__1 : d__2;
+   13603      637236 :         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      637236 :         if (iinfo != 0) {
+   13607           0 :             *info = 2;
+   13608           0 :             return;
+   13609             :         }
+   13610             :     }
+   13611             : 
+   13612      637236 :     i__1 = *m;
+   13613     1467425 :     for (j = 1; j <= i__1; ++j) {
+   13614      830189 :         itmp = iwork[iindbl + j - 1];
+   13615      830189 :         w[j] += e[iwork[iinspl + itmp - 1]];
+   13616             :     } 
+   13617             : 
+   13618      637236 :     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      637236 :     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      637236 :     work[1] = (double) lwmin;
+   13652      637236 :     iwork[1] = liwmin;
+   13653      637236 :     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      651875 : 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      651875 :     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      651875 :     a_dim1 = *lda;
+   14769      651875 :     a_offset = 1 + a_dim1;
+   14770      651875 :     a -= a_offset;
+   14771      651875 :     --w;
+   14772      651875 :     z_dim1 = *ldz;
+   14773      651875 :     z_offset = 1 + z_dim1;
+   14774      651875 :     z__ -= z_offset;
+   14775             :     --isuppz;
+   14776      651875 :     --work;
+   14777      651875 :     --iwork;
+   14778             : 
+   14779      651875 :     lower = (*uplo=='L' || *uplo=='l');
+   14780      651875 :     wantz = (*jobz=='V' || *jobz=='v');
+   14781      651875 :     alleig = (*range=='A' || *range=='a');
+   14782      651875 :     valeig = (*range=='V' || *range=='v');
+   14783      651875 :     indeig = (*range=='I' || *range=='i');
+   14784             : 
+   14785             :     indibl = 0;
+   14786      651875 :     lquery = *lwork == -1 || *liwork == -1;
+   14787             : 
+   14788             :     i__1 = 1;
+   14789      651875 :     i__2 = *n * 26;
+   14790             : 
+   14791      651875 :     if(*n>0) 
+   14792             :       lwmin = *n * 26;
+   14793             :     else
+   14794             :       lwmin = 1;
+   14795             : 
+   14796      651875 :     if(*n>0) 
+   14797      651875 :       liwmin = *n * 10;
+   14798             :     else
+   14799             :       liwmin = 1;
+   14800             : 
+   14801      651875 :     *info = 0;
+   14802      651875 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   14803           0 :         *info = -1;
+   14804      651875 :     } else if (! (alleig || valeig || indeig)) {
+   14805           0 :         *info = -2;
+   14806      651875 :     } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
+   14807           0 :         *info = -3;
+   14808      651875 :     } else if (*n < 0) {
+   14809           0 :         *info = -4;
+   14810      651875 :     } else if (*lda < ((*n>1) ? *n : 1) ) {
+   14811           0 :         *info = -6;
+   14812             :     } else {
+   14813      651875 :         if (valeig) {
+   14814           0 :             if (*n > 0 && *vu <= *vl) {
+   14815           0 :                 *info = -8;
+   14816             :             }
+   14817      651875 :         } else if (indeig) {
+   14818      592638 :           if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
+   14819           0 :                 *info = -9;
+   14820      592638 :             } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
+   14821           0 :                 *info = -10;
+   14822             :             }
+   14823             :         }
+   14824             :     }
+   14825      651875 :     if (*info == 0) {
+   14826      651875 :       if (*ldz < 1 || (wantz && *ldz < *n)) {
+   14827           0 :             *info = -15;
+   14828      651875 :         } else if (*lwork < lwmin && ! lquery) {
+   14829           0 :             *info = -18;
+   14830      651875 :         } else if (*liwork < liwmin && ! lquery) {
+   14831           0 :             *info = -20;
+   14832             :         }
+   14833             :     }
+   14834             : 
+   14835      651875 :     if (*info == 0) {
+   14836             :       nb = 32;
+   14837             :       /* Computing MAX */
+   14838      651875 :       i__1 = (nb + 1) * *n;
+   14839             :       lwkopt = (i__1>lwmin) ? i__1 : lwmin;
+   14840      651875 :       work[1] = (double) lwkopt;
+   14841      651875 :       iwork[1] = liwmin;
+   14842             :     } else 
+   14843             :       return;
+   14844             : 
+   14845      651875 :     if (lquery) 
+   14846             :         return;
+   14847             :     
+   14848      637818 :     *m = 0;
+   14849      637818 :     if (*n == 0) {
+   14850           0 :         work[1] = 1.;
+   14851           0 :         return;
+   14852             :     }
+   14853             : 
+   14854      637818 :     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      637236 :     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      637236 :     anrm = PLUMED_BLAS_F77_FUNC(dlansy,DLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
+   14883      637236 :     if (anrm > 0. && anrm < rmin) {
+   14884             :         iscale = 1;
+   14885           0 :         sigma = rmin / anrm;
+   14886      637236 :     } 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      637236 :     inde = indtau + *n;
+   14908      637236 :     indd = inde + *n;
+   14909      637236 :     indee = indd + *n;
+   14910      637236 :     inddd = indee + *n;
+   14911      637236 :     indifl = inddd + *n;
+   14912      637236 :     indwk = indifl + *n;
+   14913      637236 :     llwork = *lwork - indwk + 1;
+   14914      637236 :     PLUMED_BLAS_F77_FUNC(dsytrd,DSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
+   14915      637236 :             indtau], &work[indwk], &llwork, &iinfo);
+   14916             : 
+   14917      637236 :     i__1 = *n - 1;
+   14918      637236 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
+   14919      637236 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
+   14920             : 
+   14921      637236 :     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      637236 :     if (wantz && *info == 0) {
+   14925             :       indwkn = inde;
+   14926      637236 :       llwrkn = *lwork - indwkn + 1;
+   14927      637236 :       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      637236 :     if (*info != 0) 
+   14932             :       return;
+   14933             : 
+   14934      637236 :     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      637236 :     if (wantz) {
+   14945      637236 :         i__1 = *m - 1;
+   14946             :         
+   14947      830189 :         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      637236 :     work[1] = (double) lwkopt;
+   14971      637236 :     iwork[1] = liwmin;
+   14972      637236 :     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      637236 : 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      637236 :   const char ch=std::toupper(*uplo);
+   15003             : 
+   15004      637236 :   zero = 0.0;
+   15005      637236 :   minusone = -1.0;
+   15006             : 
+   15007      637236 :   if(*n<=0)
+   15008             :     return;
+   15009             : 
+   15010      637236 :   if(ch=='U') {
+   15011     2523248 :     for(i=*n-1;i>=1;i--) {
+   15012             : 
+   15013     1886012 :       ti1 = 1;
+   15014     1886012 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i,&(a[i*(*lda)+(i-1)]),&(a[i*(*lda)+0]),&ti1,&taui);
+   15015     1886012 :       e[i-1] = a[i*(*lda) + (i-1)];
+   15016     1886012 :       if(std::abs(taui)>PLUMED_GMX_DOUBLE_MIN) {
+   15017     1248709 :         a[i*(*lda)+(i-1)] = 1.0;
+   15018             :       
+   15019     1248709 :         ti1 = 1;
+   15020     1248709 :         PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)("U",&i,&taui,a,lda,&(a[i*(*lda)+0]),&ti1,&zero,tau,&ti1);
+   15021             : 
+   15022     1248709 :         tmp = PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&i,tau,&ti1,&(a[i*(*lda)+0]),&ti1);
+   15023             : 
+   15024     1248709 :         alpha = -0.5*taui*tmp;
+   15025             : 
+   15026     1248709 :         PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&i,&alpha,&(a[i*(*lda)+0]),&ti1,tau,&ti1);
+   15027             : 
+   15028     1248709 :         PLUMED_BLAS_F77_FUNC(dsyr2,DSYR2)("U",&i,&minusone,&(a[i*(*lda)+0]),&ti1,tau,&ti1,a,lda);
+   15029             : 
+   15030     1248709 :         a[i*(*lda)+(i-1)] = e[i-1]; 
+   15031             : 
+   15032             :       }
+   15033     1886012 :       d[i] = a[i*(*lda)+i];
+   15034     1886012 :       tau[i-1] = taui;
+   15035             :     }
+   15036      637236 :     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      637236 : 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      637236 :     double c_b22 = -1.;
+   15103      637236 :     double c_b23 = 1.;
+   15104             : 
+   15105             : 
+   15106             :     /* Parameter adjustments */
+   15107      637236 :     a_dim1 = *lda;
+   15108      637236 :     a_offset = 1 + a_dim1;
+   15109      637236 :     a -= a_offset;
+   15110      637236 :     --d__;
+   15111      637236 :     --e;
+   15112      637236 :     --tau;
+   15113             :     --work;
+   15114             : 
+   15115             :     /* Function Body */
+   15116      637236 :     *info = 0;
+   15117      637236 :     upper = (*uplo=='U' || *uplo=='u');
+   15118      637236 :     lquery = (*lwork == -1);
+   15119             : 
+   15120      637236 :     if (! upper && ! (*uplo=='L' || *uplo=='l')) {
+   15121           0 :         *info = -1;
+   15122      637236 :     } else if (*n < 0) {
+   15123           0 :         *info = -2;
+   15124      637236 :     } else if (*lda < ((1>*n) ? 1 : *n)) {
+   15125           0 :         *info = -4;
+   15126      637236 :     } else if (*lwork < 1 && ! lquery) {
+   15127           0 :         *info = -9;
+   15128             :     }
+   15129             : 
+   15130      637236 :     if (*info == 0) {
+   15131             : 
+   15132      637236 :       nb = DSYTRD_BLOCKSIZE;
+   15133      637236 :       lwkopt = *n * nb;
+   15134      637236 :       work[1] = (double) lwkopt;
+   15135             :     } else
+   15136             :       return;
+   15137             : 
+   15138      637236 :     if (lquery) 
+   15139             :       return;
+   15140             :   
+   15141      637236 :     if (*n == 0) {
+   15142           0 :         work[1] = 1.;
+   15143           0 :         return;
+   15144             :     }
+   15145             : 
+   15146             :     nx = *n;
+   15147      637236 :     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      637226 :         nb = 1;
+   15168             :     }
+   15169             : 
+   15170      637236 :     if (upper) {
+   15171             : 
+   15172      637236 :         kk = *n - (*n - nx + nb - 1) / nb * nb;
+   15173      637236 :         i__1 = kk + 1;
+   15174             :         i__2 = -nb;
+   15175      637255 :         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      637236 :         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      637236 :     work[1] = (double) lwkopt;
+   15229      637236 :     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 000000000..e91653f89 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22723198.3 %
Date:2024-10-17 16:45:02Functions:1919100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_88
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE112
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv259
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev3294
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE12420
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE16282
_ZN4PLMD6lepton18CompiledExpressionC2Ev16307
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE16365
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_16365
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv31999
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev32677
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev32677
_ZN4PLMD6lepton18CompiledExpressionD2Ev32677
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE74596
_ZN4PLMD6lepton9useAsmJitEv82153
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE102810
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE189338
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd11049185
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv68478984
+
+
+ + + +
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 000000000..eb4e22aa7 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22723198.3 %
Date:2024-10-17 16:45:02Functions:1919100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev32677
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev32677
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE189338
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv31999
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE102810
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE74596
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE16365
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE16282
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_88
_ZN4PLMD6lepton18CompiledExpressionC2Ev16307
_ZN4PLMD6lepton18CompiledExpressionD2Ev32677
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_16365
_ZN4PLMD6lepton9useAsmJitEv82153
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd11049185
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE112
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE12420
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev3294
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv68478984
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv259
+
+
+ + + +
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 000000000..808577401 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html @@ -0,0 +1,585 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22723198.3 %
Date:2024-10-17 16:45:02Functions: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       82153 : bool lepton::useAsmJit() {
+      80             : #ifdef __PLUMED_HAS_ASMJIT
+      81         259 :   static const bool use=[](){
+      82         259 :     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       82153 :   }();
+      90       82153 :   return use;
+      91             : #else
+      92             :   return false;
+      93             : #endif
+      94             : }
+      95             : 
+      96       32677 : AsmJitRuntimePtr::AsmJitRuntimePtr()
+      97             : #ifdef __PLUMED_HAS_ASMJIT
+      98       32677 :   : ptr(useAsmJit()?new asmjit::JitRuntime:nullptr)
+      99             : #endif
+     100       32677 : {}
+     101             : 
+     102       32677 : AsmJitRuntimePtr::~AsmJitRuntimePtr()
+     103             : {
+     104             : #ifdef __PLUMED_HAS_ASMJIT
+     105       32677 :   if(useAsmJit()) delete static_cast<asmjit::JitRuntime*>(ptr);
+     106             : #endif
+     107       32677 : }
+     108             : 
+     109       16307 : CompiledExpression::CompiledExpression() : jitCode(NULL) {
+     110       16307 : }
+     111             : 
+     112       16282 : CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jitCode(NULL) {
+     113       16282 :     ParsedExpression expr = expression.optimize(); // Just in case it wasn't already optimized.
+     114             :     vector<pair<ExpressionTreeNode, int> > temps;
+     115       16282 :     compileExpression(expr.getRootNode(), temps);
+     116             :     int maxArguments = 1;
+     117       80656 :     for (int i = 0; i < (int) operation.size(); i++)
+     118       64374 :         if (operation[i]->getNumArguments() > maxArguments)
+     119       10203 :             maxArguments = operation[i]->getNumArguments();
+     120       16282 :     argValues.resize(maxArguments);
+     121             : #ifdef __PLUMED_HAS_ASMJIT
+     122       16282 :     if(useAsmJit()) generateJitCode();
+     123             : #endif
+     124       32564 : }
+     125             : 
+     126       32677 : CompiledExpression::~CompiledExpression() {
+     127      161996 :     for (int i = 0; i < (int) operation.size(); i++)
+     128      129319 :         if (operation[i] != NULL)
+     129      129319 :             delete operation[i];
+     130       65354 : }
+     131             : 
+     132          88 : CompiledExpression::CompiledExpression(const CompiledExpression& expression) : jitCode(NULL) {
+     133          88 :     *this = expression;
+     134          88 : }
+     135             : 
+     136       16365 : CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expression) {
+     137       16365 :     arguments = expression.arguments;
+     138       16365 :     target = expression.target;
+     139             :     variableIndices = expression.variableIndices;
+     140             :     variableNames = expression.variableNames;
+     141       16365 :     workspace.resize(expression.workspace.size());
+     142       16365 :     argValues.resize(expression.argValues.size());
+     143       16365 :     operation.resize(expression.operation.size());
+     144       81310 :     for (int i = 0; i < (int) operation.size(); i++)
+     145       64945 :         operation[i] = expression.operation[i]->clone();
+     146       16365 :     setVariableLocations(variablePointers);
+     147       16365 :     return *this;
+     148             : }
+     149             : 
+     150      102810 : void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     151      102810 :     if (findTempIndex(node, temps) != -1)
+     152       15593 :         return; // We have already processed a node identical to this one.
+     153             :     
+     154             :     // Process the child nodes.
+     155             :     
+     156             :     vector<int> args;
+     157      173745 :     for (int i = 0; i < node.getChildren().size(); i++) {
+     158       86528 :         compileExpression(node.getChildren()[i], temps);
+     159       86528 :         args.push_back(findTempIndex(node.getChildren()[i], temps));
+     160             :     }
+     161             :     
+     162             :     // Process this node.
+     163             :     
+     164       87217 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     165       22843 :         variableIndices[node.getOperation().getName()] = (int) workspace.size();
+     166       45686 :         variableNames.insert(node.getOperation().getName());
+     167             :     }
+     168             :     else {
+     169       64374 :         int stepIndex = (int) arguments.size();
+     170       64374 :         arguments.push_back(vector<int>());
+     171       64374 :         target.push_back((int) workspace.size());
+     172       64374 :         operation.push_back(node.getOperation().clone());
+     173       64374 :         if (args.size() == 0)
+     174        2276 :             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       86528 :             for (int i = 1; i < args.size(); i++)
+     180       24430 :                 if (args[i] != args[i-1]+1)
+     181             :                     sequential = false;
+     182       62098 :             if (sequential)
+     183       47566 :                 arguments[stepIndex].push_back(args[0]);
+     184             :             else
+     185       14532 :                 arguments[stepIndex] = args;
+     186             :         }
+     187             :     }
+     188       87217 :     temps.push_back(make_pair(node, (int) workspace.size()));
+     189       87217 :     workspace.push_back(0.0);
+     190             : }
+     191             : 
+     192      189338 : int CompiledExpression::findTempIndex(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     193     3631316 :     for (int i = 0; i < (int) temps.size(); i++)
+     194     3544099 :         if (temps[i].first == node)
+     195             :             return i;
+     196             :     return -1;
+     197             : }
+     198             : 
+     199        3294 : const set<string>& CompiledExpression::getVariables() const {
+     200        3294 :     return variableNames;
+     201             : }
+     202             : 
+     203       74596 : double& CompiledExpression::getVariableReference(const string& name) {
+     204             :     map<string, double*>::iterator pointer = variablePointers.find(name);
+     205       74596 :     if (pointer != variablePointers.end())
+     206           0 :         return *pointer->second;
+     207             :     map<string, int>::iterator index = variableIndices.find(name);
+     208       74596 :     if (index == variableIndices.end())
+     209       12418 :         throw Exception("getVariableReference: Unknown variable '"+name+"'");
+     210       68387 :     return workspace[index->second];
+     211             : }
+     212             : 
+     213       16365 : void CompiledExpression::setVariableLocations(map<string, double*>& variableLocations) {
+     214             :   variablePointers = variableLocations;
+     215       16365 :   static const bool asmjit=useAsmJit();
+     216       16365 :   if(asmjit) {
+     217             : #ifdef __PLUMED_HAS_ASMJIT
+     218             :     // Rebuild the JIT code.
+     219             :     
+     220       16041 :     if (workspace.size() > 0)
+     221       16041 :         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       16365 : }
+     234             : 
+     235    68478984 : double CompiledExpression::evaluate() const {
+     236    68478984 :     static const bool asmjit=useAsmJit();
+     237             : #ifdef __PLUMED_HAS_ASMJIT
+     238    68478984 :     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       31999 : void CompiledExpression::generateJitCode() {
+     268       31999 :     CodeHolder code;
+     269             :     auto & runtime(*static_cast<asmjit::JitRuntime*>(runtimeptr.get()));
+     270       31999 :     code.init(runtime.getCodeInfo());
+     271       31999 :     X86Compiler c(&code);
+     272       31999 :     c.addFunc(FuncSignature0<double>());
+     273       31999 :     vector<X86Xmm> workspaceVar(workspace.size());
+     274      205263 :     for (int i = 0; i < (int) workspaceVar.size(); i++)
+     275      173264 :         workspaceVar[i] = c.newXmmSd();
+     276             :     X86Gp argsPointer = c.newIntPtr();
+     277       31999 :     c.mov(argsPointer, imm_ptr(&argValues[0]));
+     278             :     
+     279             :     // Load the arguments into variables.
+     280             :     
+     281       77248 :     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       90498 :         c.mov(variablePointer, imm_ptr(&getVariableReference(index->first)));
+     285       45249 :         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       31999 :     vector<int> operationConstantIndex(operation.size(), -1);
+     291      160014 :     for (int step = 0; step < (int) operation.size(); step++) {
+     292             :         // Find the constant value (if any) used by this operation.
+     293             :         
+     294      128015 :         Operation& op = *operation[step];
+     295             :         double value;
+     296      128015 :         if (op.getId() == Operation::CONSTANT)
+     297        4282 :             value = dynamic_cast<Operation::Constant&>(op).getValue();
+     298      123733 :         else if (op.getId() == Operation::ADD_CONSTANT)
+     299        7112 :             value = dynamic_cast<Operation::AddConstant&>(op).getValue();
+     300      116621 :         else if (op.getId() == Operation::MULTIPLY_CONSTANT)
+     301       27442 :             value = dynamic_cast<Operation::MultiplyConstant&>(op).getValue();
+     302       89179 :         else if (op.getId() == Operation::RECIPROCAL)
+     303        2902 :             value = 1.0;
+     304       86277 :         else if (op.getId() == Operation::STEP)
+     305        1246 :             value = 1.0;
+     306       85031 :         else if (op.getId() == Operation::DELTA)
+     307        1012 :             value = 1.0/0.0;
+     308       84019 :         else if (op.getId() == Operation::NANDELTA)
+     309          12 :             value = std::numeric_limits<double>::quiet_NaN();
+     310             :         else
+     311       84007 :             continue;
+     312             :         
+     313             :         // See if we already have a variable for this constant.
+     314             :         
+     315      500974 :         for (int i = 0; i < (int) constants.size(); i++)
+     316      463368 :             if (value == constants[i]) {
+     317        6402 :                 operationConstantIndex[step] = i;
+     318        6402 :                 break;
+     319             :             }
+     320       44008 :         if (operationConstantIndex[step] == -1) {
+     321       37606 :             operationConstantIndex[step] = constants.size();
+     322       37606 :             constants.push_back(value);
+     323             :         }
+     324             :     }
+     325             :     
+     326             :     // Load constants into variables.
+     327             :     
+     328       31999 :     vector<X86Xmm> constantVar(constants.size());
+     329       31999 :     if (constants.size() > 0) {
+     330             :         X86Gp constantsPointer = c.newIntPtr();
+     331       14780 :         c.mov(constantsPointer, imm_ptr(&constants[0]));
+     332       52386 :         for (int i = 0; i < (int) constants.size(); i++) {
+     333       37606 :             constantVar[i] = c.newXmmSd();
+     334       37606 :             c.movsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0));
+     335             :         }
+     336             :     }
+     337             :     
+     338             :     // Evaluate the operations.
+     339             :     
+     340      160014 :     for (int step = 0; step < (int) operation.size(); step++) {
+     341      128015 :         Operation& op = *operation[step];
+     342      128015 :         vector<int> args = arguments[step];
+     343      128015 :         if (args.size() == 1) {
+     344             :             // One or more sequential arguments.  Fill out the list.
+     345             :             
+     346      118581 :             for (int i = 1; i < op.getNumArguments(); i++)
+     347       19642 :                 args.push_back(args[0]+i);
+     348             :         }
+     349             :         
+     350             :         // Generate instructions to execute this operation.
+     351             :         
+     352      128015 :         switch (op.getId()) {
+     353        4282 :             case Operation::CONSTANT:
+     354        4282 :                 c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     355      127609 :                 break;
+     356             :             case Operation::ADD:
+     357       18886 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     358       18886 :                 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       13188 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     366       13188 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     367             :                 break;
+     368             :             case Operation::DIVIDE:
+     369       11900 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     370       11900 :                 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        3016 :             case Operation::NEGATE:
+     376        3016 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     377        3016 :                 c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     378             :                 break;
+     379             :             case Operation::SQRT:
+     380        2716 :                 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        1458 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sin);
+     390             :                 break;
+     391             :             case Operation::COS:
+     392        2154 :                 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       16625 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     444       16625 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     445             :                 break;
+     446             :             case Operation::CUBE:
+     447         202 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     448         202 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     449         202 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     450             :                 break;
+     451        2902 :             case Operation::RECIPROCAL:
+     452        2902 :                 c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     453        2902 :                 c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     454             :                 break;
+     455             :             case Operation::ADD_CONSTANT:
+     456        7112 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     457        7112 :                 c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     458             :                 break;
+     459             :             case Operation::MULTIPLY_CONSTANT:
+     460       27442 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     461       27442 :                 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         924 :                 for (int i = 0; i < (int) args.size(); i++)
+     476         518 :                     c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]);
+     477             :                 X86Gp fn = c.newIntPtr();
+     478         406 :                 c.mov(fn, imm_ptr((void*) evaluateOperation));
+     479         406 :                 CCFuncCall* call = c.call(fn, FuncSignature2<double, Operation*, double*>());
+     480         406 :                 call->setArg(0, imm_ptr(&op));
+     481         406 :                 call->setArg(1, imm_ptr(&argValues[0]));
+     482         406 :                 call->setRet(0, workspaceVar[target[step]]);
+     483             :         }
+     484             :     }
+     485       31999 :     c.ret(workspaceVar[workspace.size()-1]);
+     486       31999 :     c.endFunc();
+     487       31999 :     c.finalize();
+     488       31999 :     runtime.add(&jitCode, &code);
+     489       31999 : }
+     490             : 
+     491       12420 : void generateSingleArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg, double (*function)(double)) {
+     492             :     X86Gp fn = c.newIntPtr();
+     493       12420 :     c.mov(fn, imm_ptr((void*) function));
+     494       12420 :     CCFuncCall* call = c.call(fn, FuncSignature1<double, double>());
+     495             :     call->setArg(0, arg);
+     496             :     call->setRet(0, dest);
+     497       12420 : }
+     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 000000000..78eb0b3b4 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..856ca0c2c --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..337824fa9 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.gcov.html @@ -0,0 +1,240 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-10-17 16:45:02Functions: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       31999 :     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 000000000..209f11a3a --- /dev/null +++ b/coverage-libs/lepton/Exception.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-10-17 16:45:02Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZNK4PLMD6lepton9Exception4whatEv14
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6258
_ZN4PLMD6lepton9ExceptionD2Ev6258
+
+
+ + + +
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 000000000..6bbb62989 --- /dev/null +++ b/coverage-libs/lepton/Exception.h.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-10-17 16:45:02Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6258
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZN4PLMD6lepton9ExceptionD2Ev6258
_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 000000000..b21a7d926 --- /dev/null +++ b/coverage-libs/lepton/Exception.h.gcov.html @@ -0,0 +1,169 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-10-17 16:45:02Functions: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        6258 :     Exception(const std::string& message) : message(message) {
+      80        6258 :     }
+      81        6258 :     ~Exception() throw() {
+      82        6258 :     }
+      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 000000000..13d4bc101 --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionProgram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionProgram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0520.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..685114ccf --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionProgram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionProgram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0520.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..02a7116ee --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionProgram.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionProgram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0520.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..d6fd29f58 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-10-17 16:45:02Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_31641
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_55531
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_298974
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_507416
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE510080
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE724390
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2090977
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2717759
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev3089498
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_4765880
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_5524554
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_15323798
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev21400499
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv36269866
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv66534719
+
+
+ + + +
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 000000000..a63ffcb70 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-10-17 16:45:02Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_298974
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2090977
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_31641
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_55531
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE510080
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_15323798
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev3089498
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev21400499
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2717759
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_507416
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE724390
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv66534719
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv36269866
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_4765880
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_5524554
+
+
+ + + +
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 000000000..7e5f06d90 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-10-17 16:45:02Functions: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      510080 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const vector<ExpressionTreeNode>& children) : operation(operation), children(children) {
+      74      510080 :     if (operation->getNumArguments() != children.size())
+      75           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      76      510080 : }
+      77             : 
+      78       55531 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child1, const ExpressionTreeNode& child2) : operation(operation) {
+      79       55531 :     children.push_back(child1);
+      80       55531 :     children.push_back(child2);
+      81       55531 :     if (operation->getNumArguments() != children.size())
+      82           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      83       55531 : }
+      84             : 
+      85       31641 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child) : operation(operation) {
+      86       31641 :     children.push_back(child);
+      87       31641 :     if (operation->getNumArguments() != children.size())
+      88           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      89       31641 : }
+      90             : 
+      91     2090977 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation) : operation(operation) {
+      92     2090977 :     if (operation->getNumArguments() != children.size())
+      93           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      94     2090977 : }
+      95             : 
+      96    15323798 : ExpressionTreeNode::ExpressionTreeNode(const ExpressionTreeNode& node) : operation(node.operation == NULL ? NULL : node.operation->clone()), children(node.getChildren()) {
+      97    15323798 : }
+      98             : 
+      99      298974 : ExpressionTreeNode::ExpressionTreeNode(ExpressionTreeNode&& node) : operation(node.operation), children(move(node.children)) {
+     100      298974 :     node.operation = NULL;
+     101             :     node.children.clear();
+     102      298974 : }
+     103             : 
+     104     3089498 : ExpressionTreeNode::ExpressionTreeNode() : operation(NULL) {
+     105     3089498 : }
+     106             : 
+     107    21400499 : ExpressionTreeNode::~ExpressionTreeNode() {
+     108    21400499 :     if (operation != NULL)
+     109    18383536 :         delete operation;
+     110    21400499 : }
+     111             : 
+     112     5524554 : bool ExpressionTreeNode::operator!=(const ExpressionTreeNode& node) const {
+     113     5524554 :     if (node.getOperation() != getOperation())
+     114             :         return true;
+     115     1596364 :     if (getOperation().isSymmetric() && getChildren().size() == 2) {
+     116      570258 :         if (getChildren()[0] == node.getChildren()[0] && getChildren()[1] == node.getChildren()[1])
+     117             :             return false;
+     118      442932 :         if (getChildren()[0] == node.getChildren()[1] && getChildren()[1] == node.getChildren()[0])
+     119             :             return false;
+     120      442932 :         return true;
+     121             :     }
+     122     1479265 :     for (int i = 0; i < (int) getChildren().size(); i++)
+     123      758674 :         if (getChildren()[i] != node.getChildren()[i])
+     124             :             return true;
+     125             :     return false;
+     126             : }
+     127             : 
+     128     4765880 : bool ExpressionTreeNode::operator==(const ExpressionTreeNode& node) const {
+     129     4765880 :     return !(*this != node);
+     130             : }
+     131             : 
+     132      507416 : ExpressionTreeNode& ExpressionTreeNode::operator=(const ExpressionTreeNode& node) {
+     133      507416 :     if (operation != NULL)
+     134       62510 :         delete operation;
+     135      507416 :     operation = node.getOperation().clone();
+     136      507416 :     children = node.getChildren();
+     137      507416 :     return *this;
+     138             : }
+     139             : 
+     140     2717759 : ExpressionTreeNode& ExpressionTreeNode::operator=(ExpressionTreeNode&& node) {
+     141     2717759 :     if (operation != NULL)
+     142       73397 :         delete operation;
+     143     2717759 :     operation = node.operation;
+     144     2717759 :     children = move(node.children);
+     145     2717759 :     node.operation = NULL;
+     146             :     node.children.clear();
+     147     2717759 :     return *this;
+     148             : }
+     149             : 
+     150    36269866 : const Operation& ExpressionTreeNode::getOperation() const {
+     151    36269866 :     return *operation;
+     152             : }
+     153             : 
+     154    66534719 : const vector<ExpressionTreeNode>& ExpressionTreeNode::getChildren() const {
+     155    66534719 :     return children;
+     156             : }
+     157             : 
+     158      724390 : 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      724390 :     int numTags = examples.size();
+     164     1388313 :     for (const ExpressionTreeNode& child : getChildren())
+     165      663923 :         child.assignTags(examples);
+     166      724390 :     if (numTags == examples.size()) {
+     167             :         // All the children matched existing tags, so possibly this node does too.
+     168             :         
+     169    17669919 :         for (int i = 0; i < examples.size(); i++) {
+     170    17502524 :             const ExpressionTreeNode& example = *examples[i];
+     171    17502524 :             bool matches = (getChildren().size() == example.getChildren().size() && getOperation() == example.getOperation());
+     172    19165755 :             for (int j = 0; matches && j < getChildren().size(); j++)
+     173     1663231 :                 if (getChildren()[j].tag != example.getChildren()[j].tag)
+     174             :                     matches = false;
+     175    17502524 :             if (matches) {
+     176      299993 :                 tag = i;
+     177      299993 :                 return;
+     178             :             }
+     179             :         }
+     180             :     }
+     181             :     
+     182             :     // This node does not match any previous node, so assign a new tag.
+     183             :     
+     184      424397 :     tag = examples.size();
+     185      424397 :     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 000000000..19e4a139c --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.func-sort-c.html @@ -0,0 +1,300 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27231586.3 %
Date:2024-10-17 16:45:02Functions: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_traitsIcESaIcEEE122
_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_traitsIcESaIcEEE297
_ZNK4PLMD6lepton9Operation3Log13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE334
_ZNK4PLMD6lepton9Operation4Sqrt13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE385
_ZNK4PLMD6lepton9Operation3Exp13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1296
_ZNK4PLMD6lepton9Operation5Power13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1388
_ZNK4PLMD6lepton9Operation6Negate13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1695
_ZNK4PLMD6lepton9Operation8Subtract13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2098
_ZNK4PLMD6lepton9Operation6Divide13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3184
_ZNK4PLMD6lepton9Operation3Add13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3481
_ZNK4PLMD6lepton9Operation8Constant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5816
_ZNK4PLMD6lepton9Operation8Multiply13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6649
_ZNK4PLMD6lepton9Operation8Variable13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9954
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE34197
+
+
+ + + +
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 000000000..91bcf0c94 --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.func.html @@ -0,0 +1,300 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27231586.3 %
Date:2024-10-17 16:45:02Functions:535793.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE34197
_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_traitsIcESaIcEEE3481
_ZNK4PLMD6lepton9Operation3Cos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE297
_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_traitsIcESaIcEEE122
_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_traitsIcESaIcEEE385
_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_traitsIcESaIcEEE1388
_ZNK4PLMD6lepton9Operation6Custom13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation6Divide13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3184
_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_traitsIcESaIcEEE5816
_ZNK4PLMD6lepton9Operation8Multiply13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6649
_ZNK4PLMD6lepton9Operation8Nandelta13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation8Subtract13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2098
_ZNK4PLMD6lepton9Operation8Variable13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9954
+
+
+ + + +
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 000000000..f2a094f26 --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.gcov.html @@ -0,0 +1,746 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27231586.3 %
Date:2024-10-17 16:45:02Functions: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       34197 : static bool isZero(const ExpressionTreeNode& node) {
+      74       34197 :     if (node.getOperation().getId() != Operation::CONSTANT)
+      75             :         return false;
+      76       23059 :     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        5816 : ExpressionTreeNode Operation::Constant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      88        5816 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+      89             : }
+      90             : 
+      91        9954 : ExpressionTreeNode Operation::Variable::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      92        9954 :     if (variable == name)
+      93        5036 :         return ExpressionTreeNode(new Operation::Constant(1.0));
+      94        4918 :     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        3481 : ExpressionTreeNode Operation::Add::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     120        3481 :     if (isZero(childDerivs[0]))
+     121         803 :         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        2098 : ExpressionTreeNode Operation::Subtract::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     128        2098 :     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         709 :     if (isZero(childDerivs[1]))
+     134         510 :         return childDerivs[0];
+     135         199 :     return ExpressionTreeNode(new Operation::Subtract(), childDerivs[0], childDerivs[1]);
+     136             : }
+     137             : 
+     138        6649 : ExpressionTreeNode Operation::Multiply::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     139        6649 :     if (isZero(childDerivs[0])) {
+     140        4525 :         if (isZero(childDerivs[1]))
+     141        2343 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     142        2182 :         return ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]);
+     143             :     }
+     144        2124 :     if (isZero(childDerivs[1]))
+     145        1147 :         return ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]);
+     146         977 :     return ExpressionTreeNode(new Operation::Add(),
+     147        1954 :                               ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]),
+     148        2931 :                               ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]));
+     149             : }
+     150             : 
+     151        3184 : ExpressionTreeNode Operation::Divide::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     152        3184 :     ExpressionTreeNode subexp;
+     153        3184 :     if (isZero(childDerivs[0])) {
+     154        1275 :         if (isZero(childDerivs[1]))
+     155         230 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     156        1045 :         subexp = ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]));
+     157             :     }
+     158        1909 :     else if (isZero(childDerivs[1]))
+     159        1879 :         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        2954 :     return ExpressionTreeNode(new Operation::Divide(), subexp, ExpressionTreeNode(new Operation::Square(), children[1]));
+     165        3184 : }
+     166             : 
+     167        1388 : ExpressionTreeNode Operation::Power::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     168        1388 :     return ExpressionTreeNode(new Operation::Add(),
+     169        2776 :                               ExpressionTreeNode(new Operation::Multiply(),
+     170        2776 :                                                  ExpressionTreeNode(new Operation::Multiply(),
+     171             :                                                                     children[1],
+     172        2776 :                                                                     ExpressionTreeNode(new Operation::Power(),
+     173        2776 :                                                                                        children[0], ExpressionTreeNode(new Operation::AddConstant(-1.0), children[1]))),
+     174             :                                                  childDerivs[0]),
+     175        2776 :                               ExpressionTreeNode(new Operation::Multiply(),
+     176        2776 :                                                  ExpressionTreeNode(new Operation::Multiply(),
+     177        2776 :                                                                     ExpressionTreeNode(new Operation::Log(), children[0]),
+     178        2776 :                                                                     ExpressionTreeNode(new Operation::Power(), children[0], children[1])),
+     179        2776 :                                                  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         385 : ExpressionTreeNode Operation::Sqrt::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     189         385 :     if (isZero(childDerivs[0]))
+     190          36 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     191         349 :     return ExpressionTreeNode(new Operation::Multiply(),
+     192         698 :                               ExpressionTreeNode(new Operation::MultiplyConstant(0.5),
+     193         698 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
+     194         698 :                                                                     ExpressionTreeNode(new Operation::Sqrt(), children[0]))),
+     195         349 :                               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         122 : ExpressionTreeNode Operation::Sin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     215         122 :     if (isZero(childDerivs[0]))
+     216          30 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     217          92 :     return ExpressionTreeNode(new Operation::Multiply(),
+     218         184 :                               ExpressionTreeNode(new Operation::Cos(), children[0]),
+     219          92 :                               childDerivs[0]);
+     220             : }
+     221             : 
+     222         297 : ExpressionTreeNode Operation::Cos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     223         297 :     if (isZero(childDerivs[0]))
+     224          52 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     225         245 :     return ExpressionTreeNode(new Operation::Multiply(),
+     226         490 :                               ExpressionTreeNode(new Operation::Negate(),
+     227         490 :                                                  ExpressionTreeNode(new Operation::Sin(), children[0])),
+     228         245 :                               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 000000000..2102163d8 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.func-sort-c.html @@ -0,0 +1,1232 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-10-17 16:45:02Functions: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
_ZNK4PLMD6lepton9Operation4Cube7getNameB5cxx11Ev51
_ZNK4PLMD6lepton9Operation3Cot15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation3Tan15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Cosh15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Csch15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Sech15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Sinh15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation3Erf5getIdEv68
_ZNK4PLMD6lepton9Operation3Max15getNumArgumentsEv68
_ZNK4PLMD6lepton9Operation3Min15getNumArgumentsEv68
_ZNK4PLMD6lepton9Operation4Acot5getIdEv68
_ZNK4PLMD6lepton9Operation4Acsc5getIdEv68
_ZNK4PLMD6lepton9Operation4Asec5getIdEv68
_ZNK4PLMD6lepton9Operation4Ceil5getIdEv68
_ZNK4PLMD6lepton9Operation4Erfc5getIdEv68
_ZNK4PLMD6lepton9Operation5Acosh5getIdEv68
_ZNK4PLMD6lepton9Operation5Acoth5getIdEv68
_ZNK4PLMD6lepton9Operation5Acsch5getIdEv68
_ZNK4PLMD6lepton9Operation5Asech5getIdEv68
_ZNK4PLMD6lepton9Operation5Asinh5getIdEv68
_ZNK4PLMD6lepton9Operation5Atanh5getIdEv68
_ZNK4PLMD6lepton9Operation5Floor5getIdEv68
_ZNK4PLMD6lepton9Operation13PowerConstant7getNameB5cxx11Ev69
_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
_ZNK4PLMD6lepton9Operation3Max5getIdEv136
_ZNK4PLMD6lepton9Operation3Min5getIdEv136
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv138
_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
_ZNK4PLMD6lepton9Operation4Cube15getNumArgumentsEv689
_ZNK4PLMD6lepton9Operation4Sqrt7getNameB5cxx11Ev732
_ZNK4PLMD6lepton9Operation10Reciprocal7getNameB5cxx11Ev738
_ZNK4PLMD6lepton9Operation13PowerConstant15getNumArgumentsEv761
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev772
_ZNK4PLMD6lepton9Operation6Divide8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE805
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev846
_ZNK4PLMD6lepton9Operation6Select5getIdEv852
_ZNK4PLMD6lepton9Operation3Abs5getIdEv1092
_ZNK4PLMD6lepton9Operation4Sqrt8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1116
_ZNK4PLMD6lepton9Operation3Abs5cloneEv1152
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1260
_ZNK4PLMD6lepton9Operation5Atan25cloneEv1270
_ZNK4PLMD6lepton9Operation13PowerConstantneERKS1_1277
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev1307
_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
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2811
_ZNK4PLMD6lepton9Operation4Cube5cloneEv2879
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2887
_ZNK4PLMD6lepton9Operation6Divide15isInfixOperatorEv2990
_ZNK4PLMD6lepton9Operation6Divide7getNameB5cxx11Ev2990
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv3292
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev3292
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3439
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3707
_ZNK4PLMD6lepton9Operation5Delta15getNumArgumentsEv3899
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv3978
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv4021
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev4400
_ZNK4PLMD6lepton9Operation4Step15getNumArgumentsEv5084
_ZNK4PLMD6lepton9Operation4Cube5getIdEv5171
_ZNK4PLMD6lepton9Operation3Add15isInfixOperatorEv6111
_ZNK4PLMD6lepton9Operation3Add7getNameB5cxx11Ev6111
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv6286
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev6521
_ZNK4PLMD6lepton9Operation16MultiplyConstant7getNameB5cxx11Ev8277
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv10022
_ZNK4PLMD6lepton9Operation4Sqrt15getNumArgumentsEv10688
_ZNK4PLMD6lepton9Operation10Reciprocal15getNumArgumentsEv10874
_ZNK4PLMD6lepton9Operation3Log15getNumArgumentsEv11847
_ZNK4PLMD6lepton9Operation5Power15getNumArgumentsEv17617
_ZNK4PLMD6lepton9Operation5Delta5cloneEv25363
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv26608
_ZNK4PLMD6lepton9Operation3Exp15getNumArgumentsEv29973
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv32372
_ZNK4PLMD6lepton9Operation10Reciprocal5cloneEv36189
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv37041
_ZNK4PLMD6lepton9Operation10Reciprocal5getIdEv43704
_ZNK4PLMD6lepton9Operation4Step5cloneEv48060
_ZNK4PLMD6lepton9Operation4Sqrt5cloneEv50179
_ZNK4PLMD6lepton9Operation4Sqrt5getIdEv54306
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv60400
_ZNK4PLMD6lepton9Operation6Divide15getNumArgumentsEv61621
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv64926
_ZNK4PLMD6lepton9Operation3Sin5cloneEv75613
_ZNK4PLMD6lepton9Operation3Add15getNumArgumentsEv78970
_ZNK4PLMD6lepton9Operation3Sin5getIdEv87498
_ZNK4PLMD6lepton9Operation16MultiplyConstant15getNumArgumentsEv91090
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev97496
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv98166
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv99323
_ZNK4PLMD6lepton9Operation3Cos5getIdEv113955
_ZNK4PLMD6lepton9Operation3Cos5cloneEv114839
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv125232
_ZNK4PLMD6lepton9Operation5Delta5getIdEv126045
_ZNK4PLMD6lepton9Operation4Step5getIdEv163299
_ZNK4PLMD6lepton9Operation3Log5cloneEv180809
_ZNK4PLMD6lepton9Operation3Log5getIdEv196293
_ZNK4PLMD6lepton9Operation8Constant5getIdEv234511
_ZNK4PLMD6lepton9Operation6Divide5cloneEv240755
_ZNK4PLMD6lepton9Operation6Negate5getIdEv342025
_ZNK4PLMD6lepton9Operation3Exp5cloneEv354615
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv419762
_ZNK4PLMD6lepton9Operation6Negate5cloneEv447000
_ZNK4PLMD6lepton9Operation3Add11isSymmetricEv505332
_ZNK4PLMD6lepton9Operation8Variable5getIdEv508071
_ZNK4PLMD6lepton9Operation5Power5cloneEv560283
_ZNK4PLMD6lepton9Operation6Divide5getIdEv707003
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv790372
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv823719
_ZNK4PLMD6lepton9Operation6Square5cloneEv841065
_ZNK4PLMD6lepton9Operation8VariableneERKS1_895092
_ZNK4PLMD6lepton9Operation16MultiplyConstant5cloneEv930827
_ZNK4PLMD6lepton9Operation16MultiplyConstant5getIdEv941398
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_982782
_ZNK4PLMD6lepton9Operation11isSymmetricEv1026106
_ZNK4PLMD6lepton9Operation3Exp5getIdEv1165561
_ZNK4PLMD6lepton9Operation3Add5cloneEv1369480
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_1376819
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv1557142
_ZNK4PLMD6lepton9Operation5Power5getIdEv1589975
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv1760240
_ZNK4PLMD6lepton9Operation16MultiplyConstantneERKS1_2020871
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2039267
_ZNK4PLMD6lepton9Operation6Square5getIdEv2042212
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2158227
_ZNK4PLMD6lepton9Operation8Variable5cloneEv3190068
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv4227821
_ZNK4PLMD6lepton9Operation3Add5getIdEv4691473
_ZNK4PLMD6lepton9Operation8Constant5cloneEv4813700
_ZNK4PLMD6lepton9OperationeqERKS1_8266744
_ZNK4PLMD6lepton9OperationneERKS1_8514457
_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 000000000..438883f80 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.func.html @@ -0,0 +1,1232 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-10-17 16:45:02Functions:28029096.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9Operation6CustomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionE0
_ZN4PLMD6lepton9Operation6CustomC2ERKS2_i0
_ZN4PLMD6lepton9Operation6CustomD0Ev0
_ZN4PLMD6lepton9Operation6CustomD2Ev0
_ZNK4PLMD6lepton9Operation10Reciprocal15getNumArgumentsEv10874
_ZNK4PLMD6lepton9Operation10Reciprocal5cloneEv36189
_ZNK4PLMD6lepton9Operation10Reciprocal5getIdEv43704
_ZNK4PLMD6lepton9Operation10Reciprocal7getNameB5cxx11Ev738
_ZNK4PLMD6lepton9Operation10Reciprocal8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2122
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv26608
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv790372
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv419762
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev4400
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2887
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_982782
_ZNK4PLMD6lepton9Operation11isSymmetricEv1026106
_ZNK4PLMD6lepton9Operation13PowerConstant15getNumArgumentsEv761
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv138
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv3978
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv4021
_ZNK4PLMD6lepton9Operation13PowerConstant7getNameB5cxx11Ev69
_ZNK4PLMD6lepton9Operation13PowerConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE11045323
_ZNK4PLMD6lepton9Operation13PowerConstantneERKS1_1277
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv98166
_ZNK4PLMD6lepton9Operation16MultiplyConstant15getNumArgumentsEv91090
_ZNK4PLMD6lepton9Operation16MultiplyConstant5cloneEv930827
_ZNK4PLMD6lepton9Operation16MultiplyConstant5getIdEv941398
_ZNK4PLMD6lepton9Operation16MultiplyConstant7getNameB5cxx11Ev8277
_ZNK4PLMD6lepton9Operation16MultiplyConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2634
_ZNK4PLMD6lepton9Operation16MultiplyConstantneERKS1_2020871
_ZNK4PLMD6lepton9Operation3Abs15getNumArgumentsEv200
_ZNK4PLMD6lepton9Operation3Abs5cloneEv1152
_ZNK4PLMD6lepton9Operation3Abs5getIdEv1092
_ZNK4PLMD6lepton9Operation3Abs7getNameB5cxx11Ev18
_ZNK4PLMD6lepton9Operation3Abs8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE507
_ZNK4PLMD6lepton9Operation3Add11isSymmetricEv505332
_ZNK4PLMD6lepton9Operation3Add15getNumArgumentsEv78970
_ZNK4PLMD6lepton9Operation3Add15isInfixOperatorEv6111
_ZNK4PLMD6lepton9Operation3Add5cloneEv1369480
_ZNK4PLMD6lepton9Operation3Add5getIdEv4691473
_ZNK4PLMD6lepton9Operation3Add7getNameB5cxx11Ev6111
_ZNK4PLMD6lepton9Operation3Add8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE424
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv10022
_ZNK4PLMD6lepton9Operation3Cos5cloneEv114839
_ZNK4PLMD6lepton9Operation3Cos5getIdEv113955
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1260
_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
_ZNK4PLMD6lepton9Operation3Log15getNumArgumentsEv11847
_ZNK4PLMD6lepton9Operation3Log5cloneEv180809
_ZNK4PLMD6lepton9Operation3Log5getIdEv196293
_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
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv6286
_ZNK4PLMD6lepton9Operation3Sin5cloneEv75613
_ZNK4PLMD6lepton9Operation3Sin5getIdEv87498
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev846
_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
_ZNK4PLMD6lepton9Operation4Cube15getNumArgumentsEv689
_ZNK4PLMD6lepton9Operation4Cube5cloneEv2879
_ZNK4PLMD6lepton9Operation4Cube5getIdEv5171
_ZNK4PLMD6lepton9Operation4Cube7getNameB5cxx11Ev51
_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
_ZNK4PLMD6lepton9Operation4Sqrt15getNumArgumentsEv10688
_ZNK4PLMD6lepton9Operation4Sqrt5cloneEv50179
_ZNK4PLMD6lepton9Operation4Sqrt5getIdEv54306
_ZNK4PLMD6lepton9Operation4Sqrt7getNameB5cxx11Ev732
_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
_ZNK4PLMD6lepton9Operation5Power15getNumArgumentsEv17617
_ZNK4PLMD6lepton9Operation5Power15isInfixOperatorEv4
_ZNK4PLMD6lepton9Operation5Power5cloneEv560283
_ZNK4PLMD6lepton9Operation5Power5getIdEv1589975
_ZNK4PLMD6lepton9Operation5Power7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation5Power8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE205
_ZNK4PLMD6lepton9Operation6Custom15getNumArgumentsEv0
_ZNK4PLMD6lepton9Operation6Custom5cloneEv0
_ZNK4PLMD6lepton9Operation6Custom5getIdEv0
_ZNK4PLMD6lepton9Operation6Custom7getNameB5cxx11Ev0
_ZNK4PLMD6lepton9Operation6Custom8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE0
_ZNK4PLMD6lepton9Operation6CustomneERKS1_0
_ZNK4PLMD6lepton9Operation6Divide15getNumArgumentsEv61621
_ZNK4PLMD6lepton9Operation6Divide15isInfixOperatorEv2990
_ZNK4PLMD6lepton9Operation6Divide5cloneEv240755
_ZNK4PLMD6lepton9Operation6Divide5getIdEv707003
_ZNK4PLMD6lepton9Operation6Divide7getNameB5cxx11Ev2990
_ZNK4PLMD6lepton9Operation6Divide8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE805
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv32372
_ZNK4PLMD6lepton9Operation6Negate5cloneEv447000
_ZNK4PLMD6lepton9Operation6Negate5getIdEv342025
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev772
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2811
_ZNK4PLMD6lepton9Operation6Select15getNumArgumentsEv424
_ZNK4PLMD6lepton9Operation6Select5cloneEv592
_ZNK4PLMD6lepton9Operation6Select5getIdEv852
_ZNK4PLMD6lepton9Operation6Select7getNameB5cxx11Ev24
_ZNK4PLMD6lepton9Operation6Select8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2444
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv60400
_ZNK4PLMD6lepton9Operation6Square5cloneEv841065
_ZNK4PLMD6lepton9Operation6Square5getIdEv2042212
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev6521
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3707
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2158227
_ZNK4PLMD6lepton9Operation8Constant5cloneEv4813700
_ZNK4PLMD6lepton9Operation8Constant5getIdEv234511
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev1307
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2039267
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_1376819
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv64926
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv125232
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv3292
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv1557142
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv4227821
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev3292
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3439
_ZNK4PLMD6lepton9Operation8Nandelta15getNumArgumentsEv74
_ZNK4PLMD6lepton9Operation8Nandelta5cloneEv138
_ZNK4PLMD6lepton9Operation8Nandelta5getIdEv204
_ZNK4PLMD6lepton9Operation8Nandelta7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation8Nandelta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE304
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv37041
_ZNK4PLMD6lepton9Operation8Subtract15isInfixOperatorEv1359
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv823719
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv1760240
_ZNK4PLMD6lepton9Operation8Subtract7getNameB5cxx11Ev1359
_ZNK4PLMD6lepton9Operation8Subtract8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1324
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv99323
_ZNK4PLMD6lepton9Operation8Variable5cloneEv3190068
_ZNK4PLMD6lepton9Operation8Variable5getIdEv508071
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev97496
_ZNK4PLMD6lepton9Operation8Variable8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE30
_ZNK4PLMD6lepton9Operation8VariableneERKS1_895092
_ZNK4PLMD6lepton9OperationeqERKS1_8266744
_ZNK4PLMD6lepton9OperationneERKS1_8514457
+
+
+ + + +
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 000000000..8379cc562 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.gcov.html @@ -0,0 +1,1378 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-10-17 16:45:02Functions: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       98166 :     virtual bool isInfixOperator() const {
+     139       98166 :         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     1026106 :     virtual bool isSymmetric() const {
+     146     1026106 :         return false;
+     147             :     }
+     148     8514457 :     virtual bool operator!=(const Operation& op) const {
+     149     8514457 :         return op.getId() != getId();
+     150             :     }
+     151     8266744 :     virtual bool operator==(const Operation& op) const {
+     152     8266744 :         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     2069942 :     Constant(double value) : value(value) {
+     213             :     }
+     214        1307 :     std::string getName() const {
+     215        1307 :         std::stringstream name;
+     216        1307 :         name << value;
+     217        1307 :         return name.str();
+     218        1307 :     }
+     219      234511 :     Id getId() const {
+     220      234511 :         return CONSTANT;
+     221             :     }
+     222     2158227 :     int getNumArguments() const {
+     223     2158227 :         return 0;
+     224             :     }
+     225     4813700 :     Operation* clone() const {
+     226     4813700 :         return new Constant(value);
+     227             :     }
+     228     2039267 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     229     2039267 :         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       57307 :         return value;
+     234             :     }
+     235     1376819 :     bool operator!=(const Operation& op) const {
+     236     1376819 :         const Constant* o = dynamic_cast<const Constant*>(&op);
+     237     1376819 :         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     3211103 :     Variable(const std::string& name) : name(name) {
+     246     3211103 :     }
+     247       97496 :     std::string getName() const {
+     248       97496 :         return name;
+     249             :     }
+     250      508071 :     Id getId() const {
+     251      508071 :         return VARIABLE;
+     252             :     }
+     253       99323 :     int getNumArguments() const {
+     254       99323 :         return 0;
+     255             :     }
+     256     3190068 :     Operation* clone() const {
+     257     6380136 :         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      895092 :     bool operator!=(const Operation& op) const {
+     267      895092 :         const Variable* o = dynamic_cast<const Variable*>(&op);
+     268      895092 :         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        9144 :     Add() {
+     327             :     }
+     328        6111 :     std::string getName() const {
+     329        6111 :         return "+";
+     330             :     }
+     331     4691473 :     Id getId() const {
+     332     4691473 :         return ADD;
+     333             :     }
+     334       78970 :     int getNumArguments() const {
+     335       78970 :         return 2;
+     336             :     }
+     337     1369480 :     Operation* clone() const {
+     338     1369480 :         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        6111 :     bool isInfixOperator() const {
+     345        6111 :         return true;
+     346             :     }
+     347      505332 :     bool isSymmetric() const {
+     348      505332 :         return true;
+     349             :     }
+     350             : };
+     351             : 
+     352             : class LEPTON_EXPORT Operation::Subtract : public Operation {
+     353             : public:
+     354        4752 :     Subtract() {
+     355             :     }
+     356        1359 :     std::string getName() const {
+     357        1359 :         return "-";
+     358             :     }
+     359     1760240 :     Id getId() const {
+     360     1760240 :         return SUBTRACT;
+     361             :     }
+     362       37041 :     int getNumArguments() const {
+     363       37041 :         return 2;
+     364             :     }
+     365      823719 :     Operation* clone() const {
+     366      823719 :         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       27283 :     Multiply() {
+     380             :     }
+     381        3292 :     std::string getName() const {
+     382        3292 :         return "*";
+     383             :     }
+     384     4227821 :     Id getId() const {
+     385     4227821 :         return MULTIPLY;
+     386             :     }
+     387      125232 :     int getNumArguments() const {
+     388      125232 :         return 2;
+     389             :     }
+     390     1557142 :     Operation* clone() const {
+     391     1557142 :         return new Multiply();
+     392             :     }
+     393        3439 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     394        3439 :         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        3292 :     bool isInfixOperator() const {
+     398        3292 :         return true;
+     399             :     }
+     400       64926 :     bool isSymmetric() const {
+     401       64926 :         return true;
+     402             :     }
+     403             : };
+     404             : 
+     405             : class LEPTON_EXPORT Operation::Divide : public Operation {
+     406             : public:
+     407        8788 :     Divide() {
+     408             :     }
+     409        2990 :     std::string getName() const {
+     410        2990 :         return "/";
+     411             :     }
+     412      707003 :     Id getId() const {
+     413      707003 :         return DIVIDE;
+     414             :     }
+     415       61621 :     int getNumArguments() const {
+     416       61621 :         return 2;
+     417             :     }
+     418      240755 :     Operation* clone() const {
+     419      240755 :         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        2990 :     bool isInfixOperator() const {
+     426        2990 :         return true;
+     427             :     }
+     428             : };
+     429             : 
+     430             : class LEPTON_EXPORT Operation::Power : public Operation {
+     431             : public:
+     432        5564 :     Power() {
+     433             :     }
+     434           4 :     std::string getName() const {
+     435           4 :         return "^";
+     436             :     }
+     437     1589975 :     Id getId() const {
+     438     1589975 :         return POWER;
+     439             :     }
+     440       17617 :     int getNumArguments() const {
+     441       17617 :         return 2;
+     442             :     }
+     443      560283 :     Operation* clone() const {
+     444      560283 :         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        6058 :     Negate() {
+     458             :     }
+     459         772 :     std::string getName() const {
+     460         772 :         return "-";
+     461             :     }
+     462      342025 :     Id getId() const {
+     463      342025 :         return NEGATE;
+     464             :     }
+     465       32372 :     int getNumArguments() const {
+     466       32372 :         return 1;
+     467             :     }
+     468      447000 :     Operation* clone() const {
+     469      447000 :         return new Negate();
+     470             :     }
+     471        2811 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     472        2811 :         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        1063 :     Sqrt() {
+     480             :     }
+     481         732 :     std::string getName() const {
+     482         732 :         return "sqrt";
+     483             :     }
+     484       54306 :     Id getId() const {
+     485       54306 :         return SQRT;
+     486             :     }
+     487       10688 :     int getNumArguments() const {
+     488       10688 :         return 1;
+     489             :     }
+     490       50179 :     Operation* clone() const {
+     491       50179 :         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        1957 :     Log() {
+     524             :     }
+     525         370 :     std::string getName() const {
+     526         370 :         return "log";
+     527             :     }
+     528      196293 :     Id getId() const {
+     529      196293 :         return LOG;
+     530             :     }
+     531       11847 :     int getNumArguments() const {
+     532       11847 :         return 1;
+     533             :     }
+     534      180809 :     Operation* clone() const {
+     535      180809 :         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         466 :     Sin() {
+     546             :     }
+     547         846 :     std::string getName() const {
+     548         846 :         return "sin";
+     549             :     }
+     550       87498 :     Id getId() const {
+     551       87498 :         return SIN;
+     552             :     }
+     553        6286 :     int getNumArguments() const {
+     554        6286 :         return 1;
+     555             :     }
+     556       75613 :     Operation* clone() const {
+     557       75613 :         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        1503 :     Cos() {
+     568             :     }
+     569        1260 :     std::string getName() const {
+     570        1260 :         return "cos";
+     571             :     }
+     572      113955 :     Id getId() const {
+     573      113955 :         return COS;
+     574             :     }
+     575       10022 :     int getNumArguments() const {
+     576       10022 :         return 1;
+     577             :     }
+     578      114839 :     Operation* clone() const {
+     579      114839 :         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        5378 :     Square() {
+     938             :     }
+     939        6521 :     std::string getName() const {
+     940        6521 :         return "square";
+     941             :     }
+     942     2042212 :     Id getId() const {
+     943     2042212 :         return SQUARE;
+     944             :     }
+     945       60400 :     int getNumArguments() const {
+     946       60400 :         return 1;
+     947             :     }
+     948      841065 :     Operation* clone() const {
+     949      841065 :         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        3024 :     Cube() {
+     960             :     }
+     961          51 :     std::string getName() const {
+     962          51 :         return "cube";
+     963             :     }
+     964        5171 :     Id getId() const {
+     965        5171 :         return CUBE;
+     966             :     }
+     967         689 :     int getNumArguments() const {
+     968         689 :         return 1;
+     969             :     }
+     970        2879 :     Operation* clone() const {
+     971        2879 :         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         870 :     Reciprocal() {
+     982             :     }
+     983         738 :     std::string getName() const {
+     984         738 :         return "recip";
+     985             :     }
+     986       43704 :     Id getId() const {
+     987       43704 :         return RECIPROCAL;
+     988             :     }
+     989       10874 :     int getNumArguments() const {
+     990       10874 :         return 1;
+     991             :     }
+     992       36189 :     Operation* clone() const {
+     993       36189 :         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        3205 :     AddConstant(double value) : value(value) {
+    1004             :     }
+    1005        4400 :     std::string getName() const {
+    1006        4400 :         std::stringstream name;
+    1007        4400 :         name << value << "+";
+    1008        4400 :         return name.str();
+    1009        4400 :     }
+    1010      419762 :     Id getId() const {
+    1011      419762 :         return ADD_CONSTANT;
+    1012             :     }
+    1013       26608 :     int getNumArguments() const {
+    1014       26608 :         return 1;
+    1015             :     }
+    1016      790372 :     Operation* clone() const {
+    1017      790372 :         return new AddConstant(value);
+    1018             :     }
+    1019        2887 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1020        2887 :         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        7112 :         return value;
+    1025             :     }
+    1026      982782 :     bool operator!=(const Operation& op) const {
+    1027      982782 :         const AddConstant* o = dynamic_cast<const AddConstant*>(&op);
+    1028      982782 :         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       12286 :     MultiplyConstant(double value) : value(value) {
+    1037             :     }
+    1038        8277 :     std::string getName() const {
+    1039        8277 :         std::stringstream name;
+    1040        8277 :         name << value << "*";
+    1041        8277 :         return name.str();
+    1042        8277 :     }
+    1043      941398 :     Id getId() const {
+    1044      941398 :         return MULTIPLY_CONSTANT;
+    1045             :     }
+    1046       91090 :     int getNumArguments() const {
+    1047       91090 :         return 1;
+    1048             :     }
+    1049      930827 :     Operation* clone() const {
+    1050      930827 :         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       31836 :         return value;
+    1058             :     }
+    1059     2020871 :     bool operator!=(const Operation& op) const {
+    1060     2020871 :         const MultiplyConstant* o = dynamic_cast<const MultiplyConstant*>(&op);
+    1061     2020871 :         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        4093 :     PowerConstant(double value) : value(value) {
+    1070        4093 :         intValue = (int) value;
+    1071         115 :         isIntPower = (intValue == value);
+    1072             :     }
+    1073          69 :     std::string getName() const {
+    1074          69 :         std::stringstream name;
+    1075          69 :         name << "^" << value;
+    1076          69 :         return name.str();
+    1077          69 :     }
+    1078        4021 :     Id getId() const {
+    1079        4021 :         return POWER_CONSTANT;
+    1080             :     }
+    1081         761 :     int getNumArguments() const {
+    1082         761 :         return 1;
+    1083             :     }
+    1084        3978 :     Operation* clone() const {
+    1085        3978 :         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        1277 :     bool operator!=(const Operation& op) const {
+    1114        1277 :         const PowerConstant* o = dynamic_cast<const PowerConstant*>(&op);
+    1115        1277 :         return (o == NULL || o->value != value);
+    1116             :     }
+    1117         138 :     bool isInfixOperator() const {
+    1118         138 :         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 000000000..4736dd73c --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:23025789.5 %
Date:2024-10-17 16:45:02Functions: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_traitsIcESaIcEEE5055
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE8187
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE8225
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv16282
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv16282
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE29966
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE43274
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE62908
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE178235
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE209757
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE218139
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE238568
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2036706
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2045864
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2067163
+
+
+ + + +
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 000000000..17df6273a --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.func.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:23025789.5 %
Date:2024-10-17 16:45:02Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE238568
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE43274
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE29966
_ZN4PLMD6lepton16ParsedExpression19renameNodeVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEE0
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE178235
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE218139
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE209757
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2036706
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2045864
_ZN4PLMD6lepton16ParsedExpressionC2Ev0
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE8187
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE62908
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2067163
_ZNK4PLMD6lepton16ParsedExpression13createProgramEv0
_ZNK4PLMD6lepton16ParsedExpression13differentiateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5055
_ZNK4PLMD6lepton16ParsedExpression15renameVariablesERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEE0
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv16282
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZNK4PLMD6lepton16ParsedExpression8evaluateEv0
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE8225
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv16282
+
+
+ + + +
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 000000000..41bbc6466 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html @@ -0,0 +1,527 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:23025789.5 %
Date:2024-10-17 16:45:02Functions: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     2045864 : ParsedExpression::ParsedExpression(const ExpressionTreeNode& rootNode) : rootNode(rootNode) {
+      79     2045864 : }
+      80             : 
+      81     2067163 : const ExpressionTreeNode& ParsedExpression::getRootNode() const {
+      82     2067163 :     if (&rootNode.getOperation() == NULL)
+      83           0 :         throw Exception("Illegal call to an initialized ParsedExpression");
+      84     2067163 :     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     2036706 : double ParsedExpression::evaluate(const ExpressionTreeNode& node, const map<string, double>& variables) {
+      96     2036706 :     int numArgs = (int) node.getChildren().size();
+      97     4068505 :     vector<double> args(max(numArgs, 1));
+      98     2044282 :     for (int i = 0; i < numArgs; i++)
+      99        7581 :         args[i] = evaluate(node.getChildren()[i], variables);
+     100     4073380 :     return node.getOperation().evaluate(&args[0], variables);
+     101             : }
+     102             : 
+     103       16282 : ParsedExpression ParsedExpression::optimize() const {
+     104       16282 :     ExpressionTreeNode result = getRootNode();
+     105             :     vector<const ExpressionTreeNode*> examples;
+     106       16282 :     result.assignTags(examples);
+     107             :     map<int, ExpressionTreeNode> nodeCache;
+     108       16282 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     109             :     while (true) {
+     110             :         examples.clear();
+     111       16282 :         result.assignTags(examples);
+     112             :         nodeCache.clear();
+     113       16282 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     114       16282 :         if (simplified == result)
+     115             :             break;
+     116           0 :         result = simplified;
+     117       16282 :     }
+     118       32564 :     return ParsedExpression(result);
+     119       16282 : }
+     120             : 
+     121        8225 : ParsedExpression ParsedExpression::optimize(const map<string, double>& variables) const {
+     122        8225 :     ExpressionTreeNode result = preevaluateVariables(getRootNode(), variables);
+     123             :     vector<const ExpressionTreeNode*> examples;
+     124        8225 :     result.assignTags(examples);
+     125             :     map<int, ExpressionTreeNode> nodeCache;
+     126        8225 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     127             :     while (true) {
+     128             :         examples.clear();
+     129       14623 :         result.assignTags(examples);
+     130             :         nodeCache.clear();
+     131       14623 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     132       14623 :         if (simplified == result)
+     133             :             break;
+     134        6398 :         result = simplified;
+     135       14623 :     }
+     136       16450 :     return ParsedExpression(result);
+     137        8225 : }
+     138             : 
+     139      178235 : ExpressionTreeNode ParsedExpression::preevaluateVariables(const ExpressionTreeNode& node, const map<string, double>& variables) {
+     140      178235 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     141       31088 :         const Operation::Variable& var = dynamic_cast<const Operation::Variable&>(node.getOperation());
+     142       62176 :         map<string, double>::const_iterator iter = variables.find(var.getName());
+     143       31088 :         if (iter == variables.end())
+     144       29692 :             return node;
+     145        1396 :         return ExpressionTreeNode(new Operation::Constant(iter->second));
+     146             :     }
+     147      147147 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     148      317157 :     for (int i = 0; i < (int) children.size(); i++)
+     149      170010 :         children[i] = preevaluateVariables(node.getChildren()[i], variables);
+     150      147147 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     151      147147 : }
+     152             : 
+     153      209757 : ExpressionTreeNode ParsedExpression::precalculateConstantSubexpressions(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     154      209757 :     auto cached = nodeCache.find(node.tag);
+     155      209757 :     if (cached != nodeCache.end())
+     156       40603 :         return cached->second;
+     157      169154 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     158      354404 :     for (int i = 0; i < (int) children.size(); i++)
+     159      185250 :         children[i] = precalculateConstantSubexpressions(node.getChildren()[i], nodeCache);
+     160      169154 :     ExpressionTreeNode result = ExpressionTreeNode(node.getOperation().clone(), children);
+     161      169154 :     if (node.getOperation().getId() == Operation::VARIABLE || node.getOperation().getId() == Operation::CUSTOM) {
+     162       34409 :         nodeCache[node.tag] = result;
+     163       34409 :         return result;
+     164             :     }
+     165      151015 :     for (int i = 0; i < (int) children.size(); i++)
+     166      129967 :         if (children[i].getOperation().getId() != Operation::CONSTANT) {
+     167      113697 :             nodeCache[node.tag] = result;
+     168      113697 :             return result;
+     169             :         }
+     170       21048 :     result = ExpressionTreeNode(new Operation::Constant(evaluate(result, map<string, double>())));
+     171       21048 :     nodeCache[node.tag] = result;
+     172       21048 :     return result;
+     173      169154 : }
+     174             : 
+     175      218139 : ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     176      218139 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     177      456783 :     for (int i = 0; i < (int) children.size(); i++) {
+     178      238644 :         const ExpressionTreeNode& child = node.getChildren()[i];
+     179      238644 :         auto cached = nodeCache.find(child.tag);
+     180      238644 :         if (cached == nodeCache.end()) {
+     181      187234 :             children[i] = substituteSimplerExpression(child, nodeCache);
+     182      187234 :             nodeCache[child.tag] = children[i];
+     183             :         }
+     184             :         else
+     185       51410 :             children[i] = cached->second;
+     186             :     }
+     187             :     
+     188             :     // Collect some info on constant expressions in children
+     189      218139 :     bool first_const = children.size() > 0 && isConstant(children[0]); // is first child constant?
+     190      218139 :     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      218139 :     if (first_const)
+     193       11252 :         first = getConstantValue(children[0]);
+     194      218139 :     if (second_const)
+     195       18714 :         second = getConstantValue(children[1]);
+     196             : 
+     197      218139 :     switch (node.getOperation().getId()) {
+     198       25316 :         case Operation::ADD:
+     199             :         {
+     200       25316 :             if (first_const) {
+     201        1770 :                 if (first == 0.0) { // Add 0
+     202        1673 :                     return children[1];
+     203             :                 } else { // Add a constant
+     204          97 :                     return ExpressionTreeNode(new Operation::AddConstant(first), children[1]);
+     205             :                 }
+     206             :             }
+     207       23546 :             if (second_const) {
+     208        1332 :                 if (second == 0.0) { // Add 0
+     209        1067 :                     return children[0];
+     210             :                 } else { // Add a constant
+     211         265 :                     return ExpressionTreeNode(new Operation::AddConstant(second), children[0]);
+     212             :                 }
+     213             :             }
+     214       22214 :             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       22212 :             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        6347 :             if (children[0] == children[1])
+     223           2 :                 return ExpressionTreeNode(new Operation::Constant(0.0)); // Subtracting anything from itself is 0
+     224        6345 :             if (first_const) {
+     225        1673 :                 if (first == 0.0) // Subtract from 0
+     226          28 :                     return ExpressionTreeNode(new Operation::Negate(), children[1]);
+     227             :             }
+     228        6317 :             if (second_const) {
+     229        1683 :                 if (second == 0.0) { // Subtract 0
+     230         243 :                     return children[0];
+     231             :                 } else { // Subtract a constant
+     232        1440 :                     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       31441 :         case Operation::MULTIPLY:
+     240             :         {   
+     241       31441 :             if ((first_const && first == 0.0) || (second_const && second == 0.0)) // Multiply by 0
+     242        3170 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     243       28271 :             if (first_const && first == 1.0) // Multiply by 1
+     244          30 :                 return children[1];
+     245       28241 :             if (second_const && second == 1.0) // Multiply by 1
+     246        4277 :                 return children[0];
+     247       23964 :             if (first_const) { // Multiply by a constant
+     248        5979 :                 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        5188 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(first), children[1]);
+     251             :             }
+     252       17985 :             if (second_const) { // Multiply by a constant
+     253        1397 :                 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        1105 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(second), children[0]);
+     256             :             }
+     257       16588 :             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       16586 :             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       16584 :             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       16383 :             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       16279 :             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       16269 :             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       16180 :             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       16148 :             if (children[0] == children[1])
+     272         589 :                 return ExpressionTreeNode(new Operation::Square(), children[0]); // x*x = square(x)
+     273       15559 :             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       15557 :             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       13665 :             if (children[0] == children[1])
+     282           2 :                 return ExpressionTreeNode(new Operation::Constant(1.0)); // Dividing anything from itself is 0
+     283       13663 :             if (first_const && first == 0.0) // 0 divided by something
+     284         212 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     285       13451 :             if (first_const && first == 1.0) // 1 divided by something
+     286         232 :                 return ExpressionTreeNode(new Operation::Reciprocal(), children[1]);
+     287       13219 :             if (second_const && second == 1.0) // Divide by 1
+     288          11 :                 return children[0];
+     289       13208 :             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       11196 :             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       11196 :             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       11196 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     299         721 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Divide(), children[0].getChildren()[0], children[1]));
+     300       10475 :             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       10475 :             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        3225 :         case Operation::POWER:
+     307             :         {
+     308        3225 :             if (first_const && first == 0.0) // 0 to any power is 0
+     309           6 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     310        3219 :             if (first_const && first == 1.0) // 1 to any power is 1
+     311           6 :                 return ExpressionTreeNode(new Operation::Constant(1.0));
+     312        3213 :             if (second_const) { // Constant exponent
+     313        3197 :                 if (second == 0.0) // x^0 = 1
+     314           4 :                     return ExpressionTreeNode(new Operation::Constant(1.0));
+     315        3193 :                 if (second == 1.0) // x^1 = x
+     316        1258 :                     return children[0];
+     317        1935 :                 if (second == -1.0) // x^-1 = recip(x)
+     318           0 :                     return ExpressionTreeNode(new Operation::Reciprocal(), children[0]);
+     319        1935 :                 if (second == 2.0) // x^2 = square(x)
+     320        1674 :                     return ExpressionTreeNode(new Operation::Square(), children[0]);
+     321         261 :                 if (second == 3.0) // x^3 = cube(x)
+     322         139 :                     return ExpressionTreeNode(new Operation::Cube(), children[0]);
+     323         122 :                 if (second == 0.5) // x^0.5 = sqrt(x)
+     324           7 :                     return ExpressionTreeNode(new Operation::Sqrt(), children[0]);
+     325             :                 // Constant power
+     326         115 :                 return ExpressionTreeNode(new Operation::PowerConstant(second), children[0]);
+     327             :             }
+     328             :             break;
+     329             :         }
+     330             :         case Operation::NEGATE:
+     331             :         {
+     332        6858 :             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        6232 :             if (first_const) // Negate a constant
+     335         208 :                 return ExpressionTreeNode(new Operation::Constant(-first));
+     336        6024 :             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       24921 :             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       24921 :             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       24921 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Combine a multiply and a negate into a single multiply
+     347        1713 :                 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        2629 :             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       18621 :             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      188407 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     369      218139 : }
+     370             : 
+     371        5055 : ParsedExpression ParsedExpression::differentiate(const string& variable) const {
+     372             :     vector<const ExpressionTreeNode*> examples;
+     373        5055 :     getRootNode().assignTags(examples);
+     374             :     map<int, ExpressionTreeNode> nodeCache;
+     375       10110 :     return differentiate(getRootNode(), variable, nodeCache);
+     376             : }
+     377             : 
+     378       43274 : ExpressionTreeNode ParsedExpression::differentiate(const ExpressionTreeNode& node, const string& variable, map<int, ExpressionTreeNode>& nodeCache) {
+     379       43274 :     auto cached = nodeCache.find(node.tag);
+     380       43274 :     if (cached != nodeCache.end())
+     381        6170 :         return cached->second;
+     382       37104 :     vector<ExpressionTreeNode> childDerivs(node.getChildren().size());
+     383       75323 :     for (int i = 0; i < (int) childDerivs.size(); i++)
+     384       38219 :         childDerivs[i] = differentiate(node.getChildren()[i], variable, nodeCache);
+     385       37104 :     ExpressionTreeNode result = node.getOperation().differentiate(node.getChildren(), childDerivs, variable);
+     386       37104 :     nodeCache[node.tag] = result;
+     387       37104 :     return result;
+     388       37104 : }
+     389             : 
+     390      238568 : bool ParsedExpression::isConstant(const ExpressionTreeNode& node) {
+     391      238568 :     return (node.getOperation().getId() == Operation::CONSTANT);
+     392             : }
+     393             : 
+     394       29966 : double ParsedExpression::getConstantValue(const ExpressionTreeNode& node) {
+     395       29966 :     if (node.getOperation().getId() != Operation::CONSTANT) {
+     396           0 :         throw Exception("getConstantValue called on a non-constant ExpressionNode");
+     397             :     }
+     398       29966 :     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       16282 : CompiledExpression ParsedExpression::createCompiledExpression() const {
+     406       16282 :     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       62908 : ostream& lepton::operator<<(ostream& out, const ExpressionTreeNode& node) {
+     426       62908 :     if (node.getOperation().isInfixOperator() && node.getChildren().size() == 2) {
+     427       41268 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName() << "(" << node.getChildren()[1] << ")";
+     428             :     }
+     429       49152 :     else if (node.getOperation().isInfixOperator() && node.getChildren().size() == 1) {
+     430         138 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName();
+     431             :     }
+     432             :     else {
+     433       49083 :         out << node.getOperation().getName();
+     434       49083 :         if (node.getChildren().size() > 0) {
+     435       27054 :             out << "(";
+     436       54194 :             for (int i = 0; i < (int) node.getChildren().size(); i++) {
+     437       27140 :                 if (i > 0)
+     438          86 :                     out << ", ";
+     439       27140 :                 out << node.getChildren()[i];
+     440             :             }
+     441       27054 :             out << ")";
+     442             :         }
+     443             :     }
+     444       62908 :     return out;
+     445             : }
+     446             : 
+     447        8187 : ostream& lepton::operator<<(ostream& out, const ParsedExpression& exp) {
+     448        8187 :     out << exp.getRootNode();
+     449        8187 :     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 000000000..138b5aa95 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..b712ff5f3 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..0d5175a3d --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.gcov.html @@ -0,0 +1,241 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-10-17 16:45:02Functions: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     2040791 : 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 000000000..333a26272 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27429891.9 %
Date:2024-10-17 16:45:02Functions: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_clEv194
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE5352
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27842
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2016292
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016315
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2016315
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016319
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2060695
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2102406
+
+
+ + + +
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 000000000..fabfb7343 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27429891.9 %
Date:2024-10-17 16:45:02Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2102406
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2060695
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE5352
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27842
_ZN4PLMD6lepton6Parser4trimERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016315
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2016315
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016319
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2016292
_ZZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEEENKUlvE_clEv194
+
+
+ + + +
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 000000000..fccd7ce7e --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.gcov.html @@ -0,0 +1,584 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27429891.9 %
Date:2024-10-17 16:45:02Functions: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     2016292 : 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     2019383 :   };
+     101     2016292 :   return constants;
+     102             : }
+     103             : 
+     104             : }
+     105             : 
+     106             : 
+     107     6554103 : class lepton::ParseToken {
+     108             : public:
+     109             :     enum Type {Number, Operator, Variable, Function, LeftParen, RightParen, Comma, Whitespace};
+     110             : 
+     111     2102406 :     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       70749 :         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     2102406 : ParseToken Parser::getNextToken(const string& expression, int start) {
+     138     2102406 :     char c = expression[start];
+     139     2102406 :     if (c == '(')
+     140       16658 :         return ParseToken("(", ParseToken::LeftParen);
+     141     2094077 :     if (c == ')')
+     142       27362 :         return ParseToken(")", ParseToken::RightParen);
+     143     2080396 :     if (c == ',')
+     144         294 :         return ParseToken(",", ParseToken::Comma);
+     145     2080249 :     if (Operators.find(c) != string::npos)
+     146       30548 :         return ParseToken(string(1, c), ParseToken::Operator);
+     147     2049701 :     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     2049673 :     if (c == '.' || Digits.find(c) != string::npos) {
+     157             :         // A number
+     158             : 
+     159     2023269 :         bool foundDecimal = (c == '.');
+     160             :         bool foundExp = false;
+     161             :         int pos;
+     162    20148014 :         for (pos = start+1; pos < (int) expression.size(); pos++) {
+     163    18139333 :             c = expression[pos];
+     164    18139333 :             if (Digits.find(c) != string::npos)
+     165    16108599 :                 continue;
+     166     2030734 :             if (c == '.' && !foundDecimal) {
+     167             :                 foundDecimal = true;
+     168     2015960 :                 continue;
+     169             :             }
+     170       14774 :             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     4046538 :         return ParseToken(expression.substr(start, pos-start), ParseToken::Number);
+     179             :     }
+     180             : 
+     181             :     // A variable, function, or left parenthesis
+     182             : 
+     183       67154 :     for (int pos = start; pos < (int) expression.size(); pos++) {
+     184       62841 :         c = expression[pos];
+     185       62841 :         if (c == '(')
+     186       10704 :             return ParseToken(expression.substr(start, pos-start+1), ParseToken::Function);
+     187       57489 :         if (Operators.find(c) != string::npos || c == ',' || c == ')' || isspace(c))
+     188       33478 :             return ParseToken(expression.substr(start, pos-start), ParseToken::Variable);
+     189             :     }
+     190        8626 :     return ParseToken(expression.substr(start, string::npos), ParseToken::Variable);
+     191             : }
+     192             : 
+     193     2016319 : vector<ParseToken> Parser::tokenize(const string& expression) {
+     194             :     vector<ParseToken> tokens;
+     195             :     int pos = 0;
+     196     4118725 :     while (pos < (int) expression.size()) {
+     197     2102406 :         ParseToken token = getNextToken(expression, pos);
+     198     2102406 :         if (token.getType() != ParseToken::Whitespace)
+     199     2102378 :             tokens.push_back(token);
+     200     2102406 :         pos += (int) token.getText().size();
+     201             :     }
+     202     2016319 :     return tokens;
+     203           0 : }
+     204             : 
+     205     2016315 : ParsedExpression Parser::parse(const string& expression) {
+     206     4032617 :     return parse(expression, map<string, CustomFunction*>());
+     207             : }
+     208             : 
+     209     2016315 : ParsedExpression Parser::parse(const string& expression, const map<string, CustomFunction*>& customFunctions) {
+     210             :     try {
+     211             :         // First split the expression into subexpressions.
+     212             : 
+     213     2016315 :         string primaryExpression = expression;
+     214             :         vector<string> subexpressions;
+     215             :         while (true) {
+     216             :             string::size_type pos = primaryExpression.find_last_of(';');
+     217     2016319 :             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     2016319 :         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     2016315 :         vector<ParseToken> tokens = tokenize(primaryExpression);
+     245     2016315 :         int pos = 0;
+     246     2016315 :         ExpressionTreeNode result = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0);
+     247     2016315 :         if (pos != tokens.size())
+     248          26 :             throw Exception("unexpected text at end of expression: "+tokens[pos].getText());
+     249     4032604 :         return ParsedExpression(result);
+     250     4032643 :     }
+     251          13 :     catch (Exception& ex) {
+     252          26 :         throw Exception("Parse error in expression \""+expression+"\": "+ex.what());
+     253          13 :     }
+     254             : }
+     255             : 
+     256     2060695 : ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int& pos, const map<string, CustomFunction*>& customFunctions,
+     257             :             const map<string, ExpressionTreeNode>& subexpressionDefs, int precedence) {
+     258     2060695 :     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     2060695 :     ExpressionTreeNode result;
+     265     2060695 :     if (token.getType() == ParseToken::Number) {
+     266             :         double value;
+     267     4046538 :         stringstream(token.getText()) >> value;
+     268     2023269 :         result = ExpressionTreeNode(new Operation::Constant(value));
+     269     2023269 :         pos++;
+     270             :     }
+     271       37426 :     else if (token.getType() == ParseToken::Variable) {
+     272             :         map<string, ExpressionTreeNode>::const_iterator subexp = subexpressionDefs.find(token.getText());
+     273       21039 :         if (subexp == subexpressionDefs.end()) {
+     274       21035 :             Operation* op = new Operation::Variable(token.getText());
+     275       21035 :             result = ExpressionTreeNode(op);
+     276             :         }
+     277             :         else
+     278           4 :             result = subexp->second;
+     279       21039 :         pos++;
+     280             :     }
+     281       16387 :     else if (token.getType() == ParseToken::LeftParen) {
+     282        8329 :         pos++;
+     283        8329 :         result = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0);
+     284        8329 :         if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
+     285           0 :             throw Exception("unbalanced parentheses");
+     286        8329 :         pos++;
+     287             :     }
+     288        8058 :     else if (token.getType() == ParseToken::Function) {
+     289        5352 :         pos++;
+     290             :         vector<ExpressionTreeNode> args;
+     291             :         bool moreArgs;
+     292        5499 :         do {
+     293       10998 :             args.push_back(parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0));
+     294        5499 :             moreArgs = (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Comma);
+     295             :             if (moreArgs)
+     296         147 :                 pos++;
+     297             :         } while (moreArgs);
+     298        5352 :         if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
+     299           0 :             throw Exception("unbalanced parentheses");
+     300        5352 :         pos++;
+     301        5352 :         Operation* op = getFunctionOperation(token.getText(), customFunctions);
+     302             :         try {
+     303        5352 :             result = ExpressionTreeNode(op, args);
+     304             :         }
+     305           0 :         catch (...) {
+     306           0 :             delete op;
+     307           0 :             throw;
+     308           0 :         }
+     309        5352 :     }
+     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     2088537 :     while (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Operator) {
+     321             :         token = tokens[pos];
+     322       38130 :         int opIndex = (int) Operators.find(token.getText());
+     323       38130 :         int opPrecedence = Precedence[opIndex];
+     324       38130 :         if (opPrecedence < precedence)
+     325       10288 :             return result;
+     326       27842 :         pos++;
+     327       27842 :         ExpressionTreeNode arg = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, LeftAssociative[opIndex] ? opPrecedence+1 : opPrecedence);
+     328       27842 :         Operation* op = getOperatorOperation(token.getText());
+     329             :         try {
+     330       27842 :             result = ExpressionTreeNode(op, result, arg);
+     331             :         }
+     332           0 :         catch (...) {
+     333           0 :             delete op;
+     334           0 :             throw;
+     335           0 :         }
+     336       27842 :     }
+     337             :     return result;
+     338           0 : }
+     339             : 
+     340       27842 : Operation* Parser::getOperatorOperation(const std::string& name) {
+     341       27842 :     switch (OperationId[Operators.find(name)]) {
+     342        4880 :         case Operation::ADD:
+     343        4880 :             return new Operation::Add();
+     344        4406 :         case Operation::SUBTRACT:
+     345        4406 :             return new Operation::Subtract();
+     346       10831 :         case Operation::MULTIPLY:
+     347       10831 :             return new Operation::Multiply();
+     348        4937 :         case Operation::DIVIDE:
+     349        4937 :             return new Operation::Divide();
+     350        2788 :         case Operation::POWER:
+     351        2788 :             return new Operation::Power();
+     352           0 :         default:
+     353           0 :             throw Exception("unknown operator");
+     354             :     }
+     355             : }
+     356             : 
+     357        5352 : Operation* Parser::getFunctionOperation(const std::string& name, const map<string, CustomFunction*>& customFunctions) {
+     358             : 
+     359         194 :     const static map<string, Operation::Id> opMap = []() {
+     360             :         map<string, Operation::Id> opMap;
+     361         194 :         opMap["sqrt"] = Operation::SQRT;
+     362         194 :         opMap["exp"] = Operation::EXP;
+     363         194 :         opMap["log"] = Operation::LOG;
+     364         194 :         opMap["sin"] = Operation::SIN;
+     365         194 :         opMap["cos"] = Operation::COS;
+     366         194 :         opMap["sec"] = Operation::SEC;
+     367         194 :         opMap["csc"] = Operation::CSC;
+     368         194 :         opMap["tan"] = Operation::TAN;
+     369         194 :         opMap["cot"] = Operation::COT;
+     370         194 :         opMap["asin"] = Operation::ASIN;
+     371         194 :         opMap["acos"] = Operation::ACOS;
+     372         194 :         opMap["atan"] = Operation::ATAN;
+     373         194 :         opMap["atan2"] = Operation::ATAN2;
+     374         194 :         opMap["sinh"] = Operation::SINH;
+     375         194 :         opMap["cosh"] = Operation::COSH;
+     376         194 :         opMap["tanh"] = Operation::TANH;
+     377         194 :         opMap["erf"] = Operation::ERF;
+     378         194 :         opMap["erfc"] = Operation::ERFC;
+     379         194 :         opMap["step"] = Operation::STEP;
+     380         194 :         opMap["delta"] = Operation::DELTA;
+     381         194 :         opMap["nandelta"] = Operation::NANDELTA;
+     382         194 :         opMap["square"] = Operation::SQUARE;
+     383         194 :         opMap["cube"] = Operation::CUBE;
+     384         194 :         opMap["recip"] = Operation::RECIPROCAL;
+     385         194 :         opMap["min"] = Operation::MIN;
+     386         194 :         opMap["max"] = Operation::MAX;
+     387         194 :         opMap["abs"] = Operation::ABS;
+     388         194 :         opMap["floor"] = Operation::FLOOR;
+     389         194 :         opMap["ceil"] = Operation::CEIL;
+     390         194 :         opMap["select"] = Operation::SELECT;
+     391         194 :         opMap["acot"] = Operation::ACOT;
+     392         194 :         opMap["asec"] = Operation::ASEC;
+     393         194 :         opMap["acsc"] = Operation::ACSC;
+     394         194 :         opMap["coth"] = Operation::COTH;
+     395         194 :         opMap["sech"] = Operation::SECH;
+     396         194 :         opMap["csch"] = Operation::CSCH;
+     397         194 :         opMap["asinh"] = Operation::ASINH;
+     398         194 :         opMap["acosh"] = Operation::ACOSH;
+     399         194 :         opMap["atanh"] = Operation::ATANH;
+     400         194 :         opMap["acoth"] = Operation::ACOTH;
+     401         194 :         opMap["asech"] = Operation::ASECH;
+     402         194 :         opMap["acsch"] = Operation::ACSCH;
+     403         194 :         opMap["atan2"] = Operation::ATAN2;
+     404         194 :         return opMap;
+     405        5352 :     }();
+     406        5352 :     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        5352 :     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        5352 :     if (iter == opMap.end())
+     418           0 :         throw Exception("unknown function: "+trimmed);
+     419        5352 :     switch (iter->second) {
+     420         684 :         case Operation::SQRT:
+     421         684 :             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         221 :         case Operation::SIN:
+     427         221 :             return new Operation::Sin();
+     428        1411 :         case Operation::COS:
+     429        1411 :             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 000000000..6e61be7b1 --- /dev/null +++ b/coverage-libs/lepton/index-sort-f.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1609178989.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..33e36cb25 --- /dev/null +++ b/coverage-libs/lepton/index-sort-l.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1609178989.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..4e6bdad75 --- /dev/null +++ b/coverage-libs/lepton/index.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1609178989.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..b04942a97 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.func-sort-c.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-10-17 16:45:02Functions: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 000000000..92d31fe7f --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.func.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-10-17 16:45:02Functions: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 000000000..fb46f0a65 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.gcov.html @@ -0,0 +1,2089 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-10-17 16:45:02Functions: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 000000000..dc8e58d67 --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-10-17 16:45:02Functions: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_initEv10602
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
+
+
+ + + +
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 000000000..b12bb310c --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-10-17 16:45:02Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_crdplugin_finiEv0
_ZN4PLMD7molfile22molfile_crdplugin_initEv10602
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
_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 000000000..700b1712d --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.gcov.html @@ -0,0 +1,338 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-10-17 16:45:02Functions: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       10602 : VMDPLUGIN_API int VMDPLUGIN_init(void) { 
+     226             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     227       10602 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     228       10602 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     229       10602 :   plugin.name = "crd";
+     230       10602 :   plugin.prettyname = "AMBER Coordinates";
+     231       10602 :   plugin.author = "Justin Gullingsrud, John Stone";
+     232             :   plugin.majorv = 0;
+     233       10602 :   plugin.minorv = 9;
+     234       10602 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     235       10602 :   plugin.filename_extension = "mdcrd,crd";
+     236       10602 :   plugin.open_file_read = open_crd_read;
+     237       10602 :   plugin.read_next_timestep = read_crd_timestep;
+     238       10602 :   plugin.close_file_read = close_crd_read;
+     239       10602 :   plugin.open_file_write = open_crd_write;
+     240       10602 :   plugin.write_timestep = write_crd_timestep;
+     241       10602 :   plugin.close_file_write = close_crd_write;
+     242             : 
+     243             :   memcpy(&crdboxplugin, &plugin, sizeof(molfile_plugin_t));
+     244       10602 :   crdboxplugin.name = "crdbox";
+     245       10602 :   crdboxplugin.prettyname = "AMBER Coordinates with Periodic Box";
+     246             : 
+     247       10602 :   return VMDPLUGIN_SUCCESS; 
+     248             : }
+     249             : 
+     250       10602 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     251       10602 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     252       10602 :   (*cb)(v, (vmdplugin_t *)&crdboxplugin);
+     253       10602 :   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 000000000..c2f50842d --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-10-17 16:45:02Functions: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_initEv10602
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
+
+
+ + + +
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 000000000..86d78173b --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-10-17 16:45:02Functions:101952.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_dcdplugin_finiEv0
_ZN4PLMD7molfile22molfile_dcdplugin_initEv10602
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
_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 000000000..7fe16dff8 --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.gcov.html @@ -0,0 +1,1393 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-10-17 16:45:02Functions: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       10602 : VMDPLUGIN_API int VMDPLUGIN_init() {
+    1218             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+    1219       10602 :   plugin.abiversion = vmdplugin_ABIVERSION;
+    1220       10602 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+    1221       10602 :   plugin.name = "dcd";
+    1222       10602 :   plugin.prettyname = "CHARMM,NAMD,XPLOR DCD Trajectory";
+    1223       10602 :   plugin.author = "Axel Kohlmeyer, Justin Gullingsrud, John Stone";
+    1224       10602 :   plugin.majorv = 1;
+    1225       10602 :   plugin.minorv = 18;
+    1226       10602 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+    1227       10602 :   plugin.filename_extension = "dcd";
+    1228       10602 :   plugin.open_file_read = open_dcd_read;
+    1229       10602 :   plugin.read_next_timestep = read_next_timestep;
+    1230       10602 :   plugin.close_file_read = close_file_read;
+    1231       10602 :   plugin.open_file_write = open_dcd_write;
+    1232       10602 :   plugin.write_timestep = write_timestep;
+    1233       10602 :   plugin.close_file_write = close_file_write;
+    1234       10602 :   return VMDPLUGIN_SUCCESS;
+    1235             : }
+    1236             : 
+    1237       10602 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+    1238       10602 :   (*cb)(v, (vmdplugin_t *)&plugin);
+    1239       10602 :   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 000000000..3eb70bf16 --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/endianswap.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - endianswap.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:64812.5 %
Date:2024-10-17 16:45:02Functions: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 000000000..c9718f9ad --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/endianswap.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - endianswap.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:64812.5 %
Date:2024-10-17 16:45:02Functions: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 000000000..728f50fb4 --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.gcov.html @@ -0,0 +1,293 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/endianswap.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - endianswap.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:64812.5 %
Date:2024-10-17 16:45:02Functions: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 000000000..d3371e5f7 --- /dev/null +++ b/coverage-libs/molfile/fastio.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/fastio.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - fastio.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:193455.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..610978706 --- /dev/null +++ b/coverage-libs/molfile/fastio.h.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/fastio.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - fastio.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:193455.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..292300232 --- /dev/null +++ b/coverage-libs/molfile/fastio.h.gcov.html @@ -0,0 +1,759 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/fastio.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - fastio.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:193455.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..ec1205def --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.func-sort-c.html @@ -0,0 +1,164 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/gromacsplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - gromacsplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10736029.7 %
Date:2024-10-17 16:45:02Functions: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_initEv10602
_ZN4PLMD7molfile30molfile_gromacsplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
_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 000000000..211722d4f --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.func.html @@ -0,0 +1,164 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/gromacsplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - gromacsplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10736029.7 %
Date:2024-10-17 16:45:02Functions:52321.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile26molfile_gromacsplugin_finiEv0
_ZN4PLMD7molfile26molfile_gromacsplugin_initEv10602
_ZN4PLMD7molfile30molfile_gromacsplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
_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 000000000..b81bdbb20 --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.gcov.html @@ -0,0 +1,936 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/gromacsplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - gromacsplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10736029.7 %
Date:2024-10-17 16:45:02Functions: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       10602 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     684             :   // GRO plugin init
+     685             :   memset(&gro_plugin, 0, sizeof(molfile_plugin_t));
+     686       10602 :   gro_plugin.abiversion = vmdplugin_ABIVERSION;
+     687       10602 :   gro_plugin.type = MOLFILE_PLUGIN_TYPE;
+     688       10602 :   gro_plugin.name = "gro";
+     689       10602 :   gro_plugin.prettyname = "Gromacs GRO";
+     690       10602 :   gro_plugin.author = "David Norris, Justin Gullingsrud, Magnus Lundborg";
+     691       10602 :   gro_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     692       10602 :   gro_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     693             :   gro_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     694       10602 :   gro_plugin.filename_extension = "gro";
+     695       10602 :   gro_plugin.open_file_read = open_gro_read;
+     696       10602 :   gro_plugin.read_structure = read_gro_structure;
+     697       10602 :   gro_plugin.read_next_timestep = read_gro_timestep;
+     698       10602 :   gro_plugin.close_file_read = close_gro_read;
+     699       10602 :   gro_plugin.open_file_write = open_gro_write;
+     700       10602 :   gro_plugin.write_structure = write_gro_structure;
+     701       10602 :   gro_plugin.write_timestep = write_gro_timestep;
+     702       10602 :   gro_plugin.close_file_write = close_gro_write;
+     703       10602 :   gro_plugin.read_molecule_metadata = read_gro_molecule_metadata;
+     704             : 
+     705             :   // G96 plugin init
+     706             :   memset(&g96_plugin, 0, sizeof(molfile_plugin_t));
+     707       10602 :   g96_plugin.abiversion = vmdplugin_ABIVERSION;
+     708       10602 :   g96_plugin.type = MOLFILE_PLUGIN_TYPE;
+     709       10602 :   g96_plugin.name = "g96";
+     710       10602 :   g96_plugin.prettyname = "Gromacs g96";
+     711       10602 :   g96_plugin.author = "David Norris, Justin Gullingsrud";
+     712       10602 :   g96_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     713       10602 :   g96_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     714             :   g96_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     715       10602 :   g96_plugin.filename_extension = "g96";
+     716       10602 :   g96_plugin.open_file_read = open_g96_read;
+     717       10602 :   g96_plugin.read_structure = read_g96_structure;
+     718       10602 :   g96_plugin.read_next_timestep = read_g96_timestep;
+     719       10602 :   g96_plugin.close_file_read = close_g96_read;
+     720             : 
+     721             :   // TRR plugin
+     722             :   memset(&trr_plugin, 0, sizeof(molfile_plugin_t));
+     723       10602 :   trr_plugin.abiversion = vmdplugin_ABIVERSION;
+     724       10602 :   trr_plugin.type = MOLFILE_PLUGIN_TYPE;
+     725       10602 :   trr_plugin.name = "trr";
+     726       10602 :   trr_plugin.prettyname = "Gromacs TRR Trajectory";
+     727       10602 :   trr_plugin.author = "David Norris, Justin Gullingsrud, Axel Kohlmeyer";
+     728       10602 :   trr_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     729       10602 :   trr_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     730             :   trr_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     731       10602 :   trr_plugin.filename_extension = "trr";
+     732       10602 :   trr_plugin.open_file_read = open_trr_read;
+     733       10602 :   trr_plugin.read_next_timestep = read_trr_timestep;
+     734       10602 :   trr_plugin.close_file_read = close_trr_read;
+     735       10602 :   trr_plugin.open_file_write = open_trr_write;
+     736       10602 :   trr_plugin.write_timestep = write_trr_timestep;
+     737       10602 :   trr_plugin.close_file_write = close_trr_write;
+     738             : 
+     739             :   // XTC plugin 
+     740             :   memset(&xtc_plugin, 0, sizeof(molfile_plugin_t));
+     741       10602 :   xtc_plugin.abiversion = vmdplugin_ABIVERSION;
+     742       10602 :   xtc_plugin.type = MOLFILE_PLUGIN_TYPE;
+     743       10602 :   xtc_plugin.name = "xtc";
+     744       10602 :   xtc_plugin.prettyname = "Gromacs XTC Compressed Trajectory";
+     745       10602 :   xtc_plugin.author = "David Norris, Justin Gullingsrud";
+     746       10602 :   xtc_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     747       10602 :   xtc_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     748             :   xtc_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     749       10602 :   xtc_plugin.filename_extension = "xtc";
+     750       10602 :   xtc_plugin.open_file_read = open_trr_read;
+     751       10602 :   xtc_plugin.read_next_timestep = read_trr_timestep;
+     752       10602 :   xtc_plugin.close_file_read = close_trr_read;
+     753             : 
+     754             :   // TRJ plugin
+     755             :   memset(&trj_plugin, 0, sizeof(molfile_plugin_t));
+     756       10602 :   trj_plugin.abiversion = vmdplugin_ABIVERSION;
+     757       10602 :   trj_plugin.type = MOLFILE_PLUGIN_TYPE;
+     758       10602 :   trj_plugin.name = "trj";
+     759       10602 :   trj_plugin.prettyname = "Gromacs TRJ Trajectory";
+     760       10602 :   trj_plugin.author = "David Norris, Justin Gullingsrud";
+     761       10602 :   trj_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     762       10602 :   trj_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     763             :   trj_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     764       10602 :   trj_plugin.filename_extension = "trj";
+     765       10602 :   trj_plugin.open_file_read = open_trr_read;
+     766       10602 :   trj_plugin.read_next_timestep = read_trr_timestep;
+     767       10602 :   trj_plugin.close_file_read = close_trr_read;
+     768             : 
+     769       10602 :   return 0;
+     770             : }
+     771             : 
+     772       10602 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     773       10602 :   (*cb)(v, (vmdplugin_t *)&gro_plugin);
+     774       10602 :   (*cb)(v, (vmdplugin_t *)&g96_plugin);
+     775       10602 :   (*cb)(v, (vmdplugin_t *)&trr_plugin);
+     776       10602 :   (*cb)(v, (vmdplugin_t *)&trj_plugin);
+     777       10602 :   (*cb)(v, (vmdplugin_t *)&xtc_plugin);
+     778       10602 :   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 000000000..d54199d26 --- /dev/null +++ b/coverage-libs/molfile/index-sort-f.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:861210440.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..163e48fba --- /dev/null +++ b/coverage-libs/molfile/index-sort-l.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:861210440.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..ed7228052 --- /dev/null +++ b/coverage-libs/molfile/index.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:861210440.9 %
Date:2024-10-17 16:45:02Functions: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 000000000..ffcf81e35 --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/pdbplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - pdbplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8721141.2 %
Date:2024-10-17 16:45:02Functions: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_Pi57
_ZN4PLMD7molfileL14close_pdb_readEPv57
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE130
_ZN4PLMD7molfile22molfile_pdbplugin_initEv10602
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
+
+
+ + + +
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 000000000..c3a06f9ec --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/pdbplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - pdbplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8721141.2 %
Date:2024-10-17 16:45:02Functions:51435.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_pdbplugin_finiEv0
_ZN4PLMD7molfile22molfile_pdbplugin_initEv10602
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10602
_ZN4PLMD7molfileL10read_bondsEPvPiPS2_S3_PPfS3_S2_PPPc0
_ZN4PLMD7molfileL12write_cryst1EP8_IO_FILEPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL13open_pdb_readEPKcS2_Pi57
_ZN4PLMD7molfileL14close_pdb_readEPv57
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15open_file_writeEPKcS2_i0
_ZN4PLMD7molfileL15write_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE130
_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 000000000..a4d6aca98 --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.gcov.html @@ -0,0 +1,724 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/pdbplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - pdbplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8721141.2 %
Date:2024-10-17 16:45:02Functions: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          57 : 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          57 :   fd = fopen(filepath, "r");
+      95          57 :   if (!fd) 
+      96             :     return NULL;
+      97          57 :   pdb = (pdbdata *)malloc(sizeof(pdbdata));
+      98          57 :   pdb->fd = fd;
+      99          57 :   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          57 :   *natoms=0;
+     106             :   nconect=0;
+     107             :   do {
+     108      112709 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     109      112709 :     if (indx == PDB_ATOM) {
+     110      111941 :       *natoms += 1;
+     111         768 :     } else if (indx == PDB_CONECT) {
+     112           0 :       nconect++;
+     113         768 :     } 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         768 :     } else if (indx == PDB_REMARK || indx == PDB_CONECT || indx == PDB_UNKNOWN) {
+     118         676 :       int len=strlen(pdbstr);
+     119         676 :       int newlen = len + pdb->meta->remarklen;
+     120             : 
+     121         676 :       char *newstr=(char*)realloc(pdb->meta->remarks, newlen + 1);
+     122         676 :       if (newstr != NULL) {
+     123         676 :         pdb->meta->remarks = newstr;
+     124         676 :         pdb->meta->remarks[pdb->meta->remarklen] = '\0';
+     125         676 :         memcpy(pdb->meta->remarks + pdb->meta->remarklen, pdbstr, len);
+     126         676 :         pdb->meta->remarks[newlen] = '\0';
+     127         676 :         pdb->meta->remarklen = newlen;
+     128             :       }
+     129             :     }
+     130             :  
+     131      112709 :   } while (indx != PDB_END && indx != PDB_EOF);
+     132             : 
+     133             :   /* If no atoms were found, this is probably not a PDB file! */
+     134          57 :   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          57 :   rewind(pdb->fd); /* if ok, rewind file and prepare to parse it for real */
+     145          57 :   pdb->natoms = *natoms;
+     146          57 :   pdb->nconect = nconect;
+     147          57 :   pdb->nbonds = 0;
+     148          57 :   pdb->maxbnum = 0;
+     149          57 :   pdb->from = NULL;
+     150          57 :   pdb->to = NULL;
+     151          57 :   pdb->idxmap = NULL;
+     152          57 :   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          57 :   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         130 : 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         130 :   if (pdb->natoms == 0) 
+     286             :     return MOLFILE_ERROR; /* EOF */
+     287         130 :   if (ts) {
+     288         130 :     x = ts->coords;
+     289         130 :     y = x+1;
+     290         130 :     z = x+2;
+     291             :   } else {
+     292             :     x = y = z = 0;
+     293             :   } 
+     294             :   i = 0;
+     295             :   do {
+     296      127148 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     297      127148 :     if((indx == PDB_END || indx == PDB_EOF) && (i < pdb->natoms)) {
+     298             :       return MOLFILE_ERROR;
+     299      127091 :     } else if(indx == PDB_ATOM) {
+     300      123714 :       if(i++ >= pdb->natoms) {
+     301             :         break;      
+     302             :       }
+     303             :       /* just get the coordinates, and store them */
+     304      123714 :       if (ts) {
+     305      123714 :         get_pdb_coordinates(pdbstr, x, y, z, &occup, &bfac);
+     306      123714 :         x += 3;
+     307      123714 :         y += 3;
+     308      123714 :         z += 3;
+     309             :       } 
+     310        3377 :     } 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      127091 :   } while(!(indx == PDB_END || indx == PDB_EOF));
+     317             : 
+     318             :   return MOLFILE_SUCCESS;
+     319             : }
+     320             : 
+     321          57 : static void close_pdb_read(void *v) { 
+     322             :   pdbdata *pdb = (pdbdata *)v;
+     323          57 :   if (pdb->fd != NULL)
+     324          57 :     fclose(pdb->fd);
+     325          57 :   if (pdb->idxmap != NULL)
+     326           0 :     free(pdb->idxmap);
+     327          57 :   if (pdb->meta->remarks != NULL)
+     328          46 :     free(pdb->meta->remarks);
+     329          57 :   if (pdb->meta != NULL) 
+     330          57 :     free(pdb->meta);
+     331          57 :   free(pdb);
+     332          57 : }
+     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       10602 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     613             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     614       10602 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     615       10602 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     616       10602 :   plugin.name = "pdb";
+     617       10602 :   plugin.prettyname = "PDB";
+     618       10602 :   plugin.author = "Justin Gullingsrud, John Stone";
+     619       10602 :   plugin.majorv = 1;
+     620       10602 :   plugin.minorv = 16;
+     621       10602 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     622       10602 :   plugin.filename_extension = "pdb,ent";
+     623       10602 :   plugin.open_file_read = open_pdb_read;
+     624       10602 :   plugin.read_structure = read_pdb_structure;
+     625       10602 :   plugin.read_bonds = read_bonds;
+     626       10602 :   plugin.read_next_timestep = read_next_timestep;
+     627       10602 :   plugin.close_file_read = close_pdb_read;
+     628       10602 :   plugin.open_file_write = open_file_write;
+     629       10602 :   plugin.write_structure = write_structure;
+     630       10602 :   plugin.write_timestep = write_timestep;
+     631       10602 :   plugin.close_file_write = close_file_write;
+     632       10602 :   plugin.read_molecule_metadata = read_molecule_metadata;
+     633       10602 :   return VMDPLUGIN_SUCCESS;
+     634             : }
+     635             : 
+     636       10602 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     637       10602 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     638       10602 :   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 000000000..df429ae7e --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/periodic_table.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - periodic_table.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0200.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..1cfc992dd --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/periodic_table.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - periodic_table.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0200.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..3f505b852 --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.gcov.html @@ -0,0 +1,324 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/periodic_table.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - periodic_table.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0200.0 %
Date:2024-10-17 16:45:02Functions: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 000000000..a5b1d1977 --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/readpdb.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - readpdb.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4413532.6 %
Date:2024-10-17 16:45:02Functions: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_123714
_ZN4PLMD7molfileL15read_pdb_recordEP8_IO_FILEPc239857
+
+
+ + + +
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 000000000..4a4858d0c --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/readpdb.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - readpdb.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4413532.6 %
Date:2024-10-17 16:45:02Functions: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_FILEPc239857
_ZN4PLMD7molfileL19get_pdb_coordinatesEPKcPfS3_S3_S3_S3_123714
_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 000000000..5275ac3dc --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.gcov.html @@ -0,0 +1,523 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/readpdb.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - readpdb.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4413532.6 %
Date:2024-10-17 16:45:02Functions: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      239857 : 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      239857 :   if (inbuf != fgets(inbuf, PDB_RECORD_LENGTH + 2, f)) {
+      93          57 :     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      239800 :     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        4145 :     } else if (!strncmp(inbuf, "CONECT", 6)) {
+     113             :       recType = PDB_CONECT;
+     114        4145 :     } else if (!strncmp(inbuf, "REMARK", 6)) {
+     115             :       recType = PDB_REMARK;
+     116        4032 :     } else if (!strncmp(inbuf, "CRYST1", 6)) {
+     117             :       recType = PDB_CRYST1;
+     118        3960 :     } else if (!strncmp(inbuf, "HEADER", 6)) {
+     119             :       recType = PDB_HEADER;
+     120        3960 :     } 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      239857 :   ch = fgetc(f);
+     146      239857 :   if (ch != '\r')
+     147      239857 :     ungetc(ch, f);
+     148             :   
+     149      239857 :   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      123714 : 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      123714 :   if (x != NULL) {
+     185      123714 :     strncpy(numstr, record + 30, 8);
+     186      123714 :     *x = (float) atof(numstr);
+     187             :   }
+     188             : 
+     189      123714 :   if (y != NULL) {
+     190      123714 :     strncpy(numstr+10, record + 38, 8);
+     191      123714 :     *y = (float) atof(numstr+10);
+     192             :   }
+     193             : 
+     194      123714 :   if (z != NULL) {
+     195      123714 :     strncpy(numstr+20, record + 46, 8);
+     196      123714 :     *z = (float) atof(numstr+20);
+     197             :   }
+     198             : 
+     199      123714 :   if (occup != NULL) {
+     200      123714 :     strncpy(numstr+30, record + 54, 6);
+     201      123714 :     *occup = (float) atof(numstr+30);
+     202             :   }
+     203             : 
+     204      123714 :   if (beta != NULL) {
+     205      123714 :     strncpy(numstr+40, record + 60, 6);
+     206      123714 :     *beta = (float) atof(numstr+40);
+     207             :   }
+     208      123714 : }
+     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 000000000..076f7a9a7 --- /dev/null +++ b/coverage-libs/xdrfile/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:563116648.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..d3e07b4cd --- /dev/null +++ b/coverage-libs/xdrfile/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:563116648.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..ee8eba19b --- /dev/null +++ b/coverage-libs/xdrfile/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:563116648.3 %
Date:2024-10-17 16:45:02Functions: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 000000000..b6fdd37d6 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html @@ -0,0 +1,396 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:43294345.8 %
Date:2024-10-17 16:45:02Functions: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
_ZN4PLMD7xdrfile19xdrfile_read_opaqueEPciPNS0_7XDRFILEE28
_ZN4PLMD7xdrfile30xdrfile_decompress_coord_floatEPfPiS1_PNS0_7XDRFILEE28
_ZN4PLMD7xdrfile12xdrfile_openEPKcS2_32
_ZN4PLMD7xdrfile13xdrfile_closeEPNS0_7XDRFILEE32
_ZN4PLMD7xdrfileL15xdrstdio_createEPNS0_3XDREP8_IO_FILENS0_6xdr_opE32
_ZN4PLMD7xdrfileL16xdrstdio_destroyEPNS0_3XDRE32
_ZN4PLMD7xdrfile20xdrfile_write_stringEPcPNS0_7XDRFILEE48
_ZN4PLMD7xdrfile20xdrfile_write_opaqueEPciPNS0_7XDRFILEE60
_ZN4PLMD7xdrfile28xdrfile_compress_coord_floatEPfifPNS0_7XDRFILEE72
_ZN4PLMD7xdrfile19xdrfile_read_stringEPciPNS0_7XDRFILEE75
_ZN4PLMD7xdrfileL10sizeofintsEiPj88
_ZN4PLMD7xdrfileL10xdr_stringEPNS0_3XDREPPcj123
_ZN4PLMD7xdrfileL9xdr_u_intEPNS0_3XDREPj123
_ZN4PLMD7xdrfileL17xdrstdio_getbytesEPNS0_3XDREPcj125
_ZN4PLMD7xdrfileL17xdrstdio_putbytesEPNS0_3XDREPcj147
_ZN4PLMD7xdrfile19xdrfile_write_floatEPfiPNS0_7XDRFILEE174
_ZN4PLMD7xdrfileL10xdr_opaqueEPNS0_3XDREPcj211
_ZN4PLMD7xdrfile18xdrfile_read_floatEPfiPNS0_7XDRFILEE602
_ZN4PLMD7xdrfile17xdrfile_write_intEPiiPNS0_7XDRFILEE620
_ZN4PLMD7xdrfileL10decodeintsEPiiiPjS1_1936
_ZN4PLMD7xdrfile16xdrfile_read_intEPiiPNS0_7XDRFILEE1994
_ZN4PLMD7xdrfileL7xdr_intEPNS0_3XDREPi2966
_ZN4PLMD7xdrfileL10encodeintsEPiiiPjS2_3960
_ZN4PLMD7xdrfileL16xdrstdio_putlongEPNS0_3XDREPi9972
_ZN4PLMD7xdrfileL9xdr_htonlEi9972
_ZN4PLMD7xdrfileL10decodebitsEPii14579
_ZN4PLMD7xdrfileL9xdr_ntohlEi16582
_ZN4PLMD7xdrfileL16xdrstdio_getlongEPNS0_3XDREPi16593
_ZN4PLMD7xdrfileL10encodebitsEPiii21991
_ZN4PLMD7xdrfileL9xdr_floatEPNS0_3XDREPf23476
_ZN4PLMD7xdrfileL13xdr_swapbytesEi26554
+
+
+ + + +
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 000000000..f01e6826f --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.func.html @@ -0,0 +1,396 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:43294345.8 %
Date:2024-10-17 16:45:02Functions: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_32
_ZN4PLMD7xdrfile13xdrfile_closeEPNS0_7XDRFILEE32
_ZN4PLMD7xdrfile16xdrfile_read_intEPiiPNS0_7XDRFILEE1994
_ZN4PLMD7xdrfile17xdrfile_read_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_read_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_write_intEPiiPNS0_7XDRFILEE620
_ZN4PLMD7xdrfile18xdrfile_read_floatEPfiPNS0_7XDRFILEE602
_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_7XDRFILEE75
_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_3XDREPcj211
_ZN4PLMD7xdrfileL10xdr_stringEPNS0_3XDREPPcj123
_ZN4PLMD7xdrfileL10xdr_u_charEPNS0_3XDREPh0
_ZN4PLMD7xdrfileL11xdr_u_shortEPNS0_3XDREPt0
_ZN4PLMD7xdrfileL13xdr_swapbytesEi26554
_ZN4PLMD7xdrfileL15xdrstdio_createEPNS0_3XDREP8_IO_FILENS0_6xdr_opE32
_ZN4PLMD7xdrfileL15xdrstdio_getposEPNS0_3XDRE0
_ZN4PLMD7xdrfileL15xdrstdio_setposEPNS0_3XDREj0
_ZN4PLMD7xdrfileL16xdrstdio_destroyEPNS0_3XDRE32
_ZN4PLMD7xdrfileL16xdrstdio_getlongEPNS0_3XDREPi16593
_ZN4PLMD7xdrfileL16xdrstdio_putlongEPNS0_3XDREPi9972
_ZN4PLMD7xdrfileL17xdrstdio_getbytesEPNS0_3XDREPcj125
_ZN4PLMD7xdrfileL17xdrstdio_putbytesEPNS0_3XDREPcj147
_ZN4PLMD7xdrfileL7ctofstrEPciS1_0
_ZN4PLMD7xdrfileL7ftocstrEPciS1_i0
_ZN4PLMD7xdrfileL7xdr_intEPNS0_3XDREPi2966
_ZN4PLMD7xdrfileL8xdr_charEPNS0_3XDREPc0
_ZN4PLMD7xdrfileL9sizeofintEi0
_ZN4PLMD7xdrfileL9xdr_floatEPNS0_3XDREPf23476
_ZN4PLMD7xdrfileL9xdr_htonlEi9972
_ZN4PLMD7xdrfileL9xdr_ntohlEi16582
_ZN4PLMD7xdrfileL9xdr_shortEPNS0_3XDREPs0
_ZN4PLMD7xdrfileL9xdr_u_intEPNS0_3XDREPj123
+
+
+ + + +
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 000000000..222d5bde0 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.gcov.html @@ -0,0 +1,2724 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:43294345.8 %
Date:2024-10-17 16:45:02Functions: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          32 : 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          32 :         if(*mode=='w' || *mode=='W') 
+     234             :     {
+     235             :                 snprintf(newmode,5,"wb+");
+     236             :                 xdrmode=XDR_ENCODE;
+     237          22 :         } else if(*mode == 'a' || *mode == 'A') 
+     238             :     {
+     239             :                 snprintf(newmode,5,"ab+");
+     240             :                 xdrmode = XDR_ENCODE;
+     241          22 :         } 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          32 :         if((xfp=(XDRFILE *)malloc(sizeof(XDRFILE)))==NULL)
+     249             :                 return NULL;
+     250          32 :         if((xfp->fp=fopen(path,newmode))==NULL)
+     251             :     {
+     252           0 :                 free(xfp);
+     253           0 :                 return NULL;
+     254             :         }
+     255          32 :         if((xfp->xdr=(XDR *)malloc(sizeof(XDR)))==NULL) 
+     256             :     {
+     257           0 :                 fclose(xfp->fp);
+     258           0 :                 free(xfp);
+     259           0 :                 return NULL;
+     260             :         }
+     261          32 :         xfp->mode=*mode;
+     262          32 :         xdrstdio_create((XDR *)(xfp->xdr),xfp->fp,xdrmode);
+     263          32 :         xfp->buf1 = xfp->buf2 = NULL;
+     264          32 :         xfp->buf1size = xfp->buf2size = 0;
+     265          32 :         return xfp;
+     266             : }
+     267             : 
+     268             : int 
+     269          32 : xdrfile_close(XDRFILE *xfp)
+     270             : {
+     271             :         int ret=exdrCLOSE;
+     272          32 :         if(xfp) 
+     273             :     {
+     274             :                 /* flush and destroy XDR stream */
+     275          32 :                 if(xfp->xdr)
+     276          32 :                         xdr_destroy((XDR *)(xfp->xdr));
+     277          32 :                 free(xfp->xdr);
+     278             :                 /* close the file */
+     279          32 :                 ret=fclose(xfp->fp);
+     280          32 :                 if(xfp->buf1size)
+     281           7 :                         free(xfp->buf1);
+     282          32 :                 if(xfp->buf2size)
+     283           7 :                         free(xfp->buf2);
+     284          32 :                 free(xfp);
+     285             :         }
+     286          32 :         return ret; /* return 0 if ok */
+     287             : }
+     288             : 
+     289             : 
+     290             : 
+     291             : int 
+     292        1994 : 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        4091 :         while(i<ndata && xdr_int((XDR *)(xfp->xdr),ptr+i))
+     298        2097 :                 i++;
+     299             :   
+     300        1994 :         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         602 : xdrfile_read_float(float *ptr, int ndata, XDRFILE* xfp) 
+     434             : {
+     435             :         int i=0;
+     436             :         /* read write is encoded in the XDR struct */
+     437       23916 :         while(i<ndata && xdr_float((XDR *)(xfp->xdr),ptr+i))
+     438       23314 :                 i++;
+     439         602 :         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          75 : xdrfile_read_string(char *ptr, int maxlen, XDRFILE* xfp)
+     474             : {
+     475             :         int i;
+     476          75 :         if(xdr_string((XDR *)(xfp->xdr),&ptr,maxlen)) {
+     477             :                 i=0;
+     478         975 :                 while(i<maxlen && ptr[i]!=0)
+     479         900 :                         i++;
+     480          75 :                 if(i==maxlen)
+     481             :                         return maxlen;
+     482             :                 else
+     483          75 :                         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       26554 : xdr_swapbytes(int32_t x)
+    2143             : {
+    2144             :         int32_t y,i;
+    2145             :         char *px=(char *)&x;
+    2146             :         char *py=(char *)&y;
+    2147             :   
+    2148      132770 :         for(i=0;i<4;i++)
+    2149      106216 :                 py[i]=px[3-i];
+    2150             :   
+    2151       26554 :         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       16582 : xdr_ntohl(int x)
+    2169             : {
+    2170             :         int s=0x1234;
+    2171             :         if( *((char *)&s)==(char)0x34) {
+    2172             :                 /* smallendian, swap bytes */
+    2173       16582 :                 return xdr_swapbytes(x);
+    2174             :         } else {
+    2175             :                 /* bigendian, do nothing */
+    2176             :                 return x;
+    2177             :         }
+    2178             : }
+    2179             : 
+    2180             : static int
+    2181        2966 : xdr_int (XDR *xdrs, int *ip)
+    2182             : {
+    2183             :         int32_t i32;
+    2184             : 
+    2185        2966 :         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        1478 :                 case XDR_DECODE:
+    2192        1478 :                         if (!xdr_getlong (xdrs, &i32))
+    2193             :                                 {
+    2194             :                                         return 0;
+    2195             :                                 }
+    2196        1467 :                         *ip = (int) i32;
+    2197             :                 case XDR_FREE:
+    2198             :                         return 1;
+    2199             :                 }
+    2200             :         return 0;
+    2201             : }
+    2202             : 
+    2203             : static int
+    2204         123 : xdr_u_int (XDR *xdrs, unsigned int *up)
+    2205             : {
+    2206             :         uint32_t ui32;
+    2207             : 
+    2208         123 :         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          75 :                 case XDR_DECODE:
+    2215          75 :                         if (!xdr_getlong (xdrs, (int32_t *)&ui32))
+    2216             :                                 {
+    2217             :                                         return 0;
+    2218             :                                 }
+    2219          75 :                         *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         211 : 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         211 :         if (cnt == 0)
+    2319             :                 return 1;
+    2320             : 
+    2321             :         /*
+    2322             :          * round byte count to full xdr units
+    2323             :          */
+    2324         211 :         rndup = cnt % BYTES_PER_XDR_UNIT;
+    2325         211 :         if (rndup > 0)
+    2326          61 :                 rndup = BYTES_PER_XDR_UNIT - rndup;
+    2327             : 
+    2328         211 :         switch (xdrs->x_op)
+    2329             :                 {
+    2330         103 :                 case XDR_DECODE:
+    2331         103 :                         if (!xdr_getbytes (xdrs, cp, cnt))
+    2332             :                                 {
+    2333             :                                         return 0;
+    2334             :                                 }
+    2335         103 :                         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         123 : xdr_string (XDR *xdrs, char **cpp, unsigned int maxsize)
+    2361             : {
+    2362         123 :         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         123 :         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         123 :         if (!xdr_u_int (xdrs, &size))
+    2386             :                 {
+    2387             :                         return 0;
+    2388             :                 }
+    2389         123 :         if (size > maxsize)
+    2390             :                 {
+    2391             :                         return 0;
+    2392             :                 }
+    2393         123 :         nodesize = size + 1;
+    2394             : 
+    2395             :         /*
+    2396             :          * now deal with the actual bytes
+    2397             :          */
+    2398         123 :         switch (xdrs->x_op)
+    2399             :                 {
+    2400          75 :                 case XDR_DECODE:
+    2401          75 :                         if (nodesize == 0)
+    2402             :                                 {
+    2403             :                                         return 1;
+    2404             :                                 }
+    2405          75 :                         if (sp == NULL)
+    2406           0 :                                 *cpp = sp = (char *) malloc (nodesize);
+    2407          75 :                         if (sp == NULL)
+    2408             :                                 {
+    2409           0 :                                         (void) fputs ("xdr_string: out of memory\n", stderr);
+    2410           0 :                                         return 0;
+    2411             :                                 }
+    2412          75 :                         sp[size] = 0;
+    2413             :                         /* fall into ... */
+    2414             : 
+    2415         123 :                 case XDR_ENCODE:
+    2416         123 :                         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       23476 : xdr_float(XDR *xdrs, float *fp)
+    2432             : {
+    2433       23476 :         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       15040 :                         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          32 : xdrstdio_create (XDR *xdrs, FILE *file, enum xdr_op op)
+    2575             : {
+    2576          32 :         xdrs->x_op = op;
+    2577             : 
+    2578          32 :         xdrs->x_ops = (XDR::xdr_ops *) &xdrstdio_ops;
+    2579          32 :         xdrs->x_private = (char *) file;
+    2580          32 : }
+    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          32 : xdrstdio_destroy (XDR *xdrs)
+    2588             : {
+    2589          32 :         (void) fflush ((FILE *) xdrs->x_private);
+    2590             :         /* xx should we close the file ?? */
+    2591          32 : }
+    2592             : 
+    2593             : static int
+    2594       16593 : xdrstdio_getlong (XDR *xdrs, int32_t *lp)
+    2595             : {
+    2596             :         int32_t mycopy;
+    2597             : 
+    2598       16593 :         if (fread ((char *) & mycopy, 4, 1, (FILE *) xdrs->x_private) != 1)
+    2599             :                 return 0;
+    2600       16582 :         *lp = (int32_t) xdr_ntohl (mycopy);
+    2601       16582 :         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         125 : xdrstdio_getbytes (XDR *xdrs, char *addr, unsigned int len)
+    2616             : {
+    2617         250 :         if ((len != 0) && (fread (addr, (int) len, 1,
+    2618         125 :                                                           (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 000000000..e3d5703f1 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_trr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_trr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10419054.7 %
Date:2024-10-17 16:45:02Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_trr_natomsEPcPi9
_ZN4PLMD7xdrfile9write_trrEPNS0_7XDRFILEEiiffPA3_fS4_S4_S4_48
_ZN4PLMD7xdrfile8read_trrEPNS0_7XDRFILEEiPiPfS4_PA3_fS6_S6_S6_75
_ZN4PLMD7xdrfileL7do_htrnEPNS0_7XDRFILEEiPNS0_11t_trnheaderEPA3_fS6_S6_S6_114
_ZN4PLMD7xdrfileL10nFloatSizeEPNS0_11t_trnheaderEPi123
_ZN4PLMD7xdrfileL6do_trnEPNS0_7XDRFILEEiPiPfS4_PA3_fS3_S6_S6_S6_123
_ZN4PLMD7xdrfileL12do_trnheaderEPNS0_7XDRFILEEiPNS0_11t_trnheaderE132
+
+
+ + + +
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 000000000..5fd31676b --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_trr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_trr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10419054.7 %
Date:2024-10-17 16:45:02Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_trr_natomsEPcPi9
_ZN4PLMD7xdrfile8read_trrEPNS0_7XDRFILEEiPiPfS4_PA3_fS6_S6_S6_75
_ZN4PLMD7xdrfile9write_trrEPNS0_7XDRFILEEiiffPA3_fS4_S4_S4_48
_ZN4PLMD7xdrfileL10nFloatSizeEPNS0_11t_trnheaderEPi123
_ZN4PLMD7xdrfileL12do_trnheaderEPNS0_7XDRFILEEiPNS0_11t_trnheaderE132
_ZN4PLMD7xdrfileL6do_trnEPNS0_7XDRFILEEiPiPfS4_PA3_fS3_S6_S6_S6_123
_ZN4PLMD7xdrfileL7do_htrnEPNS0_7XDRFILEEiPNS0_11t_trnheaderEPA3_fS6_S6_S6_114
+
+
+ + + +
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 000000000..e627ac036 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html @@ -0,0 +1,605 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_trr.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_trr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10419054.7 %
Date:2024-10-17 16:45:02Functions: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         123 : static int nFloatSize(t_trnheader *sh,int *nflsz)
+     100             : {
+     101             :     int nflsize=0;
+     102             :   
+     103         123 :     if (sh->box_size)
+     104         123 :         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         123 :     if (((nflsize != sizeof(float)) && (nflsize != sizeof(double))))
+     115             :         return exdrHEADER;
+     116             :       
+     117         123 :     *nflsz = nflsize;
+     118             :   
+     119         123 :     return exdrOK;
+     120             : }
+     121             : 
+     122         132 : static int do_trnheader(XDRFILE *xd,mybool bRead,t_trnheader *sh)
+     123             : {
+     124         132 :         int magic=GROMACS_MAGIC;
+     125             :         int nflsz,slen,result;
+     126             :         const char *version = "GMX_trn_file";
+     127             :         char buf[BUFSIZE];
+     128             :   
+     129         132 :         if (xdrfile_read_int(&magic,1,xd) != 1)
+     130             :                 return exdrINT;
+     131             :   
+     132         123 :         if (bRead) 
+     133             :     {
+     134          75 :         if (xdrfile_read_int(&slen,1,xd) != 1)
+     135             :             return exdrINT;
+     136          75 :         if (slen != strlen(version)+1)
+     137             :             return exdrSTRING;
+     138          75 :         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         123 :         if (xdrfile_read_int(&sh->ir_size,1,xd) != 1)
+     150             :                 return exdrINT;
+     151         123 :         if (xdrfile_read_int(&sh->e_size,1,xd) != 1)
+     152             :                 return exdrINT;
+     153         123 :         if (xdrfile_read_int(&sh->box_size,1,xd) != 1)
+     154             :                 return exdrINT;
+     155         123 :         if (xdrfile_read_int(&sh->vir_size,1,xd) != 1)
+     156             :                 return exdrINT;
+     157         123 :         if (xdrfile_read_int(&sh->pres_size,1,xd) != 1)
+     158             :                 return exdrINT;
+     159         123 :         if (xdrfile_read_int(&sh->top_size,1,xd) != 1)
+     160             :                 return exdrINT;
+     161         123 :         if (xdrfile_read_int(&sh->sym_size,1,xd) != 1)
+     162             :                 return exdrINT;
+     163         123 :         if (xdrfile_read_int(&sh->x_size,1,xd) != 1)
+     164             :                 return exdrINT;
+     165         123 :         if (xdrfile_read_int(&sh->v_size,1,xd) != 1)
+     166             :                 return exdrINT;
+     167         123 :         if (xdrfile_read_int(&sh->f_size,1,xd) != 1)
+     168             :                 return exdrINT;
+     169         123 :         if (xdrfile_read_int(&sh->natoms,1,xd) != 1)
+     170             :                 return exdrINT;
+     171             :         
+     172         123 :         if ((result = nFloatSize(sh,&nflsz)) != exdrOK)
+     173             :                 return result;
+     174         123 :         sh->bDouble = (nflsz == sizeof(double));
+     175             :         
+     176         123 :         if (xdrfile_read_int(&sh->step,1,xd) != 1)
+     177             :                 return exdrINT;
+     178         123 :         if (xdrfile_read_int(&sh->nre,1,xd) != 1)
+     179             :                 return exdrINT;
+     180         123 :         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         123 :         if (xdrfile_read_float(&sh->tf,1,xd) != 1)
+     192             :             return exdrFLOAT;
+     193         123 :         sh->td = sh->tf;
+     194         123 :         if (xdrfile_read_float(&sh->lambdaf,1,xd) != 1)
+     195             :             return exdrFLOAT;
+     196         123 :         sh->lambdad = sh->lambdaf;
+     197             :     }
+     198             :   
+     199             :     return exdrOK;
+     200             : }
+     201             : 
+     202         114 : 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         114 :         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         114 :                 if (sh->box_size != 0) 
+     338             :         {
+     339         114 :             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         114 :             if (xdrfile_read_float(pvf,DIM*DIM,xd) == DIM*DIM) 
+     349             :             {
+     350         456 :                 for(i=0; (i<DIM); i++)
+     351             :                 {
+     352        1368 :                     for(j=0; (j<DIM); j++)
+     353             :                     {
+     354        1026 :                         if (NULL != box)
+     355             :                         {
+     356        1026 :                             box[i][j] = pvf[i*DIM+j];
+     357             :                         }
+     358             :                     }
+     359             :                 }
+     360             :             }
+     361             :             else
+     362             :                 return exdrFLOAT;
+     363             :         }
+     364             :                         
+     365         114 :                 if (sh->vir_size != 0) 
+     366             :         {
+     367           0 :             if (xdrfile_read_float(pvf,DIM*DIM,xd) != DIM*DIM) 
+     368             :                 return exdrFLOAT;
+     369             :         }
+     370             :                 
+     371         114 :                 if (sh->pres_size!= 0) 
+     372             :         {
+     373           0 :             if (xdrfile_read_float(pvf,DIM*DIM,xd) != DIM*DIM) 
+     374             :                 return exdrFLOAT;
+     375             :         }
+     376             :                 
+     377         114 :                 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
+     378         114 :                         fx = (float *)calloc(sh->natoms*DIM,sizeof(fx[0]));
+     379         114 :                         if (NULL == fx)
+     380             :                                 return exdrNOMEM;
+     381             :                 }
+     382         114 :                 if (sh->x_size   != 0) 
+     383             :         {
+     384         114 :             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         114 :             if (xdrfile_read_float(fx,sh->natoms*DIM,xd) == sh->natoms*DIM)
+     394             :             {
+     395         114 :                 if (bRead) 
+     396             :                 {
+     397        4728 :                     for(i=0; (i<sh->natoms); i++)
+     398       18648 :                         for(j=0; (j<DIM); j++)
+     399       13986 :                             if (NULL != x)
+     400       13986 :                                 x[i][j] = fx[i*DIM+j];
+     401             :                 }
+     402             :             }
+     403             :             else
+     404             :                 return exdrFLOAT;
+     405             :         }
+     406         114 :                 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         114 :                 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         114 :                 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
+     449         114 :                         free(fx);
+     450             :                 }
+     451             :         }
+     452             :         return exdrOK;
+     453             : }
+     454             : 
+     455         123 : 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         123 :     sh = (t_trnheader *)calloc(1,sizeof(*sh));
+     462             :   
+     463         123 :     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         123 :     if ((result = do_trnheader(xd,bRead,sh)) != exdrOK)
+     477             :         return result;
+     478         114 :     if (bRead) {
+     479          66 :         *natoms = sh->natoms;
+     480          66 :         *step   = sh->step;
+     481          66 :         *t      = sh->td;
+     482          66 :         *lambda = sh->lambdad;
+     483             :     }
+     484         114 :     if ((result = do_htrn(xd,bRead,sh,box,x,v,f)) != exdrOK)
+     485             :         return result;
+     486             : 
+     487         114 :     free(sh);
+     488             :   
+     489         114 :     return exdrOK;
+     490             : }
+     491             : 
+     492             : /************************************************************
+     493             :  *
+     494             :  *  The following routines are the exported ones
+     495             :  *
+     496             :  ************************************************************/
+     497             :  
+     498           9 : int read_trr_natoms(char *fn,int *natoms)
+     499             : {
+     500             :         XDRFILE *xd;
+     501             :         t_trnheader sh;
+     502             :         int  result;
+     503             :         
+     504           9 :         xd = xdrfile_open(fn,"r");
+     505           9 :         if (NULL == xd)
+     506             :                 return exdrFILENOTFOUND;
+     507           9 :         if ((result = do_trnheader(xd,1,&sh)) != exdrOK)
+     508             :                 return result;
+     509           9 :         xdrfile_close(xd);
+     510           9 :         *natoms = sh.natoms;
+     511             :         
+     512           9 :         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          75 : int read_trr(XDRFILE *xd,int natoms,int *step,float *t,float *lambda,
+     522             :                          matrix box,rvec *x,rvec *v,rvec *f)
+     523             : {
+     524          75 :         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 000000000..4ed6389b7 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_xtc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_xtc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:273381.8 %
Date:2024-10-17 16:45:02Functions: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 000000000..ba6288803 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_xtc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_xtc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:273381.8 %
Date:2024-10-17 16:45:02Functions: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 000000000..6f47d7820 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html @@ -0,0 +1,241 @@ + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_xtc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_xtc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:273381.8 %
Date:2024-10-17 16:45:02Functions: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/AdjacencyMatrixBase.cpp.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html new file mode 100644 index 000000000..0a61be6e9 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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:213213100.0 %
Date:2024-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19AdjacencyMatrixBase19setupThirdAtomBlockERKSt6vectorINS_10AtomNumberESaIS3_EERS5_24
_ZN4PLMD6adjmat19AdjacencyMatrixBase26getAdditionalTasksRequiredEPNS_16ActionWithVectorERSt6vectorIjSaIjEE216
_ZN4PLMD6adjmat19AdjacencyMatrixBase17setLinkCellCutoffERKbRKdd326
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC2ERKNS_13ActionOptionsE326
_ZN4PLMD6adjmat19AdjacencyMatrixBase16registerKeywordsERNS_8KeywordsE999
_ZN4PLMD6adjmat19AdjacencyMatrixBase22getNumberOfDerivativesEv11081
_ZN4PLMD6adjmat19AdjacencyMatrixBase7prepareEv11700
_ZN4PLMD6adjmat19AdjacencyMatrixBase19updateNeighbourListEv11750
_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 000000000..04b20de68 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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:213213100.0 %
Date:2024-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19AdjacencyMatrixBase23addThirdAtomDerivativesERKjRKNS_13VectorGenericILj3EEERNS_10MultiValueE131645
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18getNumberOfColumnsEv284222
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEERNS_10MultiValueE10682440
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17isAdjacencyMatrixEv21246780
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEERNS_10MultiValueE21364880
+
+
+ + + +
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 000000000..ffc997ae4 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:3232100.0 %
Date:2024-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEERNS_10MultiValueE10682440
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17isAdjacencyMatrixEv21246780
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEERNS_10MultiValueE21364880
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18getNumberOfColumnsEv284222
_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 000000000..c92dc085b --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html @@ -0,0 +1,195 @@ + + + + + + + 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:3232100.0 %
Date:2024-10-17 16:45:00Functions:55100.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 "core/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 maxcol;
+      40             :   unsigned nl_stride;
+      41             :   unsigned natoms_per_list;
+      42             :   std::vector<unsigned> nlist;
+      43             :   void setupThirdAtomBlock( const std::vector<AtomNumber>& tc, std::vector<AtomNumber>& t );
+      44             : protected:
+      45             :   Vector getPosition( const unsigned& indno, MultiValue& myvals ) const ;
+      46             :   void addAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const ;
+      47             :   void addThirdAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const ;
+      48             :   void setLinkCellCutoff( const bool& symmetric, const double& lcut, double tcut=-1.0 );
+      49             :   void addBoxDerivatives( const Tensor& vir, MultiValue& myvals ) const ;
+      50             : public:
+      51             :   static void registerKeywords( Keywords& keys );
+      52             :   explicit AdjacencyMatrixBase(const ActionOptions&);
+      53    21246780 :   bool isAdjacencyMatrix() const override { return true; }
+      54             :   unsigned getNumberOfDerivatives() override ;
+      55             :   unsigned getNumberOfColumns() const override;
+      56             :   void prepare() override;
+      57             :   void getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) override ;
+      58             :   void setupForTask( const unsigned& current, std::vector<unsigned> & indices, MultiValue& myvals ) const override;
+      59             :   // void setupCurrentTaskList() override;
+      60             :   void updateNeighbourList() override ;
+      61             :   unsigned retrieveNeighbours( const unsigned& current, std::vector<unsigned> & indices ) const ;
+      62             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override ;
+      63             :   virtual double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const = 0;
+      64             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      65             : };
+      66             : 
+      67             : inline
+      68             : Vector AdjacencyMatrixBase::getPosition( const unsigned& indno, MultiValue& myvals ) const {
+      69   238830408 :   unsigned index = myvals.getIndices()[ indno + myvals.getSplitIndex() ];
+      70   238830408 :   return myvals.getAtomVector()[index];
+      71             : }
+      72             : 
+      73             : inline
+      74    21364880 : void AdjacencyMatrixBase::addAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const {
+      75    21364880 :   if( doNotCalculateDerivatives() ) return;
+      76             :   plumed_dbg_assert( indno<2 ); unsigned index = myvals.getTaskIndex();
+      77    12728180 :   if( indno==1 ) index = myvals.getSecondTaskIndex();
+      78    12728180 :   unsigned w_index = getConstPntrToComponent(0)->getPositionInStream();
+      79    12728180 :   myvals.addDerivative( w_index, 3*index+0, der[0] );
+      80    12728180 :   myvals.addDerivative( w_index, 3*index+1, der[1] );
+      81    12728180 :   myvals.addDerivative( w_index, 3*index+2, der[2] );
+      82             : }
+      83             : 
+      84             : inline
+      85      131645 : void AdjacencyMatrixBase::addThirdAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const {
+      86      131645 :   if( doNotCalculateDerivatives() ) return;
+      87      113597 :   unsigned index = myvals.getIndices()[ indno + myvals.getSplitIndex() ];
+      88      113597 :   unsigned w_index = getConstPntrToComponent(0)->getPositionInStream();
+      89      113597 :   myvals.addDerivative( w_index, 3*index+0, der[0] );
+      90      113597 :   myvals.addDerivative( w_index, 3*index+1, der[1] );
+      91      113597 :   myvals.addDerivative( w_index, 3*index+2, der[2] );
+      92             : }
+      93             : 
+      94             : inline
+      95    10682440 : void AdjacencyMatrixBase::addBoxDerivatives( const Tensor& vir, MultiValue& myvals ) const {
+      96    10682440 :   if( doNotCalculateDerivatives() ) return;
+      97     6364090 :   unsigned nbase = 3*getNumberOfAtoms();
+      98     6364090 :   unsigned w_index = getConstPntrToComponent(0)->getPositionInStream();
+      99     6364090 :   myvals.addDerivative( w_index, nbase+0, vir(0,0) );
+     100     6364090 :   myvals.addDerivative( w_index, nbase+1, vir(0,1) );
+     101     6364090 :   myvals.addDerivative( w_index, nbase+2, vir(0,2) );
+     102     6364090 :   myvals.addDerivative( w_index, nbase+3, vir(1,0) );
+     103     6364090 :   myvals.addDerivative( w_index, nbase+4, vir(1,1) );
+     104     6364090 :   myvals.addDerivative( w_index, nbase+5, vir(1,2) );
+     105     6364090 :   myvals.addDerivative( w_index, nbase+6, vir(2,0) );
+     106     6364090 :   myvals.addDerivative( w_index, nbase+7, vir(2,1) );
+     107     6364090 :   myvals.addDerivative( w_index, nbase+8, vir(2,2) );
+     108             : }
+     109             : 
+     110             : inline
+     111      284222 : unsigned AdjacencyMatrixBase::getNumberOfColumns() const {
+     112      284222 :   return maxcol;
+     113             : }
+     114             : 
+     115             : 
+     116             : }
+     117             : }
+     118             : 
+     119             : #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 000000000..e6e35b4b3 --- /dev/null +++ b/coverage/adjmat/Bridge.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2020100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..8318c5537 --- /dev/null +++ b/coverage/adjmat/Bridge.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2020100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4b294437c --- /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:2020100.0 %
Date:2024-10-17 16:45:00Functions: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 switchingfunction in the above formula");
+      53          20 :   keys.add("optional","SWITCHA","The switchingfunction on the distance between bridging atoms and the atoms in "
+      54             :            "group A");
+      55          20 :   keys.add("optional","SWITCHB","The 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 :   keys.setValueDescription("the number of bridging atoms between the two groups");
+      59          10 : }
+      60             : 
+      61           8 : Bridge::Bridge(const ActionOptions& ao):
+      62             :   Action(ao),
+      63           8 :   ActionShortcut(ao)
+      64             : {
+      65             :   // Need to read in switch
+      66          24 :   std::string s_inp, sfinput; parse("SWITCH",sfinput); if( sfinput.length()>0 ) s_inp += "SWITCH={" + sfinput +"} ";
+      67          16 :   std::string sfinputa; parse("SWITCHA",sfinputa); if( sfinputa.length()>0 ) s_inp += "SWITCHA={" + sfinputa +"} ";
+      68          16 :   std::string sfinputb; parse("SWITCHB",sfinputb); if( sfinputb.length()>0 ) s_inp += "SWITCHB={" + sfinputb +"} ";
+      69             :   // Create the matrix object
+      70          16 :   readInputLine( getShortcutLabel() + "_mat: BRIDGE_MATRIX " + s_inp + convertInputLineToString() );
+      71             :   // Add all the elements of the matrix together
+      72          16 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_mat PERIODIC=NO");
+      73           8 : }
+      74             : 
+      75             : }
+      76             : }
+
+
+
+ + + + +
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 000000000..73ba492c2 --- /dev/null +++ b/coverage/adjmat/BridgeMatrix.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12BridgeMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12BridgeMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat12BridgeMatrix16registerKeywordsERNS_8KeywordsE18
_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 000000000..3ecfaeab6 --- /dev/null +++ b/coverage/adjmat/BridgeMatrix.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12BridgeMatrix16registerKeywordsERNS_8KeywordsE18
_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 000000000..234e71734 --- /dev/null +++ b/coverage/adjmat/BridgeMatrix.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + 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-10-17 16:45:00Functions: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          18 : void BridgeMatrix::registerKeywords( Keywords& keys ) {
+      74          18 :   AdjacencyMatrixBase::registerKeywords( keys );
+      75          36 :   keys.add("atoms","BRIDGING_ATOMS","The list of atoms that can form the bridge between the two interesting parts "
+      76             :            "of the structure.");
+      77          36 :   keys.add("optional","SWITCH","The parameters of the two switchingfunction in the above formula");
+      78          36 :   keys.add("optional","SWITCHA","The switchingfunction on the distance between bridging atoms and the atoms in "
+      79             :            "group A");
+      80          36 :   keys.add("optional","SWITCHB","The switchingfunction on the distance between the bridging atoms and the atoms in "
+      81             :            "group B");
+      82          18 : }
+      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 000000000..aad8b1806 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:3333100.0 %
Date:2024-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13ContactMatrix12writeInGraphB5cxx11Ev8
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE210
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE424
_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 000000000..f92e11365 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:3333100.0 %
Date:2024-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE424
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE210
_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 000000000..0b451c3ca --- /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:3333100.0 %
Date:2024-10-17 16:45:00Functions: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         424 : void ContactMatrix::registerKeywords( Keywords& keys ) {
+      81         424 :   AdjacencyMatrixBase::registerKeywords( keys ); keys.setDisplayName("CONTACT_MATRIX");
+      82         848 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      83         848 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      84         848 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      85         848 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      86         848 :   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         424 : }
+      90             : 
+      91         210 : ContactMatrix::ContactMatrix( const ActionOptions& ao ):
+      92             :   Action(ao),
+      93         210 :   AdjacencyMatrixBase(ao)
+      94             : {
+      95         420 :   std::string errors, input; parse("SWITCH",input);
+      96         210 :   if( input.length()>0 ) {
+      97         183 :     switchingFunction.set( input, errors );
+      98         183 :     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         210 :   log.printf("  switching function cutoff is %s \n",switchingFunction.description().c_str() );
+     108         210 :   setLinkCellCutoff( true, switchingFunction.get_dmax() );
+     109         210 : }
+     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 :   if( doNotCalculateDerivatives() ) return val;
+     117     5500819 :   addAtomDerivatives( 0, (-dfunc)*distance, myvals );
+     118     5500819 :   addAtomDerivatives( 1, (+dfunc)*distance, myvals );
+     119     5500819 :   addBoxDerivatives( (-dfunc)*Tensor(distance,distance), myvals );
+     120     5500819 :   return val;
+     121             : }
+     122             : 
+     123             : }
+     124             : }
+     125             : 
+
+
+
+ + + + +
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 000000000..24d26d565 --- /dev/null +++ b/coverage/adjmat/ContactMatrixShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:384486.4 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ContactMatrixShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat21ContactMatrixShortcutC1ERKNS_13ActionOptionsE208
_ZN4PLMD6adjmat21ContactMatrixShortcut16registerKeywordsERNS_8KeywordsE334
+
+
+ + + +
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 000000000..3c6a9a16b --- /dev/null +++ b/coverage/adjmat/ContactMatrixShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:384486.4 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ContactMatrixShortcut16registerKeywordsERNS_8KeywordsE334
_ZN4PLMD6adjmat21ContactMatrixShortcutC1ERKNS_13ActionOptionsE208
_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 000000000..23558bce2 --- /dev/null +++ b/coverage/adjmat/ContactMatrixShortcut.cpp.gcov.html @@ -0,0 +1,208 @@ + + + + + + + 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:384486.4 %
Date:2024-10-17 16:45:00Functions: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             : #include "AdjacencyMatrixBase.h"
+      28             : 
+      29             : //+PLUMEDOC MATRIX CONTACT_MATRIX
+      30             : /*
+      31             : Adjacency matrix in which two atoms are adjacent if they are within a certain cutoff.
+      32             : 
+      33             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      34             : 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
+      35             : 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
+      36             : analyzed using a number of other algorithms as is detailed in \cite tribello-clustering.
+      37             : 
+      38             : For this action the elements of the contact matrix are calculated using:
+      39             : 
+      40             : \f[
+      41             :  a_{ij} = \sigma( |\mathbf{r}_{ij}| )
+      42             : \f]
+      43             : 
+      44             : 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.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : 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
+      49             : 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.
+      50             : The final quantity output in the colvar file is thus the average coordination number.
+      51             : 
+      52             : \plumedfile
+      53             : mat: CONTACT_MATRIX ATOMS=1-6 SWITCH={EXP D_0=0.2 R_0=0.1 D_MAX=0.66}
+      54             : COLUMNSUMS MATRIX=mat MEAN LABEL=csums
+      55             : PRINT ARG=csums.* FILE=colvar
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace adjmat {
+      63             : 
+      64             : class ContactMatrixShortcut : public ActionShortcut {
+      65             : public:
+      66             :   static void registerKeywords(Keywords& keys);
+      67             :   explicit ContactMatrixShortcut(const ActionOptions&);
+      68             : };
+      69             : 
+      70             : PLUMED_REGISTER_ACTION(ContactMatrixShortcut,"CONTACT_MATRIX")
+      71             : 
+      72         334 : void ContactMatrixShortcut::registerKeywords(Keywords& keys) {
+      73         334 :   AdjacencyMatrixBase::registerKeywords( keys );
+      74        1002 :   keys.remove("GROUP"); keys.add("numbered","GROUP","specifies the list of atoms that should be assumed indistinguishable");
+      75         668 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      76         668 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      77         668 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      78         668 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      79         668 :   keys.add("numbered","SWITCH","specify the switching function to use between two sets of indistinguishable atoms");
+      80        1002 :   keys.addActionNameSuffix("_PROPER"); keys.needsAction("TRANSPOSE"); keys.needsAction("CONCATENATE");
+      81         334 : }
+      82             : 
+      83         208 : ContactMatrixShortcut::ContactMatrixShortcut(const ActionOptions& ao):
+      84             :   Action(ao),
+      85         208 :   ActionShortcut(ao)
+      86             : {
+      87         208 :   std::vector<std::string> grp_str; std::string atomsstr="";
+      88         416 :   std::vector<std::string> atomsvec; parseVector("ATOMS",atomsvec);
+      89         208 :   if( atomsvec.size()>0 )  {
+      90           0 :     for(unsigned i=0; i<atomsvec.size(); ++i) {
+      91           0 :       Group* gg = plumed.getActionSet().selectWithLabel<Group*>( atomsvec[i] );
+      92           0 :       if( gg ) grp_str.push_back( atomsvec[i] );
+      93             :     }
+      94           0 :     if( grp_str.size()!=atomsvec.size() ) {
+      95           0 :       grp_str.resize(0);
+      96           0 :       atomsstr = " ATOMS=" + atomsvec[0]; for(unsigned i=1; i<atomsvec.size(); ++i) atomsstr += "," + atomsvec[i];
+      97             :     }
+      98             :   } else {
+      99             :     std::string grp_inpt;
+     100           2 :     for(unsigned i=1;; ++i) {
+     101         420 :       if( !parseNumbered("GROUP",i,grp_inpt) ) break;
+     102           2 :       grp_str.push_back( grp_inpt );
+     103             :     }
+     104             :   }
+     105         208 :   if( grp_str.size()>9 ) error("cannot handle more than 9 groups");
+     106         415 :   if( grp_str.size()==0 )  { readInputLine( getShortcutLabel() + ": CONTACT_MATRIX_PROPER " + atomsstr + " " + convertInputLineToString() ); return; }
+     107             : 
+     108           3 :   for(unsigned i=0; i<grp_str.size(); ++i) {
+     109           4 :     std::string sw_str, num; Tools::convert( i+1, num ); parseNumbered("SWITCH", (i+1)*10 + 1 + i,  sw_str );
+     110           2 :     if( sw_str.length()==0 ) error("missing SWITCH" + num + num + " keyword");
+     111           4 :     readInputLine( getShortcutLabel() + num +  num + ": CONTACT_MATRIX_PROPER GROUP=" + grp_str[i] + " SWITCH={" + sw_str + "}" );
+     112           3 :     for(unsigned j=0; j<i; ++j) {
+     113           2 :       std::string sw_str2, jnum; Tools::convert( j+1, jnum ); parseNumbered("SWITCH", (j+1)*10 + 1 + i, sw_str2);
+     114           1 :       if( sw_str2.length()==0 ) error("missing SWITCH" + jnum + num + " keyword");
+     115           2 :       readInputLine( getShortcutLabel() + jnum + num + ": CONTACT_MATRIX_PROPER GROUPA=" + grp_str[j] + " GROUPB=" + grp_str[i] + " SWITCH={" + sw_str2 +"}");
+     116           2 :       readInputLine( getShortcutLabel() + num +  jnum + ": TRANSPOSE ARG=" + getShortcutLabel() + jnum + num );
+     117             :     }
+     118             :   }
+     119           1 :   std::string join_matrices = getShortcutLabel() + ": CONCATENATE";
+     120           3 :   for(unsigned i=0; i<grp_str.size(); ++i) {
+     121           2 :     std::string inum; Tools::convert(i+1,inum);
+     122           6 :     for(unsigned j=0; j<grp_str.size(); ++j) {
+     123           4 :       std::string jnum; Tools::convert(j+1,jnum);
+     124           5 :       if( i>j ) join_matrices += " MATRIX" + inum + jnum + "=" + getShortcutLabel() + inum +  jnum;
+     125           6 :       else join_matrices += " MATRIX" + inum + jnum + "=" + getShortcutLabel() + inum +  jnum;
+     126             :     }
+     127             :   }
+     128           1 :   readInputLine( join_matrices );
+     129         416 : }
+     130             : 
+     131             : }
+     132             : }
+
+
+
+ + + + +
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 000000000..7551d91fa --- /dev/null +++ b/coverage/adjmat/DistanceMatrix.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14DistanceMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat14DistanceMatrixC1ERKNS_13ActionOptionsE92
_ZN4PLMD6adjmat14DistanceMatrix16registerKeywordsERNS_8KeywordsE178
_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 000000000..cb2550d47 --- /dev/null +++ b/coverage/adjmat/DistanceMatrix.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14DistanceMatrix16registerKeywordsERNS_8KeywordsE178
_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 000000000..50b849a62 --- /dev/null +++ b/coverage/adjmat/DistanceMatrix.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + 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-10-17 16:45:00Functions: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         178 : void DistanceMatrix::registerKeywords( Keywords& keys ) {
+      55         178 :   AdjacencyMatrixBase::registerKeywords( keys );
+      56         356 :   keys.add("compulsory","CUTOFF","-1","ignore distances that have a value larger than this cutoff");
+      57         178 : }
+      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/HbondMatrix.cpp.func-sort-c.html b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000..46fa0fc28 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:4343100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3ac064814 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:4343100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d54060f2e --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + 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:4343100.0 %
Date:2024-10-17 16:45:00Functions: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-2","DONORS","The list of atoms which can donate a hydrogen bond");
+     100           8 :   keys.add("atoms-2","ACCEPTORS","The list of atoms which can accept a hydrogen bond");
+     101           8 :   keys.add("atoms","HYDROGENS","The list of atoms that can form the bridge between the two interesting parts "
+     102             :            "of the structure.");
+     103           8 :   keys.add("numbered","SWITCH","The switchingfunction that specifies how close a pair of atoms must be together for there to be a hydrogen bond between them");
+     104           8 :   keys.add("numbered","HSWITCH","The switchingfunction that specifies how close the hydrogen must be to the donor atom of the hydrogen bond for it to be "
+     105             :            "considered a hydrogen bond");
+     106           8 :   keys.add("numbered","ASWITCH","A switchingfunction that is used to specify what the angle between the vector connecting the donor atom to the acceptor atom and "
+     107             :            "the vector connecting the donor atom to the hydrogen must be in order for it considered to be a hydrogen bond");
+     108           4 : }
+     109             : 
+     110           2 : HbondMatrix::HbondMatrix(const ActionOptions&ao):
+     111             :   Action(ao),
+     112           2 :   AdjacencyMatrixBase(ao)
+     113             : {
+     114           4 :   std::string sfinput,errors; parse("SWITCH",sfinput);
+     115           2 :   if( sfinput.length()==0 ) error("could not find SWITCH keyword");
+     116           2 :   distanceOOSwitch.set(sfinput,errors);
+     117           2 :   if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     118             : 
+     119           4 :   std::string hsfinput; parse("HSWITCH",hsfinput);
+     120           2 :   if( hsfinput.length()==0 ) error("could not find HSWITCH keyword");
+     121           2 :   distanceOHSwitch.set(hsfinput,errors);
+     122           2 :   if( errors.length()!=0 ) error("problem reading HSWITCH keyword : " + errors );
+     123             : 
+     124           4 :   std::string asfinput; parse("ASWITCH",asfinput);
+     125           2 :   if( asfinput.length()==0 ) error("could not find SWITCH keyword");
+     126           2 :   angleSwitch.set(asfinput,errors);
+     127           2 :   if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     128             : 
+     129             :   // Setup link cells
+     130           2 :   setLinkCellCutoff( false, distanceOOSwitch.get_dmax() );
+     131             : 
+     132             :   // And check everything has been read in correctly
+     133           2 :   checkRead();
+     134           2 : }
+     135             : 
+     136        4038 : double HbondMatrix::calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const {
+     137        4038 :   Vector ood = pos2; double ood_l = ood.modulo2(); // acceptor - donor
+     138        4038 :   if( ood_l<epsilon) return 0;
+     139        4038 :   double ood_df, ood_sw=distanceOOSwitch.calculateSqr( ood_l, ood_df );
+     140             : 
+     141             :   double value=0;
+     142      520170 :   for(unsigned i=0; i<natoms; ++i) {
+     143      516132 :     Vector ohd=getPosition(i,myvals); double ohd_l=ohd.modulo2();
+     144      516132 :     double ohd_df, ohd_sw=distanceOHSwitch.calculateSqr( ohd_l, ohd_df );
+     145             : 
+     146      516132 :     Angle a; Vector ood_adf, ohd_adf; double angle=a.compute( ood, ohd, ood_adf, ohd_adf );
+     147      516132 :     double angle_df, angle_sw=angleSwitch.calculate( angle, angle_df );
+     148      516132 :     value += ood_sw*ohd_sw*angle_sw;
+     149             : 
+     150      516132 :     if( !doNotCalculateDerivatives() ) {
+     151          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 );
+     152          36 :       addAtomDerivatives( 1, angle_sw*ohd_sw*(+ood_df)*ood + ood_sw*ohd_sw*angle_df*angle*ood_adf, myvals );
+     153          36 :       addThirdAtomDerivatives( i, angle_sw*ood_sw*(+ohd_df)*ohd + ood_sw*ohd_sw*angle_df*angle*ohd_adf, myvals );
+     154          72 :       addBoxDerivatives( angle_sw*ohd_sw*(-ood_df)*Tensor(ood,ood) + angle_sw*ood_sw*(-ohd_df)*Tensor(ohd,ohd) -
+     155         108 :                          ood_sw*ohd_sw*angle_df*angle*(Tensor(ood,ood_adf)+Tensor(ohd,ohd_adf)), myvals );
+     156             :     }
+     157             :   }
+     158        4038 :   return value;
+     159             : }
+     160             : 
+     161             : }
+     162             : }
+
+
+
+ + + + +
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 000000000..47eebf115 --- /dev/null +++ b/coverage/adjmat/Neighbors.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:505984.7 %
Date:2024-10-17 16:45:00Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat9Neighbors17canBeAfterInChainEPNS_16ActionWithVectorE0
_ZN4PLMD6adjmat9Neighbors17turnOnDerivativesEv0
_ZN4PLMD6adjmat9Neighbors22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat9NeighborsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat9NeighborsC1ERKNS_13ActionOptionsE3
_ZN4PLMD6adjmat9Neighbors16registerKeywordsERNS_8KeywordsE7
_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 000000000..9b5f77039 --- /dev/null +++ b/coverage/adjmat/Neighbors.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:505984.7 %
Date:2024-10-17 16:45:00Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat9Neighbors16registerKeywordsERNS_8KeywordsE7
_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 000000000..204470d74 --- /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:505984.7 %
Date:2024-10-17 16:45:00Functions: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 "core/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           7 : void Neighbors::registerKeywords( Keywords& keys ) {
+      55           7 :   ActionWithMatrix::registerKeywords( keys ); keys.use("ARG");
+      56          14 :   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          14 :   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           7 :   keys.setValueDescription("a matrix in which the ij element is one if the ij-element of the input matrix is one of the NLOWEST/NHIGHEST elements on that row of the input matrix and zero otherwise");
+      59           7 : }
+      60             : 
+      61           3 : Neighbors::Neighbors(const ActionOptions&ao):
+      62             :   Action(ao),
+      63           3 :   ActionWithMatrix(ao)
+      64             : {
+      65           3 :   if( getNumberOfArguments()!=1 ) error("found wrong number of arguments in input");
+      66           3 :   if( getPntrToArgument(0)->getRank()!=2 ) error("input argument should be a matrix");
+      67           3 :   getPntrToArgument(0)->buildDataStore();
+      68             : 
+      69           3 :   unsigned nlow; parse("NLOWEST",nlow);
+      70           3 :   unsigned nhigh; parse("NHIGHEST",nhigh);
+      71           3 :   if( nlow==0 && nhigh==0 ) error("missing NLOWEST or NHIGHEST keyword one of these two keywords must be set in input");
+      72           3 :   if( nlow>0 && nhigh>0 ) error("should only be one of NLOWEST or NHIGHEST set in input");
+      73           3 :   if( nlow>0 ) {
+      74           3 :     number=nlow; lowest=true;
+      75           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);
+      76             :   }
+      77           3 :   if( nhigh>0 ) {
+      78           0 :     number=nhigh; lowest=false;
+      79           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);
+      80             :   }
+      81             : 
+      82             :   // And get the shape
+      83           3 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      84           3 :   addValue( shape ); setNotPeriodic();
+      85           3 :   checkRead();
+      86           3 : }
+      87             : 
+      88           0 : void Neighbors::turnOnDerivatives() {
+      89           0 :   ActionWithValue::turnOnDerivatives();
+      90           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");
+      91           0 : }
+      92             : 
+      93           0 : unsigned Neighbors::getNumberOfDerivatives() {
+      94           0 :   return 0;
+      95             : }
+      96             : 
+      97        2512 : void Neighbors::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+      98        2512 :   const Value* wval = getPntrToArgument(0); unsigned nbonds = wval->getRowLength( task_index ), ncols = wval->getShape()[1];
+      99        2512 :   if( indices.size()!=1+number ) indices.resize( 1 + number );
+     100        2512 :   myvals.setSplitIndex(1+number);
+     101             : 
+     102             :   unsigned nind=0;
+     103      180890 :   for(unsigned i=0; i<nbonds; ++i) {
+     104      178378 :     unsigned ipos = ncols*task_index + wval->getRowIndex( task_index, i );
+     105      178378 :     double weighti = wval->get( ipos );
+     106      178378 :     if( weighti<epsilon ) continue ;
+     107      177866 :     nind++;
+     108             :   }
+     109        2512 :   if( number>nind ) plumed_merror("not enough matrix elements were stored");
+     110             : 
+     111             :   // Now build vectors for doing sorting
+     112        2512 :   std::vector<std::pair<double,unsigned> > rows( nind ); unsigned n=0;
+     113      180890 :   for(unsigned i=0; i<nbonds; ++i) {
+     114             :     unsigned iind = wval->getRowIndex( task_index, i );
+     115      178378 :     unsigned ipos = ncols*task_index + iind;
+     116      178378 :     double weighti = wval->get( ipos );
+     117      178378 :     if( weighti<epsilon ) continue ;
+     118      177866 :     rows[n].first=weighti; rows[n].second=iind; n++;
+     119             :   }
+     120             : 
+     121             :   // Now do the sort and clear all the stored values ready for recompute
+     122        2512 :   std::sort( rows.begin(), rows.end() );
+     123             :   // This is to make this action consistent with what in other matrix actions
+     124        2512 :   unsigned start_n = getPntrToArgument(0)->getShape()[0];
+     125             :   // And setup the lowest indices, which are the ones we need to calculate
+     126       16560 :   for(unsigned i=0; i<number; ++i) {
+     127       14048 :     indices[i+1] = start_n + rows[nind-1-i].second;
+     128       14048 :     if( lowest ) indices[i+1] = start_n + rows[i].second;
+     129             :   }
+     130        2512 : }
+     131             : 
+     132       14048 : void Neighbors::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     133       14048 :   myvals.addValue( getConstPntrToComponent(0)->getPositionInStream(), 1.0 );
+     134       14048 : }
+     135             : 
+     136             : }
+     137             : }
+
+
+
+ + + + +
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 000000000..8d85490b6 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..76ccd92a3 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0a24742ce --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.gcov.html @@ -0,0 +1,346 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d6d446755 --- /dev/null +++ b/coverage/adjmat/TorsionsMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:727398.6 %
Date:2024-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TorsionsMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14TorsionsMatrix18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat14TorsionsMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE2
_ZN4PLMD6adjmat14TorsionsMatrixC1ERKNS_13ActionOptionsE7
_ZN4PLMD6adjmat14TorsionsMatrix22getNumberOfDerivativesEv10
_ZN4PLMD6adjmat14TorsionsMatrix16registerKeywordsERNS_8KeywordsE14
_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 000000000..32434fb8d --- /dev/null +++ b/coverage/adjmat/TorsionsMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:727398.6 %
Date:2024-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TorsionsMatrix16registerKeywordsERNS_8KeywordsE14
_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 000000000..bf71bac16 --- /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:727398.6 %
Date:2024-10-17 16:45:00Functions: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 "core/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          14 : void TorsionsMatrix::registerKeywords( Keywords& keys ) {
+      55          14 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      56          28 :   keys.add("atoms","POSITIONS1","the positions to use for the molecules specified using the first argument");
+      57          28 :   keys.add("atoms","POSITIONS2","the positions to use for the molecules specified using the second argument");
+      58          14 :   keys.setValueDescription("the matrix of torsions between the two vectors of input directors");
+      59          14 : }
+      60             : 
+      61           7 : TorsionsMatrix::TorsionsMatrix(const ActionOptions&ao):
+      62             :   Action(ao),
+      63           7 :   ActionWithMatrix(ao)
+      64             : {
+      65           7 :   if( getNumberOfArguments()!=2 ) error("should be two arguments to this action, a matrix and a vector");
+      66           7 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a matrix");
+      67           7 :   if( getPntrToArgument(1)->getRank()!=2 || getPntrToArgument(1)->hasDerivatives() ) error("second argument to this action should be a matrix");
+      68           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");
+      69             : 
+      70          14 :   std::vector<AtomNumber> atoms_a; parseAtomList("POSITIONS1", atoms_a );
+      71           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");
+      72           7 :   log.printf("  using positions of these atoms for vectors in first matrix \n");
+      73         933 :   for(unsigned int i=0; i<atoms_a.size(); ++i) {
+      74         926 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      75         926 :     log.printf("  %d", atoms_a[i].serial());
+      76             :   }
+      77          14 :   log.printf("\n"); std::vector<AtomNumber> atoms_b; parseAtomList("POSITIONS2", atoms_b );
+      78           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");
+      79           7 :   log.printf("  using positions of these atoms for vectors in second matrix \n");
+      80        1225 :   for(unsigned i=0; i<atoms_b.size(); ++i) {
+      81        1218 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      82        1218 :     log.printf("  %d", atoms_b[i].serial()); atoms_a.push_back( atoms_b[i] );
+      83             :   }
+      84           7 :   log.printf("\n"); requestAtoms( atoms_a, false );
+      85             : 
+      86           7 :   std::vector<unsigned> shape(2); shape[0]=getPntrToArgument(0)->getShape()[0]; shape[1]=getPntrToArgument(1)->getShape()[1];
+      87          14 :   addValue( shape ); setPeriodic("-pi","pi"); nderivatives = buildArgumentStore(0) + 3*getNumberOfAtoms() + 9;
+      88           7 :   std::string headstr=getFirstActionInChain()->getLabel();
+      89           7 :   stored_matrix1 = getPntrToArgument(0)->ignoreStoredValue( headstr );
+      90           7 :   stored_matrix2 = getPntrToArgument(1)->ignoreStoredValue( headstr );
+      91           7 : }
+      92             : 
+      93          10 : unsigned TorsionsMatrix::getNumberOfDerivatives() {
+      94          10 :   return nderivatives;
+      95             : }
+      96             : 
+      97           2 : void TorsionsMatrix::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+      98           2 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[1];
+      99           2 :   if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+     100           6 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     101             :   myvals.setSplitIndex( size_v + 1 );
+     102           2 : }
+     103             : 
+     104     1240496 : void TorsionsMatrix::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     105     1240496 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream(), ind2=index2;
+     106     1240496 :   if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     107             : 
+     108     1240496 :   Vector v1, v2, dv1, dv2, dconn;
+     109             :   // Compute the distance connecting the two centers
+     110     1240496 :   Vector conn=pbcDistance( getPosition(index1), getPosition(index2) );
+     111     2479668 :   if( conn.modulo2()<epsilon ) return;
+     112             : 
+     113             :   // Get the two vectors
+     114     4961624 :   for(unsigned i=0; i<3; ++i) {
+     115     3721218 :     v1[i] = getElementOfMatrixArgument( 0, index1, i, myvals );
+     116     3721218 :     v2[i] = getElementOfMatrixArgument( 1, i, ind2, myvals );
+     117             :   }
+     118             :   // Evaluate angle
+     119     1240406 :   Torsion t; double angle = t.compute( v1, conn, v2, dv1, dconn, dv2 );
+     120     1240406 :   myvals.addValue( ostrn, angle );
+     121             : 
+     122     1240406 :   if( doNotCalculateDerivatives() ) return;
+     123             : 
+     124             :   // Add the derivatives on the matrices
+     125        4936 :   for(unsigned i=0; i<3; ++i) {
+     126        3702 :     addDerivativeOnMatrixArgument( stored_matrix1, 0, 0, index1, i, dv1[i], myvals );
+     127        3702 :     addDerivativeOnMatrixArgument( stored_matrix2, 0, 1, i, ind2, dv2[i], myvals );
+     128             :   }
+     129             :   // And derivatives on positions
+     130        1234 :   unsigned narg_derivatives = getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();
+     131        4936 :   for(unsigned i=0; i<3; ++i) {
+     132        3702 :     myvals.addDerivative( ostrn, narg_derivatives + 3*index1+i, -dconn[i] ); myvals.addDerivative( ostrn, narg_derivatives + 3*index2+i, dconn[i] );
+     133        3702 :     myvals.updateIndex( ostrn, narg_derivatives + 3*index1+i ); myvals.updateIndex( ostrn, narg_derivatives + 3*index2+i );
+     134             :   }
+     135             :   //And virial
+     136        1234 :   Tensor vir( -extProduct( conn, dconn ) ); unsigned virbase = narg_derivatives + 3*getNumberOfAtoms();
+     137       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 ); }
+     138             : }
+     139             : 
+     140        5366 : void TorsionsMatrix::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     141        5366 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     142             : 
+     143         178 :   unsigned mat1s = 3*ival, ss = getPntrToArgument(1)->getShape()[1];
+     144         178 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     145         178 :   unsigned narg_derivatives = getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();
+     146             :   std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntwo_atoms = myvals.getSplitIndex();
+     147         712 :   for(unsigned j=0; j<3; ++j) {
+     148         534 :     matrix_indices[nmat_ind] = mat1s + j; nmat_ind++;
+     149         534 :     matrix_indices[nmat_ind] = narg_derivatives + mat1s + j; nmat_ind++;
+     150        4242 :     for(unsigned i=1; i<ntwo_atoms; ++i) {
+     151        3708 :       unsigned ind2 = indices[i]; if( ind2>=getPntrToArgument(0)->getShape()[0] ) ind2 = indices[i] - getPntrToArgument(0)->getShape()[0];
+     152        3708 :       matrix_indices[nmat_ind] = arg_deriv_starts[1] + j*ss + ind2; nmat_ind++;
+     153        3708 :       matrix_indices[nmat_ind] = narg_derivatives + 3*indices[i] + j; nmat_ind++;
+     154             :     }
+     155             :   }
+     156        1780 :   unsigned base = narg_derivatives + 3*getNumberOfAtoms(); for(unsigned j=0; j<9; ++j) { matrix_indices[nmat_ind] = base + j; nmat_ind++; }
+     157             :   myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     158             : }
+     159             : 
+     160             : }
+     161             : }
+
+
+
+ + + + +
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 000000000..39b3c7180 --- /dev/null +++ b/coverage/adjmat/index-sort-f.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:69572096.5 %
Date:2024-10-17 16:45:00Functions:496377.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Neighbors.cpp +
84.7%84.7%
+
84.7 %50 / 5960.0 %6 / 10
ContactMatrixShortcut.cpp +
86.4%86.4%
+
86.4 %38 / 4466.7 %2 / 3
Bridge.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
BridgeMatrix.cpp +
78.6%78.6%
+
78.6 %33 / 4275.0 %3 / 4
DistanceMatrix.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
HbondMatrix.cpp +
100.0%
+
100.0 %43 / 4375.0 %3 / 4
TopologyMatrix.cpp +
100.0%
+
100.0 %140 / 14075.0 %3 / 4
TorsionsMatrix.cpp +
98.6%98.6%
+
98.6 %72 / 7375.0 %6 / 8
ContactMatrix.cpp +
100.0%
+
100.0 %33 / 3380.0 %4 / 5
AdjacencyMatrixBase.cpp +
100.0%
+
100.0 %213 / 21392.3 %12 / 13
AdjacencyMatrixBase.h +
100.0%
+
100.0 %32 / 32100.0 %5 / 5
+
+
+ + + + +
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 000000000..ed15c15da --- /dev/null +++ b/coverage/adjmat/index-sort-l.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:69572096.5 %
Date:2024-10-17 16:45:00Functions:496377.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BridgeMatrix.cpp +
78.6%78.6%
+
78.6 %33 / 4275.0 %3 / 4
Neighbors.cpp +
84.7%84.7%
+
84.7 %50 / 5960.0 %6 / 10
ContactMatrixShortcut.cpp +
86.4%86.4%
+
86.4 %38 / 4466.7 %2 / 3
TorsionsMatrix.cpp +
98.6%98.6%
+
98.6 %72 / 7375.0 %6 / 8
Bridge.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
DistanceMatrix.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
AdjacencyMatrixBase.h +
100.0%
+
100.0 %32 / 32100.0 %5 / 5
ContactMatrix.cpp +
100.0%
+
100.0 %33 / 3380.0 %4 / 5
HbondMatrix.cpp +
100.0%
+
100.0 %43 / 4375.0 %3 / 4
TopologyMatrix.cpp +
100.0%
+
100.0 %140 / 14075.0 %3 / 4
AdjacencyMatrixBase.cpp +
100.0%
+
100.0 %213 / 21392.3 %12 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index.html b/coverage/adjmat/index.html new file mode 100644 index 000000000..2a1dbe59a --- /dev/null +++ b/coverage/adjmat/index.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:69572096.5 %
Date:2024-10-17 16:45:00Functions:496377.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AdjacencyMatrixBase.cpp +
100.0%
+
100.0 %213 / 21392.3 %12 / 13
AdjacencyMatrixBase.h +
100.0%
+
100.0 %32 / 32100.0 %5 / 5
Bridge.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
BridgeMatrix.cpp +
78.6%78.6%
+
78.6 %33 / 4275.0 %3 / 4
ContactMatrix.cpp +
100.0%
+
100.0 %33 / 3380.0 %4 / 5
ContactMatrixShortcut.cpp +
86.4%86.4%
+
86.4 %38 / 4466.7 %2 / 3
DistanceMatrix.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
HbondMatrix.cpp +
100.0%
+
100.0 %43 / 4375.0 %3 / 4
Neighbors.cpp +
84.7%84.7%
+
84.7 %50 / 5960.0 %6 / 10
TopologyMatrix.cpp +
100.0%
+
100.0 %140 / 14075.0 %3 / 4
TorsionsMatrix.cpp +
98.6%98.6%
+
98.6 %72 / 7375.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/amber.png b/coverage/amber.png new file mode 100644 index 0000000000000000000000000000000000000000..2cab170d8359081983a4e343848dfe06bc490f12 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^G2tW}LqE04T&+ z;1OBOz`!j8!i<;h*8KqrvZOouIx;Y9?C1WI$O`1M1^9%x{(levWG + + + + + + LCOV - plumed test coverage - 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-10-17 16:45:00Functions: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 000000000..4a93f7b5e --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..83bc5026e --- /dev/null +++ b/coverage/annfunc/ANN.cpp.gcov.html @@ -0,0 +1,473 @@ + + + + + + + LCOV - plumed test coverage - annfunc/ANN.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfunc - ANN.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..f05fa763b --- /dev/null +++ b/coverage/annfunc/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..3ded67087 --- /dev/null +++ b/coverage/annfunc/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..a40dff679 --- /dev/null +++ b/coverage/annfunc/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..52d2589e4 --- /dev/null +++ b/coverage/bias/ABMD.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e2c1ea58d --- /dev/null +++ b/coverage/bias/ABMD.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..78669cfe4 --- /dev/null +++ b/coverage/bias/ABMD.cpp.gcov.html @@ -0,0 +1,262 @@ + + + + + + + LCOV - plumed test coverage - bias/ABMD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ABMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..c25c5f28b --- /dev/null +++ b/coverage/bias/Bias.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE963
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE1323
_ZN4PLMD4bias4Bias5applyEv99257
+
+
+ + + +
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 000000000..6ca147e97 --- /dev/null +++ b/coverage/bias/Bias.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE1323
_ZN4PLMD4bias4Bias5applyEv99257
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE963
+
+
+ + + +
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 000000000..01d4efb71 --- /dev/null +++ b/coverage/bias/Bias.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + 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:3636100.0 %
Date:2024-10-17 16:45:00Functions: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         963 : Bias::Bias(const ActionOptions&ao):
+      29             :   Action(ao),
+      30             :   ActionPilot(ao),
+      31             :   ActionWithValue(ao),
+      32             :   ActionWithArguments(ao),
+      33         963 :   outputForces(getNumberOfArguments(),0.0)
+      34             : {
+      35        1926 :   addComponentWithDerivatives("bias");
+      36         963 :   componentIsNotPeriodic("bias");
+      37         963 :   valueBias=getPntrToComponent("bias");
+      38             : 
+      39         963 :   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        5112 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      44        4149 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      45             :   }
+      46             : 
+      47         963 :   ActionWithValue::turnOnDerivatives();
+      48         963 : }
+      49             : 
+      50        1323 : void Bias::registerKeywords( Keywords& keys ) {
+      51        1323 :   Action::registerKeywords(keys);
+      52        1323 :   ActionPilot::registerKeywords(keys);
+      53        1323 :   ActionWithValue::registerKeywords(keys);
+      54        1323 :   ActionWithArguments::registerKeywords(keys);
+      55        2646 :   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        2646 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      57        1323 : }
+      58             : 
+      59       99257 : void Bias::apply() {
+      60       99257 :   const unsigned noa=getNumberOfArguments();
+      61       99257 :   const unsigned ncp=getNumberOfComponents();
+      62             : 
+      63       99257 :   if(onStep()) {
+      64       99257 :     double gstr = static_cast<double>(getStride());
+      65      273647 :     for(unsigned i=0; i<noa; ++i) {
+      66      174390 :       getPntrToArgument(i)->addForce(gstr*outputForces[i]);
+      67             :     }
+      68             :   }
+      69             : 
+      70       99257 :   f.assign(noa,0.0);
+      71       99257 :   forces.resize(noa);
+      72             : 
+      73             :   bool at_least_one_forced=false;
+      74      468021 :   for(unsigned i=0; i<ncp; ++i) {
+      75      368764 :     if(getPntrToComponent(i)->applyForce(forces)) {
+      76             :       at_least_one_forced=true;
+      77         913 :       for(unsigned j=0; j<noa; j++) f[j]+=forces[j];
+      78             :     }
+      79             :   }
+      80             : 
+      81       99257 :   if(at_least_one_forced && !onStep()) error("you are biasing a bias with an inconsistent STRIDE");
+      82             : 
+      83      100098 :   if(at_least_one_forced) for(unsigned i=0; i<noa; ++i) {
+      84         559 :       getPntrToArgument(i)->addForce(f[i]);
+      85             :     }
+      86             : 
+      87       99257 : }
+      88             : 
+      89             : }
+      90             : }
+      91             : 
+      92             : 
+
+
+
+ + + + +
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 000000000..602cdd805 --- /dev/null +++ b/coverage/bias/Bias.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv1085
_ZN4PLMD4bias4Bias7setBiasEd98997
_ZN4PLMD4bias4Bias14setOutputForceEid173392
+
+
+ + + +
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 000000000..e741d5ad6 --- /dev/null +++ b/coverage/bias/Bias.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias14setOutputForceEid173392
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv1085
_ZN4PLMD4bias4Bias7setBiasEd98997
+
+
+ + + +
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 000000000..63b1c98d3 --- /dev/null +++ b/coverage/bias/Bias.h.gcov.html @@ -0,0 +1,159 @@ + + + + + + + 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-10-17 16:45:00Functions: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      173392 : void Bias::setOutputForce(int i,double f) {
+      65      173422 :   outputForces[i]=f;
+      66      173422 :   valueBias->addDerivative(i,-f);
+      67      173392 : }
+      68             : 
+      69             : inline
+      70       98997 : void Bias::setBias(double bias) {
+      71       98997 :   valueBias->set(bias);
+      72       98997 : }
+      73             : 
+      74             : inline
+      75        1085 : unsigned Bias::getNumberOfDerivatives() {
+      76        1085 :   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 000000000..d1284464a --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE204
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE209
_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 000000000..9e177da57 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE209
_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 000000000..af4284945 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - bias/BiasValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - BiasValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-10-17 16:45:00Functions: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         209 : void BiasValue::registerKeywords(Keywords& keys) {
+      85         209 :   Bias::registerKeywords(keys);
+      86         209 :   keys.use("ARG");
+      87             :   // Should be _bias below
+      88         418 :   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         209 : }
+      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 000000000..d821068e4 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:899098.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..172b518a5 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:899098.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..73158249f --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.gcov.html @@ -0,0 +1,337 @@ + + + + + + + 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:899098.9 %
Date:2024-10-17 16:45:00Functions: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           8 :   keys.addOutputComponent("_fict","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     138             :                           "These quantities will named with the arguments of the bias followed by "
+     139             :                           "the character string _tilde. It is possible to add forces on these variable.");
+     140           8 :   keys.addOutputComponent("_vfict","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     141             :                           "These quantities will named with the arguments of the bias followed by "
+     142             :                           "the character string _tilde. It is NOT possible to add forces on these variable.");
+     143           4 : }
+     144             : 
+     145           2 : ExtendedLagrangian::ExtendedLagrangian(const ActionOptions&ao):
+     146             :   PLUMED_BIAS_INIT(ao),
+     147           2 :   firsttime(true),
+     148           4 :   fict(getNumberOfArguments(),0.0),
+     149           2 :   vfict(getNumberOfArguments(),0.0),
+     150           2 :   vfict_laststep(getNumberOfArguments(),0.0),
+     151           2 :   ffict(getNumberOfArguments(),0.0),
+     152           2 :   kappa(getNumberOfArguments(),0.0),
+     153           2 :   tau(getNumberOfArguments(),0.0),
+     154           2 :   friction(getNumberOfArguments(),0.0),
+     155           2 :   fictValue(getNumberOfArguments(),NULL),
+     156           2 :   vfictValue(getNumberOfArguments(),NULL),
+     157           4 :   kbt(0.0)
+     158             : {
+     159           2 :   parseVector("TAU",tau);
+     160           2 :   parseVector("FRICTION",friction);
+     161           2 :   parseVector("KAPPA",kappa);
+     162           2 :   kbt=getkBT(); checkRead();
+     163             : 
+     164           2 :   log.printf("  with harmonic force constant");
+     165           6 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     166           2 :   log.printf("\n");
+     167             : 
+     168           2 :   log.printf("  with relaxation time");
+     169           6 :   for(unsigned i=0; i<tau.size(); i++) log.printf(" %f",tau[i]);
+     170           2 :   log.printf("\n");
+     171             : 
+     172             :   bool hasFriction=false;
+     173           6 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) if(friction[i]>0.0) hasFriction=true;
+     174             : 
+     175           2 :   if(hasFriction) {
+     176           2 :     log.printf("  with friction");
+     177           6 :     for(unsigned i=0; i<friction.size(); i++) log.printf(" %f",friction[i]);
+     178           2 :     log.printf("\n");
+     179             :   }
+     180             : 
+     181           2 :   log.printf("  and kbt");
+     182           2 :   log.printf(" %f",kbt);
+     183           2 :   log.printf("\n");
+     184             : 
+     185           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     186           4 :     std::string comp=getPntrToArgument(i)->getName()+"_fict";
+     187           8 :     addComponentWithDerivatives(comp);
+     188           4 :     if(getPntrToArgument(i)->isPeriodic()) {
+     189             :       std::string a,b;
+     190           4 :       getPntrToArgument(i)->getDomain(a,b);
+     191           4 :       componentIsPeriodic(comp,a,b);
+     192           0 :     } else componentIsNotPeriodic(comp);
+     193           4 :     fictValue[i]=getPntrToComponent(comp);
+     194           8 :     comp=getPntrToArgument(i)->getName()+"_vfict";
+     195           4 :     addComponent(comp);
+     196           4 :     componentIsNotPeriodic(comp);
+     197           4 :     vfictValue[i]=getPntrToComponent(comp);
+     198             :   }
+     199             : 
+     200           4 :   log<<"  Bibliography "<<plumed.cite("Iannuzzi, Laio, and Parrinello, Phys. Rev. Lett. 90, 238302 (2003)");
+     201           2 :   if(hasFriction) {
+     202           4 :     log<<plumed.cite("Maragliano and Vanden-Eijnden, Chem. Phys. Lett. 426, 168 (2006)");
+     203           4 :     log<<plumed.cite("Abrams and Tuckerman, J. Phys. Chem. B 112, 15742 (2008)");
+     204             :   }
+     205           2 :   log<<"\n";
+     206           2 : }
+     207             : 
+     208             : 
+     209          24 : void ExtendedLagrangian::calculate() {
+     210             : 
+     211          24 :   if(firsttime) {
+     212           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     213           4 :       fict[i]=getArgument(i);
+     214             :     }
+     215           2 :     firsttime=false;
+     216             :   }
+     217             :   double ene=0.0;
+     218          72 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     219          48 :     const double cv=difference(i,fict[i],getArgument(i));
+     220          48 :     const double k=kappa[i];
+     221          48 :     const double f=-k*cv;
+     222          48 :     ene+=0.5*k*cv*cv;
+     223          48 :     setOutputForce(i,f);
+     224          48 :     ffict[i]=-f;
+     225             :   };
+     226          24 :   setBias(ene);
+     227          72 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     228          48 :     fict[i]=fictValue[i]->bringBackInPbc(fict[i]);
+     229          48 :     fictValue[i]->set(fict[i]);
+     230          48 :     vfictValue[i]->set(vfict_laststep[i]);
+     231             :   }
+     232          24 : }
+     233             : 
+     234          24 : void ExtendedLagrangian::update() {
+     235          24 :   double dt=getTimeStep()*getStride();
+     236          72 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     237          48 :     double mass=kappa[i]*tau[i]*tau[i]/(4*pi*pi); // should be k/omega**2
+     238          48 :     double c1=std::exp(-0.5*friction[i]*dt);
+     239          48 :     double c2=std::sqrt(kbt*(1.0-c1*c1)/mass);
+     240             : // consider additional forces on the fictitious particle
+     241             : // (e.g. MetaD stuff)
+     242          48 :     ffict[i]+=fictValue[i]->getForce();
+     243             : 
+     244             : // update velocity (half step)
+     245          48 :     vfict[i]+=ffict[i]*0.5*dt/mass;
+     246             : // thermostat (half step)
+     247          48 :     vfict[i]=c1*vfict[i]+c2*rand.Gaussian();
+     248             : // save full step velocity to be dumped at next step
+     249          48 :     vfict_laststep[i]=vfict[i];
+     250             : // thermostat (half step)
+     251          48 :     vfict[i]=c1*vfict[i]+c2*rand.Gaussian();
+     252             : // update velocity (half step)
+     253          48 :     vfict[i]+=ffict[i]*0.5*dt/mass;
+     254             : // update position (full step)
+     255          48 :     fict[i]+=vfict[i]*dt;
+     256             :   }
+     257          24 : }
+     258             : 
+     259             : }
+     260             : 
+     261             : }
+
+
+
+ + + + +
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 000000000..bbd2662d1 --- /dev/null +++ b/coverage/bias/External.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e752c7829 --- /dev/null +++ b/coverage/bias/External.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f188dc80a --- /dev/null +++ b/coverage/bias/External.cpp.gcov.html @@ -0,0 +1,256 @@ + + + + + + + LCOV - plumed test coverage - bias/External.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - External.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..526d2cdb8 --- /dev/null +++ b/coverage/bias/LWalls.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6LWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE5
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4bias6LWalls9calculateEv49
+
+
+ + + +
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 000000000..912ee059e --- /dev/null +++ b/coverage/bias/LWalls.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4bias6LWalls9calculateEv49
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE5
_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 000000000..d058a9150 --- /dev/null +++ b/coverage/bias/LWalls.cpp.gcov.html @@ -0,0 +1,240 @@ + + + + + + + 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-10-17 16:45:00Functions: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             : for UPPER_WALLS:
+      39             : \f$
+      40             :   \sum_i {k_i}((x_i-a_i+o_i)/s_i)^e_i
+      41             : \f$
+      42             : 
+      43             : for LOWER_WALLS:
+      44             : \f$
+      45             :   \sum_i {k_i}|(x_i-a_i-o_i)/s_i|^e_i
+      46             : \f$
+      47             : 
+      48             : \f$k_i\f$ (KAPPA) is an energy constant in internal unit of the code, \f$s_i\f$ (EPS) a rescaling factor and
+      49             : \f$e_i\f$ (EXP) the exponent determining the power law. By default: EXP = 2, EPS = 1.0, OFFSET = 0.
+      50             : 
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following input tells plumed to add both a lower and an upper walls on the distance
+      55             : between atoms 3 and 5 and the distance between atoms 2 and 4. The lower and upper limits
+      56             : are defined at different values. The strength of the walls is the same for the four cases.
+      57             : It also tells plumed to print the energy of the walls.
+      58             : \plumedfile
+      59             : DISTANCE ATOMS=3,5 LABEL=d1
+      60             : DISTANCE ATOMS=2,4 LABEL=d2
+      61             : 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
+      62             : 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
+      63             : PRINT ARG=uwall.bias,lwall.bias
+      64             : \endplumedfile
+      65             : (See also \ref DISTANCE and \ref PRINT).
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : //+PLUMEDOC BIAS LOWER_WALLS_SCALAR
+      71             : /*
+      72             : Defines a wall for the value of one or more collective variables,
+      73             :  which limits the region of the phase space accessible during the simulation.
+      74             : 
+      75             : \par Examples
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : class LWalls : public Bias {
+      81             :   std::vector<double> at;
+      82             :   std::vector<double> kappa;
+      83             :   std::vector<double> exp;
+      84             :   std::vector<double> eps;
+      85             :   std::vector<double> offset;
+      86             : public:
+      87             :   explicit LWalls(const ActionOptions&);
+      88             :   void calculate() override;
+      89             :   static void registerKeywords(Keywords& keys);
+      90             : };
+      91             : 
+      92             : PLUMED_REGISTER_ACTION(LWalls,"LOWER_WALLS_SCALAR")
+      93             : 
+      94          12 : void LWalls::registerKeywords(Keywords& keys) {
+      95          12 :   Bias::registerKeywords(keys); keys.setDisplayName("LOWER_WALLS");
+      96          36 :   keys.use("ARG"); keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      97          24 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      98          24 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      99          24 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+     100          24 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+     101          24 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+     102          24 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     103          12 : }
+     104             : 
+     105           5 : LWalls::LWalls(const ActionOptions&ao):
+     106             :   PLUMED_BIAS_INIT(ao),
+     107          10 :   at(getNumberOfArguments(),0),
+     108           5 :   kappa(getNumberOfArguments(),0.0),
+     109           5 :   exp(getNumberOfArguments(),2.0),
+     110           5 :   eps(getNumberOfArguments(),1.0),
+     111          10 :   offset(getNumberOfArguments(),0.0)
+     112             : {
+     113             :   // Note sizes of these vectors are automatically checked by parseVector :-)
+     114           5 :   parseVector("OFFSET",offset);
+     115           5 :   parseVector("EPS",eps);
+     116           5 :   parseVector("EXP",exp);
+     117           5 :   parseVector("KAPPA",kappa);
+     118           5 :   parseVector("AT",at);
+     119           5 :   checkRead();
+     120             : 
+     121           5 :   log.printf("  at");
+     122          10 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     123           5 :   log.printf("\n");
+     124           5 :   log.printf("  with an offset");
+     125          10 :   for(unsigned i=0; i<offset.size(); i++) log.printf(" %f",offset[i]);
+     126           5 :   log.printf("\n");
+     127           5 :   log.printf("  with force constant");
+     128          10 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     129           5 :   log.printf("\n");
+     130           5 :   log.printf("  and exponent");
+     131          10 :   for(unsigned i=0; i<exp.size(); i++) log.printf(" %f",exp[i]);
+     132           5 :   log.printf("\n");
+     133           5 :   log.printf("  rescaled");
+     134          10 :   for(unsigned i=0; i<eps.size(); i++) log.printf(" %f",eps[i]);
+     135           5 :   log.printf("\n");
+     136             : 
+     137          10 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     138           5 : }
+     139             : 
+     140          49 : void LWalls::calculate() {
+     141             :   double ene = 0.0;
+     142             :   double totf2 = 0.0;
+     143          98 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     144             :     double f = 0.0;
+     145          49 :     const double cv=difference(i,at[i],getArgument(i));
+     146          49 :     const double off=offset[i];
+     147          49 :     const double epsilon=eps[i];
+     148          49 :     const double lscale = (cv-off)/epsilon;
+     149          49 :     if( lscale < 0.) {
+     150          25 :       const double k=kappa[i];
+     151          25 :       const double exponent=exp[i];
+     152          25 :       double power = std::pow( -lscale, exponent );
+     153          25 :       f = -( k / epsilon ) * exponent * power / lscale;
+     154          25 :       ene += k * power;
+     155          25 :       totf2 += f * f;
+     156             :     }
+     157          49 :     setOutputForce(i,f);
+     158             :   }
+     159          49 :   setBias(ene);
+     160          49 :   getPntrToComponent("force2")->set(totf2);
+     161          49 : }
+     162             : 
+     163             : }
+     164             : }
+
+
+
+ + + + +
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 000000000..bf6dadbec --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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:22423296.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..08a66bf3d --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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:22423296.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..5f34b2024 --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.gcov.html @@ -0,0 +1,559 @@ + + + + + + + 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:22423296.6 %
Date:2024-10-17 16:45:00Functions: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 :   keys.use("ARG");
+     167         104 :   keys.add("compulsory","KAPPA","0.0","specifies the initial value for the learning rate");
+     168         104 :   keys.add("compulsory","TAU","Specify the dumping time for the learning rate.");
+     169         104 :   keys.add("compulsory","TYPE","specify the restraint type. "
+     170             :            "EQUAL to restrain the variable at a given equilibrium value "
+     171             :            "INEQUAL< to restrain the variable to be smaller than a given value "
+     172             :            "INEQUAL> to restrain the variable to be greater than a given value");
+     173         104 :   keys.add("optional","ERROR_TYPE","specify the prior on the error to use."
+     174             :            "GAUSSIAN: use a Gaussian prior "
+     175             :            "LAPLACE: use a Laplace prior");
+     176         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");
+     177         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;");
+     178         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.");
+     179         104 :   keys.add("compulsory","AT","the position of the restraint");
+     180         104 :   keys.add("optional","SIGMA","The typical errors expected on observable");
+     181         104 :   keys.add("optional","FILE","Lagrangian multipliers output file. The default name is: label name followed by the string .LAGMULT ");
+     182         104 :   keys.add("optional","LEARN_REPLICA","In a multiple replica environment specify which is the reference replica. By default replica 0 will be used.");
+     183         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.");
+     184         104 :   keys.add("optional","PACE","the frequency for Lagrangian multipliers update");
+     185         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).");
+     186         104 :   keys.add("optional","FMT","specify format for Lagrangian multipliers files (useful to decrease the number of digits in regtests)");
+     187         104 :   keys.addFlag("REWEIGHT",false,"to be used with plumed driver in order to reweight a trajectory a posteriori");
+     188         104 :   keys.addFlag("NO_BROADCAST",false,"If active will avoid Lagrangian multipliers to be communicated to other replicas.");
+     189         104 :   keys.add("optional","TEMP","the system temperature.  This is required if you are reweighting.");
+     190         104 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     191         104 :   keys.addOutputComponent("work","default","the instantaneous value of the work done by the biasing force");
+     192         104 :   keys.addOutputComponent("_work","default","the instantaneous value of the work done by the biasing force for each argument. "
+     193             :                           "These quantities will named with the arguments of the bias followed by "
+     194             :                           "the character string _work.");
+     195         104 :   keys.addOutputComponent("_error","default","Instantaneous values of the discrepancy between the observable and the restraint center");
+     196         104 :   keys.addOutputComponent("_coupling","default","Instantaneous values of Lagrangian multipliers. They are also written by default in a separate output file.");
+     197          52 :   keys.use("RESTART");
+     198          52 : }
+     199          50 : MaxEnt::MaxEnt(const ActionOptions&ao):
+     200             :   PLUMED_BIAS_INIT(ao),
+     201         100 :   at(getNumberOfArguments()),
+     202          50 :   kappa(getNumberOfArguments(),0.0),
+     203          50 :   lambda(getNumberOfArguments(),0.0),
+     204          50 :   avgx(getNumberOfArguments(),0.0),
+     205          50 :   oldlambda(getNumberOfArguments(),0.0),
+     206          50 :   tau(getNumberOfArguments(),getTimeStep()),
+     207          50 :   avglambda(getNumberOfArguments(),0.0),
+     208          50 :   avglambda_restart(getNumberOfArguments(),0.0),
+     209          50 :   expected_eps(getNumberOfArguments(),0.0),
+     210          50 :   sigma(0.0),
+     211          50 :   pace_(100),
+     212          50 :   stride_(100),
+     213          50 :   alpha(1.0),
+     214          50 :   avg_counter(0.0),
+     215          50 :   isFirstStep(true),
+     216          50 :   reweight(false),
+     217          50 :   no_broadcast(false),
+     218          50 :   printFirstStep(true),
+     219         150 :   done_average(getNumberOfArguments(),false)
+     220             : {
+     221          50 :   if(comm.Get_rank()==0) nrep=multi_sim_comm.Get_size();
+     222          50 :   if(comm.Get_rank()==0) myrep=multi_sim_comm.Get_rank();
+     223          50 :   comm.Bcast(nrep,0);
+     224          50 :   comm.Bcast(myrep,0);
+     225          50 :   parseFlag("NO_BROADCAST",no_broadcast);
+     226             :   //if(no_broadcast){
+     227             :   //for(int irep=0;irep<nrep;irep++){
+     228             :   //  if(irep!=myrep)
+     229             :   //    apply_weights[irep]=0.0;}
+     230             :   //}
+     231          50 :   avgstep=1.0;
+     232          50 :   tstart=-1.0;
+     233          50 :   tend=-1.0;
+     234          50 :   totalWork=0.0;
+     235          50 :   learn_replica=0;
+     236             : 
+     237          50 :   parse("LEARN_REPLICA",learn_replica);
+     238         100 :   parseVector("APPLY_WEIGHTS",apply_weights);
+     239          50 :   if(apply_weights.size()==0) apply_weights.resize(nrep,1.0);
+     240          50 :   parseVector("KAPPA",kappa);
+     241          50 :   parseVector("AT",at);
+     242          50 :   parseVector("TAU",tau);
+     243         100 :   parse("TYPE",type);
+     244             :   error_type="GAUSSIAN";
+     245          50 :   parse("ERROR_TYPE",error_type);
+     246          50 :   parse("ALPHA",alpha);
+     247          50 :   parse("SIGMA",sigma);
+     248          50 :   parse("TSTART",tstart);
+     249          50 :   if(tstart <0 && tstart != -1.0) error("TSTART should be a positive number");
+     250          50 :   parse("TEND",tend);
+     251          50 :   if(tend<0 && tend != -1.0) error("TSTART should be a positive number");
+     252          50 :   if(tend<tstart) error("TEND should be >= TSTART");
+     253          50 :   lagmultfname=getLabel()+".LAGMULT";
+     254          50 :   parse("FILE",lagmultfname);
+     255          50 :   parse("FMT",fmt);
+     256          50 :   parse("PACE",pace_);
+     257          50 :   if(pace_<=0 ) error("frequency for Lagrangian multipliers update (PACE) is nonsensical");
+     258          50 :   stride_=pace_;  //if no STRIDE is passed, then Lagrangian multipliers willbe printed at each update
+     259          50 :   parse("PRINT_STRIDE",stride_);
+     260          50 :   if(stride_<=0 ) error("frequency for Lagrangian multipliers printing (STRIDE) is nonsensical");
+     261          50 :   simtemp=getkBT();
+     262          50 :   parseFlag("REWEIGHT",reweight);
+     263          50 :   if(simtemp<=0 && reweight) error("Set the temperature (TEMP) if you want to do reweighting.");
+     264             : 
+     265          50 :   checkRead();
+     266             : 
+     267          50 :   log.printf("  at");
+     268         532 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     269          50 :   log.printf("\n");
+     270          50 :   log.printf("  with initial learning rate for optimization of");
+     271         532 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     272          50 :   log.printf("\n");
+     273          50 :   log.printf("Dumping times for the learning rates are (ps): ");
+     274         532 :   for(unsigned i=0; i<tau.size(); i++) log.printf(" %f",tau[i]);
+     275          50 :   log.printf("\n");
+     276          50 :   log.printf("Lagrangian multipliers are updated every %lld steps (PACE)\n",pace_);
+     277          50 :   log.printf("Lagrangian multipliers output file %s\n",lagmultfname.c_str());
+     278          50 :   log.printf("Lagrangian multipliers are written every %lld steps (PRINT_STRIDE)\n",stride_);
+     279          50 :   if(fmt.length()>0)
+     280          50 :     log.printf("The format for real number in Lagrangian multipliers file is %s\n",fmt.c_str());
+     281          50 :   if(tstart >-1.0 && tend>-1.0)
+     282          14 :     log.printf("Lagrangian multipliers are averaged from %lf ps to %lf ps\n",tstart,tend);
+     283          50 :   if(no_broadcast)
+     284           0 :     log.printf("Using NO_BROADCAST options. Lagrangian multipliers will not be comunicated to other replicas.\n");
+     285             :   //for(int irep=0;irep<nrep;irep++){
+     286             :   //  if(apply_weights[irep]!=0)
+     287             :   //    log.printf("%d",irep);
+     288             :   //  }
+     289         150 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     290         100 :   addComponent("work"); componentIsNotPeriodic("work");
+     291          50 :   valueForce2=getPntrToComponent("force2");
+     292          50 :   valueWork=getPntrToComponent("work");
+     293             : 
+     294             :   std::string comp;
+     295         532 :   for(unsigned i=0; i< getNumberOfArguments() ; i++) {
+     296         964 :     comp=getPntrToArgument(i)->getName()+"_coupling";
+     297         964 :     addComponent(comp); componentIsNotPeriodic(comp);
+     298         964 :     comp=getPntrToArgument(i)->getName()+"_work";
+     299         964 :     addComponent(comp); componentIsNotPeriodic(comp);
+     300         482 :     work.push_back(0.); // initialize the work value
+     301         964 :     comp=getPntrToArgument(i)->getName()+"_error";
+     302         964 :     addComponent(comp); componentIsNotPeriodic(comp);
+     303             :   }
+     304             :   std::string fname;
+     305             :   fname=lagmultfname;
+     306          50 :   ifile.link(*this);
+     307          50 :   if(ifile.FileExist(fname)) {
+     308          37 :     ifile.open(fname);
+     309          37 :     if(getRestart()) {
+     310          37 :       log.printf("  Restarting from: %s\n",fname.c_str());
+     311          37 :       ReadLagrangians(ifile);
+     312          37 :       printFirstStep=false;
+     313             :     }
+     314          37 :     ifile.reset(false);
+     315             :   }
+     316             : 
+     317          50 :   lagmultOfile_.link(*this);
+     318          50 :   lagmultOfile_.open(fname);
+     319         100 :   if(fmt.length()>0) {fmt=" "+fmt; lagmultOfile_.fmtField(fmt);}
+     320          50 : }
+     321             : ////MEMBER FUNCTIONS
+     322          37 : void MaxEnt::ReadLagrangians(IFile &ifile)
+     323             : {
+     324             :   double dummy;
+     325         888 :   while(ifile.scanField("time",dummy)) {
+     326        4708 :     for(unsigned j=0; j<getNumberOfArguments(); ++j) {
+     327        4301 :       ifile.scanField(getPntrToArgument(j)->getName()+"_coupling",lambda[j]);
+     328        4301 :       if(dummy>=tstart && dummy <=tend)
+     329          42 :         avglambda[j]+=lambda[j];
+     330        4301 :       if(dummy>=tend) {
+     331        4231 :         avglambda[j]=lambda[j];
+     332             :         done_average[j]=true;
+     333             :       }
+     334             :     }
+     335         407 :     if(dummy>=tstart && dummy <=tend)
+     336           6 :       avg_counter++;
+     337         407 :     ifile.scanField();
+     338             :   }
+     339          37 : }
+     340         550 : void MaxEnt::WriteLagrangians(std::vector<double> &lagmult,OFile &file) {
+     341         550 :   if(printFirstStep) {
+     342         143 :     unsigned ncv=getNumberOfArguments();
+     343         143 :     file.printField("time",getTimeStep()*getStep());
+     344        1144 :     for(unsigned i=0; i<ncv; ++i)
+     345        2002 :       file.printField(getPntrToArgument(i)->getName()+"_coupling",lagmult[i]);
+     346         143 :     file.printField();
+     347             :   } else {
+     348         407 :     if(!isFirstStep) {
+     349         370 :       unsigned ncv=getNumberOfArguments();
+     350         370 :       file.printField("time",getTimeStep()*getStep());
+     351        4280 :       for(unsigned i=0; i<ncv; ++i)
+     352        7820 :         file.printField(getPntrToArgument(i)->getName()+"_coupling",lagmult[i]);
+     353         370 :       file.printField();
+     354             :     }
+     355             :   }
+     356         550 : }
+     357        5302 : double MaxEnt::compute_error(const std::string &err_type,double l) {
+     358        5302 :   double sigma2=std::pow(sigma,2.0);
+     359        5302 :   double l2=convert_lambda(type,l);
+     360             :   double return_error=0;
+     361        5302 :   if(err_type=="GAUSSIAN" && sigma!=0.0)
+     362           0 :     return_error=-l2*sigma2;
+     363             :   else {
+     364        5302 :     if(err_type=="LAPLACE" && sigma!=0) {
+     365        5302 :       return_error=-l2*sigma2/(1.0-l2*l2*sigma2/(alpha+1));
+     366             :     }
+     367             :   }
+     368        5302 :   return return_error;
+     369             : }
+     370      119118 : double MaxEnt::convert_lambda(const std::string &type,double lold) {
+     371             :   double return_lambda=0;
+     372      119118 :   if(type=="EQUAL")
+     373             :     return_lambda=lold;
+     374             :   else {
+     375        5302 :     if(type=="INEQUAL>") {
+     376           0 :       if(lold>0.0)
+     377             :         return_lambda=0.0;
+     378             :       else
+     379             :         return_lambda=lold;
+     380             :     }
+     381             :     else {
+     382        5302 :       if(type=="INEQUAL<") {
+     383           0 :         if(lold<0.0)
+     384             :           return_lambda=0.0;
+     385             :         else
+     386             :           return_lambda=lold;
+     387             :       }
+     388             :     }
+     389             :   }
+     390      119118 :   return return_lambda;
+     391             : }
+     392        5302 : void MaxEnt::check_lambda_boundaries(const std::string &err_type,double &l) {
+     393        5302 :   if(err_type=="LAPLACE" && sigma !=0 ) {
+     394        5302 :     double l2=convert_lambda(err_type,l);
+     395        5302 :     if(l2 <-(std::sqrt(alpha+1)/sigma-0.01)) {
+     396           0 :       l=-(std::sqrt(alpha+1)/sigma-0.01);
+     397           0 :       log.printf("Lambda exceeded the allowed range\n");
+     398             :     }
+     399        5302 :     if(l2>(std::sqrt(alpha+1)/sigma-0.01)) {
+     400           0 :       l=std::sqrt(alpha+1)/sigma-0.01;
+     401           0 :       log.printf("Lambda exceeded the allowed range\n");
+     402             :     }
+     403             :   }
+     404        5302 : }
+     405             : 
+     406         550 : void MaxEnt::update_lambda() {
+     407             : 
+     408             :   double totalWork_=0.0;
+     409         550 :   const double time=getTime();
+     410         550 :   const double step=getStep();
+     411         550 :   double KbT=simtemp;
+     412             :   double learning_rate;
+     413         550 :   if(reweight)
+     414         396 :     BetaReweightBias=plumed.getBias()/KbT;
+     415             :   else
+     416         154 :     BetaReweightBias=0.0;
+     417             : 
+     418        5852 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     419        5302 :     const double k=kappa[i];
+     420        5302 :     double cv=(getArgument(i)+compute_error(error_type,lambda[i])-at[i]);
+     421        5302 :     if(reweight)
+     422        4224 :       learning_rate=1.0*k/(1+step/tau[i]);
+     423             :     else
+     424        1078 :       learning_rate=1.0*k/(1+time/tau[i]);
+     425        5302 :     lambda[i]+=learning_rate*cv*std::exp(-BetaReweightBias); //update Lagrangian multipliers and reweight them if REWEIGHT is set
+     426        5302 :     check_lambda_boundaries(error_type,lambda[i]);      //check that Lagrangians multipliers not exceed the allowed range
+     427        5890 :     if(time>=tstart && time <=tend && !done_average[i]) {
+     428         546 :       avglambda[i]+=convert_lambda(type,lambda[i]); //compute the average of Lagrangian multipliers over the required time window
+     429             :     }
+     430        5302 :     if(time>=tend && tend >=0) { //setting tend<0 will disable this feature
+     431          98 :       if(!done_average[i]) {
+     432          91 :         avglambda[i]=avglambda[i]/avg_counter;
+     433             :         done_average[i]=true;
+     434          91 :         lambda[i]=avglambda[i];
+     435             :       }
+     436             :       else
+     437           7 :         lambda[i]=avglambda[i]; //keep Lagrangian multipliers fixed to the previously computed average.
+     438             :     }
+     439        5302 :     work[i]+=(convert_lambda(type,lambda[i])-oldlambda[i])*getArgument(i); //compute the work performed in updating lambda
+     440        5302 :     totalWork_+=work[i];
+     441        5302 :     totalWork=totalWork_;
+     442        5302 :     oldlambda[i]=convert_lambda(type,lambda[i]);
+     443             :   };
+     444         550 :   if(time>=tstart && time <=tend)
+     445          84 :     avg_counter++;
+     446         550 : }
+     447             : 
+     448        5050 : void MaxEnt::calculate() {
+     449             :   double totf2=0.0;
+     450             :   double ene=0.0;
+     451        5050 :   double KbT=simtemp;
+     452       53732 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     453       97364 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_error")->set(expected_eps[i]);
+     454       48682 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_work")->set(work[i]);
+     455       48682 :     valueWork->set(totalWork);
+     456       48682 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_coupling")->set(lambda[i]);
+     457       48682 :     const double f=-KbT*convert_lambda(type,lambda[i])*apply_weights[myrep];
+     458       48682 :     totf2+=f*f;
+     459       48682 :     ene+=KbT*convert_lambda(type,lambda[i])*getArgument(i)*apply_weights[myrep];
+     460       48682 :     setOutputForce(i,f);
+     461             :   }
+     462        5050 :   setBias(ene);
+     463        5050 :   valueForce2->set(totf2);
+     464        5050 : }
+     465             : 
+     466        5050 : void MaxEnt::update() {
+     467             : 
+     468        5050 :   if(getStep()%stride_ == 0)
+     469         550 :     WriteLagrangians(lambda,lagmultOfile_);
+     470        5050 :   if(getStep()%pace_ == 0) {
+     471         550 :     update_lambda();
+     472         550 :     if(!no_broadcast) {
+     473         550 :       if(comm.Get_rank()==0) //Comunicate Lagrangian multipliers from reference replica to higher ones
+     474         462 :         multi_sim_comm.Bcast(lambda,learn_replica);
+     475             :     }
+     476         550 :     comm.Bcast(lambda,0);
+     477             :   }
+     478        5050 :   isFirstStep=false;
+     479        5050 : }
+     480             : 
+     481             : }
+     482             : 
+     483             : }
+
+
+
+ + + + +
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 000000000..b5fa8e16d --- /dev/null +++ b/coverage/bias/MetaD.cpp.func-sort-c.html @@ -0,0 +1,184 @@ + + + + + + + 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-10-17 16:45:00Functions: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_8GaussianE5125
_ZN4PLMD4bias5MetaD8GaussianC2EbdRKSt6vectorIdSaIdEES7_5125
_ZN4PLMD4bias5MetaD13readGaussiansEPNS_5IFileE6037
_ZN4PLMD4bias5MetaD6updateEv6239
_ZN4PLMD4bias5MetaD11scanOneHillEPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb8078
_ZN4PLMD4bias5MetaD21getBiasAndDerivativesERKSt6vectorIdSaIdEERS4_8395
_ZN4PLMD4bias5MetaD9calculateEv8435
_ZNK4PLMD4bias5MetaD19checkNeedsGradientsEv8435
_ZN4PLMD4bias5MetaD30evaluateGaussianAndDerivativesERKSt6vectorIdSaIdEERKNS1_8GaussianERS4_SA_2409206
+
+
+ + + +
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 000000000..4798b158c --- /dev/null +++ b/coverage/bias/MetaD.cpp.func.html @@ -0,0 +1,184 @@ + + + + + + + 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-10-17 16:45:00Functions:262892.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5MetaD11addGaussianERKNS1_8GaussianE5125
_ZN4PLMD4bias5MetaD11scanOneHillEPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb8078
_ZN4PLMD4bias5MetaD11updateNlistEv4
_ZN4PLMD4bias5MetaD12temperHeightERdRKNS1_14TemperingSpecsEd60
_ZN4PLMD4bias5MetaD13readGaussiansEPNS_5IFileE6037
_ZN4PLMD4bias5MetaD13writeGaussianERKNS1_8GaussianERNS_5OFileE2922
_ZN4PLMD4bias5MetaD14TemperingSpecsC2EbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ddd156
_ZN4PLMD4bias5MetaD16evaluateGaussianERKSt6vectorIdSaIdEERKNS1_8GaussianE192
_ZN4PLMD4bias5MetaD16noStretchWarningEv12
_ZN4PLMD4bias5MetaD16registerKeywordsERNS_8KeywordsE159
_ZN4PLMD4bias5MetaD17logTemperingSpecsERKNS1_14TemperingSpecsE3
_ZN4PLMD4bias5MetaD18getGaussianSupportERKNS1_8GaussianE640
_ZN4PLMD4bias5MetaD18readTemperingSpecsERNS1_14TemperingSpecsE151
_ZN4PLMD4bias5MetaD21getBiasAndDerivativesERKSt6vectorIdSaIdEERS4_8395
_ZN4PLMD4bias5MetaD24computeReweightingFactorEv102
_ZN4PLMD4bias5MetaD24getGaussianNormalizationERKNS1_8GaussianE0
_ZN4PLMD4bias5MetaD24getTransitionBarrierBiasEv273
_ZN4PLMD4bias5MetaD25registerTemperingKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RNS_8KeywordsE159
_ZN4PLMD4bias5MetaD29updateFrequencyAdaptiveStrideEv154
_ZN4PLMD4bias5MetaD30evaluateGaussianAndDerivativesERKSt6vectorIdSaIdEERKNS1_8GaussianERS4_SA_2409206
_ZN4PLMD4bias5MetaD6updateEv6239
_ZN4PLMD4bias5MetaD7getBiasERKSt6vectorIdSaIdEE285
_ZN4PLMD4bias5MetaD8GaussianC2EbdRKSt6vectorIdSaIdEES7_5125
_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 000000000..54b6645e9 --- /dev/null +++ b/coverage/bias/MetaD.cpp.gcov.html @@ -0,0 +1,2380 @@ + + + + + + + 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-10-17 16:45:00Functions: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        5125 :     Gaussian(const bool m, const double h, const std::vector<double>& c, const std::vector<double>& s):
+     381        5125 :       multivariate(m),height(h),center(c),sigma(s),invsigma(s) {
+     382             :       // to avoid troubles from zero element in flexible hills
+     383       14912 :       for(unsigned i=0; i<invsigma.size(); ++i) {
+     384        9787 :         if(std::abs(invsigma[i])>1.e-20) invsigma[i]=1.0/invsigma[i] ;
+     385           0 :         else invsigma[i]=0.0;
+     386             :       }
+     387        5125 :     }
+     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 c(t).");
+     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 c(t) reweighting factor."
+     552             :            "The default 1, so c(t) is updated every time the bias is updated.");
+     553         318 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     554         318 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     555         318 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     556         318 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     557         318 :   keys.addFlag("GRID_SPARSE",false,"use a sparse grid to store hills");
+     558         318 :   keys.addFlag("GRID_NOSPLINE",false,"don't use spline interpolation with grids");
+     559         318 :   keys.add("optional","GRID_WSTRIDE","write the grid to a file every N steps");
+     560         318 :   keys.add("optional","GRID_WFILE","the file on which to write the grid");
+     561         318 :   keys.add("optional","GRID_RFILE","a grid file from which the bias should be read at the initial step of the simulation");
+     562         318 :   keys.addFlag("STORE_GRIDS",false,"store all the grid files the calculation generates. They will be deleted if this keyword is not present");
+     563         318 :   keys.addFlag("NLIST",false,"Use neighbor list for kernels summation, faster but experimental");
+     564         318 :   keys.add("optional", "NLIST_PARAMETERS","(default=6.,0.5) the two cutoff parameters for the Gaussians neighbor list");
+     565         318 :   keys.add("optional","ADAPTIVE","use a geometric (=GEOM) or diffusion (=DIFF) based hills width scheme. Sigma is one number that has distance units or time step dimensions");
+     566         318 :   keys.add("optional","SIGMA_MAX","the upper bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     567         318 :   keys.add("optional","SIGMA_MIN","the lower bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     568         318 :   keys.add("optional","WALKERS_ID", "walker id");
+     569         318 :   keys.add("optional","WALKERS_N", "number of walkers");
+     570         318 :   keys.add("optional","WALKERS_DIR", "shared directory with the hills files from all the walkers");
+     571         318 :   keys.add("optional","WALKERS_RSTRIDE","stride for reading hills files");
+     572         318 :   keys.addFlag("WALKERS_MPI",false,"Switch on MPI version of multiple walkers - not compatible with WALKERS_* options other than WALKERS_DIR");
+     573         318 :   keys.add("optional","INTERVAL","one dimensional lower and upper limits, outside the limits the system will not feel the biasing force.");
+     574         318 :   keys.addFlag("FLYING_GAUSSIAN",false,"Switch on flying Gaussian method, must be used with WALKERS_MPI");
+     575         318 :   keys.addFlag("ACCELERATION",false,"Set to TRUE if you want to compute the metadynamics acceleration factor.");
+     576         318 :   keys.add("optional","ACCELERATION_RFILE","a data file from which the acceleration should be read at the initial step of the simulation");
+     577         318 :   keys.addFlag("CALC_MAX_BIAS", false, "Set to TRUE if you want to compute the maximum of the metadynamics V(s, t)");
+     578         318 :   keys.addFlag("CALC_TRANSITION_BIAS", false, "Set to TRUE if you want to compute a metadynamics transition bias V*(t)");
+     579         318 :   keys.add("numbered", "TRANSITIONWELL", "This keyword appears multiple times as TRANSITIONWELL followed by an integer. Each specifies the coordinates for one well as in transition-tempered metadynamics. At least one must be provided.");
+     580         318 :   keys.addFlag("FREQUENCY_ADAPTIVE",false,"Set to TRUE if you want to enable frequency adaptive metadynamics such that the frequency for hill addition to change dynamically based on the acceleration factor.");
+     581         318 :   keys.add("optional","FA_UPDATE_FREQUENCY","the frequency for updating the hill addition pace in frequency adaptive metadynamics, by default this is equal to the value given in PACE");
+     582         318 :   keys.add("optional","FA_MAX_PACE","the maximum hill addition frequency allowed in frequency adaptive metadynamics. By default there is no maximum value.");
+     583         318 :   keys.add("optional","FA_MIN_ACCELERATION","only update the hill addition pace in frequency adaptive metadynamics after reaching the minimum acceleration factor given here. By default it is 1.0.");
+     584         159 :   keys.use("RESTART");
+     585         159 :   keys.use("UPDATE_FROM");
+     586         159 :   keys.use("UPDATE_UNTIL");
+     587         159 : }
+     588             : 
+     589             : const std::string MetaD::tempering_names_[1][2] = {{"TT", "transition tempered"}};
+     590             : 
+     591         159 : void MetaD::registerTemperingKeywords(const std::string &name_stem, const std::string &name, Keywords &keys) {
+     592         318 :   keys.add("optional", name_stem + "BIASFACTOR", "use " + name + " metadynamics with this bias factor.  Please note you must also specify temp");
+     593         318 :   keys.add("optional", name_stem + "BIASTHRESHOLD", "use " + name + " metadynamics with this bias threshold.  Please note you must also specify " + name_stem + "BIASFACTOR");
+     594         318 :   keys.add("optional", name_stem + "ALPHA", "use " + name + " metadynamics with this hill size decay exponent parameter.  Please note you must also specify " + name_stem + "BIASFACTOR");
+     595         159 : }
+     596             : 
+     597         157 : MetaD::MetaD(const ActionOptions& ao):
+     598             :   PLUMED_BIAS_INIT(ao),
+     599         156 :   kbt_(0.0),
+     600         156 :   stride_(0),
+     601         156 :   calc_work_(false),
+     602         156 :   welltemp_(false),
+     603         156 :   biasf_(-1.0),
+     604         156 :   isFirstStep_(true),
+     605         156 :   height0_(std::numeric_limits<double>::max()),
+     606         156 :   adaptive_(FlexibleBin::none),
+     607         156 :   grid_(false),
+     608         156 :   wgridstride_(0),
+     609         156 :   mw_n_(1), mw_dir_(""), mw_id_(0), mw_rstride_(1),
+     610         156 :   walkers_mpi_(false), mpi_nw_(0),
+     611         156 :   flying_(false),
+     612         156 :   acceleration_(false), acc_(0.0), acc_restart_mean_(0.0),
+     613         156 :   calc_max_bias_(false), max_bias_(0.0),
+     614         156 :   calc_transition_bias_(false), transition_bias_(0.0),
+     615         156 :   dampfactor_(0.0),
+     616         312 :   tt_specs_(false, "TT", "Transition Tempered", -1.0, 0.0, 1.0),
+     617         156 :   current_stride_(0),
+     618         156 :   freq_adaptive_(false),
+     619         156 :   fa_update_frequency_(0),
+     620         156 :   fa_max_stride_(0),
+     621         156 :   fa_min_acceleration_(1.0),
+     622         156 :   uppI_(-1), lowI_(-1), doInt_(false),
+     623         156 :   calc_rct_(false),
+     624         156 :   reweight_factor_(0.0),
+     625         156 :   rct_ustride_(1),
+     626         156 :   work_(0),
+     627         156 :   nlist_(false),
+     628         156 :   nlist_update_(false),
+     629         469 :   nlist_steps_(0)
+     630             : {
+     631         156 :   if(!dp2cutoffNoStretch()) {
+     632         156 :     stretchA=dp2cutoffA;
+     633         156 :     stretchB=dp2cutoffB;
+     634             :   }
+     635             :   // parse the flexible hills
+     636             :   std::string adaptiveoption;
+     637             :   adaptiveoption="NONE";
+     638         312 :   parse("ADAPTIVE",adaptiveoption);
+     639         156 :   if(adaptiveoption=="GEOM") {
+     640          22 :     log.printf("  Uses Geometry-based hills width: sigma must be in distance units and only one sigma is needed\n");
+     641          22 :     adaptive_=FlexibleBin::geometry;
+     642         134 :   } else if(adaptiveoption=="DIFF") {
+     643           3 :     log.printf("  Uses Diffusion-based hills width: sigma must be in time steps and only one sigma is needed\n");
+     644           3 :     adaptive_=FlexibleBin::diffusion;
+     645         131 :   } else if(adaptiveoption=="NONE") {
+     646         130 :     adaptive_=FlexibleBin::none;
+     647             :   } else {
+     648           1 :     error("I do not know this type of adaptive scheme");
+     649             :   }
+     650             : 
+     651         155 :   parse("FMT",fmt_);
+     652             : 
+     653             :   // parse the sigma
+     654         155 :   parseVector("SIGMA",sigma0_);
+     655         155 :   if(adaptive_==FlexibleBin::none) {
+     656             :     // if you use normal sigma you need one sigma per argument
+     657         130 :     if( sigma0_.size()!=getNumberOfArguments() ) error("number of arguments does not match number of SIGMA parameters");
+     658             :   } else {
+     659             :     // if you use flexible hills you need one sigma
+     660          25 :     if(sigma0_.size()!=1) {
+     661           1 :       error("If you choose ADAPTIVE you need only one sigma according to your choice of type (GEOM/DIFF)");
+     662             :     }
+     663             :     // if adaptive then the number must be an integer
+     664          24 :     if(adaptive_==FlexibleBin::diffusion) {
+     665           3 :       if(int(sigma0_[0])-sigma0_[0]>1.e-9 || int(sigma0_[0])-sigma0_[0] <-1.e-9 || int(sigma0_[0])<1 ) {
+     666           0 :         error("In case of adaptive hills with diffusion, the sigma must be an integer which is the number of time steps\n");
+     667             :       }
+     668             :     }
+     669             :     // here evtl parse the sigma min and max values
+     670          48 :     parseVector("SIGMA_MIN",sigma0min_);
+     671          24 :     if(sigma0min_.size()>0 && sigma0min_.size()!=getNumberOfArguments()) {
+     672           1 :       error("the number of SIGMA_MIN values be the same of the number of the arguments");
+     673          23 :     } else if(sigma0min_.size()==0) {
+     674          23 :       sigma0min_.resize(getNumberOfArguments());
+     675          67 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {sigma0min_[i]=-1.;}
+     676             :     }
+     677             : 
+     678          46 :     parseVector("SIGMA_MAX",sigma0max_);
+     679          23 :     if(sigma0max_.size()>0 && sigma0max_.size()!=getNumberOfArguments()) {
+     680           1 :       error("the number of SIGMA_MAX values be the same of the number of the arguments");
+     681          22 :     } else if(sigma0max_.size()==0) {
+     682          22 :       sigma0max_.resize(getNumberOfArguments());
+     683          64 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {sigma0max_[i]=-1.;}
+     684             :     }
+     685             : 
+     686          44 :     flexbin_=Tools::make_unique<FlexibleBin>(adaptive_,this,sigma0_[0],sigma0min_,sigma0max_);
+     687             :   }
+     688             : 
+     689             :   // note: HEIGHT is not compulsory, since one could use the TAU keyword, see below
+     690         152 :   parse("HEIGHT",height0_);
+     691         152 :   parse("PACE",stride_);
+     692         151 :   if(stride_<=0) error("frequency for hill addition is nonsensical");
+     693         151 :   current_stride_ = stride_;
+     694         159 :   std::string hillsfname="HILLS";
+     695         151 :   parse("FILE",hillsfname);
+     696             : 
+     697             :   // Manually set to calculate special bias quantities
+     698             :   // throughout the course of simulation. (These are chosen due to
+     699             :   // relevance for tempering and event-driven logic as well.)
+     700         151 :   parseFlag("CALC_MAX_BIAS", calc_max_bias_);
+     701         305 :   parseFlag("CALC_TRANSITION_BIAS", calc_transition_bias_);
+     702             : 
+     703             :   std::vector<double> rect_biasf_;
+     704         302 :   parseVector("RECT",rect_biasf_);
+     705         151 :   if(rect_biasf_.size()>0) {
+     706          18 :     int r=0;
+     707          18 :     if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+     708          18 :     comm.Bcast(r,0);
+     709          18 :     biasf_=rect_biasf_[r];
+     710          18 :     log<<"  You are using RECT\n";
+     711             :   } else {
+     712         266 :     parse("BIASFACTOR",biasf_);
+     713             :   }
+     714         151 :   if( biasf_<1.0  && biasf_!=-1.0) error("well tempered bias factor is nonsensical");
+     715         302 :   parse("DAMPFACTOR",dampfactor_); kbt_=getkBT();
+     716         151 :   if(biasf_>=1.0) {
+     717          38 :     if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, with well-tempered metad you must specify it using TEMP");
+     718          38 :     welltemp_=true;
+     719             :   }
+     720         151 :   if(dampfactor_>0.0) {
+     721           2 :     if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, with damped metad you must specify it using TEMP");
+     722             :   }
+     723             : 
+     724         151 :   parseFlag("CALC_WORK",calc_work_);
+     725             : 
+     726             :   // Set transition tempering parameters.
+     727             :   // Transition wells are read later via calc_transition_bias_.
+     728         151 :   readTemperingSpecs(tt_specs_);
+     729         151 :   if (tt_specs_.is_active) calc_transition_bias_ = true;
+     730             : 
+     731             :   // If any previous option specified to calculate a transition bias,
+     732             :   // now read the transition wells for that quantity.
+     733         151 :   if (calc_transition_bias_) {
+     734          13 :     std::vector<double> tempcoords(getNumberOfArguments());
+     735          26 :     for (unsigned i = 0; ; i++) {
+     736          78 :       if (!parseNumberedVector("TRANSITIONWELL", i, tempcoords) ) break;
+     737          26 :       if (tempcoords.size() != getNumberOfArguments()) {
+     738           0 :         error("incorrect number of coordinates for transition tempering well");
+     739             :       }
+     740          26 :       transitionwells_.push_back(tempcoords);
+     741             :     }
+     742             :   }
+     743             : 
+     744         302 :   parse("TARGET",targetfilename_);
+     745         151 :   if(targetfilename_.length()>0 && kbt_==0.0)  error("with TARGET temperature must be specified");
+     746         151 :   double tau=0.0;
+     747         151 :   parse("TAU",tau);
+     748         151 :   if(tau==0.0) {
+     749         129 :     if(height0_==std::numeric_limits<double>::max()) error("At least one between HEIGHT and TAU should be specified");
+     750             :     // if tau is not set, we compute it here from the other input parameters
+     751         129 :     if(welltemp_) tau=(kbt_*(biasf_-1.0))/height0_*getTimeStep()*stride_;
+     752         110 :     else if(dampfactor_>0.0) tau=(kbt_*dampfactor_)/height0_*getTimeStep()*stride_;
+     753             :   } else {
+     754          22 :     if(height0_!=std::numeric_limits<double>::max()) error("At most one between HEIGHT and TAU should be specified");
+     755          22 :     if(welltemp_) {
+     756          19 :       if(biasf_!=1.0) height0_=(kbt_*(biasf_-1.0))/tau*getTimeStep()*stride_;
+     757           4 :       else           height0_=kbt_/tau*getTimeStep()*stride_; // special case for gamma=1
+     758             :     }
+     759           3 :     else if(dampfactor_>0.0) height0_=(kbt_*dampfactor_)/tau*getTimeStep()*stride_;
+     760           1 :     else error("TAU only makes sense in well-tempered or damped metadynamics");
+     761             :   }
+     762             : 
+     763             :   // Grid Stuff
+     764         153 :   std::vector<std::string> gmin(getNumberOfArguments());
+     765         300 :   parseVector("GRID_MIN",gmin);
+     766         150 :   if(gmin.size()!=getNumberOfArguments() && gmin.size()!=0) error("not enough values for GRID_MIN");
+     767         150 :   std::vector<std::string> gmax(getNumberOfArguments());
+     768         300 :   parseVector("GRID_MAX",gmax);
+     769         150 :   if(gmax.size()!=getNumberOfArguments() && gmax.size()!=0) error("not enough values for GRID_MAX");
+     770         150 :   std::vector<unsigned> gbin(getNumberOfArguments());
+     771             :   std::vector<double>   gspacing;
+     772         300 :   parseVector("GRID_BIN",gbin);
+     773         150 :   if(gbin.size()!=getNumberOfArguments() && gbin.size()!=0) error("not enough values for GRID_BIN");
+     774         300 :   parseVector("GRID_SPACING",gspacing);
+     775         150 :   if(gspacing.size()!=getNumberOfArguments() && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     776         150 :   if(gmin.size()!=gmax.size()) error("GRID_MAX and GRID_MIN should be either present or absent");
+     777         150 :   if(gspacing.size()!=0 && gmin.size()==0) error("If GRID_SPACING is present also GRID_MIN and GRID_MAX should be present");
+     778         150 :   if(gbin.size()!=0     && gmin.size()==0) error("If GRID_BIN is present also GRID_MIN and GRID_MAX should be present");
+     779         150 :   if(gmin.size()!=0) {
+     780          61 :     if(gbin.size()==0 && gspacing.size()==0) {
+     781           6 :       if(adaptive_==FlexibleBin::none) {
+     782           6 :         log<<"  Binsize not specified, 1/5 of sigma will be be used\n";
+     783           6 :         plumed_assert(sigma0_.size()==getNumberOfArguments());
+     784           6 :         gspacing.resize(getNumberOfArguments());
+     785          13 :         for(unsigned i=0; i<gspacing.size(); i++) gspacing[i]=0.2*sigma0_[i];
+     786             :       } else {
+     787             :         // with adaptive hills and grid a sigma min must be specified
+     788           0 :         for(unsigned i=0; i<sigma0min_.size(); i++) if(sigma0min_[i]<=0) error("When using ADAPTIVE Gaussians on a grid SIGMA_MIN must be specified");
+     789           0 :         log<<"  Binsize not specified, 1/5 of sigma_min will be be used\n";
+     790           0 :         gspacing.resize(getNumberOfArguments());
+     791           0 :         for(unsigned i=0; i<gspacing.size(); i++) gspacing[i]=0.2*sigma0min_[i];
+     792             :       }
+     793          55 :     } else if(gspacing.size()!=0 && gbin.size()==0) {
+     794           2 :       log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     795          53 :     } else if(gspacing.size()!=0 && gbin.size()!=0) {
+     796           1 :       log<<"  You specified both GRID_BIN and GRID_SPACING\n";
+     797           1 :       log<<"  The more conservative (highest) number of bins will be used for each variable\n";
+     798             :     }
+     799          61 :     if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     800          73 :     if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     801             :         double a,b;
+     802          13 :         Tools::convert(gmin[i],a);
+     803          12 :         Tools::convert(gmax[i],b);
+     804          12 :         unsigned n=std::ceil(((b-a)/gspacing[i]));
+     805          12 :         if(gbin[i]<n) gbin[i]=n;
+     806             :       }
+     807             :   }
+     808         149 :   if(gbin.size()>0) grid_=true;
+     809             : 
+     810         149 :   bool sparsegrid=false;
+     811         149 :   parseFlag("GRID_SPARSE",sparsegrid);
+     812         149 :   bool nospline=false;
+     813         149 :   parseFlag("GRID_NOSPLINE",nospline);
+     814         149 :   bool spline=!nospline;
+     815         300 :   parse("GRID_WSTRIDE",wgridstride_);
+     816             :   std::string gridfilename_;
+     817         149 :   parse("GRID_WFILE",gridfilename_);
+     818         149 :   parseFlag("STORE_GRIDS",storeOldGrids_);
+     819         149 :   if(grid_ && gridfilename_.length()>0) {
+     820          19 :     if(wgridstride_==0 ) error("frequency with which to output grid not specified use GRID_WSTRIDE");
+     821             :   }
+     822         149 :   if(grid_ && wgridstride_>0) {
+     823          20 :     if(gridfilename_.length()==0) error("grid filename not specified use GRID_WFILE");
+     824             :   }
+     825             : 
+     826             :   std::string gridreadfilename_;
+     827         149 :   parse("GRID_RFILE",gridreadfilename_);
+     828             : 
+     829         149 :   if(!grid_&&gridfilename_.length()> 0) error("To write a grid you need first to define it!");
+     830         149 :   if(!grid_&&gridreadfilename_.length()>0) error("To read a grid you need first to define it!");
+     831             : 
+     832             :   /*setup neighbor list stuff*/
+     833         298 :   parseFlag("NLIST", nlist_);
+     834         149 :   nlist_center_.resize(getNumberOfArguments());
+     835         149 :   nlist_dev2_.resize(getNumberOfArguments());
+     836         150 :   if(nlist_&&grid_) error("NLIST and GRID cannot be combined!");
+     837             :   std::vector<double> nlist_param;
+     838         298 :   parseVector("NLIST_PARAMETERS",nlist_param);
+     839         149 :   if(nlist_param.size()==0)
+     840             :   {
+     841         149 :     nlist_param_[0]=6.0;//*DP2CUTOFF -> max distance of neighbors
+     842         149 :     nlist_param_[1]=0.5;//*nlist_dev2_[i] -> condition for rebuilding
+     843             :   }
+     844             :   else
+     845             :   {
+     846           0 :     plumed_massert(nlist_param.size()==2,"two cutoff parameters are needed for the neighbor list");
+     847           0 :     plumed_massert(nlist_param[0]>1.0,"the first of NLIST_PARAMETERS must be greater than 1. The smaller the first, the smaller should be the second as well");
+     848           0 :     const double min_PARAM_1=(1.-1./std::sqrt(nlist_param[0]/2))+0.16;
+     849           0 :     plumed_massert(nlist_param[1]>0,"the second of NLIST_PARAMETERS must be greater than 0");
+     850           0 :     plumed_massert(nlist_param[1]<=min_PARAM_1,"the second of NLIST_PARAMETERS must be smaller to avoid systematic errors. Largest suggested value is: 1.16-1/sqrt(PARAM_0/2) = "+std::to_string(min_PARAM_1));
+     851           0 :     nlist_param_[0]=nlist_param[0];
+     852           0 :     nlist_param_[1]=nlist_param[1];
+     853             :   }
+     854             : 
+     855             :   // Reweighting factor rct
+     856         149 :   parseFlag("CALC_RCT",calc_rct_);
+     857         149 :   if (calc_rct_) plumed_massert(grid_,"CALC_RCT is supported only if bias is on a grid");
+     858         149 :   parse("RCT_USTRIDE",rct_ustride_);
+     859             : 
+     860         149 :   if(dampfactor_>0.0) {
+     861           2 :     if(!grid_) error("With DAMPFACTOR you should use grids");
+     862             :   }
+     863             : 
+     864             :   // Multiple walkers
+     865         149 :   parse("WALKERS_N",mw_n_);
+     866         149 :   parse("WALKERS_ID",mw_id_);
+     867         149 :   if(mw_n_<=mw_id_) error("walker ID should be a numerical value less than the total number of walkers");
+     868         149 :   parse("WALKERS_DIR",mw_dir_);
+     869         149 :   parse("WALKERS_RSTRIDE",mw_rstride_);
+     870             : 
+     871             :   // MPI version
+     872         149 :   parseFlag("WALKERS_MPI",walkers_mpi_);
+     873             : 
+     874             :   //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     875         149 :   if(walkers_mpi_) {
+     876          39 :     plumed_assert(Communicator::plumedHasMPI()) << "Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation";
+     877          40 :     plumed_assert(Communicator::initialized()) << "Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.";
+     878             :   }
+     879             : 
+     880             :   // Flying Gaussian
+     881         148 :   parseFlag("FLYING_GAUSSIAN", flying_);
+     882             : 
+     883             :   // Inteval keyword
+     884         149 :   std::vector<double> tmpI(2);
+     885         296 :   parseVector("INTERVAL",tmpI);
+     886         148 :   if(tmpI.size()!=2&&tmpI.size()!=0) error("both a lower and an upper limits must be provided with INTERVAL");
+     887         148 :   else if(tmpI.size()==2) {
+     888           2 :     lowI_=tmpI.at(0);
+     889           2 :     uppI_=tmpI.at(1);
+     890           2 :     if(getNumberOfArguments()!=1) error("INTERVAL limits correction works only for monodimensional metadynamics!");
+     891           2 :     if(uppI_<lowI_) error("The Upper limit must be greater than the Lower limit!");
+     892           2 :     if(getPntrToArgument(0)->isPeriodic()) error("INTERVAL cannot be used with periodic variables!");
+     893           2 :     doInt_=true;
+     894             :   }
+     895             : 
+     896         296 :   parseFlag("ACCELERATION",acceleration_);
+     897             :   // Check for a restart acceleration if acceleration is active.
+     898             :   std::string acc_rfilename;
+     899         148 :   if(acceleration_) {
+     900           8 :     parse("ACCELERATION_RFILE", acc_rfilename);
+     901             :   }
+     902             : 
+     903         148 :   freq_adaptive_=false;
+     904         148 :   parseFlag("FREQUENCY_ADAPTIVE",freq_adaptive_);
+     905             :   //
+     906         148 :   fa_update_frequency_=0;
+     907         148 :   parse("FA_UPDATE_FREQUENCY",fa_update_frequency_);
+     908         148 :   if(fa_update_frequency_!=0 && !freq_adaptive_) {
+     909           0 :     plumed_merror("It doesn't make sense to use the FA_MAX_PACE keyword if frequency adaptive METAD hasn't been activated by using the FREQUENCY_ADAPTIVE flag");
+     910             :   }
+     911         148 :   if(fa_update_frequency_==0 && freq_adaptive_) {
+     912           0 :     fa_update_frequency_=stride_;
+     913             :   }
+     914             :   //
+     915         148 :   fa_max_stride_=0;
+     916         148 :   parse("FA_MAX_PACE",fa_max_stride_);
+     917         148 :   if(fa_max_stride_!=0 && !freq_adaptive_) {
+     918           0 :     plumed_merror("It doesn't make sense to use the FA_MAX_PACE keyword if frequency adaptive METAD hasn't been activated by using the FREQUENCY_ADAPTIVE flag");
+     919             :   }
+     920             :   //
+     921         148 :   fa_min_acceleration_=1.0;
+     922         148 :   parse("FA_MIN_ACCELERATION",fa_min_acceleration_);
+     923         148 :   if(fa_min_acceleration_!=1.0 && !freq_adaptive_) {
+     924           0 :     plumed_merror("It doesn't make sense to use the FA_MIN_ACCELERATION keyword if frequency adaptive METAD hasn't been activated by using the FREQUENCY_ADAPTIVE flag");
+     925             :   }
+     926             : 
+     927         148 :   checkRead();
+     928             : 
+     929         148 :   log.printf("  Gaussian width ");
+     930         148 :   if (adaptive_==FlexibleBin::diffusion)log.printf(" (Note: The units of sigma are in timesteps) ");
+     931         148 :   if (adaptive_==FlexibleBin::geometry)log.printf(" (Note: The units of sigma are in dist units) ");
+     932         396 :   for(unsigned i=0; i<sigma0_.size(); ++i) log.printf(" %f",sigma0_[i]);
+     933         148 :   log.printf("  Gaussian height %f\n",height0_);
+     934         148 :   log.printf("  Gaussian deposition pace %d\n",stride_);
+     935         148 :   log.printf("  Gaussian file %s\n",hillsfname.c_str());
+     936         148 :   if(welltemp_) {
+     937          38 :     log.printf("  Well-Tempered Bias Factor %f\n",biasf_);
+     938          38 :     log.printf("  Hills relaxation time (tau) %f\n",tau);
+     939          38 :     log.printf("  KbT %f\n",kbt_);
+     940             :   }
+     941             : 
+     942             :   // Transition tempered metadynamics options
+     943         148 :   if (tt_specs_.is_active) {
+     944           3 :     logTemperingSpecs(tt_specs_);
+     945             :     // Check that the appropriate transition bias quantity is calculated.
+     946             :     // (Should never trip, given that the flag is automatically set.)
+     947           3 :     if (!calc_transition_bias_) {
+     948           0 :       error(" transition tempering requires calculation of a transition bias");
+     949             :     }
+     950             :   }
+     951             : 
+     952             :   // Overall tempering sanity check (this gets tricky when multiple are active).
+     953             :   // When multiple temperings are active, it's fine to have one tempering attempt
+     954             :   // to increase hill size with increasing bias, so long as the others can shrink
+     955             :   // the hills faster than it increases their size in the long-time limit.
+     956             :   // This set of checks ensures that the hill sizes eventually decay to zero as c(t)
+     957             :   // diverges to infinity.
+     958             :   // The alpha parameter allows hills to decay as 1/t^alpha instead of 1/t,
+     959             :   // a slower decay, so as t -> infinity, only the temperings with the largest
+     960             :   // alphas govern the final asymptotic decay. (Alpha helps prevent false convergence.)
+     961         148 :   if (welltemp_ || dampfactor_ > 0.0 || tt_specs_.is_active) {
+     962             :     // Determine the number of active temperings.
+     963             :     int n_active = 0;
+     964          43 :     if (welltemp_) n_active++;
+     965          43 :     if (dampfactor_ > 0.0) n_active++;
+     966          43 :     if (tt_specs_.is_active) n_active++;
+     967             :     // Find the greatest alpha.
+     968          43 :     double greatest_alpha = 0.0;
+     969          43 :     if (welltemp_) greatest_alpha = std::max(greatest_alpha, 1.0);
+     970          45 :     if (dampfactor_ > 0.0) greatest_alpha = std::max(greatest_alpha, 1.0);
+     971          46 :     if (tt_specs_.is_active) greatest_alpha = std::max(greatest_alpha, tt_specs_.alpha);
+     972             :     // Find the least alpha.
+     973          43 :     double least_alpha = 1.0;
+     974             :     if (welltemp_) least_alpha = std::min(least_alpha, 1.0);
+     975          43 :     if (dampfactor_ > 0.0) least_alpha = std::min(least_alpha, 1.0);
+     976          44 :     if (tt_specs_.is_active) least_alpha = std::min(least_alpha, tt_specs_.alpha);
+     977             :     // Find the inverse harmonic average of the delta T parameters for all
+     978             :     // of the temperings with the greatest alpha values.
+     979             :     double total_governing_deltaT_inv = 0.0;
+     980          43 :     if (welltemp_ && 1.0 == greatest_alpha && biasf_ != 1.0) total_governing_deltaT_inv += 1.0 / (biasf_ - 1.0);
+     981          43 :     if (dampfactor_ > 0.0 && 1.0 == greatest_alpha) total_governing_deltaT_inv += 1.0 / (dampfactor_);
+     982          43 :     if (tt_specs_.is_active && tt_specs_.alpha == greatest_alpha) total_governing_deltaT_inv += 1.0 / (tt_specs_.biasf - 1.0);
+     983             :     // Give a newbie-friendly error message for people using one tempering if
+     984             :     // only one is active.
+     985          43 :     if (n_active == 1 && total_governing_deltaT_inv < 0.0) {
+     986           0 :       error("for stable tempering, the bias factor must be greater than one");
+     987             :       // Give a slightly more complex error message to users stacking multiple
+     988             :       // tempering options at a time, but all with uniform alpha values.
+     989          43 :     } else if (total_governing_deltaT_inv < 0.0 && greatest_alpha == least_alpha) {
+     990           0 :       error("for stable tempering, the sum of the inverse Delta T parameters must be greater than zero!");
+     991             :       // Give the most technical error message to users stacking multiple tempering
+     992             :       // options with different alpha parameters.
+     993          43 :     } else if (total_governing_deltaT_inv < 0.0 && greatest_alpha != least_alpha) {
+     994           0 :       error("for stable tempering, the sum of the inverse Delta T parameters for the greatest asymptotic hill decay exponents must be greater than zero!");
+     995             :     }
+     996             :   }
+     997             : 
+     998         148 :   if(doInt_) log.printf("  Upper and Lower limits boundaries for the bias are activated at %f - %f\n", lowI_, uppI_);
+     999             : 
+    1000         148 :   if(grid_) {
+    1001          60 :     log.printf("  Grid min");
+    1002         161 :     for(unsigned i=0; i<gmin.size(); ++i) log.printf(" %s",gmin[i].c_str() );
+    1003          60 :     log.printf("\n");
+    1004          60 :     log.printf("  Grid max");
+    1005         161 :     for(unsigned i=0; i<gmax.size(); ++i) log.printf(" %s",gmax[i].c_str() );
+    1006          60 :     log.printf("\n");
+    1007          60 :     log.printf("  Grid bin");
+    1008         161 :     for(unsigned i=0; i<gbin.size(); ++i) log.printf(" %u",gbin[i]);
+    1009          60 :     log.printf("\n");
+    1010          60 :     if(spline) {log.printf("  Grid uses spline interpolation\n");}
+    1011          60 :     if(sparsegrid) {log.printf("  Grid uses sparse grid\n");}
+    1012          60 :     if(wgridstride_>0) {log.printf("  Grid is written on file %s with stride %d\n",gridfilename_.c_str(),wgridstride_);}
+    1013             :   }
+    1014             : 
+    1015         148 :   if(mw_n_>1) {
+    1016           6 :     if(walkers_mpi_) error("MPI version of multiple walkers is not compatible with filesystem version of multiple walkers");
+    1017           6 :     log.printf("  %d multiple walkers active\n",mw_n_);
+    1018           6 :     log.printf("  walker id %d\n",mw_id_);
+    1019           6 :     log.printf("  reading stride %d\n",mw_rstride_);
+    1020           6 :     if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+    1021             :   } else {
+    1022         142 :     if(walkers_mpi_) {
+    1023          38 :       log.printf("  Multiple walkers active using MPI communnication\n");
+    1024          38 :       if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+    1025          38 :       if(comm.Get_rank()==0) {
+    1026             :         // Only root of group can communicate with other walkers
+    1027          23 :         mpi_nw_=multi_sim_comm.Get_size();
+    1028             :       }
+    1029             :       // Communicate to the other members of the same group
+    1030             :       // info abount number of walkers and walker index
+    1031          38 :       comm.Bcast(mpi_nw_,0);
+    1032             :     }
+    1033             :   }
+    1034             : 
+    1035         148 :   if(flying_) {
+    1036           6 :     if(!walkers_mpi_) error("Flying Gaussian method must be used with MPI version of multiple walkers");
+    1037           6 :     log.printf("  Flying Gaussian method with %d walkers active\n",mpi_nw_);
+    1038             :   }
+    1039             : 
+    1040         148 :   if(nlist_) {
+    1041           2 :     addComponent("nlker");
+    1042           2 :     componentIsNotPeriodic("nlker");
+    1043           2 :     addComponent("nlsteps");
+    1044           2 :     componentIsNotPeriodic("nlsteps");
+    1045             :   }
+    1046             : 
+    1047         148 :   if(calc_rct_) {
+    1048          18 :     addComponent("rbias"); componentIsNotPeriodic("rbias");
+    1049          12 :     addComponent("rct"); componentIsNotPeriodic("rct");
+    1050           6 :     log.printf("  The c(t) reweighting factor will be calculated every %u hills\n",rct_ustride_);
+    1051          12 :     getPntrToComponent("rct")->set(reweight_factor_);
+    1052             :   }
+    1053             : 
+    1054         150 :   if(calc_work_) { addComponent("work"); componentIsNotPeriodic("work"); }
+    1055             : 
+    1056         148 :   if(acceleration_) {
+    1057           4 :     if (kbt_ == 0.0) {
+    1058           0 :       error("The calculation of the acceleration works only if simulation temperature has been defined");
+    1059             :     }
+    1060           4 :     log.printf("  calculation on the fly of the acceleration factor\n");
+    1061          12 :     addComponent("acc"); componentIsNotPeriodic("acc");
+    1062             :     // Set the initial value of the the acceleration.
+    1063             :     // If this is not a restart, set to 1.0.
+    1064           4 :     if (acc_rfilename.length() == 0) {
+    1065           4 :       getPntrToComponent("acc")->set(1.0);
+    1066           2 :       if(getRestart()) {
+    1067           1 :         log.printf("  WARNING: calculating the acceleration factor in a restarted run without reading in the previous value will most likely lead to incorrect results.\n");
+    1068           1 :         log.printf("           You should use the ACCELERATION_RFILE keyword.\n");
+    1069             :       }
+    1070             :       // Otherwise, read and set the restart value.
+    1071             :     } else {
+    1072             :       // Restart of acceleration does not make sense if the restart timestep is zero.
+    1073             :       //if (getStep() == 0) {
+    1074             :       //  error("Restarting calculation of acceleration factors works only if simulation timestep is restarted correctly");
+    1075             :       //}
+    1076             :       // Open the ACCELERATION_RFILE.
+    1077           2 :       IFile acc_rfile;
+    1078           2 :       acc_rfile.link(*this);
+    1079           2 :       if(acc_rfile.FileExist(acc_rfilename)) {
+    1080           2 :         acc_rfile.open(acc_rfilename);
+    1081             :       } else {
+    1082           0 :         error("The ACCELERATION_RFILE file you want to read: " + acc_rfilename + ", cannot be found!");
+    1083             :       }
+    1084             :       // Read the file to find the restart acceleration.
+    1085           2 :       double acc_rmean=0.0;
+    1086           2 :       double acc_rtime=0.0;
+    1087             :       bool found=false;
+    1088           2 :       std::string acclabel = getLabel() + ".acc";
+    1089           2 :       acc_rfile.allowIgnoredFields();
+    1090         248 :       while(acc_rfile.scanField("time", acc_rtime)) {
+    1091         122 :         acc_rfile.scanField(acclabel, acc_rmean);
+    1092         122 :         acc_rfile.scanField();
+    1093             :         found=true;
+    1094             :       }
+    1095           2 :       if(!found) error("The ACCELERATION_RFILE file you want to read: " + acc_rfilename + ", does not contain a time field!");
+    1096           2 :       acc_restart_mean_ = acc_rmean;
+    1097             :       // Set component based on the read values.
+    1098           2 :       getPntrToComponent("acc")->set(acc_rmean);
+    1099           2 :       log.printf("  initial acceleration factor read from file %s: value of %f at time %f\n",acc_rfilename.c_str(),acc_rmean,acc_rtime);
+    1100           2 :     }
+    1101             :   }
+    1102             : 
+    1103         148 :   if (calc_max_bias_) {
+    1104           0 :     if (!grid_) error("Calculating the maximum bias on the fly works only with a grid");
+    1105           0 :     log.printf("  calculation on the fly of the maximum bias max(V(s,t)) \n");
+    1106           0 :     addComponent("maxbias");
+    1107           0 :     componentIsNotPeriodic("maxbias");
+    1108             :   }
+    1109             : 
+    1110         148 :   if (calc_transition_bias_) {
+    1111          13 :     if (!grid_) error("Calculating the transition bias on the fly works only with a grid");
+    1112          13 :     log.printf("  calculation on the fly of the transition bias V*(t)\n");
+    1113          26 :     addComponent("transbias");
+    1114          13 :     componentIsNotPeriodic("transbias");
+    1115          13 :     log<<"  Number of transition wells "<<transitionwells_.size()<<"\n";
+    1116          13 :     if (transitionwells_.size() == 0) error("Calculating the transition bias on the fly requires definition of at least one transition well");
+    1117             :     // Check that a grid is in use.
+    1118          13 :     if (!grid_) error(" transition barrier finding requires a grid for the bias");
+    1119             :     // Log the wells and check that they are in the grid.
+    1120          39 :     for (unsigned i = 0; i < transitionwells_.size(); i++) {
+    1121             :       // Log the coordinate.
+    1122          26 :       log.printf("  Transition well %d at coordinate ", i);
+    1123          64 :       for (unsigned j = 0; j < getNumberOfArguments(); j++) log.printf("%f ", transitionwells_[i][j]);
+    1124          26 :       log.printf("\n");
+    1125             :       // Check that the coordinate is in the grid.
+    1126          64 :       for (unsigned j = 0; j < getNumberOfArguments(); j++) {
+    1127             :         double max, min;
+    1128          38 :         Tools::convert(gmin[j], min);
+    1129          38 :         Tools::convert(gmax[j], max);
+    1130          38 :         if (transitionwells_[i][j] < min || transitionwells_[i][j] > max) error(" transition well is not in grid");
+    1131             :       }
+    1132             :     }
+    1133             :   }
+    1134             : 
+    1135         148 :   if(freq_adaptive_) {
+    1136           2 :     if(!acceleration_) {
+    1137           0 :       plumed_merror("Frequency adaptive metadynamics only works if the calculation of the acceleration factor is enabled with the ACCELERATION keyword\n");
+    1138             :     }
+    1139           2 :     if(walkers_mpi_) {
+    1140           0 :       plumed_merror("Combining frequency adaptive metadynamics with MPI multiple walkers is not allowed");
+    1141             :     }
+    1142             : 
+    1143           2 :     log.printf("  Frequency adaptive metadynamics enabled\n");
+    1144           2 :     if(getRestart() && acc_rfilename.length() == 0) {
+    1145           0 :       log.printf("  WARNING: using the frequency adaptive scheme in a restarted run without reading in the previous value of the acceleration factor will most likely lead to incorrect results.\n");
+    1146           0 :       log.printf("           You should use the ACCELERATION_RFILE keyword.\n");
+    1147             :     }
+    1148           2 :     log.printf("  The frequency for hill addition will change dynamically based on the metadynamics acceleration factor\n");
+    1149           2 :     log.printf("  The hill addition frequency will be updated every %d steps\n",fa_update_frequency_);
+    1150           2 :     if(fa_min_acceleration_>1.0) {
+    1151           2 :       log.printf("  The hill addition frequency will only be updated once the metadynamics acceleration factor becomes larger than %.1f \n",fa_min_acceleration_);
+    1152             :     }
+    1153           2 :     if(fa_max_stride_!=0) {
+    1154           2 :       log.printf("  The hill addition frequency will not become larger than %d steps\n",fa_max_stride_);
+    1155             :     }
+    1156           4 :     addComponent("pace"); componentIsNotPeriodic("pace");
+    1157           2 :     updateFrequencyAdaptiveStride();
+    1158             :   }
+    1159             : 
+    1160             :   // initializing and checking grid
+    1161             :   bool restartedFromGrid=false;  // restart from grid file
+    1162         148 :   if(grid_) {
+    1163          60 :     if(!(gridreadfilename_.length()>0)) {
+    1164             :       // check for mesh and sigma size
+    1165         116 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    1166             :         double a,b;
+    1167          74 :         Tools::convert(gmin[i],a);
+    1168          74 :         Tools::convert(gmax[i],b);
+    1169          74 :         double mesh=(b-a)/((double)gbin[i]);
+    1170          74 :         if(adaptive_==FlexibleBin::none) {
+    1171          74 :           if(mesh>0.5*sigma0_[i]) log<<"  WARNING: Using a METAD with a Grid Spacing larger than half of the Gaussians width (SIGMA) can produce artifacts\n";
+    1172             :         } else {
+    1173           0 :           if(sigma0min_[i]<0.) error("When using ADAPTIVE Gaussians on a grid SIGMA_MIN must be specified");
+    1174           0 :           if(mesh>0.5*sigma0min_[i]) log<<"  WARNING: to use a METAD with a GRID and ADAPTIVE you need to set a Grid Spacing lower than half of the Gaussians (SIGMA_MIN) \n";
+    1175             :         }
+    1176             :       }
+    1177          42 :       std::string funcl=getLabel() + ".bias";
+    1178          42 :       if(!sparsegrid) {BiasGrid_=Tools::make_unique<Grid>(funcl,getArguments(),gmin,gmax,gbin,spline,true);}
+    1179           6 :       else {BiasGrid_=Tools::make_unique<SparseGrid>(funcl,getArguments(),gmin,gmax,gbin,spline,true);}
+    1180          42 :       std::vector<std::string> actualmin=BiasGrid_->getMin();
+    1181          42 :       std::vector<std::string> actualmax=BiasGrid_->getMax();
+    1182         116 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    1183             :         std::string is;
+    1184          74 :         Tools::convert(i,is);
+    1185          74 :         if(gmin[i]!=actualmin[i]) error("GRID_MIN["+is+"] must be adjusted to "+actualmin[i]+" to fit periodicity");
+    1186          74 :         if(gmax[i]!=actualmax[i]) error("GRID_MAX["+is+"] must be adjusted to "+actualmax[i]+" to fit periodicity");
+    1187             :       }
+    1188          42 :     } else {
+    1189             :       // read the grid in input, find the keys
+    1190          18 :       if(walkers_mpi_&&gridreadfilename_.at(0)!='/') {
+    1191             :         //if possible the root replica will share its current folder so that all walkers will read the same file
+    1192           0 :         const std::string ret = std::filesystem::current_path();
+    1193           0 :         gridreadfilename_ = "/" + gridreadfilename_;
+    1194           0 :         gridreadfilename_ = ret + gridreadfilename_;
+    1195           0 :         if(comm.Get_rank()==0) multi_sim_comm.Bcast(gridreadfilename_,0);
+    1196           0 :         comm.Bcast(gridreadfilename_,0);
+    1197             :       }
+    1198          18 :       IFile gridfile;
+    1199          18 :       gridfile.link(*this);
+    1200          18 :       if(gridfile.FileExist(gridreadfilename_)) {
+    1201          18 :         gridfile.open(gridreadfilename_);
+    1202             :       } else {
+    1203           0 :         error("The GRID file you want to read: " + gridreadfilename_ + ", cannot be found!");
+    1204             :       }
+    1205          18 :       std::string funcl=getLabel() + ".bias";
+    1206          36 :       BiasGrid_=GridBase::create(funcl, getArguments(), gridfile, gmin, gmax, gbin, sparsegrid, spline, true);
+    1207          18 :       if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+    1208          45 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1209          54 :         if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+    1210             :         double a, b;
+    1211          27 :         Tools::convert(gmin[i],a);
+    1212          27 :         Tools::convert(gmax[i],b);
+    1213          27 :         double mesh=(b-a)/((double)gbin[i]);
+    1214          27 :         if(mesh>0.5*sigma0_[i]) log<<"  WARNING: Using a METAD with a Grid Spacing larger than half of the Gaussians width can produce artifacts\n";
+    1215             :       }
+    1216          18 :       log.printf("  Restarting from %s\n",gridreadfilename_.c_str());
+    1217          18 :       if(getRestart()) restartedFromGrid=true;
+    1218          18 :     }
+    1219             :   }
+    1220             : 
+    1221             :   // if we are restarting from GRID and using WALKERS_MPI we can check that all walkers have actually read the grid
+    1222         148 :   if(getRestart()&&walkers_mpi_) {
+    1223           9 :     std::vector<int> restarted(mpi_nw_,0);
+    1224           9 :     if(comm.Get_rank()==0) multi_sim_comm.Allgather(int(restartedFromGrid), restarted);
+    1225           9 :     comm.Bcast(restarted,0);
+    1226             :     int result = std::accumulate(restarted.begin(),restarted.end(),0);
+    1227           9 :     if(result!=0&&result!=mpi_nw_) error("in this WALKERS_MPI run some replica have restarted from GRID while other do not!");
+    1228             :   }
+    1229             : 
+    1230         186 :   if(walkers_mpi_&&mw_dir_==""&&hillsfname.at(0)!='/') {
+    1231             :     //if possible the root replica will share its current folder so that all walkers will read the same file
+    1232          76 :     const std::string ret = std::filesystem::current_path();
+    1233             :     mw_dir_ = ret;
+    1234          38 :     mw_dir_ = mw_dir_ + "/";
+    1235          38 :     if(comm.Get_rank()==0) multi_sim_comm.Bcast(mw_dir_,0);
+    1236          38 :     comm.Bcast(mw_dir_,0);
+    1237             :   }
+    1238             : 
+    1239             :   // creating std::vector of ifile* for hills reading
+    1240             :   // open all files at the beginning and read Gaussians if restarting
+    1241             :   bool restartedFromHills=false;  // restart from hills files
+    1242         308 :   for(int i=0; i<mw_n_; ++i) {
+    1243             :     std::string fname;
+    1244         160 :     if(mw_dir_!="") {
+    1245          47 :       if(mw_n_>1) {
+    1246           9 :         std::stringstream out; out << i;
+    1247          18 :         fname = mw_dir_+"/"+hillsfname+"."+out.str();
+    1248          47 :       } else if(walkers_mpi_) {
+    1249          76 :         fname = mw_dir_+"/"+hillsfname;
+    1250             :       } else {
+    1251             :         fname = hillsfname;
+    1252             :       }
+    1253             :     } else {
+    1254         113 :       if(mw_n_>1) {
+    1255           9 :         std::stringstream out; out << i;
+    1256          18 :         fname = hillsfname+"."+out.str();
+    1257           9 :       } else {
+    1258             :         fname = hillsfname;
+    1259             :       }
+    1260             :     }
+    1261         160 :     ifiles_.emplace_back(Tools::make_unique<IFile>());
+    1262             :     // this is just a shortcut pointer to the last element:
+    1263             :     IFile *ifile = ifiles_.back().get();
+    1264         160 :     ifilesnames_.push_back(fname);
+    1265         160 :     ifile->link(*this);
+    1266         160 :     if(ifile->FileExist(fname)) {
+    1267          36 :       ifile->open(fname);
+    1268          36 :       if(getRestart()&&!restartedFromGrid) {
+    1269          19 :         log.printf("  Restarting from %s:",ifilesnames_[i].c_str());
+    1270          19 :         readGaussians(ifiles_[i].get());
+    1271             :         restartedFromHills=true;
+    1272             :       }
+    1273          36 :       ifiles_[i]->reset(false);
+    1274             :       // close only the walker own hills file for later writing
+    1275          36 :       if(i==mw_id_) ifiles_[i]->close();
+    1276             :     } else {
+    1277             :       // in case a file does not exist and we are restarting, complain that the file was not found
+    1278         124 :       if(getRestart()&&!restartedFromGrid) error("restart file "+fname+" not found");
+    1279             :     }
+    1280             :   }
+    1281             : 
+    1282             :   // if we are restarting from FILE and using WALKERS_MPI we can check that all walkers have actually read the FILE
+    1283         148 :   if(getRestart()&&walkers_mpi_) {
+    1284           9 :     std::vector<int> restarted(mpi_nw_,0);
+    1285           9 :     if(comm.Get_rank()==0) multi_sim_comm.Allgather(int(restartedFromHills), restarted);
+    1286           9 :     comm.Bcast(restarted,0);
+    1287             :     int result = std::accumulate(restarted.begin(),restarted.end(),0);
+    1288           9 :     if(result!=0&&result!=mpi_nw_) error("in this WALKERS_MPI run some replica have restarted from FILE while other do not!");
+    1289             :   }
+    1290             : 
+    1291         148 :   comm.Barrier();
+    1292             :   // this barrier is needed when using walkers_mpi
+    1293             :   // to be sure that all files have been read before
+    1294             :   // backing them up
+    1295             :   // it should not be used when walkers_mpi is false otherwise
+    1296             :   // it would introduce troubles when using replicas without METAD
+    1297             :   // (e.g. in bias exchange with a neutral replica)
+    1298             :   // see issue #168 on github
+    1299         148 :   if(comm.Get_rank()==0 && walkers_mpi_) multi_sim_comm.Barrier();
+    1300             : 
+    1301         148 :   if(targetfilename_.length()>0) {
+    1302           2 :     IFile gridfile; gridfile.open(targetfilename_);
+    1303           2 :     std::string funcl=getLabel() + ".target";
+    1304           4 :     TargetGrid_=GridBase::create(funcl,getArguments(),gridfile,false,false,true);
+    1305           2 :     if(TargetGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+    1306           4 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1307           4 :       if( getPntrToArgument(i)->isPeriodic()!=TargetGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+    1308             :     }
+    1309           2 :   }
+    1310             : 
+    1311         148 :   if(getRestart()) {
+    1312             :     // if this is a restart the neighbor list should be immediately updated
+    1313          37 :     if(nlist_) nlist_update_=true;
+    1314             :     // Calculate the Tiwary-Parrinello reweighting factor if we are restarting from previous hills
+    1315          37 :     if(calc_rct_) computeReweightingFactor();
+    1316             :     // Calculate all special bias quantities desired if restarting with nonzero bias.
+    1317          37 :     if(calc_max_bias_) {
+    1318           0 :       max_bias_ = BiasGrid_->getMaxValue();
+    1319           0 :       getPntrToComponent("maxbias")->set(max_bias_);
+    1320             :     }
+    1321          37 :     if(calc_transition_bias_) {
+    1322          13 :       transition_bias_ = getTransitionBarrierBias();
+    1323          26 :       getPntrToComponent("transbias")->set(transition_bias_);
+    1324             :     }
+    1325             :   }
+    1326             : 
+    1327             :   // open grid file for writing
+    1328         148 :   if(wgridstride_>0) {
+    1329          19 :     gridfile_.link(*this);
+    1330          19 :     if(walkers_mpi_) {
+    1331           0 :       int r=0;
+    1332           0 :       if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    1333           0 :       comm.Bcast(r,0);
+    1334           0 :       if(r>0) gridfilename_="/dev/null";
+    1335           0 :       gridfile_.enforceSuffix("");
+    1336             :     }
+    1337          19 :     if(mw_n_>1) gridfile_.enforceSuffix("");
+    1338          19 :     gridfile_.open(gridfilename_);
+    1339             :   }
+    1340             : 
+    1341             :   // open hills file for writing
+    1342         148 :   hillsOfile_.link(*this);
+    1343         148 :   if(walkers_mpi_) {
+    1344          38 :     int r=0;
+    1345          38 :     if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    1346          38 :     comm.Bcast(r,0);
+    1347          38 :     if(r>0) ifilesnames_[mw_id_]="/dev/null";
+    1348          76 :     hillsOfile_.enforceSuffix("");
+    1349             :   }
+    1350         154 :   if(mw_n_>1) hillsOfile_.enforceSuffix("");
+    1351         148 :   hillsOfile_.open(ifilesnames_[mw_id_]);
+    1352         148 :   if(fmt_.length()>0) hillsOfile_.fmtField(fmt_);
+    1353         148 :   hillsOfile_.addConstantField("multivariate");
+    1354         148 :   hillsOfile_.addConstantField("kerneltype");
+    1355         148 :   if(doInt_) {
+    1356           4 :     hillsOfile_.addConstantField("lower_int").printField("lower_int",lowI_);
+    1357           4 :     hillsOfile_.addConstantField("upper_int").printField("upper_int",uppI_);
+    1358             :   }
+    1359             :   hillsOfile_.setHeavyFlush();
+    1360             :   // output periodicities of variables
+    1361         415 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) hillsOfile_.setupPrintValue( getPntrToArgument(i) );
+    1362             : 
+    1363             :   bool concurrent=false;
+    1364         148 :   const ActionSet&actionSet(plumed.getActionSet());
+    1365        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        6037 : void MetaD::readGaussians(IFile *ifile)
+    1429             : {
+    1430        6037 :   unsigned ncv=getNumberOfArguments();
+    1431        6037 :   std::vector<double> center(ncv);
+    1432        6037 :   std::vector<double> sigma(ncv);
+    1433             :   double height;
+    1434             :   int nhills=0;
+    1435        6037 :   bool multivariate=false;
+    1436             : 
+    1437             :   std::vector<Value> tmpvalues;
+    1438       18124 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) tmpvalues.push_back( Value( this, getPntrToArgument(j)->getName(), false ) );
+    1439             : 
+    1440        8078 :   while(scanOneHill(ifile,tmpvalues,center,sigma,height,multivariate))
+    1441             :   {
+    1442        2041 :     nhills++;
+    1443             :     // note that for gamma=1 we store directly -F
+    1444        2041 :     if(welltemp_ && biasf_>1.0) height*=(biasf_-1.0)/biasf_;
+    1445        2041 :     addGaussian(Gaussian(multivariate,height,center,sigma));
+    1446             :   }
+    1447        6037 :   log.printf("      %d Gaussians read\n",nhills);
+    1448       12074 : }
+    1449             : 
+    1450        2922 : void MetaD::writeGaussian(const Gaussian& hill, OFile&file)
+    1451             : {
+    1452        2922 :   unsigned ncv=getNumberOfArguments();
+    1453        2922 :   file.printField("time",getTimeStep()*getStep());
+    1454        8194 :   for(unsigned i=0; i<ncv; ++i) {
+    1455        5272 :     file.printField(getPntrToArgument(i),hill.center[i]);
+    1456             :   }
+    1457        5844 :   hillsOfile_.printField("kerneltype","stretched-gaussian");
+    1458        2922 :   if(hill.multivariate) {
+    1459         892 :     hillsOfile_.printField("multivariate","true");
+    1460             :     Matrix<double> mymatrix(ncv,ncv);
+    1461             :     unsigned k=0;
+    1462        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1463        1357 :       for(unsigned j=i; j<ncv; j++) {
+    1464             :         // recompose the full inverse matrix
+    1465         756 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k];
+    1466         756 :         k++;
+    1467             :       }
+    1468             :     }
+    1469             :     // invert it
+    1470             :     Matrix<double> invmatrix(ncv,ncv);
+    1471         446 :     Invert(mymatrix,invmatrix);
+    1472             :     // enforce symmetry
+    1473        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1474        1357 :       for(unsigned j=i; j<ncv; j++) {
+    1475         756 :         invmatrix(i,j)=invmatrix(j,i);
+    1476             :       }
+    1477             :     }
+    1478             : 
+    1479             :     // do cholesky so to have a "sigma like" number
+    1480             :     Matrix<double> lower(ncv,ncv);
+    1481         446 :     cholesky(invmatrix,lower);
+    1482             :     // loop in band form
+    1483        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1484        1357 :       for(unsigned j=0; j<ncv-i; j++) {
+    1485        1512 :         file.printField("sigma_"+getPntrToArgument(j+i)->getName()+"_"+getPntrToArgument(j)->getName(),lower(j+i,j));
+    1486             :       }
+    1487             :     }
+    1488             :   } else {
+    1489        4952 :     hillsOfile_.printField("multivariate","false");
+    1490        7147 :     for(unsigned i=0; i<ncv; ++i)
+    1491        9342 :       file.printField("sigma_"+getPntrToArgument(i)->getName(),hill.sigma[i]);
+    1492             :   }
+    1493        2922 :   double height=hill.height;
+    1494             :   // note that for gamma=1 we store directly -F
+    1495        2922 :   if(welltemp_ && biasf_>1.0) height*=biasf_/(biasf_-1.0);
+    1496        5844 :   file.printField("height",height).printField("biasf",biasf_);
+    1497        4431 :   if(mw_n_>1) file.printField("clock",int(std::time(0)));
+    1498        2922 :   file.printField();
+    1499        2922 : }
+    1500             : 
+    1501        5125 : void MetaD::addGaussian(const Gaussian& hill)
+    1502             : {
+    1503        5125 :   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        4485 :   } else hills_.push_back(hill);
+    1543        5125 : }
+    1544             : 
+    1545         640 : std::vector<unsigned> MetaD::getGaussianSupport(const Gaussian& hill)
+    1546             : {
+    1547             :   std::vector<unsigned> nneigh;
+    1548             :   std::vector<double> cutoff;
+    1549         640 :   unsigned ncv=getNumberOfArguments();
+    1550             : 
+    1551             :   // traditional or flexible hill?
+    1552         640 :   if(hill.multivariate) {
+    1553             :     unsigned k=0;
+    1554             :     Matrix<double> mymatrix(ncv,ncv);
+    1555           0 :     for(unsigned i=0; i<ncv; i++) {
+    1556           0 :       for(unsigned j=i; j<ncv; j++) {
+    1557             :         // recompose the full inverse matrix
+    1558           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k];
+    1559           0 :         k++;
+    1560             :       }
+    1561             :     }
+    1562             :     // Reinvert so to have the ellipses
+    1563             :     Matrix<double> myinv(ncv,ncv);
+    1564           0 :     Invert(mymatrix,myinv);
+    1565             :     Matrix<double> myautovec(ncv,ncv);
+    1566           0 :     std::vector<double> myautoval(ncv); //should I take this or their square root?
+    1567           0 :     diagMat(myinv,myautoval,myautovec);
+    1568             :     double maxautoval=0.;
+    1569             :     unsigned ind_maxautoval; ind_maxautoval=ncv;
+    1570           0 :     for(unsigned i=0; i<ncv; i++) {
+    1571           0 :       if(myautoval[i]>maxautoval) {maxautoval=myautoval[i]; ind_maxautoval=i;}
+    1572             :     }
+    1573           0 :     for(unsigned i=0; i<ncv; i++) {
+    1574           0 :       cutoff.push_back(std::sqrt(2.0*dp2cutoff)*std::abs(std::sqrt(maxautoval)*myautovec(i,ind_maxautoval)));
+    1575             :     }
+    1576             :   } else {
+    1577        1618 :     for(unsigned i=0; i<ncv; ++i) {
+    1578         978 :       cutoff.push_back(std::sqrt(2.0*dp2cutoff)*hill.sigma[i]);
+    1579             :     }
+    1580             :   }
+    1581             : 
+    1582         640 :   if(doInt_) {
+    1583           2 :     if(hill.center[0]+cutoff[0] > uppI_ || hill.center[0]-cutoff[0] < lowI_) {
+    1584             :       // in this case, we updated the entire grid to avoid problems
+    1585           2 :       return BiasGrid_->getNbin();
+    1586             :     } else {
+    1587           0 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff[0]/BiasGrid_->getDx()[0])) );
+    1588             :       return nneigh;
+    1589             :     }
+    1590             :   } else {
+    1591        1614 :     for(unsigned i=0; i<ncv; i++) {
+    1592         976 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff[i]/BiasGrid_->getDx()[i])) );
+    1593             :     }
+    1594             :   }
+    1595             : 
+    1596             :   return nneigh;
+    1597             : }
+    1598             : 
+    1599         285 : double MetaD::getBias(const std::vector<double>& cv)
+    1600             : {
+    1601         285 :   double bias=0.0;
+    1602         285 :   if(grid_) bias = BiasGrid_->getValue(cv);
+    1603             :   else {
+    1604          82 :     unsigned nt=OpenMP::getNumThreads();
+    1605          82 :     unsigned stride=comm.Get_size();
+    1606          82 :     unsigned rank=comm.Get_rank();
+    1607             : 
+    1608          82 :     if(!nlist_) {
+    1609          82 :       #pragma omp parallel num_threads(nt)
+    1610             :       {
+    1611             :         #pragma omp for reduction(+:bias) nowait
+    1612             :         for(unsigned i=rank; i<hills_.size(); i+=stride) bias+=evaluateGaussian(cv,hills_[i]);
+    1613             :       }
+    1614             :     } else {
+    1615           0 :       #pragma omp parallel num_threads(nt)
+    1616             :       {
+    1617             :         #pragma omp for reduction(+:bias) nowait
+    1618             :         for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) bias+=evaluateGaussian(cv,nlist_hills_[i]);
+    1619             :       }
+    1620             :     }
+    1621          82 :     comm.Sum(bias);
+    1622             :   }
+    1623             : 
+    1624         285 :   return bias;
+    1625             : }
+    1626             : 
+    1627        8395 : double MetaD::getBiasAndDerivatives(const std::vector<double>& cv, std::vector<double>& der)
+    1628             : {
+    1629        8395 :   unsigned ncv=getNumberOfArguments();
+    1630        8395 :   double bias=0.0;
+    1631        8395 :   if(grid_) {
+    1632        1506 :     std::vector<double> vder(ncv);
+    1633        1506 :     bias=BiasGrid_->getValueAndDerivatives(cv,vder);
+    1634        3498 :     for(unsigned i=0; i<ncv; i++) der[i]=vder[i];
+    1635             :   } else {
+    1636        6889 :     unsigned nt=OpenMP::getNumThreads();
+    1637        6889 :     unsigned stride=comm.Get_size();
+    1638        6889 :     unsigned rank=comm.Get_rank();
+    1639             : 
+    1640        6889 :     if(!nlist_) {
+    1641        6884 :       if(hills_.size()<2*nt*stride||nt==1) {
+    1642             :         // for performance reasons and thread safety
+    1643        2586 :         std::vector<double> dp(ncv);
+    1644        6703 :         for(unsigned i=rank; i<hills_.size(); i+=stride) {
+    1645        4117 :           bias+=evaluateGaussianAndDerivatives(cv,hills_[i],der,dp);
+    1646             :         }
+    1647             :       } else {
+    1648        4298 :         #pragma omp parallel num_threads(nt)
+    1649             :         {
+    1650             :           std::vector<double> omp_deriv(ncv,0.);
+    1651             :           // for performance reasons and thread safety
+    1652             :           std::vector<double> dp(ncv);
+    1653             :           #pragma omp for reduction(+:bias) nowait
+    1654             :           for(unsigned i=rank; i<hills_.size(); i+=stride) {
+    1655             :             bias+=evaluateGaussianAndDerivatives(cv,hills_[i],omp_deriv,dp);
+    1656             :           }
+    1657             :           #pragma omp critical
+    1658             :           for(unsigned i=0; i<ncv; i++) der[i]+=omp_deriv[i];
+    1659             :         }
+    1660             :       }
+    1661             :     } else {
+    1662           5 :       if(hills_.size()<2*nt*stride||nt==1) {
+    1663             :         // for performance reasons and thread safety
+    1664           0 :         std::vector<double> dp(ncv);
+    1665           0 :         for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) {
+    1666           0 :           bias+=evaluateGaussianAndDerivatives(cv,nlist_hills_[i],der,dp);
+    1667             :         }
+    1668             :       } else {
+    1669           5 :         #pragma omp parallel num_threads(nt)
+    1670             :         {
+    1671             :           std::vector<double> omp_deriv(ncv,0.);
+    1672             :           // for performance reasons and thread safety
+    1673             :           std::vector<double> dp(ncv);
+    1674             :           #pragma omp for reduction(+:bias) nowait
+    1675             :           for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) {
+    1676             :             bias+=evaluateGaussianAndDerivatives(cv,nlist_hills_[i],omp_deriv,dp);
+    1677             :           }
+    1678             :           #pragma omp critical
+    1679             :           for(unsigned i=0; i<ncv; i++) der[i]+=omp_deriv[i];
+    1680             :         }
+    1681             :       }
+    1682             :     }
+    1683        6889 :     comm.Sum(bias);
+    1684        6889 :     comm.Sum(der);
+    1685             :   }
+    1686             : 
+    1687        8395 :   return bias;
+    1688             : }
+    1689             : 
+    1690           0 : double MetaD::getGaussianNormalization(const Gaussian& hill)
+    1691             : {
+    1692             :   double norm=1;
+    1693           0 :   unsigned ncv=hill.center.size();
+    1694             : 
+    1695           0 :   if(hill.multivariate) {
+    1696             :     // recompose the full sigma from the upper diag cholesky
+    1697             :     unsigned k=0;
+    1698             :     Matrix<double> mymatrix(ncv,ncv);
+    1699           0 :     for(unsigned i=0; i<ncv; i++) {
+    1700           0 :       for(unsigned j=i; j<ncv; j++) {
+    1701           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1702           0 :         k++;
+    1703             :       }
+    1704           0 :       double ldet; logdet( mymatrix, ldet );
+    1705           0 :       norm = std::exp( ldet );  // Not sure here if mymatrix is sigma or inverse
+    1706             :     }
+    1707             :   } else {
+    1708           0 :     for(unsigned i=0; i<hill.sigma.size(); i++) norm*=hill.sigma[i];
+    1709             :   }
+    1710             : 
+    1711           0 :   return norm*std::pow(2*pi,static_cast<double>(ncv)/2.0);
+    1712             : }
+    1713             : 
+    1714         192 : double MetaD::evaluateGaussian(const std::vector<double>& cv, const Gaussian& hill)
+    1715             : {
+    1716         192 :   unsigned ncv=cv.size();
+    1717             : 
+    1718             :   // I use a pointer here because cv is const (and should be const)
+    1719             :   // but when using doInt it is easier to locally replace cv[0] with
+    1720             :   // the upper/lower limit in case it is out of range
+    1721             :   double tmpcv[1];
+    1722             :   const double *pcv=NULL; // pointer to cv
+    1723         192 :   if(ncv>0) pcv=&cv[0];
+    1724         192 :   if(doInt_) {
+    1725           0 :     plumed_assert(ncv==1);
+    1726           0 :     tmpcv[0]=cv[0];
+    1727           0 :     if(cv[0]<lowI_) tmpcv[0]=lowI_;
+    1728           0 :     if(cv[0]>uppI_) tmpcv[0]=uppI_;
+    1729             :     pcv=&(tmpcv[0]);
+    1730             :   }
+    1731             : 
+    1732             :   double dp2=0.0;
+    1733         192 :   if(hill.multivariate) {
+    1734             :     unsigned k=0;
+    1735             :     // recompose the full sigma from the upper diag cholesky
+    1736             :     Matrix<double> mymatrix(ncv,ncv);
+    1737           0 :     for(unsigned i=0; i<ncv; i++) {
+    1738           0 :       for(unsigned j=i; j<ncv; j++) {
+    1739           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1740           0 :         k++;
+    1741             :       }
+    1742             :     }
+    1743           0 :     for(unsigned i=0; i<ncv; i++) {
+    1744           0 :       double dp_i=difference(i,hill.center[i],pcv[i]);
+    1745           0 :       for(unsigned j=i; j<ncv; j++) {
+    1746           0 :         if(i==j) {
+    1747           0 :           dp2+=dp_i*dp_i*mymatrix(i,j)*0.5;
+    1748             :         } else {
+    1749           0 :           double dp_j=difference(j,hill.center[j],pcv[j]);
+    1750           0 :           dp2+=dp_i*dp_j*mymatrix(i,j);
+    1751             :         }
+    1752             :       }
+    1753             :     }
+    1754             :   } else {
+    1755         576 :     for(unsigned i=0; i<ncv; i++) {
+    1756         384 :       double dp=difference(i,hill.center[i],pcv[i])*hill.invsigma[i];
+    1757         384 :       dp2+=dp*dp;
+    1758             :     }
+    1759         192 :     dp2*=0.5;
+    1760             :   }
+    1761             : 
+    1762             :   double bias=0.0;
+    1763         192 :   if(dp2<dp2cutoff) bias=hill.height*(stretchA*std::exp(-dp2)+stretchB);
+    1764             : 
+    1765         192 :   return bias;
+    1766             : }
+    1767             : 
+    1768     2409206 : double MetaD::evaluateGaussianAndDerivatives(const std::vector<double>& cv, const Gaussian& hill, std::vector<double>& der, std::vector<double>& dp_)
+    1769             : {
+    1770     2409206 :   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     2409206 :   if(ncv>0) pcv=&cv[0];
+    1778     2409206 :   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     2409206 :   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     2409206 :   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     6976182 :     for(unsigned i=0; i<ncv; i++) {
+    1829     4647574 :       dp_[i]=difference(i,hill.center[i],pcv[i])*hill.invsigma[i];
+    1830     4647574 :       dp2+=dp_[i]*dp_[i];
+    1831             :     }
+    1832     2328608 :     dp2*=0.5;
+    1833     2328608 :     if(dp2<dp2cutoff) {
+    1834     1356449 :       bias=hill.height*std::exp(-dp2);
+    1835     1356449 :       if(!int_der) {
+    1836     4060568 :         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     1356449 :       bias=stretchA*bias+hill.height*stretchB;
+    1841             :     }
+    1842             :   }
+    1843             : 
+    1844     2409206 :   return bias;
+    1845             : }
+    1846             : 
+    1847        2736 : double MetaD::getHeight(const std::vector<double>& cv)
+    1848             : {
+    1849        2736 :   double height=height0_;
+    1850        2736 :   if(welltemp_) {
+    1851         275 :     double vbias = getBias(cv);
+    1852         275 :     if(biasf_>1.0) {
+    1853         259 :       height = height0_*std::exp(-vbias/(kbt_*(biasf_-1.0)));
+    1854             :     } else {
+    1855             :       // notice that if gamma=1 we store directly -F
+    1856          16 :       height = height0_*std::exp(-vbias/kbt_);
+    1857             :     }
+    1858             :   }
+    1859        2736 :   if(dampfactor_>0.0) {
+    1860          18 :     plumed_assert(BiasGrid_);
+    1861          18 :     double m=BiasGrid_->getMaxValue();
+    1862          18 :     height*=std::exp(-m/(kbt_*(dampfactor_)));
+    1863             :   }
+    1864        2736 :   if (tt_specs_.is_active) {
+    1865          60 :     double vbarrier = transition_bias_;
+    1866          60 :     temperHeight(height, tt_specs_, vbarrier);
+    1867             :   }
+    1868        2736 :   if(TargetGrid_) {
+    1869          18 :     double f=TargetGrid_->getValue(cv)-TargetGrid_->getMaxValue();
+    1870          18 :     height*=std::exp(f/kbt_);
+    1871             :   }
+    1872        2736 :   return height;
+    1873             : }
+    1874             : 
+    1875          60 : void MetaD::temperHeight(double& height, const TemperingSpecs& t_specs, const double tempering_bias)
+    1876             : {
+    1877          60 :   if (t_specs.alpha == 1.0) {
+    1878          80 :     height *= std::exp(-std::max(0.0, tempering_bias - t_specs.threshold) / (kbt_ * (t_specs.biasf - 1.0)));
+    1879             :   } else {
+    1880          40 :     height *= std::pow(1 + (1 - t_specs.alpha) / t_specs.alpha * std::max(0.0, tempering_bias - t_specs.threshold) / (kbt_ * (t_specs.biasf - 1.0)), - t_specs.alpha / (1 - t_specs.alpha));
+    1881             :   }
+    1882          60 : }
+    1883             : 
+    1884        8435 : void MetaD::calculate()
+    1885             : {
+    1886             :   // this is because presently there is no way to properly pass information
+    1887             :   // on adaptive hills (diff) after exchanges:
+    1888        8435 :   if(adaptive_==FlexibleBin::diffusion && getExchangeStep()) error("ADAPTIVE=DIFF is not compatible with replica exchange");
+    1889             : 
+    1890        8435 :   const unsigned ncv=getNumberOfArguments();
+    1891        8435 :   std::vector<double> cv(ncv);
+    1892       21082 :   for(unsigned i=0; i<ncv; ++i) cv[i]=getArgument(i);
+    1893             : 
+    1894        8435 :   if(nlist_) {
+    1895           5 :     nlist_steps_++;
+    1896           5 :     if(getExchangeStep()) nlist_update_=true;
+    1897             :     else {
+    1898          11 :       for(unsigned i=0; i<ncv; ++i) {
+    1899           8 :         double d = difference(i, cv[i], nlist_center_[i]);
+    1900           8 :         double nk_dist2 = d*d/nlist_dev2_[i];
+    1901           8 :         if(nk_dist2>nlist_param_[1]) {nlist_update_=true; break;}
+    1902             :       }
+    1903             :     }
+    1904           5 :     if(nlist_update_) updateNlist();
+    1905             :   }
+    1906             : 
+    1907             :   double ene = 0.;
+    1908        8435 :   std::vector<double> der(ncv,0.);
+    1909        8435 :   if(biasf_!=1.0) ene = getBiasAndDerivatives(cv,der);
+    1910        8435 :   setBias(ene);
+    1911       21082 :   for(unsigned i=0; i<ncv; i++) setOutputForce(i,-der[i]);
+    1912             : 
+    1913        8440 :   if(calc_work_) getPntrToComponent("work")->set(work_);
+    1914        8545 :   if(calc_rct_) getPntrToComponent("rbias")->set(ene - reweight_factor_);
+    1915             :   // calculate the acceleration factor
+    1916        8435 :   if(acceleration_&&!isFirstStep_) {
+    1917         329 :     acc_ += static_cast<double>(getStride()) * std::exp(ene/(kbt_));
+    1918         329 :     const double mean_acc = acc_/((double) getStep());
+    1919         329 :     getPntrToComponent("acc")->set(mean_acc);
+    1920        8435 :   } else if (acceleration_ && isFirstStep_ && acc_restart_mean_ > 0.0) {
+    1921           2 :     acc_ = acc_restart_mean_ * static_cast<double>(getStep());
+    1922           2 :     if(freq_adaptive_) {
+    1923             :       // has to be done here if restarting, as the acc is not defined before
+    1924           1 :       updateFrequencyAdaptiveStride();
+    1925             :     }
+    1926             :   }
+    1927        8435 : }
+    1928             : 
+    1929        6239 : void MetaD::update()
+    1930             : {
+    1931             :   // adding hills criteria (could be more complex though)
+    1932             :   bool nowAddAHill;
+    1933        6239 :   if(getStep()%current_stride_==0 && !isFirstStep_) nowAddAHill=true;
+    1934             :   else {
+    1935             :     nowAddAHill=false;
+    1936        3503 :     isFirstStep_=false;
+    1937             :   }
+    1938             : 
+    1939        6239 :   unsigned ncv=getNumberOfArguments();
+    1940        6239 :   std::vector<double> cv(ncv);
+    1941       16690 :   for(unsigned i=0; i<ncv; ++i) cv[i] = getArgument(i);
+    1942             : 
+    1943             :   double vbias=0.;
+    1944        6239 :   if(calc_work_) vbias=getBias(cv);
+    1945             : 
+    1946             :   // if you use adaptive, call the FlexibleBin
+    1947             :   bool multivariate=false;
+    1948        6239 :   if(adaptive_!=FlexibleBin::none) {
+    1949         778 :     flexbin_->update(nowAddAHill);
+    1950             :     multivariate=true;
+    1951             :   }
+    1952             : 
+    1953             :   std::vector<double> thissigma;
+    1954        6239 :   if(nowAddAHill) {
+    1955             :     // add a Gaussian
+    1956        2736 :     double height=getHeight(cv);
+    1957             :     // returns upper diagonal inverse
+    1958        3110 :     if(adaptive_!=FlexibleBin::none) thissigma=flexbin_->getInverseMatrix();
+    1959             :     // returns normal sigma
+    1960        2362 :     else thissigma=sigma0_;
+    1961             : 
+    1962             :     // In case we use walkers_mpi, it is now necessary to communicate with other replicas.
+    1963        2736 :     if(walkers_mpi_) {
+    1964             :       // Allocate arrays to store all walkers hills
+    1965         174 :       std::vector<double> all_cv(mpi_nw_*ncv,0.0);
+    1966         174 :       std::vector<double> all_sigma(mpi_nw_*thissigma.size(),0.0);
+    1967         174 :       std::vector<double> all_height(mpi_nw_,0.0);
+    1968         174 :       std::vector<int>    all_multivariate(mpi_nw_,0);
+    1969         174 :       if(comm.Get_rank()==0) {
+    1970             :         // Communicate (only root)
+    1971          99 :         multi_sim_comm.Allgather(cv,all_cv);
+    1972          99 :         multi_sim_comm.Allgather(thissigma,all_sigma);
+    1973             :         // notice that if gamma=1 we store directly -F so this scaling is not necessary:
+    1974          99 :         multi_sim_comm.Allgather(height*(biasf_>1.0?biasf_/(biasf_-1.0):1.0),all_height);
+    1975          99 :         multi_sim_comm.Allgather(int(multivariate),all_multivariate);
+    1976             :       }
+    1977             :       // Share info with group members
+    1978         174 :       comm.Bcast(all_cv,0);
+    1979         174 :       comm.Bcast(all_sigma,0);
+    1980         174 :       comm.Bcast(all_height,0);
+    1981         174 :       comm.Bcast(all_multivariate,0);
+    1982             : 
+    1983             :       // Flying Gaussian
+    1984         174 :       if (flying_) {
+    1985          54 :         hills_.clear();
+    1986          54 :         comm.Barrier();
+    1987             :       }
+    1988             : 
+    1989         696 :       for(unsigned i=0; i<mpi_nw_; i++) {
+    1990             :         // actually add hills one by one
+    1991         522 :         std::vector<double> cv_now(ncv);
+    1992         522 :         std::vector<double> sigma_now(thissigma.size());
+    1993        1566 :         for(unsigned j=0; j<ncv; j++) cv_now[j]=all_cv[i*ncv+j];
+    1994        1674 :         for(unsigned j=0; j<thissigma.size(); j++) sigma_now[j]=all_sigma[i*thissigma.size()+j];
+    1995             :         // notice that if gamma=1 we store directly -F so this scaling is not necessary:
+    1996         522 :         double fact=(biasf_>1.0?(biasf_-1.0)/biasf_:1.0);
+    1997         522 :         Gaussian newhill=Gaussian(all_multivariate[i],all_height[i]*fact,cv_now,sigma_now);
+    1998         522 :         addGaussian(newhill);
+    1999         522 :         if(!flying_) writeGaussian(newhill,hillsOfile_);
+    2000         522 :       }
+    2001             :     } else {
+    2002        2562 :       Gaussian newhill=Gaussian(multivariate,height,cv,thissigma);
+    2003        2562 :       addGaussian(newhill);
+    2004        2562 :       writeGaussian(newhill,hillsOfile_);
+    2005        2562 :     }
+    2006             : 
+    2007             :     // this is to update the hills neighbor list
+    2008        2736 :     if(nlist_) nlist_update_=true;
+    2009             :   }
+    2010             : 
+    2011             :   // this should be outside of the if block in case
+    2012             :   // mw_rstride_ is not a multiple of stride_
+    2013        6239 :   if(mw_n_>1 && getStep()%mw_rstride_==0) hillsOfile_.flush();
+    2014             : 
+    2015        6239 :   if(calc_work_) {
+    2016           5 :     if(nlist_) updateNlist();
+    2017           5 :     double vbias1=getBias(cv);
+    2018           5 :     work_+=vbias1-vbias;
+    2019             :   }
+    2020             : 
+    2021             :   // dump grid on file
+    2022        6239 :   if(wgridstride_>0&&(getStep()%wgridstride_==0||getCPT())) {
+    2023             :     // in case old grids are stored, a sequence of grids should appear
+    2024             :     // this call results in a repetition of the header:
+    2025          91 :     if(storeOldGrids_) gridfile_.clearFields();
+    2026             :     // in case only latest grid is stored, file should be rewound
+    2027             :     // this will overwrite previously written grids
+    2028             :     else {
+    2029          51 :       int r = 0;
+    2030          51 :       if(walkers_mpi_) {
+    2031           0 :         if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    2032           0 :         comm.Bcast(r,0);
+    2033             :       }
+    2034          51 :       if(r==0) gridfile_.rewind();
+    2035             :     }
+    2036          91 :     BiasGrid_->writeToFile(gridfile_);
+    2037             :     // if a single grid is stored, it is necessary to flush it, otherwise
+    2038             :     // the file might stay empty forever (when a single grid is not large enough to
+    2039             :     // trigger flushing from the operating system).
+    2040             :     // on the other hand, if grids are stored one after the other this is
+    2041             :     // no necessary, and we leave the flushing control to the user as usual
+    2042             :     // (with FLUSH keyword)
+    2043          91 :     if(!storeOldGrids_) gridfile_.flush();
+    2044             :   }
+    2045             : 
+    2046             :   // if multiple walkers and time to read Gaussians
+    2047        6239 :   if(mw_n_>1 && getStep()%mw_rstride_==0) {
+    2048       12048 :     for(int i=0; i<mw_n_; ++i) {
+    2049             :       // don't read your own Gaussians
+    2050        9036 :       if(i==mw_id_) continue;
+    2051             :       // if the file is not open yet
+    2052        6024 :       if(!(ifiles_[i]->isOpen())) {
+    2053             :         // check if it exists now and open it!
+    2054           6 :         if(ifiles_[i]->FileExist(ifilesnames_[i])) {
+    2055           6 :           ifiles_[i]->open(ifilesnames_[i]);
+    2056           6 :           ifiles_[i]->reset(false);
+    2057             :         }
+    2058             :         // otherwise read the new Gaussians
+    2059             :       } else {
+    2060        6018 :         log.printf("  Reading hills from %s:",ifilesnames_[i].c_str());
+    2061        6018 :         readGaussians(ifiles_[i].get());
+    2062        6018 :         ifiles_[i]->reset(false);
+    2063             :       }
+    2064             :     }
+    2065             :     // this is to update the hills neighbor list
+    2066        3012 :     if(nlist_) nlist_update_=true;
+    2067             :   }
+    2068             : 
+    2069             :   // Recalculate special bias quantities whenever the bias has been changed by the update.
+    2070        6239 :   bool bias_has_changed = (nowAddAHill || (mw_n_ > 1 && getStep() % mw_rstride_ == 0));
+    2071        6239 :   if (calc_rct_ && bias_has_changed && getStep()%(stride_*rct_ustride_)==0) computeReweightingFactor();
+    2072        6239 :   if (calc_max_bias_ && bias_has_changed) {
+    2073           0 :     max_bias_ = BiasGrid_->getMaxValue();
+    2074           0 :     getPntrToComponent("maxbias")->set(max_bias_);
+    2075             :   }
+    2076        6239 :   if (calc_transition_bias_ && bias_has_changed) {
+    2077         260 :     transition_bias_ = getTransitionBarrierBias();
+    2078         520 :     getPntrToComponent("transbias")->set(transition_bias_);
+    2079             :   }
+    2080             : 
+    2081             :   // Frequency adaptive metadynamics - update hill addition frequency
+    2082        6239 :   if(freq_adaptive_ && getStep()%fa_update_frequency_==0) {
+    2083         151 :     updateFrequencyAdaptiveStride();
+    2084             :   }
+    2085        6239 : }
+    2086             : 
+    2087             : /// takes a pointer to the file and a template std::string with values v and gives back the next center, sigma and height
+    2088        8078 : 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        8078 :   multivariate=false;
+    2092       16156 :   if(ifile->scanField("time",dummy)) {
+    2093        2041 :     unsigned ncv=tmpvalues.size();
+    2094        6077 :     for(unsigned i=0; i<ncv; ++i) {
+    2095        4036 :       ifile->scanField( &tmpvalues[i] );
+    2096        4036 :       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        4036 :       } 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        4036 :       center[i]=tmpvalues[i].get();
+    2106             :     }
+    2107             :     // scan for kerneltype
+    2108        2041 :     std::string ktype="stretched-gaussian";
+    2109        6114 :     if( ifile->FieldExist("kerneltype") ) ifile->scanField("kerneltype",ktype);
+    2110        2041 :     if( ktype=="gaussian" ) {
+    2111          12 :       noStretchWarning();
+    2112        2029 :     } 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        4082 :     ifile->scanField("multivariate",sss);
+    2118        2041 :     if(sss=="true") multivariate=true;
+    2119        2041 :     else if(sss=="false") multivariate=false;
+    2120           0 :     else plumed_merror("cannot parse multivariate = "+ sss);
+    2121        2041 :     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        6077 :       for(unsigned i=0; i<ncv; ++i) {
+    2146        8072 :         ifile->scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+    2147             :       }
+    2148             :     }
+    2149             : 
+    2150        2041 :     ifile->scanField("height",height);
+    2151        2041 :     ifile->scanField("biasf",dummy);
+    2152        5940 :     if(ifile->FieldExist("clock")) ifile->scanField("clock",dummy);
+    2153        4082 :     if(ifile->FieldExist("lower_int")) ifile->scanField("lower_int",dummy);
+    2154        4082 :     if(ifile->FieldExist("upper_int")) ifile->scanField("upper_int",dummy);
+    2155        2041 :     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 000000000..3c3878639 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..44c8877ac --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2aa0d3eb9 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.gcov.html @@ -0,0 +1,356 @@ + + + + + + + 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-10-17 16:45:00Functions: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 STEPx with x=0,1,2,...,n. Each value given represents "
+     131             :            "the MD step at which the restraint parameters take the values KAPPAx and ATx.");
+     132          12 :   keys.reset_style("STEP","compulsory");
+     133          12 :   keys.add("numbered","AT","ATx is equal to the position of the restraint at time STEPx. For intermediate times this parameter "
+     134             :            "is linearly interpolated. If no ATx is specified for STEPx then the values of AT are kept constant "
+     135             :            "during the interval of time between STEP(x-1) and STEPx.");
+     136          12 :   keys.reset_style("AT","compulsory");
+     137          12 :   keys.add("numbered","KAPPA","KAPPAx is equal to the value of the force constants at time STEPx. For intermediate times this "
+     138             :            "parameter is linearly interpolated.  If no KAPPAx is specified for STEPx then the values of KAPPAx "
+     139             :            "are kept constant during the interval of time between STEP(x-1) and STEPx.");
+     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 000000000..d4ff92d3c --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..62665660b --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..154004b80 --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.gcov.html @@ -0,0 +1,1390 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..21fc98222 --- /dev/null +++ b/coverage/bias/Restraint.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE286
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE575
_ZN4PLMD4bias9Restraint9calculateEv4850
+
+
+ + + +
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 000000000..421ae27de --- /dev/null +++ b/coverage/bias/Restraint.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE575
_ZN4PLMD4bias9Restraint9calculateEv4850
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE286
_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 000000000..8c2e99798 --- /dev/null +++ b/coverage/bias/Restraint.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + 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-10-17 16:45:00Functions: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         575 : void Restraint::registerKeywords(Keywords& keys) {
+      82         575 :   Bias::registerKeywords(keys);
+      83        1150 :   keys.use("ARG"); keys.setDisplayName("RESTRAINT");
+      84        1150 :   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        1150 :   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        1150 :   keys.add("compulsory","AT","the position of the restraint");
+      87        1150 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      88         575 : }
+      89             : 
+      90         286 : Restraint::Restraint(const ActionOptions&ao):
+      91             :   PLUMED_BIAS_INIT(ao),
+      92         572 :   at(getNumberOfArguments()),
+      93         286 :   kappa(getNumberOfArguments(),0.0),
+      94         572 :   slope(getNumberOfArguments(),0.0)
+      95             : {
+      96         286 :   parseVector("SLOPE",slope);
+      97         286 :   parseVector("KAPPA",kappa);
+      98         286 :   parseVector("AT",at);
+      99         286 :   checkRead();
+     100             : 
+     101         286 :   log.printf("  at");
+     102         628 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     103         286 :   log.printf("\n");
+     104         286 :   log.printf("  with harmonic force constant");
+     105         628 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     106         286 :   log.printf("\n");
+     107         286 :   log.printf("  and linear force constant");
+     108         628 :   for(unsigned i=0; i<slope.size(); i++) log.printf(" %f",slope[i]);
+     109         286 :   log.printf("\n");
+     110             : 
+     111         572 :   addComponent("force2");
+     112         286 :   componentIsNotPeriodic("force2");
+     113         286 :   valueForce2=getPntrToComponent("force2");
+     114         286 : }
+     115             : 
+     116             : 
+     117        4850 : void Restraint::calculate() {
+     118             :   double ene=0.0;
+     119             :   double totf2=0.0;
+     120       10040 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     121        5190 :     const double cv=difference(i,at[i],getArgument(i));
+     122        5190 :     const double k=kappa[i];
+     123        5190 :     const double m=slope[i];
+     124        5190 :     const double f=-(k*cv+m);
+     125        5190 :     ene+=0.5*k*cv*cv+m*cv;
+     126        5190 :     setOutputForce(i,f);
+     127        5190 :     totf2+=f*f;
+     128             :   }
+     129        4850 :   setBias(ene);
+     130        4850 :   valueForce2->set(totf2);
+     131        4850 : }
+     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 000000000..38e760ddd --- /dev/null +++ b/coverage/bias/RestraintShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:485194.1 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias17RestraintShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias17RestraintShortcutC1ERKNS_13ActionOptionsE290
_ZN4PLMD4bias17RestraintShortcut16registerKeywordsERNS_8KeywordsE321
+
+
+ + + +
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 000000000..47405efe2 --- /dev/null +++ b/coverage/bias/RestraintShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:485194.1 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias17RestraintShortcut16registerKeywordsERNS_8KeywordsE321
_ZN4PLMD4bias17RestraintShortcutC1ERKNS_13ActionOptionsE290
_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 000000000..e22241027 --- /dev/null +++ b/coverage/bias/RestraintShortcut.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + 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:485194.1 %
Date:2024-10-17 16:45:00Functions: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         321 : void RestraintShortcut::registerKeywords(Keywords& keys) {
+      40         321 :   ActionShortcut::registerKeywords( keys );
+      41         642 :   keys.add("numbered","ARG","the arguments on which the bias is acting");
+      42         642 :   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         642 :   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         642 :   keys.add("compulsory","AT","the position of the restraint");
+      45         642 :   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         642 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      47         642 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      48        1605 :   keys.addActionNameSuffix("_SCALAR"); keys.needsAction("COMBINE"); keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("BIASVALUE");
+      49         321 : }
+      50             : 
+      51         290 : RestraintShortcut::RestraintShortcut(const ActionOptions&ao):
+      52             :   Action(ao),
+      53         290 :   ActionShortcut(ao)
+      54             : {
+      55             :   // Read in the args
+      56         580 :   std::vector<std::string> args; parseVector("ARG",args);
+      57         290 :   if( args.size()==0 ) error("found no input arguments");
+      58         290 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals );
+      59         287 :   if( vals.size()==0 ) error("found no input arguments");
+      60             : 
+      61             :   // Find the rank
+      62         287 :   unsigned rank=vals[0]->getRank();
+      63         630 :   for(unsigned i=0; i<vals.size(); ++i) {
+      64         343 :     if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) error("argument should not be function on grid");
+      65         343 :     if( vals[i]->getRank()!=rank ) error("all arguments should have same rank");
+      66             :   }
+      67         287 :   if( rank==0 ) {
+      68         575 :     std::vector<std::string> slope(args.size()); parseVector("SLOPE",slope); std::string slopestr="";
+      69         386 :     if( slope[0]!="0.0" ) { slopestr="SLOPE=" + slope[0]; for(unsigned i=1; i<slope.size(); ++i) slopestr += "," + slope[i]; }
+      70         342 :     std::string allargs=args[0]; for(unsigned i=1; i<args.size(); ++i) allargs += "," + args[i];
+      71         572 :     readInputLine( getShortcutLabel() + ": RESTRAINT_SCALAR ARG=" + allargs + " " + slopestr + " " + convertInputLineToString() );
+      72             :     return;
+      73         286 :   }
+      74             : 
+      75           2 :   std::string stride; parse("STRIDE",stride);
+      76           2 :   std::vector<std::string> at; parseVector("AT",at);
+      77           2 :   std::vector<std::string> slope(at.size()); parseVector("SLOPE",slope);
+      78           2 :   std::vector<std::string> kappa(at.size()); parseVector("KAPPA",kappa);
+      79             : 
+      80             :   std::string biasargs, forceargs; bool non_constant_force=false;
+      81           2 :   for(unsigned i=0; i<args.size(); ++i) {
+      82           1 :     std::string argn; std::size_t dot=args[i].find_first_of(".");
+      83           1 :     if(dot!=std::string::npos) argn = args[i].substr(0,dot) + "_" + args[i].substr(dot+1);
+      84             :     else argn = args[i];
+      85           2 :     readInputLine( getShortcutLabel() + "_cv_" + argn + ": COMBINE PERIODIC=NO ARG=" + args[i] + " PARAMETERS=" + at[i] );
+      86           1 :     double kap; Tools::convert(  kappa[i], kap );
+      87           1 :     if( fabs(kap)>0 ) {
+      88             :       non_constant_force = true;
+      89           2 :       readInputLine( getShortcutLabel() + "_harm_" + argn + ": CUSTOM PERIODIC=NO FUNC=0.5*" + kappa[i] + "*x^2 ARG=" + getShortcutLabel() + "_cv_" + argn );
+      90           2 :       readInputLine( getShortcutLabel() + "_kap_" + argn + ": SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_harm_" + argn );
+      91           2 :       readInputLine( getShortcutLabel() + "_f2_" + argn + ": CUSTOM PERIODIC=NO FUNC=" + kappa[i] + "*2*x+" + slope[i] + "*" + slope[i] + " ARG=" + getShortcutLabel() + "_harm_" + argn );
+      92           2 :       if( i==0 ) biasargs = "ARG=" + getShortcutLabel() + "_kap_" + argn; else biasargs += "," + getShortcutLabel() + "_kap_" + argn;
+      93           2 :       if( i==0 ) forceargs = "ARG=" + getShortcutLabel() + "_f2_" + argn; else forceargs += "," + getShortcutLabel() + "_f2_" + argn;
+      94             :     }
+      95           1 :     double slo; Tools::convert( slope[i], slo );
+      96           1 :     if( fabs(slo)>0 ) {
+      97           0 :       readInputLine( getShortcutLabel() + "_linear_" + argn + ": CUSTOM PERIODIC=NO FUNC=" + slope[i] + "*x ARG=" + getShortcutLabel() + "_cv_" + argn );
+      98           0 :       readInputLine( getShortcutLabel() + "_slope_" + argn + ": SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_linear_" + argn );
+      99           0 :       if( biasargs.length()==0 ) biasargs = "ARG=" + getShortcutLabel() + "_slope_" + argn; else biasargs += "," + getShortcutLabel() + "_slope_" + argn;
+     100             :     }
+     101             :   }
+     102             :   // This is the bias
+     103           2 :   readInputLine( getShortcutLabel() + "_bias: COMBINE PERIODIC=NO " + biasargs );
+     104           2 :   readInputLine( getShortcutLabel() + ": BIASVALUE ARG=" + getShortcutLabel() + "_bias STRIDE=" + stride );
+     105           2 :   if( non_constant_force ) readInputLine( getShortcutLabel() + "_force2: COMBINE PERIODIC=NO " + forceargs );
+     106         297 : }
+     107             : 
+     108             : }
+     109             : 
+     110             : 
+     111             : }
+
+
+
+ + + + +
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 000000000..0b65f3f8c --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..29668cd76 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4929849fc --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.gcov.html @@ -0,0 +1,129 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..22b5d691a --- /dev/null +++ b/coverage/bias/ReweightBase.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..09306ef51 --- /dev/null +++ b/coverage/bias/ReweightBase.h.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..823c162af --- /dev/null +++ b/coverage/bias/ReweightBase.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..272dfb621 --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..bdcf220a1 --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..173d0aadd --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.gcov.html @@ -0,0 +1,175 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightBias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the weight to use for this frame to negate the effect the bias");
+      84           5 : }
+      85             : 
+      86           3 : ReweightBias::ReweightBias(const ActionOptions&ao):
+      87             :   Action(ao),
+      88           3 :   ReweightBase(ao)
+      89             : {
+      90           3 : }
+      91             : 
+      92        1007 : double ReweightBias::getLogWeight() {
+      93             :   // Retrieve the bias
+      94        2014 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+      95        1007 :   return bias / simtemp;
+      96             : }
+      97             : 
+      98             : }
+      99             : }
+
+
+
+ + + + +
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 000000000..fcc6204ab --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightMetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightMetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..454a498ae --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightMetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightMetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..192d659ce --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightMetad.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightMetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the weight to use for this frame to negate the effect the metadynamics bias");
+      81           3 : }
+      82             : 
+      83           1 : ReweightMetad::ReweightMetad(const ActionOptions&ao):
+      84             :   Action(ao),
+      85           1 :   ReweightBase(ao)
+      86             : {
+      87           1 : }
+      88             : 
+      89           2 : double ReweightMetad::getLogWeight() {
+      90             :   // Retrieve the bias
+      91           4 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+      92           2 :   return bias / simtemp;
+      93             : }
+      94             : 
+      95             : }
+      96             : }
+
+
+
+ + + + +
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 000000000..6ff42b5b6 --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightTemperaturePressure.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightTemperaturePressure.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464797.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..bcc452d3f --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - bias/ReweightTemperaturePressure.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightTemperaturePressure.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464797.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..197259fd2 --- /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:464797.9 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the weight to use for this frame to determine its contribution at a different temperature/pressure");
+     199           6 : }
+     200             : 
+     201           4 : ReweightTemperaturePressure::ReweightTemperaturePressure(const ActionOptions&ao):
+     202             :   Action(ao),
+     203           4 :   ReweightBase(ao)
+     204             : {
+     205             :   // Initialize to not defined (negative)
+     206           4 :   rpress_=-1;
+     207           4 :   press_=-1;
+     208           4 :   rtemp_=-1;
+     209           4 :   parse("REWEIGHT_PRESSURE",rpress_);
+     210           4 :   parse("PRESSURE",press_);
+     211           4 :   parse("REWEIGHT_TEMP",rtemp_);
+     212           4 :   rtemp_*=getKBoltzmann();
+     213             : 
+     214           8 :   parseArgumentList("ENERGY",myenergy);
+     215           4 :   if(!myenergy.empty()) {
+     216           3 :     log.printf("  with energies: ");
+     217           6 :     for(unsigned i=0; i<myenergy.size(); i++) log.printf(" %s",myenergy[i]->getName().c_str());
+     218           3 :     log.printf("\n");
+     219             :   }
+     220             :   //requestArguments(myenergy);
+     221             : 
+     222           8 :   parseArgumentList("VOLUME",myvol);
+     223           4 :   if(!myvol.empty()) {
+     224           3 :     log.printf("  with volumes: ");
+     225           6 :     for(unsigned i=0; i<myvol.size(); i++) log.printf(" %s",myvol[i]->getName().c_str());
+     226           3 :     log.printf("\n");
+     227             :   }
+     228             : 
+     229             :   std::vector<Value*> conc;
+     230           4 :   conc.insert(conc.begin(), myenergy.begin(), myenergy.end());
+     231           4 :   conc.insert(conc.end(), myvol.begin(), myvol.end());
+     232           4 :   requestArguments(conc);
+     233             : 
+     234             :   // 4 possible cases
+     235             :   // Case 1) Reweight from T to T' with V=const (canonical)
+     236           4 :   if (rtemp_>=0 && press_<0 && rpress_<0 && !myenergy.empty() && myvol.empty() ) {
+     237           1 :     log.printf("  reweighting simulation from temperature %f to temperature %f at constant volume \n",simtemp/getKBoltzmann(),rtemp_/getKBoltzmann() );
+     238           1 :     log.printf("  WARNING: If the simulation is performed at constant pressure add the keywords PRESSURE and VOLUME \n" );
+     239             :   }
+     240             :   // Case 2) Reweight from T to T' with P=const (isothermal-isobaric)
+     241           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_ );
+     242             :   // Case 3) Reweight from P to P' with T=const (isothermal-isobaric)
+     243           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() );
+     244             :   // Case 4) Reweight from T,P to T',P' (isothermal-isobaric)
+     245           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_);
+     246           0 :   else error("Combination of ENERGY, VOLUME, REWEIGHT_PRESSURE, PRESSURE and REWEIGHT_TEMP not supported. Please refer to the manual for supported combinations.");
+     247           4 : }
+     248             : 
+     249        1001 : double ReweightTemperaturePressure::getLogWeight() {
+     250        2002 :   double energy=0.0; for(unsigned i=0; i<myenergy.size(); ++i) energy+=getArgument(i);
+     251        2002 :   double volume=0.0; for(unsigned i=0; i<myvol.size(); ++i) volume+=getArgument(myenergy.size()+i);
+     252             :   // 4 possible cases
+     253             :   // Case 1) Reweight from T to T' with V=const (canonical)
+     254        1001 :   if (rtemp_>=0 && press_<0 && rpress_<0) return ((1.0/simtemp)- (1.0/rtemp_) )*energy;
+     255             :   // Case 2) Reweight from T to T' with P=const (isothermal-isobaric)
+     256        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;
+     257             :   // Case 3) Reweight from P to P' with T=const (isothermal-isobaric)
+     258        1001 :   else if (rtemp_<0 && press_>=0 && rpress_>=0)  return (1.0/simtemp)*(press_ - rpress_)*volume;
+     259             :   // Case 4) Reweight from T,P to T',P' (isothermal-isobaric)
+     260        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;
+     261             :   else return 0;
+     262             : }
+     263             : 
+     264             : }
+     265             : }
+
+
+
+ + + + +
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 000000000..86ea5cf94 --- /dev/null +++ b/coverage/bias/UWalls.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE14
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD4bias6UWalls9calculateEv14059
+
+
+ + + +
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 000000000..ceae67489 --- /dev/null +++ b/coverage/bias/UWalls.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD4bias6UWalls9calculateEv14059
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE14
_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 000000000..1c0bea80e --- /dev/null +++ b/coverage/bias/UWalls.cpp.gcov.html @@ -0,0 +1,239 @@ + + + + + + + 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-10-17 16:45:00Functions: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             : for UPPER_WALLS:
+      39             : \f$
+      40             :   \sum_i {k_i}((x_i-a_i+o_i)/s_i)^e_i
+      41             : \f$
+      42             : 
+      43             : for LOWER_WALLS:
+      44             : \f$
+      45             :   \sum_i {k_i}|(x_i-a_i-o_i)/s_i|^e_i
+      46             : \f$
+      47             : 
+      48             : \f$k_i\f$ (KAPPA) is an energy constant in internal unit of the code, \f$s_i\f$ (EPS) a rescaling factor and
+      49             : \f$e_i\f$ (EXP) the exponent determining the power law. By default: EXP = 2, EPS = 1.0, OFFSET = 0.
+      50             : 
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following input tells plumed to add both a lower and an upper walls on the distance
+      55             : between atoms 3 and 5 and the distance between atoms 2 and 4. The lower and upper limits
+      56             : are defined at different values. The strength of the walls is the same for the four cases.
+      57             : It also tells plumed to print the energy of the walls.
+      58             : \plumedfile
+      59             : DISTANCE ATOMS=3,5 LABEL=d1
+      60             : DISTANCE ATOMS=2,4 LABEL=d2
+      61             : 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
+      62             : 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
+      63             : PRINT ARG=uwall.bias,lwall.bias
+      64             : \endplumedfile
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : //+PLUMEDOC BIAS UPPER_WALLS_SCALAR
+      70             : /*
+      71             : Defines a wall for the value of one or more collective variables,
+      72             :  which limits the region of the phase space accessible during the simulation.
+      73             : 
+      74             : \par Examples
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class UWalls : public Bias {
+      80             :   std::vector<double> at;
+      81             :   std::vector<double> kappa;
+      82             :   std::vector<double> exp;
+      83             :   std::vector<double> eps;
+      84             :   std::vector<double> offset;
+      85             : public:
+      86             :   explicit UWalls(const ActionOptions&);
+      87             :   void calculate() override;
+      88             :   static void registerKeywords(Keywords& keys);
+      89             : };
+      90             : 
+      91             : PLUMED_REGISTER_ACTION(UWalls,"UPPER_WALLS_SCALAR")
+      92             : 
+      93          30 : void UWalls::registerKeywords(Keywords& keys) {
+      94          30 :   Bias::registerKeywords(keys); keys.setDisplayName("UPPER_WALLS");
+      95          90 :   keys.use("ARG"); keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      96          60 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      97          60 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      98          60 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      99          60 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+     100          60 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+     101          60 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     102          30 : }
+     103             : 
+     104          14 : UWalls::UWalls(const ActionOptions&ao):
+     105             :   PLUMED_BIAS_INIT(ao),
+     106          28 :   at(getNumberOfArguments(),0),
+     107          14 :   kappa(getNumberOfArguments(),0.0),
+     108          14 :   exp(getNumberOfArguments(),2.0),
+     109          14 :   eps(getNumberOfArguments(),1.0),
+     110          28 :   offset(getNumberOfArguments(),0.0)
+     111             : {
+     112             :   // Note : the sizes of these vectors are checked automatically by parseVector
+     113          14 :   parseVector("OFFSET",offset);
+     114          14 :   parseVector("EPS",eps);
+     115          14 :   parseVector("EXP",exp);
+     116          14 :   parseVector("KAPPA",kappa);
+     117          14 :   parseVector("AT",at);
+     118          14 :   checkRead();
+     119             : 
+     120          14 :   log.printf("  at");
+     121          28 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     122          14 :   log.printf("\n");
+     123          14 :   log.printf("  with an offset");
+     124          28 :   for(unsigned i=0; i<offset.size(); i++) log.printf(" %f",offset[i]);
+     125          14 :   log.printf("\n");
+     126          14 :   log.printf("  with force constant");
+     127          28 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     128          14 :   log.printf("\n");
+     129          14 :   log.printf("  and exponent");
+     130          28 :   for(unsigned i=0; i<exp.size(); i++) log.printf(" %f",exp[i]);
+     131          14 :   log.printf("\n");
+     132          14 :   log.printf("  rescaled");
+     133          28 :   for(unsigned i=0; i<eps.size(); i++) log.printf(" %f",eps[i]);
+     134          14 :   log.printf("\n");
+     135             : 
+     136          28 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     137          14 : }
+     138             : 
+     139       14059 : void UWalls::calculate() {
+     140             :   double ene=0.0;
+     141             :   double totf2=0.0;
+     142       28118 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     143             :     double f = 0.0;
+     144       14059 :     const double cv=difference(i,at[i],getArgument(i));
+     145       14059 :     const double off=offset[i];
+     146       14059 :     const double epsilon=eps[i];
+     147       14059 :     const double uscale = (cv+off)/epsilon;
+     148       14059 :     if( uscale > 0.) {
+     149          26 :       const double k=kappa[i];
+     150          26 :       const double exponent=exp[i];
+     151          26 :       double power = pow( uscale, exponent );
+     152          26 :       f = -( k / epsilon ) * exponent * power / uscale;
+     153          26 :       ene += k * power;
+     154          26 :       totf2 += f * f;
+     155             :     }
+     156       14059 :     setOutputForce(i,f);
+     157             :   }
+     158       14059 :   setBias(ene);
+     159       14059 :   getPntrToComponent("force2")->set(totf2);
+     160       14059 : }
+     161             : 
+     162             : }
+     163             : }
+
+
+
+ + + + +
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 000000000..996833fc3 --- /dev/null +++ b/coverage/bias/Walls.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5WallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias5WallsC1ERKNS_13ActionOptionsE21
_ZN4PLMD4bias5Walls16registerKeywordsERNS_8KeywordsE58
+
+
+ + + +
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 000000000..d1bc2f489 --- /dev/null +++ b/coverage/bias/Walls.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5Walls16registerKeywordsERNS_8KeywordsE58
_ZN4PLMD4bias5WallsC1ERKNS_13ActionOptionsE21
_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 000000000..a15a5be6e --- /dev/null +++ b/coverage/bias/Walls.cpp.gcov.html @@ -0,0 +1,195 @@ + + + + + + + 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-10-17 16:45:00Functions: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          58 : void Walls::registerKeywords(Keywords& keys) {
+      41          58 :   ActionShortcut::registerKeywords(keys);
+      42         116 :   keys.add("numbered","ARG","the arguments on which the bias is acting");
+      43         116 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      44         116 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      45         116 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      46         116 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      47         116 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      48         116 :   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         116 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      50         116 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      51         174 :   keys.addActionNameSuffix("_SCALAR"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      52         174 :   keys.needsAction("SUM"); keys.needsAction("COMBINE"); keys.needsAction("BIASVALUE");
+      53          58 : }
+      54             : 
+      55          21 : Walls::Walls(const ActionOptions&ao):
+      56             :   Action(ao),
+      57          21 :   ActionShortcut(ao)
+      58             : {
+      59             :   // Read the arguments
+      60          42 :   std::vector<std::string> args; parseVector("ARG",args);
+      61          21 :   if( args.size()==0 ) error("found no input arguments");
+      62          21 :   std::string allargs=args[0]; for(unsigned i=1; i<args.size(); ++i) allargs += "," + args[i];
+      63          21 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals );
+      64          21 :   if( vals.size()==0 ) error("found no input arguments");
+      65             : 
+      66             :   // Find the rank
+      67          21 :   unsigned rank=vals[0]->getRank();
+      68          42 :   for(unsigned i=0; i<vals.size(); ++i) {
+      69          21 :     if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) error("argument should not be function on grid");
+      70          21 :     if( vals[i]->getRank()!=rank ) error("all arguments should have same rank");
+      71             :   }
+      72          21 :   if( rank==0 ) {
+      73          33 :     if( getName()=="UPPER_WALLS") readInputLine( getShortcutLabel() + ": UPPER_WALLS_SCALAR ARG=" + allargs + " " + convertInputLineToString() );
+      74          10 :     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          23 : }
+     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 000000000..99d76cd6c --- /dev/null +++ b/coverage/bias/index-sort-f.html @@ -0,0 +1,283 @@ + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2446267291.5 %
Date:2024-10-17 16:45:00Functions: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
RestraintShortcut.cpp +
94.1%94.1%
+
94.1 %48 / 5166.7 %2 / 3
Walls.cpp +
89.8%89.8%
+
89.8 %53 / 5966.7 %2 / 3
MovingRestraint.cpp +
100.0%
+
100.0 %109 / 10975.0 %3 / 4
ReweightBase.cpp +
100.0%
+
100.0 %18 / 1875.0 %3 / 4
External.cpp +
100.0%
+
100.0 %40 / 4075.0 %3 / 4
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
BiasValue.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
LWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
ReweightMetad.cpp +
100.0%
+
100.0 %11 / 1175.0 %3 / 4
ReweightTemperaturePressure.cpp +
97.9%97.9%
+
97.9 %46 / 4775.0 %3 / 4
Restraint.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %36 / 3675.0 %3 / 4
ABMD.cpp +
100.0%
+
100.0 %62 / 6275.0 %3 / 4
ReweightBias.cpp +
100.0%
+
100.0 %11 / 1175.0 %3 / 4
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %89 / 9080.0 %4 / 5
PBMetaD.cpp +
88.3%88.3%
+
88.3 %566 / 64186.7 %13 / 15
MaxEnt.cpp +
96.6%96.6%
+
96.6 %224 / 23290.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 000000000..f41cb2ba0 --- /dev/null +++ b/coverage/bias/index-sort-l.html @@ -0,0 +1,283 @@ + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2446267291.5 %
Date:2024-10-17 16:45:00Functions: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 +
94.1%94.1%
+
94.1 %48 / 5166.7 %2 / 3
MaxEnt.cpp +
96.6%96.6%
+
96.6 %224 / 23290.9 %10 / 11
ReweightTemperaturePressure.cpp +
97.9%97.9%
+
97.9 %46 / 4775.0 %3 / 4
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %89 / 9080.0 %4 / 5
Bias.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
ReweightMetad.cpp +
100.0%
+
100.0 %11 / 1175.0 %3 / 4
ReweightBias.cpp +
100.0%
+
100.0 %11 / 1175.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 %36 / 3675.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
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
LWalls.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 000000000..f63e85f21 --- /dev/null +++ b/coverage/bias/index.html @@ -0,0 +1,283 @@ + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2446267291.5 %
Date:2024-10-17 16:45:00Functions: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 %36 / 3675.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 %89 / 9080.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 %224 / 23290.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 +
94.1%94.1%
+
94.1 %48 / 5166.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 %11 / 1175.0 %3 / 4
ReweightMetad.cpp +
100.0%
+
100.0 %11 / 1175.0 %3 / 4
ReweightTemperaturePressure.cpp +
97.9%97.9%
+
97.9 %46 / 4775.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 000000000..eaec0cc7b --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.func-sort-c.html @@ -0,0 +1,180 @@ + + + + + + + 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:203415.9 %
Date:2024-10-17 16:45:00Functions: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_119BenchmarkRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMeD2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_19Benchmark16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..70c699124 --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.func.html @@ -0,0 +1,180 @@ + + + + + + + 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:203415.9 %
Date:2024-10-17 16:45:00Functions: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_119BenchmarkRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMeD2Ev5301
_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_8KeywordsE5301
_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 000000000..63d2f06d2 --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.gcov.html @@ -0,0 +1,928 @@ + + + + + + + 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:203415.9 %
Date:2024-10-17 16:45:00Functions: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 interrupt received\n");
+     199             :   }
+     200           0 :   if (signal == SIGTERM) {
+     201             :     signalReceived.store(true);
+     202           0 :     fprintf(stderr, "Signal termination received\n");
+     203             :   }
+     204           0 : }
+     205             : 
+     206             : /// This base class contains members that are movable with default operations
+     207             : struct KernelBase {
+     208             :   std::string path;
+     209             :   std::string plumed_dat;
+     210             :   PlumedHandle handle;
+     211             :   Stopwatch stopwatch;
+     212             :   std::vector<long long int> timings;
+     213             :   double comparative_timing=-1.0;
+     214             :   double comparative_timing_error=-1.0;
+     215           0 :   KernelBase(const std::string & path_,const std::string & plumed_dat_, Log* log_):
+     216           0 :     path(path_),
+     217           0 :     plumed_dat(plumed_dat_),
+     218           0 :     handle([&]() {
+     219           0 :     if(path_=="this") return PlumedHandle();
+     220           0 :     else return PlumedHandle::dlopen(path.c_str());
+     221             :   }()),
+     222           0 :   stopwatch(*log_)
+     223             :   {
+     224           0 :   }
+     225             : };
+     226             : 
+     227             : /// Local structure handling a kernel and the related timers.
+     228             : /// This structure specifically contain the Log, which needs special treatment
+     229             : /// in move semantics
+     230             : struct Kernel :
+     231             :   public KernelBase {
+     232             :   Log* log=nullptr;
+     233           0 :   Kernel(const std::string & path_,const std::string & the_plumed_dat, Log* log_):
+     234             :     KernelBase(path_,the_plumed_dat,log_),
+     235           0 :     log(log_)
+     236             :   {
+     237             :   }
+     238             : 
+     239           0 :   ~Kernel() {
+     240           0 :     if(log) {
+     241           0 :       (*log)<<"\n";
+     242           0 :       (*log)        <<"Kernel:      "<<path<<"\n";
+     243           0 :       (*log)        <<"Input:       "<<plumed_dat<<"\n";
+     244           0 :       if(comparative_timing>0.0) {
+     245           0 :         (*log).printf("Comparative: %.3f +- %.3f\n",comparative_timing,comparative_timing_error);
+     246             :       }
+     247             :     }
+     248           0 :   }
+     249             : 
+     250           0 :   Kernel(Kernel && other) noexcept:
+     251             :     KernelBase(std::move(other)),
+     252           0 :     log(other.log)
+     253             :   {
+     254           0 :     other.log=nullptr; // ensure no log is done in the moved away object
+     255             :   }
+     256             : 
+     257           0 :   Kernel & operator=(Kernel && other) noexcept
+     258             :   {
+     259           0 :     if(this != &other) {
+     260           0 :       KernelBase::operator=(std::move(other));
+     261           0 :       log=other.log;
+     262           0 :       other.log=nullptr; // ensure no log is done in the moved away object
+     263             :     }
+     264           0 :     return *this;
+     265             :   }
+     266             : };
+     267             : 
+     268             : namespace  {
+     269             : 
+     270             : class UniformSphericalVector {
+     271             :   //double rminCub;
+     272             :   double rCub;
+     273             : 
+     274             : public:
+     275             :   //assuming rmin=0
+     276           0 :   UniformSphericalVector(const double rmax):
+     277           0 :     rCub (rmax*rmax*rmax/*-rminCub*/) {}
+     278           0 :   PLMD::Vector operator()(Random& rng) {
+     279           0 :     double rho = std::cbrt (/*rminCub + */rng.RandU01()*rCub);
+     280           0 :     double theta =std::acos (2.0*rng.RandU01() -1.0);
+     281           0 :     double phi = 2.0 * PLMD::pi * rng.RandU01();
+     282             :     return Vector (
+     283           0 :              rho * sin (theta) * cos (phi),
+     284           0 :              rho * sin (theta) * sin (phi),
+     285           0 :              rho * cos (theta));
+     286             :   }
+     287             : };
+     288             : 
+     289             : ///Acts as a template for any distribution
+     290             : struct AtomDistribution {
+     291             :   virtual void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random&)=0;
+     292           0 :   virtual void box(std::vector<double>& box, unsigned /*natoms*/, unsigned /*step*/, Random&) {
+     293             :     std::fill(box.begin(), box.end(),0);
+     294           0 :   };
+     295             :   virtual ~AtomDistribution() noexcept {}
+     296             : };
+     297             : 
+     298           0 : struct theLine:public AtomDistribution {
+     299           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned step, Random&rng) override {
+     300             :     auto nat = posToUpdate.size();
+     301             :     UniformSphericalVector usv(0.5);
+     302             : 
+     303           0 :     for (unsigned i=0; i<nat; ++i) {
+     304           0 :       posToUpdate[i] = Vector(i, 0, 0) + usv(rng);
+     305             :     }
+     306           0 :   }
+     307             : };
+     308             : 
+     309           0 : struct uniformSphere:public AtomDistribution {
+     310           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random& rng) override {
+     311             : 
+     312             :     //giving more or less a cubic udm of volume for each atom: V=nat
+     313           0 :     const double rmax= std::cbrt ((3.0/(4.0*PLMD::pi)) * posToUpdate.size());
+     314             : 
+     315             :     UniformSphericalVector usv(rmax);
+     316             :     auto s=posToUpdate.begin();
+     317             :     auto e=posToUpdate.end();
+     318             :     //I am using the iterators:this is slightly faster,
+     319             :     // enough to overcome the cost of the vtable that I added
+     320           0 :     for (unsigned i=0; s!=e; ++s,++i) {
+     321           0 :       *s = usv (rng);
+     322             :     }
+     323             : 
+     324           0 :   }
+     325           0 :   void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) override {
+     326           0 :     const double rmax= 2.0*std::cbrt((3.0/(4.0*PLMD::pi)) * natoms);
+     327           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     328           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     329           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     330             : 
+     331           0 :   }
+     332             : };
+     333             : 
+     334           0 : struct twoGlobs: public AtomDistribution {
+     335           0 :   virtual void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random&rng) {
+     336             :     //I am using two unigform spheres and 2V=n
+     337           0 :     const double rmax= std::cbrt ((3.0/(8.0*PLMD::pi)) * posToUpdate.size());
+     338             : 
+     339             :     UniformSphericalVector usv(rmax);
+     340             :     std::array<Vector,2> centers{
+     341             :       PLMD::Vector{0.0,0.0,0.0},
+     342             : //so they do not overlap
+     343             :       PLMD::Vector{2.0*rmax,2.0*rmax,2.0*rmax}
+     344           0 :     };
+     345           0 :     std::generate(posToUpdate.begin(),posToUpdate.end(),[&]() {
+     346             :       //RandInt is only declared
+     347             :       // return usv (rng) + centers[rng.RandInt(1)];
+     348           0 :       return usv (rng) + centers[rng.RandU01()>0.5];
+     349             :     });
+     350           0 :   }
+     351             : 
+     352           0 :   virtual void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) {
+     353             : 
+     354           0 :     const double rmax= 4.0 * std::cbrt ((3.0/(8.0*PLMD::pi)) * natoms);
+     355           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     356           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     357           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     358           0 :   };
+     359             : };
+     360             : 
+     361           0 : struct uniformCube:public AtomDistribution {
+     362           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random& rng) override {
+     363             :     //giving more or less a cubic udm of volume for each atom: V = nat
+     364           0 :     const double rmax = std::cbrt(static_cast<double>(posToUpdate.size()));
+     365             : 
+     366             : 
+     367             : 
+     368             :     // std::generate(posToUpdate.begin(),posToUpdate.end(),[&]() {
+     369             :     //   return Vector (rndR(rng),rndR(rng),rndR(rng));
+     370             :     // });
+     371             :     auto s=posToUpdate.begin();
+     372             :     auto e=posToUpdate.end();
+     373             :     //I am using the iterators:this is slightly faster,
+     374             :     // enough to overcome the cost of the vtable that I added
+     375           0 :     for (unsigned i=0; s!=e; ++s,++i) {
+     376           0 :       *s = Vector (rng.RandU01()*rmax,rng.RandU01()*rmax,rng.RandU01()*rmax);
+     377             :     }
+     378           0 :   }
+     379           0 :   void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) override {
+     380             :     //+0.05 to avoid overlap
+     381           0 :     const double rmax= std::cbrt(natoms)+0.05;
+     382           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     383           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     384           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     385             : 
+     386           0 :   }
+     387             : };
+     388             : 
+     389           0 : struct tiledSimpleCubic:public AtomDistribution {
+     390           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random& rng) override {
+     391             :     //Tiling the space in this way will not tests 100% the pbc, but
+     392             :     //I do not think that write a spacefilling curve, like Hilbert, Peano or Morton
+     393             :     //could be a good idea, in this case
+     394           0 :     const unsigned rmax = std::ceil(std::cbrt(static_cast<double>(posToUpdate.size())));
+     395             : 
+     396             :     auto s=posToUpdate.begin();
+     397             :     auto e=posToUpdate.end();
+     398             :     //I am using the iterators:this is slightly faster,
+     399             :     // enough to overcome the cost of the vtable that I added
+     400           0 :     for (unsigned k=0; k<rmax&&s!=e; ++k) {
+     401           0 :       for (unsigned j=0; j<rmax&&s!=e; ++j) {
+     402           0 :         for (unsigned i=0; i<rmax&&s!=e; ++i) {
+     403           0 :           *s = Vector (i,j,k);
+     404             :           ++s;
+     405             :         }
+     406             :       }
+     407             :     }
+     408           0 :   }
+     409           0 :   void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) override {
+     410           0 :     const double rmax= std::ceil(std::cbrt(static_cast<double>(natoms)));;
+     411           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     412           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     413           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     414             : 
+     415           0 :   }
+     416             : };
+     417           0 : std::unique_ptr<AtomDistribution> getAtomDistribution(std::string_view atomicDistr) {
+     418           0 :   std::unique_ptr<AtomDistribution> distribution;
+     419           0 :   if(atomicDistr == "line") {
+     420           0 :     distribution = std::make_unique<theLine>();
+     421           0 :   } else if (atomicDistr == "cube") {
+     422           0 :     distribution = std::make_unique<uniformCube>();
+     423           0 :   } else if (atomicDistr == "sphere") {
+     424           0 :     distribution = std::make_unique<uniformSphere>();
+     425           0 :   } else if (atomicDistr == "globs") {
+     426           0 :     distribution = std::make_unique<twoGlobs>();
+     427           0 :   } else if (atomicDistr == "sc") {
+     428           0 :     distribution = std::make_unique<tiledSimpleCubic>();
+     429             :   } else {
+     430           0 :     plumed_error() << R"(The atomic distribution can be only "line", "cube", "sphere", "globs" and "sc", the input was ")"
+     431           0 :                    << atomicDistr <<'"';
+     432             :   }
+     433           0 :   return distribution;
+     434           0 : }
+     435             : } //anonymus namespace for benchmark distributions
+     436             : class Benchmark:
+     437             :   public CLTool
+     438             : {
+     439             : public:
+     440             :   static void registerKeywords( Keywords& keys );
+     441             :   explicit Benchmark(const CLToolOptions& co );
+     442             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+     443           4 :   std::string description()const override {
+     444           4 :     return "run a calculation with a fixed trajectory to find bottlenecks in PLUMED";
+     445             :   }
+     446             : };
+     447             : 
+     448       15907 : PLUMED_REGISTER_CLTOOL(Benchmark,"benchmark")
+     449             : 
+     450        5301 : void Benchmark::registerKeywords( Keywords& keys ) {
+     451        5301 :   CLTool::registerKeywords( keys );
+     452       10602 :   keys.add("compulsory","--plumed","plumed.dat","colon separated path(s) to the input file(s)");
+     453       10602 :   keys.add("compulsory","--kernel","this","colon separated path(s) to kernel(s)");
+     454       10602 :   keys.add("compulsory","--natoms","100000","the number of atoms to use for the simulation");
+     455       10602 :   keys.add("compulsory","--nsteps","2000","number of steps of MD to perform (-1 means forever)");
+     456       10602 :   keys.add("compulsory","--maxtime","-1","maximum number of seconds (-1 means forever)");
+     457       10602 :   keys.add("compulsory","--sleep","0","number of seconds of sleep, mimicking MD calculation");
+     458       10602 :   keys.add("compulsory","--atom-distribution","line","the kind of possible atomic displacement at each step");
+     459       10602 :   keys.add("optional","--dump-trajectory","dump the trajectory to this file");
+     460       10602 :   keys.addFlag("--domain-decomposition",false,"simulate domain decomposition, implies --shuffle");
+     461       10602 :   keys.addFlag("--shuffled",false,"reshuffle atoms");
+     462        5301 : }
+     463             : 
+     464           4 : Benchmark::Benchmark(const CLToolOptions& co ):
+     465           4 :   CLTool(co)
+     466             : {
+     467           4 :   inputdata=commandline;
+     468           4 : }
+     469             : 
+     470             : 
+     471           0 : int Benchmark::main(FILE* in, FILE*out,Communicator& pc) {
+     472             :   // deterministic initializations to avoid issues with MPI
+     473             :   generator rng;
+     474           0 :   PLMD::Random atomicGenerator;
+     475           0 :   std::unique_ptr<AtomDistribution> distribution;
+     476             : 
+     477             :   struct FileDeleter {
+     478             :     void operator()(FILE*f) const noexcept {
+     479           0 :       if(f) std::fclose(f);
+     480           0 :     }
+     481             :   };
+     482             : 
+     483           0 :   std::unique_ptr<FILE,FileDeleter> log_dev_null{std::fopen("/dev/null","w")};
+     484             : 
+     485           0 :   Log log;
+     486           0 :   if(pc.Get_rank()==0) {
+     487           0 :     log.link(out);
+     488             :   } else {
+     489           0 :     log.link(log_dev_null.get());
+     490             :   }
+     491           0 :   log.setLinePrefix("BENCH:  ");
+     492           0 :   log <<"Welcome to PLUMED benchmark\n";
+     493             :   std::vector<Kernel> kernels;
+     494             : 
+     495             :   // perform comparative analysis
+     496             :   // ensure that kernels vector is destroyed from last to first element upon exit
+     497           0 :   auto kernels_deleter=[&log](auto f) {
+     498           0 :     if(!f) {
+     499           0 :       return;
+     500             :     }
+     501           0 :     if(f->empty()) {
+     502             :       return;
+     503             :     }
+     504             :     generator bootstrapRng;
+     505             : 
+     506             :     const auto size=f->back().timings.size();
+     507             :     //B are the bootstrap iterations
+     508             :     constexpr int B=200;
+     509           0 :     const size_t numblocks=size;
+     510             :     // for some reasons, blocked bootstrap underestimates error
+     511             :     // For now I keep it off. If I remove it, the code below could be simplified
+     512             :     // if(numblocks>20) numblocks=20;
+     513           0 :     const auto blocksize=size/numblocks;
+     514             : 
+     515           0 :     if(f->size()<2) {
+     516           0 :       log<<"Single run, skipping comparative analysis\n";
+     517           0 :     } else if(size<10) {
+     518           0 :       log<<"Too small sample, skipping comparative analysis\n";
+     519             :     } else try {
+     520             : 
+     521           0 :         log<<"Running comparative analysis, "<<numblocks<<" blocks with size "<<blocksize<<"\n";
+     522             : 
+     523           0 :         std::vector<std::size_t> choice(size);
+     524           0 :         std::uniform_int_distribution<> distrib(0, numblocks-1);
+     525           0 :         std::vector<std::vector<long long int>> blocks(f->size());
+     526             : 
+     527             :         { int i=0;
+     528           0 :           for(auto it = f->rbegin(); it != f->rend(); ++it,++i) {
+     529             :             size_t l=0;
+     530           0 :             blocks[i].assign(numblocks,0);
+     531           0 :             for(auto j=0ULL; j<numblocks; j++) {
+     532           0 :               for(auto k=0ULL; k<blocksize; k++) {
+     533           0 :                 plumed_assert(l<it->timings.size());
+     534           0 :                 blocks[i][j]+=it->timings[l];
+     535           0 :                 l++;
+     536             :               }
+     537             :             }
+     538             :           }
+     539             :         }
+     540             : 
+     541           0 :         std::vector<std::vector<double>> ratios(f->size());
+     542           0 :         for(auto & r : ratios) {
+     543             :           //B are the bootstrap iterations
+     544           0 :           r.resize(B);
+     545             :         }
+     546             : 
+     547             :         //B are the bootstrap iterations
+     548           0 :         for(unsigned b=0; b<B; b++) {
+     549           0 :           for(auto & c : choice) c=distrib(bootstrapRng);
+     550             :           long long int reference=0;
+     551           0 :           for(auto & c : choice) {
+     552           0 :             reference+=blocks[0][c];
+     553             :           }
+     554           0 :           for(auto i=0ULL; i<blocks.size(); i++) {
+     555             :             long long int estimate=0;
+     556             :             // this would lead to separate bootstrap samples for each estimate:
+     557             :             // for(auto & c : choice){c=distrib(bootstrapRng);}
+     558           0 :             for(auto & c : choice) {
+     559           0 :               estimate+=blocks[i][c];
+     560             :             }
+     561           0 :             ratios[i][b]=double(estimate)/double(reference);
+     562             :           }
+     563             :         }
+     564             : 
+     565             :         {
+     566             :           int i=0;
+     567           0 :           for(auto it = f->rbegin(); it != f->rend(); ++it,++i) {
+     568             :             double sum=0.0;
+     569             :             double sum2=0.0;
+     570           0 :             for(auto r : ratios[i]) {
+     571           0 :               sum+=r;
+     572           0 :               sum2+=r*r;
+     573             :             }
+     574             :             //B are the bootstrap iterations
+     575           0 :             it->comparative_timing=sum/B;
+     576           0 :             it->comparative_timing_error=std::sqrt(sum2/B-sum*sum/(B*B));
+     577             :           }
+     578             :         }
+     579             : 
+     580           0 :       } catch(std::exception & e) {
+     581           0 :         log<<"Unexpected error during comparative analysis\n";
+     582           0 :         log<<e.what()<<"\n";
+     583             :       }
+     584           0 :     while(!f->empty()) f->pop_back();
+     585             : 
+     586             :   };
+     587             :   std::unique_ptr<decltype(kernels),decltype(kernels_deleter)> kernels_deleter_obj(&kernels,kernels_deleter);
+     588             : 
+     589             : 
+     590             :   // construct the kernels vector:
+     591             :   {
+     592             :     std::vector<std::string> allpaths;
+     593             : 
+     594             :     {
+     595             :       std::string paths;
+     596           0 :       parse("--kernel",paths);
+     597           0 :       log <<"Using --kernel=" << paths << "\n";
+     598           0 :       allpaths=Tools::getWords(paths,":");
+     599             :     }
+     600             : 
+     601             :     std::vector<std::string> allplumed;
+     602             :     {
+     603             :       std::string paths;
+     604           0 :       parse("--plumed",paths);
+     605           0 :       log <<"Using --plumed=" << paths << "\n";
+     606           0 :       allplumed=Tools::getWords(paths,":");
+     607             :     }
+     608             : 
+     609           0 :     plumed_assert(allplumed.size()>0 && allpaths.size()>0);
+     610             : 
+     611             :     // this check only works on MacOS
+     612             : #if defined(__APPLE__)
+     613             :     // if any of the paths if different from "this", we check if libplumed was loaded locally to avoid conflicts.
+     614             :     if(std::any_of(allpaths.begin(),allpaths.end(),[](auto value) {return value != "this";})) {
+     615             :       if(DLLoader::isPlumedGlobal()) {
+     616             :         plumed_error()<<"It looks like libplumed is loaded in the global namespace, you cannot load a different version of the kernel\n"
+     617             :                       <<"Please make sure you use the plumed-runtime executable and that the env var PLUMED_LOAD_NAMESPACE is not set to GLOBAL";
+     618             :       }
+     619             :     }
+     620             : #endif
+     621             : 
+     622           0 :     if(allplumed.size()>1 && allpaths.size()>1 && allplumed.size() != allpaths.size()) {
+     623           0 :       plumed_error() << "--kernel and --plumed should have either one element or the same number of elements";
+     624             :     }
+     625             : 
+     626           0 :     if(allplumed.size()>1 && allpaths.size()==1) for(unsigned i=1; i<allplumed.size(); i++) allpaths.push_back(allpaths[0]);
+     627           0 :     if(allplumed.size()==1 && allpaths.size()>1) for(unsigned i=1; i<allpaths.size(); i++) allplumed.push_back(allplumed[0]);
+     628             : 
+     629           0 :     for(unsigned i=0; i<allpaths.size(); i++) kernels.emplace_back(allpaths[i],allplumed[i],&log);
+     630           0 :   }
+     631             : 
+     632             :   // reverse order so that log happens in the forward order:
+     633           0 :   std::reverse(kernels.begin(),kernels.end());
+     634             : 
+     635             :   // read other flags:
+     636           0 :   bool shuffled=false;
+     637           0 :   parseFlag("--shuffled",shuffled);
+     638             : 
+     639           0 :   int nf; parse("--nsteps",nf);
+     640           0 :   log << "Using --nsteps=" << nf << "\n";
+     641           0 :   unsigned natoms; parse("--natoms",natoms);
+     642           0 :   log << "Using --natoms=" << natoms << "\n";
+     643           0 :   double maxtime; parse("--maxtime",maxtime);
+     644           0 :   log << "Using --maxtime=" << maxtime << "\n";
+     645             : 
+     646           0 :   bool domain_decomposition=false;
+     647           0 :   parseFlag("--domain-decomposition",domain_decomposition);
+     648             : 
+     649           0 :   if(pc.Get_size()>1) domain_decomposition=true;
+     650           0 :   if(domain_decomposition) shuffled=true;
+     651             : 
+     652           0 :   if (shuffled)
+     653           0 :     log << "Using --shuffled\n";
+     654           0 :   if (domain_decomposition)
+     655           0 :     log << "Using --domain-decomposition\n";
+     656             : 
+     657             :   double timeToSleep;
+     658           0 :   parse("--sleep",timeToSleep);
+     659           0 :   log << "Using --sleep=" << timeToSleep << "\n";
+     660             : 
+     661             :   std::vector<int> shuffled_indexes;
+     662             : 
+     663             :   {
+     664             :     std::string atomicDistr;
+     665           0 :     parse("--atom-distribution",atomicDistr);
+     666           0 :     distribution = getAtomDistribution(atomicDistr);
+     667           0 :     log << "Using --atom-distribution=" << atomicDistr << "\n";
+     668             :   }
+     669             : 
+     670             :   {
+     671             :     std::string fileToDump;
+     672           0 :     if(parse("--dump-trajectory",fileToDump)) {
+     673           0 :       log << "Saving the trajectory to \"" << fileToDump << "\" and exiting\n";
+     674           0 :       std::vector<double> cell(9);
+     675           0 :       std::vector<Vector> pos(natoms);
+     676           0 :       std::ofstream ofile(fileToDump);
+     677           0 :       if (nf<0) {
+     678             :         //if the user accidentally sets infinite steps, we set it to print only one
+     679           0 :         nf=1;
+     680             :       }
+     681           0 :       for(int step=0; step<nf; ++step) {
+     682           0 :         auto sw=kernels[0].stopwatch.startStop("TrajectoryGeneration");
+     683           0 :         distribution->positions(pos,step,atomicGenerator);
+     684           0 :         distribution->box(cell,natoms,step,atomicGenerator);
+     685           0 :         ofile << natoms << "\n"
+     686           0 :               << cell[0] << " " << cell[1] << " " << cell[2] << " "
+     687           0 :               << cell[3] << " " << cell[4] << " " << cell[5] << " "
+     688           0 :               << cell[6] << " " << cell[7] << " " << cell[8] << "\n";
+     689           0 :         for(int i=0; i<natoms; ++i) {
+     690           0 :           ofile << "X\t" << pos[i]<< "\n";
+     691             :         }
+     692           0 :       }
+     693           0 :       ofile.close();
+     694             :       return 0;
+     695           0 :     }
+     696             :   }
+     697             : 
+     698           0 :   log <<"Initializing the setup of the kernel(s)\n";
+     699           0 :   const auto initial_time=std::chrono::high_resolution_clock::now();
+     700             : 
+     701           0 :   for(auto & k : kernels) {
+     702             :     auto & p(k.handle);
+     703           0 :     auto sw=k.stopwatch.startStop("A Initialization");
+     704           0 :     if(Communicator::plumedHasMPI() && domain_decomposition) p.cmd("setMPIComm",&pc.Get_comm());
+     705           0 :     p.cmd("setRealPrecision",(int)sizeof(double));
+     706           0 :     p.cmd("setMDLengthUnits",1.0);
+     707           0 :     p.cmd("setMDChargeUnits",1.0);
+     708           0 :     p.cmd("setMDMassUnits",1.0);
+     709           0 :     p.cmd("setMDEngine","benchmarks");
+     710           0 :     p.cmd("setTimestep",1.0);
+     711           0 :     p.cmd("setPlumedDat",k.plumed_dat.c_str());
+     712           0 :     p.cmd("setLog",out);
+     713           0 :     p.cmd("setNatoms",natoms);
+     714           0 :     p.cmd("init");
+     715           0 :   }
+     716             : 
+     717           0 :   std::vector<double> cell( 9 ), virial( 9 );
+     718           0 :   std::vector<Vector> pos( natoms ), forces( natoms );
+     719           0 :   std::vector<double> masses( natoms, 1 ), charges( natoms, 0 );
+     720             : 
+     721           0 :   if(shuffled) {
+     722           0 :     shuffled_indexes.resize(natoms);
+     723           0 :     for(unsigned i=0; i<natoms; i++) shuffled_indexes[i]=i;
+     724           0 :     std::shuffle(shuffled_indexes.begin(),shuffled_indexes.end(),rng);
+     725             :   }
+     726             : 
+     727             :   // non owning pointers, used for shuffling the execution order
+     728             :   std::vector<Kernel*> kernels_ptr;
+     729           0 :   for(unsigned i=0; i<kernels.size(); i++) kernels_ptr.push_back(&kernels[i]);
+     730             : 
+     731           0 :   int plumedStopCondition=0;
+     732             :   bool fast_finish=false;
+     733             :   int part=0;
+     734             : 
+     735           0 :   log<<"Starting MD loop\n";
+     736           0 :   log<<"Use CTRL+C to stop at any time and collect timers (not working in MPI runs)\n";
+     737             :   // trap signals:
+     738           0 :   SignalHandlerGuard sigIntGuard(SIGINT, signalHandler);
+     739           0 :   SignalHandlerGuard sigTermGuard(SIGTERM, signalHandler);
+     740             : 
+     741           0 :   for(int step=0; nf<0 || step<nf; ++step) {
+     742           0 :     std::shuffle(kernels_ptr.begin(),kernels_ptr.end(),rng);
+     743           0 :     distribution->positions(pos,step,atomicGenerator);
+     744           0 :     distribution->box(cell,natoms,step,atomicGenerator);
+     745             :     double* pos_ptr;
+     746             :     double* for_ptr;
+     747             :     double* charges_ptr;
+     748             :     double* masses_ptr;
+     749             :     int* indexes_ptr=nullptr;
+     750             :     int n_local_atoms;
+     751             : 
+     752           0 :     if(domain_decomposition) {
+     753           0 :       const auto nproc=pc.Get_size();
+     754           0 :       const auto nn=natoms/nproc;
+     755             :       //using int to remove warning, MPI don't work with unsigned
+     756           0 :       int excess=natoms%nproc;
+     757           0 :       const auto myrank=pc.Get_rank();
+     758             :       auto shift=0;
+     759           0 :       n_local_atoms=nn;
+     760           0 :       if(myrank<excess) n_local_atoms+=1;
+     761           0 :       for(int i=0; i<myrank; i++) {
+     762           0 :         shift+=nn;
+     763           0 :         if(i<excess) shift+=1;
+     764             :       }
+     765           0 :       pos_ptr=&pos[shift][0];
+     766           0 :       for_ptr=&forces[shift][0];
+     767             :       charges_ptr=&charges[shift];
+     768             :       masses_ptr=&masses[shift];
+     769           0 :       indexes_ptr=shuffled_indexes.data()+shift;
+     770             :     } else {
+     771           0 :       pos_ptr=&pos[0][0];
+     772           0 :       for_ptr=&forces[0][0];
+     773             :       charges_ptr=&charges[0];
+     774             :       masses_ptr=&masses[0];
+     775           0 :       n_local_atoms=natoms;
+     776             :       indexes_ptr=shuffled_indexes.data();
+     777             :     }
+     778             : 
+     779             :     const char* sw_name;
+     780           0 :     if(part==0)      sw_name="B0 First step";
+     781           0 :     else if(part==1) sw_name="B1 Warm-up";
+     782           0 :     else if(part==2) sw_name="B2 Calculation part 1";
+     783             :     else             sw_name="B3 Calculation part 2";
+     784             : 
+     785             : 
+     786           0 :     for(unsigned i=0; i<kernels_ptr.size(); i++) {
+     787           0 :       auto & p(kernels_ptr[i]->handle);
+     788             : 
+     789             :       {
+     790           0 :         auto sw=kernels_ptr[i]->stopwatch.startPause(sw_name);
+     791           0 :         p.cmd("setStep",step);
+     792           0 :         p.cmd("setStopFlag",&plumedStopCondition);
+     793           0 :         p.cmd("setForces",for_ptr, {n_local_atoms,3});
+     794           0 :         p.cmd("setBox",&cell[0], {3,3});
+     795           0 :         p.cmd("setVirial",&virial[0], {3,3});
+     796           0 :         p.cmd("setPositions",pos_ptr, {n_local_atoms,3});
+     797           0 :         p.cmd("setMasses",masses_ptr, {n_local_atoms});
+     798           0 :         p.cmd("setCharges",charges_ptr, {n_local_atoms});
+     799           0 :         if(shuffled) {
+     800           0 :           p.cmd("setAtomsNlocal",n_local_atoms);
+     801           0 :           p.cmd("setAtomsGatindex",indexes_ptr, {n_local_atoms});
+     802             :         }
+     803           0 :         p.cmd("prepareCalc");
+     804           0 :       }
+     805             : 
+     806             :       // mimick MD calculation here
+     807             :       {
+     808             :         unsigned k=0;
+     809           0 :         auto start=std::chrono::high_resolution_clock::now();
+     810           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;
+     811             :         std::fprintf(log_dev_null.get(),"%u",k);
+     812             :       }
+     813             : 
+     814             :       {
+     815           0 :         auto sw=kernels_ptr[i]->stopwatch.startStop(sw_name);
+     816           0 :         p.cmd("performCalc");
+     817           0 :       }
+     818             : 
+     819           0 :       if(kernels_ptr.size()>1 && part>1) kernels_ptr[i]->timings.push_back(kernels_ptr[i]->stopwatch.getLastCycle(sw_name));
+     820           0 :       if(plumedStopCondition || signalReceived.load()) fast_finish=true;
+     821             :     }
+     822           0 :     auto elapsed=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-initial_time).count();
+     823           0 :     if(part==0) part=1;
+     824           0 :     if(part<2) {
+     825           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)) {
+     826             :         part=2;
+     827           0 :         log<<"Warm-up completed\n";
+     828             :       }
+     829             :     }
+     830           0 :     if(part<3) {
+     831           0 :       if((maxtime>0 && elapsed>(long long int)(0.6*1e9*maxtime)) || (nf>0 && step+1>=3*nf/5)) {
+     832             :         part=3;
+     833           0 :         log<<"60% completed\n";
+     834             :       }
+     835             :     }
+     836             : 
+     837           0 :     if(maxtime>0 && elapsed>(long long int)(1e9*maxtime)) fast_finish=true;
+     838             : 
+     839             :     {
+     840           0 :       unsigned tmp=fast_finish;
+     841           0 :       pc.Bcast(tmp,0);
+     842           0 :       fast_finish=tmp;
+     843             :     }
+     844           0 :     if(fast_finish) break;
+     845             :   }
+     846             : 
+     847             :   return 0;
+     848           0 : }
+     849             : 
+     850             : } // namespace unnamed
+     851             : } // namespace cltools
+     852             : } // 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 000000000..fac7e273c --- /dev/null +++ b/coverage/cltools/Completion.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE5301
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev5301
+
+
+ + + +
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 000000000..8cfd69067 --- /dev/null +++ b/coverage/cltools/Completion.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10Completion16registerKeywordsERNS_8KeywordsE5301
_ZN4PLMD7cltools10Completion4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10CompletionC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev5301
_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 000000000..bb717a361 --- /dev/null +++ b/coverage/cltools/Completion.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-10-17 16:45:00Functions: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       15907 : PLUMED_REGISTER_CLTOOL(Completion,"completion")
+      65             : 
+      66        5301 : void Completion::registerKeywords( Keywords& keys ) {
+      67        5301 :   CLTool::registerKeywords( keys );
+      68        5301 : }
+      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 000000000..5e454973d --- /dev/null +++ b/coverage/cltools/Driver.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - cltools/Driver.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Driver.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:64767595.9 %
Date:2024-10-17 16:45:00Functions: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_267
_ZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorE939
_ZN4PLMD7cltools6DriverIdEC2ERKNS_13CLToolOptionsE943
_ZN4PLMD7cltools6DriverIdE16registerKeywordsERNS_8KeywordsE5301
_ZN4PLMD7cltools6DriverIfE16registerKeywordsERNS_8KeywordsE5301
_ZN4PLMD7cltoolsL11register_cbEPvPNS_7molfile11vmdplugin_tE95418
+
+
+ + + +
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 000000000..bbab6ac2d --- /dev/null +++ b/coverage/cltools/Driver.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - cltools/Driver.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Driver.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:64767595.9 %
Date:2024-10-17 16:45:00Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE943
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev5301
+
+
+ + + +
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 000000000..7a0667a19 --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - cltools/DriverDouble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverDouble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE943
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev5301
+
+
+ + + +
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 000000000..4d5e475c7 --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.gcov.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - cltools/DriverDouble.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverDouble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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       16846 : 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 000000000..b40e941a3 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev5301
+
+
+ + + +
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 000000000..b58abb356 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev5301
_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 000000000..823940ca9 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.gcov.html @@ -0,0 +1,118 @@ + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions: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       15907 : 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 000000000..7bf4dcb30 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172128.0 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE5301
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev5301
+
+
+ + + +
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 000000000..d45b82c71 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172128.0 %
Date:2024-10-17 16:45:00Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10GenExample15createLongInputERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EE0
_ZN4PLMD7cltools10GenExample16registerKeywordsERNS_8KeywordsE5301
_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_120GenExampleRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev5301
_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 000000000..69a7281c3 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.gcov.html @@ -0,0 +1,419 @@ + + + + + + + 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:172128.0 %
Date:2024-10-17 16:45:00Functions: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       15907 : PLUMED_REGISTER_CLTOOL(GenExample,"gen_example")
+      82             : 
+      83        5301 : void GenExample::registerKeywords( Keywords& keys ) {
+      84        5301 :   CLTool::registerKeywords( keys );
+      85       10602 :   keys.add("compulsory","--plumed","plumed.dat","convert the input in this file to the html manual");
+      86       10602 :   keys.add("compulsory","--out","example.html","the file on which to output the example in html");
+      87       10602 :   keys.add("compulsory","--name","ppp","the name to use for this particular input");
+      88       10602 :   keys.add("compulsory","--status","nobadge","whether or not the input file works");
+      89       10602 :   keys.add("compulsory","--multi","0","set number of replicas for multi environment (needs MPI)");
+      90        5301 : }
+      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);
+     323           0 :               ofile<<"<tr><td width=\"5%%\">"<<myname<<"</td><td>"<<av->getOutputComponentDescription(tname,keys)<<"</td></tr>"<<std::endl;
+     324             :             }
+     325           0 :             ofile<<"</table>"<<std::endl;
+     326             :           }
+     327             :         } else {
+     328           0 :           ActionWithVirtualAtom* avv=myplumed.getActionSet().selectWithLabel<ActionWithVirtualAtom*>(lab);
+     329           0 :           if( avv ) ofile<<" calculates the position of a virtual atom";
+     330           0 :           else if( interpreted[0]=="GROUP" ) ofile<<" defines a group of atoms so that they can be referred to later in the input";
+     331             :         }
+     332           0 :         ofile<<"</span>"<<std::endl;
+     333             :       } else {
+     334           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;
+     335             :       }
+     336           0 :     }
+     337           0 :     ofile.flush();
+     338             :   }
+     339           0 :   ofile<<"</pre>"<<std::endl;
+     340           0 : }
+     341             : 
+     342             : } // End of namespace
+     343             : }
+
+
+
+ + + + +
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 000000000..4dfe7613e --- /dev/null +++ b/coverage/cltools/GenJson.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:104104100.0 %
Date:2024-10-17 16:45:00Functions: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_117GenJsonRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeD2Ev5301
_ZN4PLMD7cltools7GenJson16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..2a1ff94cf --- /dev/null +++ b/coverage/cltools/GenJson.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:104104100.0 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMe6createERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeD2Ev5301
_ZN4PLMD7cltools7GenJson16registerKeywordsERNS_8KeywordsE5301
_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 000000000..6c4f92b84 --- /dev/null +++ b/coverage/cltools/GenJson.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + 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:104104100.0 %
Date:2024-10-17 16:45:00Functions: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 "core/ModuleMap.h"
+      29             : #include <cstdio>
+      30             : #include <string>
+      31             : #include <iostream>
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace cltools {
+      35             : 
+      36             : //+PLUMEDOC TOOLS gen_json
+      37             : /*
+      38             : 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
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : The following command generates the json file
+      43             : \verbatim
+      44             : plumed gen_json
+      45             : \endverbatim
+      46             : 
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : class GenJson : public CLTool {
+      52             : private:
+      53             :   std::string version;
+      54             : public:
+      55             :   static void registerKeywords( Keywords& keys );
+      56             :   explicit GenJson(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 json file that contains the pluemd syntax";
+      60             :   }
+      61             : };
+      62             : 
+      63       15908 : PLUMED_REGISTER_CLTOOL(GenJson,"gen_json")
+      64             : 
+      65        5301 : void GenJson::registerKeywords( Keywords& keys ) {
+      66        5301 :   CLTool::registerKeywords( keys );
+      67       10602 :   keys.add("compulsory","--actions","a file containing one line descriptions of the various actions");
+      68        5301 : }
+      69             : 
+      70           5 : GenJson::GenJson(const CLToolOptions& co ):
+      71             :   CLTool(co),
+      72           5 :   version("master")
+      73             : {
+      74           5 :   inputdata=commandline;
+      75          15 :   if( config::getVersionLong().find("dev")==std::string::npos ) version="v"+config::getVersion();
+      76           5 : }
+      77             : 
+      78           1 : int GenJson::main(FILE* in, FILE*out,Communicator& pc) {
+      79           1 :   std::string line(""), actionfile; parse("--actions",actionfile);
+      80           1 :   IFile myfile; myfile.open(actionfile); bool stat;
+      81             :   std::map<std::string,std::string> action_map;
+      82         464 :   while((stat=myfile.getline(line))) {
+      83         463 :     std::size_t col = line.find_first_of(":"); std::string docs = line.substr(col+1);
+      84         463 :     if( docs.find("\\")!=std::string::npos ) error("found invalid backslash character in first line of documentation for action " + line.substr(0,col) );
+      85         926 :     action_map.insert(std::pair<std::string,std::string>( line.substr(0,col), docs ) );
+      86             :   }
+      87           1 :   myfile.close();
+      88             : 
+      89             :   // Cycle over all the action names
+      90           1 :   std::cout<<"{"<<std::endl;
+      91             :   // Get the vimlink
+      92           2 :   std::cout<<"  \"vimlink\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_vim_syntax.html\","<<std::endl;
+      93             :   // And the replicas link
+      94           2 :   std::cout<<"  \"replicalink\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/special-replica-syntax.html\","<<std::endl;
+      95             :   // Get the names of all the actions
+      96           1 :   std::vector<std::string> action_names( actionRegister().getActionNames() );
+      97         439 :   for(unsigned i=0; i<action_names.size(); ++i) {
+      98        1314 :     std::cout<<"  \""<<action_names[i]<<'"'<<": {"<<std::endl; std::string action=action_names[i];
+      99             :     // Handle conversion of action names to links
+     100         876 :     std::cout<<"    \"hyperlink\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/";
+     101        5705 :     std::transform(action.begin(), action.end(), action.begin(), [](unsigned char c) { return std::tolower(c); });
+     102             :     while(true) {
+     103         758 :       std::size_t und=action.find_first_of("_");
+     104         758 :       if( und==std::string::npos ) break;
+     105         320 :       std::string first=action.substr(0,und);
+     106        4192 :       for(auto c : first ) { if( isdigit(c) ) std::cout<<c; else std::cout<<"_"<<c; }
+     107         640 :       std::cout<<"_"; action=action.substr(und+1);
+     108         320 :     }
+     109        6460 :     for(auto c : action ) { if( isdigit(c) ) std::cout<<c; else std::cout<<"_"<<c; }
+     110         438 :     std::cout<<".html\","<<std::endl;
+     111         876 :     std::cout<<"    \"description\" : \""<<action_map[action_names[i]]<<"\",\n";
+     112         876 :     std::cout<<"    \"module\" : \""<<getModuleMap().find(action_names[i])->second<<"\",\n";
+     113             :     // Now output keyword information
+     114         438 :     Keywords keys; actionRegister().getKeywords( action_names[i], keys );
+     115         876 :     std::cout<<"    \"displayname\" : \""<<keys.getDisplayName()<<"\",\n";
+     116         438 :     std::cout<<"    \"syntax\" : {"<<std::endl;
+     117        5482 :     for(unsigned j=0; j<keys.size(); ++j) {
+     118        5044 :       std::string desc = keys.getKeywordDescription( keys.getKeyword(j) );
+     119        5044 :       if( desc.find("default=")!=std::string::npos ) {
+     120        3274 :         std::size_t brac=desc.find_first_of(")"); desc = desc.substr(brac+1);
+     121             :       }
+     122        5044 :       std::size_t dot=desc.find_first_of("."); std::string mydescrip = desc.substr(0,dot);
+     123        5044 :       if( mydescrip.find("\\")!=std::string::npos ) error("found invalid backslash character documentation for keyword " + keys.getKeyword(j) + " in action " + action_names[i] );
+     124       25220 :       std::cout<<"       \""<<keys.getKeyword(j)<<"\" : { \"type\": \""<<keys.getStyle(keys.getKeyword(j))<<"\", \"description\": \""<<mydescrip<<"\", \"multiple\": "<<keys.numbered( keys.getKeyword(j) )<<"}";
+     125        5848 :       if( j==keys.size()-1 && !keys.exists("HAS_VALUES") ) std::cout<<std::endl; else std::cout<<","<<std::endl;
+     126             :     }
+     127         876 :     if( keys.exists("HAS_VALUES") ) {
+     128         366 :       std::cout<<"       \"output\" : {"<<std::endl;
+     129         366 :       std::vector<std::string> components( keys.getOutputComponents() );
+     130             :       // Check if we have a value
+     131             :       bool hasvalue=true;
+     132         914 :       for(unsigned k=0; k<components.size(); ++k) {
+     133        1732 :         if( keys.getOutputComponentFlag( components[k] )=="default" ) { hasvalue=false; break; }
+     134             :       }
+     135        1638 :       for(unsigned k=0; k<components.size(); ++k) {
+     136        2544 :         std::string compname=components[k]; if( components[k]==".#!value" ) { hasvalue=false; compname="value"; }
+     137        2544 :         std::cout<<"         \""<<compname<<"\" : {"<<std::endl;
+     138        3816 :         std::cout<<"           \"flag\": \""<<keys.getOutputComponentFlag( components[k] )<<"\","<<std::endl;
+     139        1272 :         std::string desc=keys.getOutputComponentDescription( components[k] );
+     140        1272 :         std::size_t dot=desc.find_first_of("."); std::string mydescrip = desc.substr(0,dot);
+     141        1272 :         if( mydescrip.find("\\")!=std::string::npos ) error("found invalid backslash character documentation for output component " + compname + " in action " + action_names[i] );
+     142        2544 :         std::cout<<"           \"description\": \""<<mydescrip<<"\""<<std::endl;
+     143        1272 :         if( k==components.size()-1 ) std::cout<<"         }"<<std::endl; else std::cout<<"         },"<<std::endl;
+     144             :       }
+     145         366 :       if( hasvalue && components.size()==0 ) printf("WARNING: no components have been registered for action %s \n", action_names[i].c_str() );
+     146         366 :       std::cout<<"       }"<<std::endl;
+     147             : 
+     148         366 :     }
+     149         438 :     std::cout<<"    },"<<std::endl;
+     150         438 :     if( keys.getNeededKeywords().size()>0 ) {
+     151         122 :       std::vector<std::string> neededActions( keys.getNeededKeywords() );
+     152         244 :       std::cout<<"    \"needs\" : ["<<"\""<<neededActions[0]<<"\"";
+     153        1006 :       for(unsigned j=1; j<neededActions.size(); ++j) std::cout<<", \""<<neededActions[j]<<"\"";
+     154         122 :       std::cout<<"],"<<std::endl;
+     155         122 :     }
+     156             :     // This ensures that \n is replaced by \\n
+     157         438 :     std::string unsafen="\n", safen="\\n", helpstr = keys.getHelpString();
+     158         438 :     for( std::size_t pos = helpstr.find("\n");
+     159       13735 :          pos != std::string::npos;
+     160       13297 :          pos = helpstr.find("\n", pos)
+     161       13297 :        ) { helpstr.replace(pos, unsafen.size(), safen); pos += safen.size(); }
+     162         876 :     std::cout<<"    \"help\" : \""<<helpstr<<"\"\n";
+     163         438 :     std::cout<<"  },"<<std::endl;
+     164         438 :   }
+     165             :   // Get all the special groups
+     166           1 :   std::cout<<"  \"groups\" : {"<<std::endl;
+     167           1 :   std::cout<<"    \"@allatoms\" : { \n"<<std::endl;
+     168           1 :   std::cout<<"        \"description\" : \"refers to all the MD codes atoms and PLUMEDs vatoms\","<<std::endl;
+     169           2 :   std::cout<<"        \"link\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_group.html\""<<std::endl;
+     170           1 :   std::cout<<"    },"<<std::endl;
+     171           1 :   std::cout<<"    \"@mdatoms\" : { \n"<<std::endl;
+     172           1 :   std::cout<<"        \"description\" : \"refers to all the MD codes atoms but not PLUMEDs vatoms\","<<std::endl;
+     173           2 :   std::cout<<"        \"link\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_group.html\""<<std::endl;
+     174           1 :   std::cout<<"    },"<<std::endl;
+     175           1 :   std::cout<<"    \"@ndx\" : { \n"<<std::endl;
+     176           1 :   std::cout<<"        \"description\" : \"load a group from a GROMACS index file\","<<std::endl;
+     177           2 :   std::cout<<"        \"link\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_group.html\""<<std::endl;
+     178             :   // Now print all the special keywords in molinfo
+     179           1 :   std::map<std::string,std::string> specials( GenericMolInfo::getSpecialKeywords() );
+     180          36 :   for(auto const& s : specials ) {
+     181          35 :     std::cout<<"    },"<<std::endl;
+     182          70 :     std::cout<<"    \""<<s.first<<"\" : { \n"<<std::endl;
+     183          70 :     std::cout<<"        \"description\" : \""<<s.second<<"\","<<std::endl;
+     184          70 :     std::cout<<"        \"link\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_m_o_l_i_n_f_o.html\""<<std::endl;
+     185             :   }
+     186           1 :   std::cout<<"        }"<<std::endl;
+     187           1 :   std::cout<<"  }"<<std::endl;
+     188           1 :   std::cout<<"}"<<std::endl;
+     189           1 :   return 0;
+     190           2 : }
+     191             : 
+     192             : } // End of namespace
+     193             : }
+
+
+
+ + + + +
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 000000000..fabab73c1 --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenTemplate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132356.5 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE5301
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeD2Ev5301
+
+
+ + + +
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 000000000..5f696acce --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenTemplate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132356.5 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11GenTemplate16registerKeywordsERNS_8KeywordsE5301
_ZN4PLMD7cltools11GenTemplate4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools11GenTemplateC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeD2Ev5301
_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 000000000..31d354717 --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenTemplate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132356.5 %
Date:2024-10-17 16:45:00Functions: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       15907 : PLUMED_REGISTER_CLTOOL(GenTemplate,"gentemplate")
+      64             : 
+      65        5301 : void GenTemplate::registerKeywords( Keywords& keys ) {
+      66        5301 :   CLTool::registerKeywords( keys );
+      67       10602 :   keys.add("optional","--action","print the template for this particular action");
+      68       10602 :   keys.addFlag("--list",false,"print a list of the available actions");
+      69       10602 :   keys.addFlag("--include-optional",false,"also print optional modifiers");
+      70        5301 : }
+      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 000000000..297d1ad3a --- /dev/null +++ b/coverage/cltools/Info.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE2295
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE2299
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE2299
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev5301
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..e6093f117 --- /dev/null +++ b/coverage/cltools/Info.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE2299
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev5301
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE5301
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE2295
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE2299
_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 000000000..45a24775a --- /dev/null +++ b/coverage/cltools/Info.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-10-17 16:45:00Functions: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       18202 : PLUMED_REGISTER_CLTOOL(Info,"info")
+      62             : 
+      63        5301 : void Info::registerKeywords( Keywords& keys ) {
+      64        5301 :   CLTool::registerKeywords( keys );
+      65       10602 :   keys.addFlag("--configuration",false,"prints the configuration file");
+      66       10602 :   keys.addFlag("--root",false,"print the location of the root directory for the plumed source");
+      67       10602 :   keys.addFlag("--user-doc",false,"print the location of user manual (html)");
+      68       10602 :   keys.addFlag("--developer-doc",false,"print the location of user manual (html)");
+      69       10602 :   keys.addFlag("--version",false,"print the version number");
+      70       10602 :   keys.addFlag("--long-version",false,"print the version number (long version)");
+      71       10602 :   keys.addFlag("--git-version",false,"print the version number (git version, if available)");
+      72       10602 :   keys.addFlag("--include-dir",false,"print the location of the include dir");
+      73       10602 :   keys.addFlag("--soext",false,"print the extension of shared libraries (so or dylib)");
+      74        5301 : }
+      75             : 
+      76        2299 : Info::Info(const CLToolOptions& co ):
+      77        2299 :   CLTool(co)
+      78             : {
+      79        2299 :   inputdata=commandline;
+      80        2299 : }
+      81             : 
+      82        2295 : int Info::main(FILE* in, FILE*out,Communicator& pc) {
+      83             : 
+      84        2295 :   bool printconfiguration; parseFlag("--configuration",printconfiguration);
+      85        2295 :   bool printroot; parseFlag("--root",printroot);
+      86        2295 :   bool printuserdoc; parseFlag("--user-doc",printuserdoc);
+      87        2295 :   bool printdeveloperdoc; parseFlag("--developer-doc",printdeveloperdoc);
+      88        2295 :   bool printversion; parseFlag("--version",printversion);
+      89        2295 :   bool printlongversion; parseFlag("--long-version",printlongversion);
+      90        2295 :   bool printgitversion; parseFlag("--git-version",printgitversion);
+      91        2295 :   bool printincludedir; parseFlag("--include-dir",printincludedir);
+      92        2295 :   bool printsoext; parseFlag("--soext",printsoext);
+      93        3048 :   if(printroot) std::fprintf(out,"%s\n",config::getPlumedRoot().c_str());
+      94        2335 :   if(printconfiguration) std::fprintf(out,"%s",config::getMakefile().c_str());
+      95        2295 :   if(printincludedir) std::fprintf(out,"%s\n",config::getPlumedIncludedir().c_str());
+      96        2295 :   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        2295 :   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        2295 :   if(printversion) std::fprintf(out,"%s\n",config::getVersion().c_str());
+     113        2295 :   if(printlongversion) std::fprintf(out,"%s\n",config::getVersionLong().c_str());
+     114        2295 :   if(printgitversion) std::fprintf(out,"%s\n",config::getVersionGit().c_str());
+     115        3797 :   if(printsoext) std::fprintf(out,"%s\n",config::getSoExt().c_str());
+     116             : 
+     117        2295 :   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 000000000..49c8dfdd3 --- /dev/null +++ b/coverage/cltools/Manual.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE439
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE443
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE443
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev5301
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..50f6937a8 --- /dev/null +++ b/coverage/cltools/Manual.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE443
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev5301
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE5301
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE439
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE443
_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 000000000..549e99e91 --- /dev/null +++ b/coverage/cltools/Manual.cpp.gcov.html @@ -0,0 +1,177 @@ + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-10-17 16:45:00Functions: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       16346 : PLUMED_REGISTER_CLTOOL(Manual,"manual")
+      67             : 
+      68        5301 : void Manual::registerKeywords( Keywords& keys ) {
+      69        5301 :   CLTool::registerKeywords( keys );
+      70       10602 :   keys.add("compulsory","--action","print the manual for this particular action");
+      71       10602 :   keys.addFlag("--vim",false,"print the keywords in vim syntax");
+      72       10602 :   keys.addFlag("--spelling",false,"print a list of the keywords and component names for the spell checker");
+      73        5301 : }
+      74             : 
+      75         443 : Manual::Manual(const CLToolOptions& co ):
+      76         443 :   CLTool(co)
+      77             : {
+      78         443 :   inputdata=commandline;
+      79         443 : }
+      80             : 
+      81         439 : int Manual::main(FILE* in, FILE*out,Communicator& pc) {
+      82             : 
+      83             :   std::string action;
+      84         878 :   if( !parse("--action",action) ) return 1;
+      85         439 :   std::cerr<<"LIST OF DOCUMENTED ACTIONS:\n";
+      86         439 :   std::cerr<<actionRegister()<<"\n";
+      87         439 :   std::cerr<<"LIST OF DOCUMENTED COMMAND LINE TOOLS:\n";
+      88         439 :   std::cerr<<cltoolRegister()<<"\n\n";
+      89         439 :   bool vimout; parseFlag("--vim",vimout);
+      90         439 :   bool spellout; parseFlag("--spelling",spellout);
+      91         439 :   if( vimout && spellout ) error("can only use one of --vim and --spelling at a time");
+      92         439 :   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 000000000..309f50bcd --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/PdbRenumber.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - PdbRenumber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE5301
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev5301
+
+
+ + + +
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 000000000..cfd070702 --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/PdbRenumber.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - PdbRenumber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11PdbRenumber16registerKeywordsERNS_8KeywordsE5301
_ZN4PLMD7cltools11PdbRenumber4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZN4PLMD7cltools11PdbRenumberC2ERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev5301
_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 000000000..89dd65747 --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.gcov.html @@ -0,0 +1,274 @@ + + + + + + + LCOV - plumed test coverage - cltools/PdbRenumber.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - PdbRenumber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-10-17 16:45:00Functions: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       15910 : PLUMED_REGISTER_CLTOOL(PdbRenumber,"pdbrenumber")
+     113             : 
+     114        5301 : void PdbRenumber::registerKeywords( Keywords& keys ) {
+     115        5301 :   CLTool::registerKeywords( keys );
+     116       10602 :   keys.add("compulsory","--ipdb","specify the name of the input PDB file");
+     117       10602 :   keys.add("compulsory","--opdb","specify the name of the output PDB file");
+     118       10602 :   keys.add("optional","--firstatomnumber","specify the desired serial number of the first atom of the output file");
+     119       10602 :   keys.add("optional","--atomnumbers","specify the desired serial numbers of the atoms of the output file using a separate list");
+     120        5301 : }
+     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 000000000..d141edbe0 --- /dev/null +++ b/coverage/cltools/ShowGraph.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions: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_119ShowGraphRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMeD2Ev5301
_ZN4PLMD7cltools9ShowGraph16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..b09858d15 --- /dev/null +++ b/coverage/cltools/ShowGraph.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMe6createERKNS_13CLToolOptionsE12
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMeD2Ev5301
_ZN4PLMD7cltools9ShowGraph10printStyleERKjPKNS_5ValueERNS_5OFileE85
_ZN4PLMD7cltools9ShowGraph16registerKeywordsERNS_8KeywordsE5301
_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 000000000..fa112cccb --- /dev/null +++ b/coverage/cltools/ShowGraph.cpp.gcov.html @@ -0,0 +1,403 @@ + + + + + + + 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-10-17 16:45:00Functions: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       15915 : PLUMED_REGISTER_CLTOOL(ShowGraph,"show_graph")
+      79             : 
+      80        5301 : void ShowGraph::registerKeywords( Keywords& keys ) {
+      81        5301 :   CLTool::registerKeywords( keys );
+      82       10602 :   keys.add("compulsory","--plumed","plumed.dat","the plumed input that we are generating the graph for");
+      83       10602 :   keys.add("compulsory","--out","graph.md","the dot file containing the graph that has been generated");
+      84       10602 :   keys.addFlag("--force",false,"print a graph that shows how forces are passed through the actions");
+      85        5301 : }
+      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          24 :   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 000000000..544c8e1d2 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func-sort-c.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-10-17 16:45:00Functions: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_118SimpleMDRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev5301
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE5301
_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 000000000..fc41c7a6a --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-10-17 16:45:00Functions:2020100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev5301
_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_8KeywordsE5301
_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 000000000..56eaec8ef --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.gcov.html @@ -0,0 +1,684 @@ + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-10-17 16:45:00Functions: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        5301 :   static void registerKeywords( Keywords& keys ) {
+      97       10602 :     keys.add("compulsory","nstep","The number of steps of dynamics you want to run");
+      98       10602 :     keys.add("compulsory","temperature","NVE","the temperature at which you wish to run the simulation in LJ units");
+      99       10602 :     keys.add("compulsory","friction","off","The friction (in LJ units) for the Langevin thermostat that is used to keep the temperature constant");
+     100       10602 :     keys.add("compulsory","tstep","0.005","the integration timestep in LJ units");
+     101       10602 :     keys.add("compulsory","epsilon","1.0","LJ parameter");
+     102       10602 :     keys.add("compulsory","sigma","1.0","LJ parameter");
+     103       10602 :     keys.add("compulsory","inputfile","An xyz file containing the initial configuration of the system");
+     104       10602 :     keys.add("compulsory","forcecutoff","2.5","");
+     105       10602 :     keys.add("compulsory","listcutoff","3.0","");
+     106       10602 :     keys.add("compulsory","outputfile","An output xyz file containing the final configuration of the system");
+     107       10602 :     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       10602 :     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       10602 :     keys.add("compulsory","idum","0","The random number seed");
+     110       10602 :     keys.add("compulsory","ndim","3","The dimensionality of the system (some interesting LJ clusters are two dimensional)");
+     111       10602 :     keys.add("compulsory","wrapatoms","false","If true, atomic coordinates are written wrapped in minimal cell");
+     112        5301 :   }
+     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       15916 : 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 000000000..eb345a665 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-10-17 16:45:00Functions: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_124CLToolSumHillsRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev5301
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..319147a81 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-10-17 16:45:00Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev5301
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE5301
_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 000000000..367a10b0d --- /dev/null +++ b/coverage/cltools/SumHills.cpp.gcov.html @@ -0,0 +1,701 @@ + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-10-17 16:45:00Functions: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        5301 : void CLToolSumHills::registerKeywords( Keywords& keys ) {
+     199        5301 :   CLTool::registerKeywords( keys );
+     200       10602 :   keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
+     201       10602 :   keys.add("optional","--hills","specify the name of the hills file");
+     202       10602 :   keys.add("optional","--histo","specify the name of the file for histogram a colvar/hills file is good");
+     203       10602 :   keys.add("optional","--stride","specify the stride for integrating hills file (default 0=never)");
+     204       10602 :   keys.add("optional","--min","the lower bounds for the grid");
+     205       10602 :   keys.add("optional","--max","the upper bounds for the grid");
+     206       10602 :   keys.add("optional","--bin","the number of bins for the grid");
+     207       10602 :   keys.add("optional","--spacing","grid spacing, alternative to the number of bins");
+     208       10602 :   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       10602 :   keys.add("optional","--outfile","specify the output file for sumhills");
+     210       10602 :   keys.add("optional","--outhisto","specify the output file for the histogram");
+     211       10602 :   keys.add("optional","--kt","specify temperature in energy units for integrating out variables");
+     212       10602 :   keys.add("optional","--sigma"," a vector that specify the sigma for binning (only needed when doing histogram ");
+     213       10602 :   keys.addFlag("--negbias",false," print the negative bias instead of the free energy (only needed with well tempered runs and flexible hills) ");
+     214       10602 :   keys.addFlag("--nohistory",false," to be used with --stride:  it splits the bias/histogram in pieces without previous history ");
+     215       10602 :   keys.addFlag("--mintozero",false," it translate all the minimum value in bias/histogram to zero (useful to compare results) ");
+     216       10602 :   keys.add("optional","--fmt","specify the output format");
+     217        5301 : }
+     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       15916 : 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 000000000..2e96aae65 --- /dev/null +++ b/coverage/cltools/SwitchingPlotter.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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_126SwitchingPlotterRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMeD2Ev5301
_ZN4PLMD7cltools16SwitchingPlotter16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..6975afd08 --- /dev/null +++ b/coverage/cltools/SwitchingPlotter.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMeD2Ev5301
_ZN4PLMD7cltools16SwitchingPlotter16registerKeywordsERNS_8KeywordsE5301
_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 000000000..35103489d --- /dev/null +++ b/coverage/cltools/SwitchingPlotter.cpp.gcov.html @@ -0,0 +1,268 @@ + + + + + + + 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-10-17 16:45:00Functions: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       15907 : PLUMED_REGISTER_CLTOOL(SwitchingPlotter,"plotswitch")
+      72             : 
+      73        5301 : void SwitchingPlotter::registerKeywords( Keywords& keys ) {
+      74        5301 :   CLTool::registerKeywords( keys );
+      75       10602 :   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       10602 :   keys.add("compulsory","--steps","50",
+      79             :            "the number of steps between 0 and R_O, or in the specified interval");
+      80       10602 :   keys.add("compulsory","--from","-1",
+      81             :            "the start of the interval, if negative will be set to 0");
+      82       10602 :   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       10602 :   keys.add("compulsory","--plotprecision","8",
+      85             :            "the precision to use for the tabulated results");
+      86       10602 :   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       10602 :   keys.add("compulsory","--rationalNN","6",
+      90             :            "The n parameter of the switching function");
+      91       10602 :   keys.add("compulsory","--rationalMM","0",
+      92             :            "The m parameter of the switching function; 0 implies 2*NN");
+      93       10602 :   keys.add("compulsory","--rationalD_0","0.0",
+      94             :            "The d_0 parameter of the switching function");
+      95       10602 :   keys.addFlag("--nosquare",false,"use calculate instead of calculateSqr");
+      96       10602 :   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        5301 : }
+     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 000000000..ec7b28262 --- /dev/null +++ b/coverage/cltools/index-sort-f.html @@ -0,0 +1,253 @@ + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1697235672.0 %
Date:2024-10-17 16:45:00Functions:12815980.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
5.9%5.9%
+
5.9 %20 / 34122.2 %6 / 27
GenExample.cpp +
8.0%8.0%
+
8.0 %17 / 21266.7 %6 / 9
SwitchingPlotter.cpp +
27.9%27.9%
+
27.9 %19 / 6871.4 %5 / 7
Driver.cpp +
95.9%95.9%
+
95.9 %647 / 67575.0 %9 / 12
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
GenTemplate.cpp +
56.5%56.5%
+
56.5 %13 / 2385.7 %6 / 7
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
Info.cpp +
83.0%83.0%
+
83.0 %39 / 47100.0 %7 / 7
kT.cpp +
100.0%
+
100.0 %19 / 19100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %127 / 127100.0 %7 / 7
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
GenJson.cpp +
100.0%
+
100.0 %104 / 104100.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 000000000..c165be1c8 --- /dev/null +++ b/coverage/cltools/index-sort-l.html @@ -0,0 +1,253 @@ + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1697235672.0 %
Date:2024-10-17 16:45:00Functions:12815980.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
5.9%5.9%
+
5.9 %20 / 34122.2 %6 / 27
GenExample.cpp +
8.0%8.0%
+
8.0 %17 / 21266.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
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
Driver.cpp +
95.9%95.9%
+
95.9 %647 / 67575.0 %9 / 12
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 %104 / 104100.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 000000000..230cba96f --- /dev/null +++ b/coverage/cltools/index.html @@ -0,0 +1,253 @@ + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1697235672.0 %
Date:2024-10-17 16:45:00Functions:12815980.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
5.9%5.9%
+
5.9 %20 / 34122.2 %6 / 27
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
Driver.cpp +
95.9%95.9%
+
95.9 %647 / 67575.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 +
8.0%8.0%
+
8.0 %17 / 21266.7 %6 / 9
GenJson.cpp +
100.0%
+
100.0 %104 / 104100.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 000000000..e6b1f42d8 --- /dev/null +++ b/coverage/cltools/kT.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-10-17 16:45:00Functions: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_112ktRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev5301
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..c807c1fbd --- /dev/null +++ b/coverage/cltools/kT.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMe6createERKNS_13CLToolOptionsE10
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev5301
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE5301
_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 000000000..df8882f99 --- /dev/null +++ b/coverage/cltools/kT.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-10-17 16:45:00Functions: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 k_B T at a particular temperature
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following command will tell you the value of \f$k_BT\f$ when T is equal
+      41             : to 300 K in eV
+      42             : 
+      43             : \verbatim
+      44             : plumed kt --temp 300 --units eV
+      45             : \endverbatim
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : class kt:
+      51             :   public CLTool
+      52             : {
+      53             : public:
+      54             :   static void registerKeywords( Keywords& keys );
+      55             :   explicit kt(const CLToolOptions& co );
+      56             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      57           4 :   std::string description()const override {
+      58           4 :     return "print out the value of kT at a particular temperature";
+      59             :   }
+      60             : };
+      61             : 
+      62       15913 : PLUMED_REGISTER_CLTOOL(kt,"kt")
+      63             : 
+      64        5301 : void kt::registerKeywords( Keywords& keys ) {
+      65        5301 :   CLTool::registerKeywords( keys );
+      66       10602 :   keys.add("compulsory","--temp","print the manual for this particular action");
+      67       10602 :   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        5301 : }
+      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 000000000..4ed43934c --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-10-17 16:45:00Functions: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_115PesMDRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev5301
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..51acdb15c --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeC2Ev5301
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev5301
_ZN4PLMD7cltools5PesMD10read_inputERdS2_S2_RiRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEES3_RbSE_S3_3
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE5301
_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 000000000..b1b6cba00 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.gcov.html @@ -0,0 +1,388 @@ + + + + + + + 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-10-17 16:45:00Functions: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        5301 :   static void registerKeywords( Keywords& keys ) {
+     104       10602 :     keys.add("compulsory","nstep","The number of steps of dynamics you want to run");
+     105       10602 :     keys.add("compulsory","temperature","NVE","the temperature at which you wish to run the simulation in LJ units");
+     106       10602 :     keys.add("compulsory","friction","off","The friction (in LJ units) for the Langevin thermostat that is used to keep the temperature constant");
+     107       10602 :     keys.add("compulsory","tstep","0.005","the integration timestep in LJ units");
+     108       10602 :     keys.add("compulsory","dimension","the dimension of your energy landscape");
+     109       10602 :     keys.add("compulsory","plumed","plumed.dat","the name of the plumed input file containing the potential");
+     110       10602 :     keys.add("compulsory","ipos","0.0","the initial position of the system");
+     111       10602 :     keys.add("compulsory","idum","0","The random number seed");
+     112       10602 :     keys.addFlag("periodic",false,"are your input coordinates periodic");
+     113       10602 :     keys.add("optional","min","minimum value the coordinates can take for a periodic domain");
+     114       10602 :     keys.add("optional","max","maximum value the coordinates can take for a periodic domain");
+     115        5301 :   }
+     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           9 :     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       15910 : 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 000000000..0aeb565bd --- /dev/null +++ b/coverage/clusters/ClusterDiameter.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1717100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..18d94d293 --- /dev/null +++ b/coverage/clusters/ClusterDiameter.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1717100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..af1a15f86 --- /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:1717100.0 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("the largest of all the distances between the pairs of atom in the cluster");
+      76          12 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("CUSTOM");
+      77           8 :   keys.needsAction("FLATTEN"); keys.needsAction("HIGHEST");
+      78           4 : }
+      79             : 
+      80           2 : ClusterDiameter::ClusterDiameter(const ActionOptions& ao):
+      81             :   Action(ao),
+      82           2 :   ActionShortcut(ao)
+      83             : {
+      84             :   // Read in the argument
+      85           4 :   std::string arg_str, atdata; parse("ARG",arg_str); parse("ATOMS",atdata);
+      86             :   // Distance matrix
+      87           4 :   readInputLine( getShortcutLabel() + "_dmat: DISTANCE_MATRIX GROUP=" + atdata );
+      88             :   // Matrix of bonds in cluster
+      89           4 :   readInputLine( getShortcutLabel() + "_bmat: OUTER_PRODUCT FUNC=x*y ARG=" + arg_str + "," + arg_str );
+      90             :   // Product of matrices
+      91           4 :   readInputLine( getShortcutLabel() + "_dcls: CUSTOM ARG=" + getShortcutLabel() + "_dmat," + getShortcutLabel() + "_bmat FUNC=x*y PERIODIC=NO");
+      92             :   // Convert matrix to a vector to get highest
+      93           4 :   readInputLine( getShortcutLabel() + "_vdcls: FLATTEN ARG=" + getShortcutLabel() + "_dcls" );
+      94             :   // And take the highest value
+      95           4 :   readInputLine( getShortcutLabel() + ": HIGHEST ARG=" + getShortcutLabel() + "_vdcls");
+      96           2 : }
+      97             : 
+      98             : }
+      99             : }
+
+
+
+ + + + +
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 000000000..11fd42d4c --- /dev/null +++ b/coverage/clusters/ClusterDistribution.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:555894.8 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE6
_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 000000000..e6da41649 --- /dev/null +++ b/coverage/clusters/ClusterDistribution.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:555894.8 %
Date:2024-10-17 16:45:00Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters19ClusterDistribution16registerKeywordsERNS_8KeywordsE6
_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 000000000..39b3f4ca1 --- /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:555894.8 %
Date:2024-10-17 16:45:00Functions: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           6 : void ClusterDistribution::registerKeywords( Keywords& keys ) {
+      99           6 :   Action::registerKeywords( keys );
+     100           6 :   ActionWithArguments::registerKeywords( keys );
+     101           6 :   ActionWithValue::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+     102          12 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering"); keys.setDisplayName("CLUSTER_DISTRIBUTION");
+     103          12 :   keys.add("optional","WEIGHTS","use the vector of values calculated by this action as weights rather than giving each atom a unit weight");
+     104           6 :   keys.setValueDescription("a vector containing the sum of a atomic-cv that is calculated for each of the identified clusters");
+     105           6 : }
+     106             : 
+     107           2 : ClusterDistribution::ClusterDistribution(const ActionOptions&ao):
+     108             :   Action(ao),
+     109             :   ActionWithArguments(ao),
+     110           2 :   ActionWithValue(ao)
+     111             : {
+     112             :   // Read in the clustering object
+     113           4 :   std::vector<Value*> clusters; parseArgumentList("CLUSTERS",clusters);
+     114           2 :   if( clusters.size()!=1 ) error("should pass only one matrix to clustering base");
+     115           2 :   ClusteringBase* cc = dynamic_cast<ClusteringBase*>( clusters[0]->getPntrToAction() );
+     116           2 :   if( !cc ) error("input to CLUSTERS keyword should be a clustering action");
+     117           4 :   std::vector<Value*> weights; parseArgumentList("WEIGHTS",weights);
+     118           2 :   if( weights.size()==0 ) {
+     119           1 :     log.printf("  using unit weights in cluster distribution \n");
+     120           1 :   } else if( weights.size()==1 ) {
+     121           1 :     if( weights[0]->getRank()!=1 ) error("input weights has wrong shape");
+     122           1 :     if( weights[0]->getShape()[0]!=clusters[0]->getShape()[0] ) error("mismatch between number of weights and number of atoms");
+     123           1 :     log.printf("  using weights from action with label %s in cluster distribution \n", weights[0]->getName().c_str() );
+     124           1 :     clusters.push_back( weights[0] );
+     125             :   } else {
+     126           0 :     error("should have only one argument for weights \n");
+     127             :   }
+     128             :   // Request the arguments
+     129           2 :   requestArguments( clusters );
+     130           2 :   getPntrToArgument(0)->buildDataStore();
+     131           2 :   if( getNumberOfArguments()>1 ) getPntrToArgument(1)->buildDataStore();
+     132             :   // Now create the value
+     133           2 :   std::vector<unsigned> shape(1); shape[0]=clusters[0]->getShape()[0];
+     134           2 :   addValue( shape ); setNotPeriodic(); getPntrToValue()->buildDataStore();
+     135           2 : }
+     136             : 
+     137           0 : unsigned ClusterDistribution::getNumberOfDerivatives() {
+     138           0 :   return 0;
+     139             : }
+     140             : 
+     141           2 : void ClusterDistribution::calculate() {
+     142           2 :   plumed_assert( getPntrToArgument(0)->valueHasBeenSet() );
+     143           2 :   if( getNumberOfArguments()>1 ) plumed_assert( getPntrToArgument(1)->valueHasBeenSet() );
+     144           2 :   double csize = getPntrToArgument(0)->get(0);
+     145          12 :   for(unsigned i=1; i<getPntrToArgument(0)->getShape()[0]; ++i) {
+     146          10 :     if( getPntrToArgument(0)->get(i)>csize ) csize = getPntrToArgument(0)->get(i);
+     147             :   }
+     148           2 :   unsigned ntasks = static_cast<unsigned>( csize );
+     149           8 :   for(unsigned i=0; i<ntasks; ++i) {
+     150          42 :     for(unsigned j=0; j<getPntrToArgument(0)->getShape()[0]; ++j) {
+     151          36 :       if( fabs(getPntrToArgument(0)->get(j)-i)<epsilon ) {
+     152          10 :         if( getNumberOfArguments()==2 ) getPntrToValue()->add( i, getPntrToArgument(1)->get(j) );
+     153           5 :         else getPntrToValue()->add( i, 1.0 );
+     154             :       }
+     155             :     }
+     156             :   }
+     157           2 : }
+     158             : 
+     159             : class ClusterDistributionShortcut : public ActionShortcut {
+     160             : public:
+     161             :   static void registerKeywords( Keywords& keys );
+     162             :   ClusterDistributionShortcut(const ActionOptions&);
+     163             : };
+     164             : 
+     165             : PLUMED_REGISTER_ACTION(ClusterDistributionShortcut,"CLUSTER_DISTRIBUTION")
+     166             : 
+     167           6 : void ClusterDistributionShortcut::registerKeywords( Keywords& keys ) {
+     168           6 :   ActionShortcut::registerKeywords( keys );
+     169          12 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+     170          12 :   keys.add("optional","WEIGHTS","use the vector of values calculated by this action as weights rather than giving each atom a unit weight");
+     171           6 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+     172           6 :   keys.addActionNameSuffix("_CALC");
+     173           6 : }
+     174             : 
+     175           2 : ClusterDistributionShortcut::ClusterDistributionShortcut(const ActionOptions&ao):
+     176             :   Action(ao),
+     177           2 :   ActionShortcut(ao)
+     178             : {
+     179           2 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     180           4 :   readInputLine( getShortcutLabel() + ": CLUSTER_DISTRIBUTION_CALC " + convertInputLineToString() );
+     181           4 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(),  getShortcutLabel(),  "", keymap, this );
+     182           2 : }
+     183             : 
+     184             : }
+     185             : }
+
+
+
+ + + + +
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 000000000..7cf2dabaf --- /dev/null +++ b/coverage/clusters/ClusterNatoms.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1212100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..40ae770db --- /dev/null +++ b/coverage/clusters/ClusterNatoms.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1212100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..9e95f1061 --- /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:1212100.0 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("the number of atoms in the cluster");
+      50           8 :   keys.needsAction("CLUSTER_WEIGHTS"); keys.needsAction("SUM");
+      51           4 : }
+      52             : 
+      53           2 : ClusterNatoms::ClusterNatoms(const ActionOptions& ao):
+      54             :   Action(ao),
+      55           2 :   ActionShortcut(ao)
+      56             : {
+      57             :   // Create a cluster weights object
+      58           4 :   readInputLine( getShortcutLabel() + "_weights: CLUSTER_WEIGHTS " + convertInputLineToString() );
+      59             :   // Add all the weights together (weights are 1 or 0)
+      60           4 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_weights PERIODIC=NO");
+      61           2 : }
+      62             : 
+      63             : }
+      64             : }
+
+
+
+ + + + +
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 000000000..1eec09574 --- /dev/null +++ b/coverage/clusters/ClusterProperties.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..963b475df --- /dev/null +++ b/coverage/clusters/ClusterProperties.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..36ecb4215 --- /dev/null +++ b/coverage/clusters/ClusterProperties.cpp.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5be8661c9 --- /dev/null +++ b/coverage/clusters/ClusterWeights.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:3333100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusterWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters14ClusterWeights22getNumberOfDerivativesEv24
_ZN4PLMD8clusters14ClusterWeightsC1ERKNS_13ActionOptionsE29
_ZN4PLMD8clusters14ClusterWeights5applyEv51
_ZN4PLMD8clusters14ClusterWeights9calculateEv51
_ZN4PLMD8clusters14ClusterWeights16registerKeywordsERNS_8KeywordsE57
+
+
+ + + +
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 000000000..b7d993b47 --- /dev/null +++ b/coverage/clusters/ClusterWeights.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:3333100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusterWeights16registerKeywordsERNS_8KeywordsE57
_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 000000000..19a3bfc06 --- /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:3333100.0 %
Date:2024-10-17 16:45:00Functions: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          57 : void ClusterWeights::registerKeywords( Keywords& keys ) {
+      66          57 :   Action::registerKeywords( keys );
+      67          57 :   ActionWithArguments::registerKeywords( keys ); keys.remove("ARG");
+      68          57 :   ActionWithValue::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+      69         114 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      70         114 :   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         114 :   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          57 :   keys.setValueDescription("vector with elements that are one if the atom of interest is part of the required cluster and zero otherwise");
+      74          57 : }
+      75             : 
+      76          29 : ClusterWeights::ClusterWeights(const ActionOptions&ao):
+      77             :   Action(ao),
+      78             :   ActionWithArguments(ao),
+      79          29 :   ActionWithValue(ao)
+      80             : {
+      81          29 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+      82          29 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+      83             :   // Read in the clustering object
+      84          58 :   std::vector<Value*> clusters; parseArgumentList("CLUSTERS",clusters);
+      85          29 :   if( clusters.size()!=1 ) error("should pass only one matrix to clustering base");
+      86          29 :   ClusteringBase* cc = dynamic_cast<ClusteringBase*>( clusters[0]->getPntrToAction() );
+      87          29 :   if( !cc ) error("input to CLUSTERS keyword should be a clustering action");
+      88             :   // Request the arguments
+      89          29 :   requestArguments( clusters );
+      90             :   // Now create the value
+      91          29 :   std::vector<unsigned> shape(1); shape[0]=clusters[0]->getShape()[0];
+      92          29 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      93             :   // Find out which cluster we want
+      94          29 :   parse("CLUSTER",clustr);
+      95          29 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      96          29 :   if( clustr>clusters[0]->getShape()[0] ) error("cluster selected is invalid - too few atoms in system");
+      97          29 :   log.printf("  atoms in %dth largest cluster calculated by %s are equal to one \n",clustr, cc->getLabel().c_str() );
+      98          29 : }
+      99             : 
+     100          24 : unsigned ClusterWeights::getNumberOfDerivatives() {
+     101          24 :   return 0;
+     102             : }
+     103             : 
+     104          51 : void ClusterWeights::calculate() {
+     105          51 :   plumed_assert( getPntrToArgument(0)->valueHasBeenSet() );
+     106       36627 :   for(unsigned i=0; i<getPntrToArgument(0)->getShape()[0]; ++i) {
+     107       36576 :     if( fabs(getPntrToArgument(0)->get(i)-clustr)<epsilon ) getPntrToComponent(0)->set( i, 1.0 );
+     108             :   }
+     109          51 : }
+     110             : 
+     111             : }
+     112             : }
+
+
+
+ + + + +
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 000000000..959c1f3fa --- /dev/null +++ b/coverage/clusters/ClusterWithSurface.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4ccb56df2 --- /dev/null +++ b/coverage/clusters/ClusterWithSurface.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..ea428944e --- /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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("a vector that is one for those atoms that are within the cluster or that are within a cetain cutoff of one of the atoms in the cluster and zero otherwise");
+      53           8 :   keys.needsAction("CLUSTER_WEIGHTS"); keys.needsAction("CONTACT_MATRIX");
+      54           8 :   keys.needsAction("OUTER_PRODUCT"); keys.needsAction("CUSTOM");
+      55           4 :   keys.needsAction("DFSCLUSTERING");
+      56           4 : }
+      57             : 
+      58           2 : ClusterWithSurface::ClusterWithSurface(const ActionOptions& ao):
+      59             :   Action(ao),
+      60           2 :   ActionShortcut(ao)
+      61             : {
+      62             :   // Read atoms for contact matrix
+      63           4 :   std::string atdata; parse("ATOMS",atdata);
+      64             :   // Read rcut input
+      65           2 :   std::string rcut_surf_str; parse("RCUT_SURF",rcut_surf_str);
+      66             :   // Create a cluster weights object
+      67           4 :   readInputLine( getShortcutLabel() + "_wnosurf: CLUSTER_WEIGHTS " + convertInputLineToString() );
+      68             :   // Now create a contact matrix
+      69           4 :   readInputLine( getShortcutLabel() + "_cmat: CONTACT_MATRIX GROUP=" + atdata + " SWITCH={" + rcut_surf_str +"}" );
+      70             :   // Now create a custom matrix
+      71           4 :   readInputLine( getShortcutLabel() + "_cwmat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_wnosurf," + getShortcutLabel() + "_wnosurf FUNC=max");
+      72             :   // Product of matrices
+      73           4 :   readInputLine( getShortcutLabel() + "_pmat: CUSTOM ARG=" + getShortcutLabel() + "_cmat," + getShortcutLabel() + "_cwmat FUNC=x*y PERIODIC=NO");
+      74             :   // DFS clustering
+      75           4 :   readInputLine( getShortcutLabel() + "_clust: DFSCLUSTERING ARG=" + getShortcutLabel() + "_pmat");
+      76             :   // And final cluster weights
+      77           4 :   readInputLine( getShortcutLabel() + ": CLUSTER_WEIGHTS CLUSTERS=" + getShortcutLabel() + "_clust CLUSTER=1");
+      78           2 : }
+      79             : 
+      80             : }
+      81             : }
+
+
+
+ + + + +
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 000000000..8e68260ce --- /dev/null +++ b/coverage/clusters/ClusteringBase.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZN4PLMD8clusters14ClusteringBase16registerKeywordsERNS_8KeywordsE21
_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 000000000..268a1885d --- /dev/null +++ b/coverage/clusters/ClusteringBase.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusteringBase16registerKeywordsERNS_8KeywordsE21
_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 000000000..6d257c15f --- /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:3434100.0 %
Date:2024-10-17 16:45:00Functions: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          21 : void ClusteringBase::registerKeywords( Keywords& keys ) {
+      29          21 :   matrixtools::MatrixOperationBase::registerKeywords( keys ); keys.use("ARG");
+      30          21 :   keys.setValueDescription("vector with length that is equal to the number of rows in the input matrix.  Elements of this vector are equal to the cluster that each node is a part of");
+      31          21 : }
+      32             : 
+      33          17 : ClusteringBase::ClusteringBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   matrixtools::MatrixOperationBase(ao),
+      36          17 :   number_of_cluster(-1)
+      37             : {
+      38             :   // Do some checks on the input
+      39          17 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) error("input matrix should be square");
+      40             : 
+      41             :   // Now create a value - this holds the data on which cluster each guy is in
+      42          17 :   std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getShape()[0];
+      43             :   // Build the store here to make sure that next action has all data
+      44          17 :   addValue( shape ); setNotPeriodic(); getPntrToValue()->buildDataStore();
+      45             :   // Resize local variables
+      46          17 :   which_cluster.resize( getPntrToArgument(0)->getShape()[0] ); cluster_sizes.resize( getPntrToArgument(0)->getShape()[0] );
+      47          17 : }
+      48             : 
+      49          38 : void ClusteringBase::retrieveAdjacencyLists( std::vector<unsigned>& nneigh, Matrix<unsigned>& adj_list ) {
+      50             :   // Make sure we have the edges stored
+      51             :   std::vector<std::pair<unsigned,unsigned> > pairs; std::vector<double> vals;
+      52          38 :   unsigned nedge; getPntrToArgument(0)->retrieveEdgeList( nedge, pairs, vals );
+      53             :   // Currently everything has zero neighbors
+      54       20912 :   for(unsigned i=0; i<nneigh.size(); ++i) nneigh[i]=0;
+      55             :   // Resize the adjacency list if it is needed
+      56          38 :   if( adj_list.ncols()!=getPntrToArgument(0)->getNumberOfColumns() ) {
+      57          21 :     unsigned nrows = getPntrToArgument(0)->getShape()[0];
+      58             :     adj_list.resize( nrows, getPntrToArgument(0)->getNumberOfColumns() );
+      59             :   }
+      60             : 
+      61             :   // And set up the adjacency list
+      62       66502 :   for(unsigned i=0; i<nedge; ++i) {
+      63             :     // Store if atoms are connected
+      64       66464 :     unsigned j=pairs[i].first, k=pairs[i].second;
+      65       66464 :     if( j==k ) continue;
+      66       66464 :     adj_list(j,nneigh[j])=k; nneigh[j]++;
+      67       66464 :     adj_list(k,nneigh[k])=j; nneigh[k]++;
+      68             :   }
+      69          38 : }
+      70             : 
+      71          38 : void ClusteringBase::calculate() {
+      72             :   // All the clusters have zero size initially
+      73       20912 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) { cluster_sizes[i].first=0; cluster_sizes[i].second=i; }
+      74             :   // Do the clustering bit
+      75          38 :   performClustering();
+      76             :   // Order the clusters in the system by size (this returns ascending order )
+      77          38 :   std::sort( cluster_sizes.begin(), cluster_sizes.end() );
+      78             :   // Set the elements of the value to the cluster identies
+      79       20912 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) {
+      80       20874 :     double this_size = static_cast<double>(cluster_sizes.size()-i);
+      81    21921410 :     for(unsigned j=0; j<cluster_sizes.size(); ++j) {
+      82    21900536 :       if( which_cluster[j]==cluster_sizes[i].second ) getPntrToValue()->set( j, this_size );
+      83             :     }
+      84             :   }
+      85          38 : }
+      86             : 
+      87          38 : void ClusteringBase::apply() {
+      88          38 :   if( getPntrToComponent(0)->forcesWereAdded() ) error("forces on clustering actions cannot work as clustering is not differentiable");
+      89          38 : }
+      90             : 
+      91             : }
+      92             : }
+
+
+
+ + + + +
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 000000000..b7b536b7a --- /dev/null +++ b/coverage/clusters/ClusteringBase.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..963224a4e --- /dev/null +++ b/coverage/clusters/ClusteringBase.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..61b720570 --- /dev/null +++ b/coverage/clusters/ClusteringBase.h.gcov.html @@ -0,0 +1,142 @@ + + + + + + + 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-10-17 16:45:00Functions: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 "matrixtools/MatrixOperationBase.h"
+      26             : #include "tools/Matrix.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace clusters {
+      30             : 
+      31             : class ClusteringBase : public matrixtools::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 000000000..ae920eb48 --- /dev/null +++ b/coverage/clusters/DFSClustering.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13DFSClusteringC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters13DFSClusteringC1ERKNS_13ActionOptionsE17
_ZN4PLMD8clusters13DFSClustering16registerKeywordsERNS_8KeywordsE21
_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 000000000..aa97f6a0b --- /dev/null +++ b/coverage/clusters/DFSClustering.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13DFSClustering16registerKeywordsERNS_8KeywordsE21
_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 000000000..1d1666bd9 --- /dev/null +++ b/coverage/clusters/DFSClustering.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-10-17 16:45:00Functions: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          21 : void DFSClustering::registerKeywords( Keywords& keys ) {
+      93          21 :   ClusteringBase::registerKeywords( keys );
+      94          42 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+      95          21 : }
+      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 000000000..5c470bf7c --- /dev/null +++ b/coverage/clusters/OutputCluster.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..18dce99ae --- /dev/null +++ b/coverage/clusters/OutputCluster.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1c1e25ad7 --- /dev/null +++ b/coverage/clusters/OutputCluster.cpp.gcov.html @@ -0,0 +1,169 @@ + + + + + + + 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-10-17 16:45:00Functions: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           8 :   keys.remove("HAS_VALUES"); 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 000000000..3ec592602 --- /dev/null +++ b/coverage/clusters/index-sort-f.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - clusters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clustersHitTotalCoverage
Test:plumed test coverageLines:23223698.3 %
Date:2024-10-17 16:45:00Functions: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
ClusterWithSurface.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
ClusterProperties.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ClusterDiameter.cpp +
100.0%
+
100.0 %17 / 1766.7 %2 / 3
ClusterNatoms.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
OutputCluster.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
ClusterDistribution.cpp +
94.8%94.8%
+
94.8 %55 / 5866.7 %6 / 9
DFSClustering.cpp +
100.0%
+
100.0 %24 / 2480.0 %4 / 5
ClusterWeights.cpp +
100.0%
+
100.0 %33 / 3383.3 %5 / 6
ClusteringBase.cpp +
100.0%
+
100.0 %34 / 3483.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 000000000..16c6bbe6f --- /dev/null +++ b/coverage/clusters/index-sort-l.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - clusters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clustersHitTotalCoverage
Test:plumed test coverageLines:23223698.3 %
Date:2024-10-17 16:45:00Functions: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.8%94.8%
+
94.8 %55 / 5866.7 %6 / 9
ClusterNatoms.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
ClusterProperties.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ClusterDiameter.cpp +
100.0%
+
100.0 %17 / 1766.7 %2 / 3
OutputCluster.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
ClusterWithSurface.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
DFSClustering.cpp +
100.0%
+
100.0 %24 / 2480.0 %4 / 5
ClusterWeights.cpp +
100.0%
+
100.0 %33 / 3383.3 %5 / 6
ClusteringBase.cpp +
100.0%
+
100.0 %34 / 3483.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 000000000..cb74ce3c3 --- /dev/null +++ b/coverage/clusters/index.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - clusters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clustersHitTotalCoverage
Test:plumed test coverageLines:23223698.3 %
Date:2024-10-17 16:45:00Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClusterDiameter.cpp +
100.0%
+
100.0 %17 / 1766.7 %2 / 3
ClusterDistribution.cpp +
94.8%94.8%
+
94.8 %55 / 5866.7 %6 / 9
ClusterNatoms.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
ClusterProperties.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ClusterWeights.cpp +
100.0%
+
100.0 %33 / 3383.3 %5 / 6
ClusterWithSurface.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
ClusteringBase.cpp +
100.0%
+
100.0 %34 / 3483.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 000000000..debadc608 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5Angle21getModeAndSetupValuesEPNS_15ActionWithValueE3
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE23
_ZN4PLMD6colvar5Angle13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE73
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE89
_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 000000000..005fc3d50 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE89
_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 000000000..f1a572602 --- /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:515298.1 %
Date:2024-10-17 16:45:00Functions: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          89 : void Angle::registerKeywords( Keywords& keys ) {
+     125          89 :   Colvar::registerKeywords(keys); keys.setDisplayName("ANGLE");
+     126         178 :   keys.add("atoms","ATOMS","the list of atoms involved in this collective variable (either 3 or 4 atoms)");
+     127         178 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     128          89 :   keys.setValueDescription("the ANGLE involving these atoms");
+     129          89 : }
+     130             : 
+     131          73 : void Angle::parseAtomList( const int& num, std::vector<AtomNumber>& atoms, ActionAtomistic* aa ) {
+     132         146 :   aa->parseAtomList("ATOMS",num,atoms);
+     133          73 :   if(atoms.size()==3) {
+     134          62 :     aa->log.printf("  between atoms %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial());
+     135          62 :     atoms.resize(4);
+     136          62 :     atoms[3]=atoms[2];
+     137          62 :     atoms[2]=atoms[1];
+     138          11 :   } else if(atoms.size()==4) {
+     139           7 :     aa->log.printf("  between lines %d-%d and %d-%d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
+     140           4 :   } else if( num<0 || atoms.size()>0 ) aa->error("Number of specified atoms should be either 3 or 4");
+     141          72 : }
+     142             : 
+     143           3 : unsigned Angle::getModeAndSetupValues( ActionWithValue* av ) {
+     144           6 :   av->addValueWithDerivatives(); av->setNotPeriodic(); return 0;
+     145             : }
+     146             : 
+     147          23 : Angle::Angle(const ActionOptions&ao):
+     148             :   PLUMED_COLVAR_INIT(ao),
+     149          23 :   pbc(true),
+     150          23 :   value(1),
+     151          24 :   derivs(1),
+     152          46 :   virial(1)
+     153             : {
+     154          23 :   derivs[0].resize(4);
+     155          23 :   std::vector<AtomNumber> atoms; parseAtomList( -1, atoms, this );
+     156          22 :   bool nopbc=!pbc;
+     157          22 :   parseFlag("NOPBC",nopbc);
+     158          22 :   pbc=!nopbc;
+     159             : 
+     160          22 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     161           0 :   else    log.printf("  without periodic boundary conditions\n");
+     162             : 
+     163          45 :   addValueWithDerivatives(); setNotPeriodic();
+     164          22 :   requestAtoms(atoms);
+     165          22 :   checkRead();
+     166          25 : }
+     167             : 
+     168             : // calculator
+     169         319 : void Angle::calculate() {
+     170             : 
+     171         319 :   if(pbc) makeWhole();
+     172         319 :   calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     173         319 :   setValue( value[0] );
+     174        1595 :   for(unsigned i=0; i<derivs[0].size(); ++i) setAtomsDerivatives( i, derivs[0][i] );
+     175         319 :   setBoxDerivatives( virial[0] );
+     176         319 : }
+     177             : 
+     178         554 : void Angle::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     179             :                          const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     180             :                          std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     181         554 :   Vector dij,dik;
+     182         554 :   dij=delta(pos[2],pos[3]);
+     183         554 :   dik=delta(pos[1],pos[0]);
+     184         554 :   Vector ddij,ddik; PLMD::Angle a;
+     185         554 :   vals[0]=a.compute(dij,dik,ddij,ddik);
+     186         554 :   derivs[0][0]=ddik; derivs[0][1]=-ddik;
+     187         554 :   derivs[0][2]=-ddij; derivs[0][3]=ddij;
+     188         554 :   setBoxDerivativesNoPbc( pos, derivs, virial );
+     189         554 : }
+     190             : 
+     191             : }
+     192             : }
+     193             : 
+     194             : 
+     195             : 
+
+
+
+ + + + +
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 000000000..60acee66e --- /dev/null +++ b/coverage/colvar/Cell.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4CellC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE10
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD6colvar4Cell9calculateEv151
+
+
+ + + +
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 000000000..b6faa9c8d --- /dev/null +++ b/coverage/colvar/Cell.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD6colvar4Cell9calculateEv151
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE10
_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 000000000..216074dea --- /dev/null +++ b/coverage/colvar/Cell.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions: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          10 : Cell::Cell(const ActionOptions&ao):
+      61          10 :   PLUMED_COLVAR_INIT(ao)
+      62             : {
+      63             :   std::vector<AtomNumber> atoms;
+      64          10 :   checkRead();
+      65             : 
+      66          30 :   addComponentWithDerivatives("ax"); componentIsNotPeriodic("ax"); components[0][0]=getPntrToComponent("ax");
+      67          30 :   addComponentWithDerivatives("ay"); componentIsNotPeriodic("ay"); components[0][1]=getPntrToComponent("ay");
+      68          30 :   addComponentWithDerivatives("az"); componentIsNotPeriodic("az"); components[0][2]=getPntrToComponent("az");
+      69          30 :   addComponentWithDerivatives("bx"); componentIsNotPeriodic("bx"); components[1][0]=getPntrToComponent("bx");
+      70          30 :   addComponentWithDerivatives("by"); componentIsNotPeriodic("by"); components[1][1]=getPntrToComponent("by");
+      71          30 :   addComponentWithDerivatives("bz"); componentIsNotPeriodic("bz"); components[1][2]=getPntrToComponent("bz");
+      72          30 :   addComponentWithDerivatives("cx"); componentIsNotPeriodic("cx"); components[2][0]=getPntrToComponent("cx");
+      73          30 :   addComponentWithDerivatives("cy"); componentIsNotPeriodic("cy"); components[2][1]=getPntrToComponent("cy");
+      74          30 :   addComponentWithDerivatives("cz"); componentIsNotPeriodic("cz"); components[2][2]=getPntrToComponent("cz");
+      75          10 :   requestAtoms(atoms);
+      76          10 : }
+      77             : 
+      78          12 : void Cell::registerKeywords( Keywords& keys ) {
+      79          12 :   Action::registerKeywords( keys );
+      80          12 :   ActionWithValue::registerKeywords( keys );
+      81          12 :   ActionAtomistic::registerKeywords( keys );
+      82          24 :   keys.addOutputComponent("ax","default","the ax component of the cell matrix");
+      83          24 :   keys.addOutputComponent("ay","default","the ay component of the cell matrix");
+      84          24 :   keys.addOutputComponent("az","default","the az component of the cell matrix");
+      85          24 :   keys.addOutputComponent("bx","default","the bx component of the cell matrix");
+      86          24 :   keys.addOutputComponent("by","default","the by component of the cell matrix");
+      87          24 :   keys.addOutputComponent("bz","default","the bz component of the cell matrix");
+      88          24 :   keys.addOutputComponent("cx","default","the cx component of the cell matrix");
+      89          24 :   keys.addOutputComponent("cy","default","the cy component of the cell matrix");
+      90          24 :   keys.addOutputComponent("cz","default","the cz component of the cell matrix");
+      91          12 : }
+      92             : 
+      93             : 
+      94             : // calculator
+      95         151 : void Cell::calculate() {
+      96             : 
+      97        1963 :   for(int i=0; i<3; i++) for(int j=0; j<3; j++) components[i][j]->set(getBox()[i][j]);
+      98        1963 :   for(int l=0; l<3; l++) for(int m=0; m<3; m++) {
+      99        5436 :       Tensor der; for(int i=0; i<3; i++) der[i][m]=getBox()[l][i];
+     100        1359 :       setBoxDerivatives(components[l][m],-der);
+     101             :     }
+     102         151 : }
+     103             : 
+     104             : }
+     105             : }
+     106             : 
+     107             : 
+     108             : 
+
+
+
+ + + + +
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 000000000..d11c7467a --- /dev/null +++ b/coverage/colvar/ColvarShortcut.h.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + 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-10-17 16:45:00Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEE16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEE16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEEC1ERKNS_13ActionOptionsE61
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE66
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEEC1ERKNS_13ActionOptionsE135
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEE16registerKeywordsERNS_8KeywordsE195
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEEC1ERKNS_13ActionOptionsE685
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE696
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEEC1ERKNS_13ActionOptionsE728
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE906
+
+
+ + + +
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 000000000..462059b01 --- /dev/null +++ b/coverage/colvar/ColvarShortcut.h.func.html @@ -0,0 +1,144 @@ + + + + + + + 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-10-17 16:45:00Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEE16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE66
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEEC1ERKNS_13ActionOptionsE61
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE696
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEEC1ERKNS_13ActionOptionsE685
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE906
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEEC1ERKNS_13ActionOptionsE728
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEE16registerKeywordsERNS_8KeywordsE195
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEEC1ERKNS_13ActionOptionsE135
_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 000000000..fcfa330cf --- /dev/null +++ b/coverage/colvar/ColvarShortcut.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-10-17 16:45:00Functions: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        1993 : void ColvarShortcut<T>::registerKeywords(Keywords& keys ) {
+      39        1993 :   T::registerKeywords( keys ); keys.remove("NO_ACTION_LOG");
+      40        1993 :   unsigned nkeys = keys.size();
+      41       18637 :   for(unsigned i=0; i<nkeys; ++i) {
+      42       38996 :     if( keys.style( keys.get(i), "atoms" ) ) keys.reset_style( keys.get(i), "numbered" );
+      43             :   }
+      44        3986 :   keys.addActionNameSuffix("_SCALAR"); keys.addActionNameSuffix("_VECTOR");
+      45        1993 : }
+      46             : 
+      47             : template <class T>
+      48        1672 : ColvarShortcut<T>::ColvarShortcut(const ActionOptions&ao):
+      49             :   Action(ao),
+      50        1672 :   ActionShortcut(ao)
+      51             : {
+      52        1672 :   bool scalar=true; unsigned nkeys = keywords.size();
+      53        4989 :   if( getName()=="MASS" || getName()=="CHARGE" || getName()=="POSITION" ) {
+      54         306 :     std::string inpt; parse("ATOMS",inpt);
+      55         153 :     if( inpt.length()>0 ) {
+      56         114 :       readInputLine( getShortcutLabel() + ": " + getName() + "_VECTOR ATOMS=" + inpt + " " + convertInputLineToString() );
+      57             :       scalar=false;
+      58             :     }
+      59             :   }
+      60       15632 :   for(unsigned i=0; i<nkeys; ++i) {
+      61       28208 :     if( keywords.style( keywords.get(i), "atoms" ) ) {
+      62       10362 :       std::string inpt; parseNumbered( keywords.get(i), 1, inpt );
+      63        5181 :       if( inpt.length()>0 ) {
+      64         288 :         readInputLine( getShortcutLabel() + ": " + getName() + "_VECTOR " + keywords.get(i) + "1=" + inpt + " " + convertInputLineToString() );
+      65             :         scalar=false; break;
+      66             :       }
+      67             :     }
+      68             :   }
+      69        3017 :   if( scalar ) readInputLine( getShortcutLabel() + ": " + getName() + "_SCALAR " + convertInputLineToString() );
+      70        1678 : }
+      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 000000000..1b9a184e5 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..08233e424 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e360b8857 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.gcov.html @@ -0,0 +1,403 @@ + + + + + + + LCOV - plumed test coverage - colvar/ContactMap.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ContactMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12013191.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..f923ce25f --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..c0535191f --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d92e10b11 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the coordination");
+     117         221 : }
+     118             : 
+     119         219 : Coordination::Coordination(const ActionOptions&ao):
+     120             :   Action(ao),
+     121         219 :   CoordinationBase(ao)
+     122             : {
+     123             : 
+     124             :   std::string sw,errors;
+     125         438 :   parse("SWITCH",sw);
+     126         219 :   if(sw.length()>0) {
+     127         170 :     switchingFunction.set(sw,errors);
+     128         168 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     129             :   } else {
+     130          49 :     int nn=6;
+     131          49 :     int mm=0;
+     132          49 :     double d0=0.0;
+     133          49 :     double r0=0.0;
+     134          49 :     parse("R_0",r0);
+     135          49 :     if(r0<=0.0) error("R_0 should be explicitly specified and positive");
+     136          49 :     parse("D_0",d0);
+     137          49 :     parse("NN",nn);
+     138          47 :     parse("MM",mm);
+     139          47 :     switchingFunction.set(nn,mm,r0,d0);
+     140             :   }
+     141             : 
+     142         214 :   checkRead();
+     143             : 
+     144         433 :   log<<"  contacts are counted with cutoff "<<switchingFunction.description()<<"\n";
+     145         224 : }
+     146             : 
+     147    15264886 : double Coordination::pairing(double distance,double&dfunc,unsigned i,unsigned j)const {
+     148             :   (void) i; // avoid warnings
+     149             :   (void) j; // avoid warnings
+     150    15264886 :   return switchingFunction.calculateSqr(distance,dfunc);
+     151             : }
+     152             : 
+     153             : }
+     154             : 
+     155             : }
+
+
+
+ + + + +
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 000000000..f7a184c97 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - colvar/CoordinationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - CoordinationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:929398.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..85ae6f854 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - colvar/CoordinationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - CoordinationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:929398.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..fdae3a0d9 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.gcov.html @@ -0,0 +1,288 @@ + + + + + + + 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:929398.9 %
Date:2024-10-17 16:45:00Functions: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 :   const unsigned elementsPerRank = std::ceil(double(nn)/stride);
+     153        3787 :   const unsigned int start= rank*elementsPerRank;
+     154        3787 :   const unsigned int end = ((start + elementsPerRank)< nn)?(start + elementsPerRank): nn;
+     155             : 
+     156        3787 :   #pragma omp parallel num_threads(nt)
+     157             :   {
+     158             :     std::vector<Vector> omp_deriv(getPositions().size());
+     159             :     Tensor omp_virial;
+     160             : 
+     161             :     #pragma omp for reduction(+:ncoord) nowait
+     162             :     for(unsigned int i=start; i<end; ++i) {
+     163             : 
+     164             :       Vector distance;
+     165             :       const unsigned i0=nl->getClosePair(i).first;
+     166             :       const unsigned i1=nl->getClosePair(i).second;
+     167             : 
+     168             :       if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) continue;
+     169             : 
+     170             :       if(pbc) {
+     171             :         distance=pbcDistance(getPosition(i0),getPosition(i1));
+     172             :       } else {
+     173             :         distance=delta(getPosition(i0),getPosition(i1));
+     174             :       }
+     175             : 
+     176             :       double dfunc=0.;
+     177             :       ncoord += pairing(distance.modulo2(), dfunc,i0,i1);
+     178             : 
+     179             :       Vector dd(dfunc*distance);
+     180             :       Tensor vv(dd,distance);
+     181             :       if(nt>1) {
+     182             :         omp_deriv[i0]-=dd;
+     183             :         omp_deriv[i1]+=dd;
+     184             :         omp_virial-=vv;
+     185             :       } else {
+     186             :         deriv[i0]-=dd;
+     187             :         deriv[i1]+=dd;
+     188             :         virial-=vv;
+     189             :       }
+     190             : 
+     191             :     }
+     192             :     #pragma omp critical
+     193             :     if(nt>1) {
+     194             :       for(unsigned i=0; i<getPositions().size(); i++)
+     195             :         deriv[i]+=omp_deriv[i];
+     196             :       virial+=omp_virial;
+     197             :     }
+     198             :   }
+     199             : 
+     200        3787 :   if(!serial) {
+     201        3787 :     comm.Sum(ncoord);
+     202        3787 :     if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
+     203        3787 :     comm.Sum(virial);
+     204             :   }
+     205             : 
+     206      380565 :   for(unsigned i=0; i<deriv.size(); ++i) setAtomsDerivatives(i,deriv[i]);
+     207        3787 :   setValue           (ncoord);
+     208        3787 :   setBoxDerivatives  (virial);
+     209             : 
+     210        3787 : }
+     211             : }
+     212             : }
+
+
+
+ + + + +
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 000000000..0302ecfe7 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323494.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..6be710df8 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323494.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..4eedeb547 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323494.1 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the DHENERGY");
+      82          10 : }
+      83             : 
+      84             : /*
+      85             : Global constants in SI unit used in this calculation:
+      86             :       N_A = 6.0221412927 * 10^(23) mol^(-1) : Avogadro number
+      87             :       q = 1.60217656535 * 10^(-19) C : proton charge
+      88             :       e_0 = 8.854187817620 * 10^(-12) C^2/(N*m^2) : vacuum's dielectric constant
+      89             :       k_B = 1.380648813 * 10^(-23) N*m/K : Boltzmann constant
+      90             : In SI unit, Debye Huckel CV is defined as:
+      91             :       DHen = \sum_i\sum_j (q_i*q_j*q^2*N_A)/(4*pi*eps*e_0) * exp(-k*|f_ij|)/(|f_ij|)
+      92             :              + \sum_i\sum_j (q_i*q_j*q^2*N_A)/(4*pi*epp*e_0) * (1/|r_ij| - 1/|f_ij|)
+      93             :            = (q^2*N_A)/(4*pi*e_0) * \sum_i\sum_j q_i*q_j * (exp(-k*|f_ij|)/(eps*|f_ij|) + 1/epp*(1/|r_ij| - 1/|f_ij|))
+      94             : (in which |f_ij| = \sqrt(|r_ij|^2+\sigma_i*\sigma_j*exp(-|r_ij|^2/4*\sigma_i*\sigma_j)),
+      95             :  \sigma_i and \sigma_j are the effective Born radius.)
+      96             : For an efficient calculation, we group constants and variables into groups:
+      97             :       constant = (q^2*N_A)/(4*pi*e_0)
+      98             :       tmp = 1/eps*exp(-k*|f_ij|)/(|f_ij|) + 1/epp*(1/|r_ij| - 1/|f_ij|)
+      99             : 
+     100             : To speed up the loop calculation, constant can be modified as followed:
+     101             :       constant= (q^2*N_A)/(4*pi*e_0*10^(-9))*10^(-3) (kJ/mol)
+     102             :               = ((1.60217656535*10^(-19))^2*6.0221412927*10^(23)*10^(-3))/(4*3.14159265*8.854187817620*10^(-12)*10^(-9))
+     103             :               = 138.935458111 (kJ/mol)
+     104             : 
+     105             : */
+     106             : 
+     107           8 : DHEnergy::DHEnergy(const ActionOptions&ao):
+     108             :   Action(ao),
+     109             :   CoordinationBase(ao),
+     110           8 :   k(0.0),
+     111           8 :   constant(0.0)
+     112             : {
+     113             :   double I,T;
+     114           8 :   parse("I",I);
+     115           8 :   parse("TEMP",T);
+     116           8 :   parse("EPSILON",epsilon);
+     117           8 :   checkRead();
+     118           8 :   if( usingNaturalUnits() ) error("DHENERGY cannot be used for calculations performed with natural units");
+     119           8 :   constant=138.935458111/getUnits().getEnergy()/getUnits().getLength()*getUnits().getCharge()*getUnits().getCharge();
+     120           8 :   k=std::sqrt(I/(epsilon*T))*502.903741125*getUnits().getLength();
+     121           8 :   checkRead();
+     122           8 :   log<<"  with solvent dielectric constant "<<epsilon<<"\n";
+     123           8 :   log<<"  at temperature "<<T<<" K\n";
+     124           8 :   log<<"  at ionic strength "<<I<< "M\n";
+     125           8 :   log<<"  these parameters correspond to a screening length of "<<(1.0/k)<<"\n";
+     126          16 :   log<<"  Bibliography "<<plumed.cite("Do, Carloni, Varani and Bussi, J. Chem. Theory Comput. 9, 1720 (2013)")<<" \n";
+     127           8 : }
+     128             : 
+     129         840 : double DHEnergy::pairing(double distance2,double&dfunc,unsigned i,unsigned j)const {
+     130         840 :   double distance=std::sqrt(distance2);
+     131         840 :   if(getAbsoluteIndex(i)==getAbsoluteIndex(j)) {
+     132           0 :     dfunc=0.0;
+     133           0 :     return 0.0;
+     134             :   }
+     135         840 :   double invdistance=1.0/distance;
+     136         840 :   double tmp=std::exp(-k*distance)*invdistance*constant*getCharge(i)*getCharge(j)/epsilon;
+     137         840 :   double dtmp=-(k+invdistance)*tmp;
+     138         840 :   dfunc=dtmp*invdistance;
+     139         840 :   return tmp;
+     140             : }
+     141             : 
+     142             : }
+     143             : 
+     144             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.func-sort-c.html b/coverage/colvar/DRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000..02d3b88a4 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:9810197.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE13
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE16
+
+
+ + + +
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 000000000..b08069c8a --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:9810197.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE16
_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 000000000..9db7c4ec0 --- /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:9810197.0 %
Date:2024-10-17 16:45:00Functions: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          16 : void DRMSD::registerKeywords( Keywords& keys ) {
+     116          16 :   ActionShortcut::registerKeywords( keys );
+     117          32 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     118          32 :   keys.add("optional","LOWER_CUTOFF","only pairs of atoms further than LOWER_CUTOFF are considered in the calculation.");
+     119          32 :   keys.add("optional","UPPER_CUTOFF","only pairs of atoms closer than UPPER_CUTOFF are considered in the calculation.");
+     120          32 :   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          32 :   keys.addFlag("SQUARED",false,"This should be setted if you want MSD instead of RMSD ");
+     125          32 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     126             :   // This is just ignored in reality which is probably bad
+     127          32 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"calculate the derivatives for these quantities numerically");
+     128          16 :   keys.setValueDescription("the DRMSD distance between the instantaneous structure and the reference structure");
+     129          80 :   keys.needsAction("SUM"); keys.needsAction("DISTANCE"); keys.needsAction("CONSTANT"); keys.needsAction("EUCLIDEAN_DISTANCE"); keys.needsAction("CUSTOM");
+     130          16 : }
+     131             : 
+     132          13 : DRMSD::DRMSD( const ActionOptions& ao ):
+     133             :   Action(ao),
+     134          13 :   ActionShortcut(ao)
+     135             : {
+     136             :   // Read in the reference configuration
+     137          13 :   std::string reference; parse("REFERENCE",reference);
+     138             :   // First bit of input for the instantaneous distances
+     139          26 :   bool numder; parseFlag("NUMERICAL_DERIVATIVES",numder); double fake_unit=0.1;
+     140          13 :   FILE* fp2=fopen(reference.c_str(),"r"); bool do_read=true; unsigned nframes=0;
+     141          65 :   while( do_read ) {
+     142          54 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp2,false,fake_unit);
+     143          54 :     if( !do_read && nframes>0 ) break ;
+     144          53 :     nframes++;
+     145          54 :   }
+     146          12 :   fclose(fp2);
+     147             : 
+     148             :   // Get cutoff information
+     149          25 :   double lcut=0; parse("LOWER_CUTOFF",lcut); std::string drmsd_type; parse("TYPE",drmsd_type);
+     150          12 :   double ucut=std::numeric_limits<double>::max(); parse("UPPER_CUTOFF",ucut);
+     151          24 :   bool nopbc; parseFlag("NOPBC",nopbc); std::string pbc_str; if(nopbc) pbc_str="NOPBC";
+     152             :   // Open the pdb file
+     153          12 :   FILE* fp=fopen(reference.c_str(),"r"); do_read=true;
+     154          12 :   if(!fp) error("could not open reference file " + reference ); unsigned n=0; std::string allpairs="";
+     155             :   std::vector<std::pair<unsigned,unsigned> > upairs; std::vector<std::string> refvals;
+     156          65 :   while ( do_read ) {
+     157          54 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp,false,fake_unit);
+     158          54 :     if( !do_read && n>0 ) break ;
+     159          53 :     std::vector<Vector> pos( mypdb.getPositions() ); unsigned nn=1;
+     160          53 :     if( pos.size()==0 ) error("read no atoms from file named " + reference );
+     161             :     // This is what we do for the first frame
+     162          53 :     if( n==0 ) {
+     163          12 :       std::vector<AtomNumber> atoms( mypdb.getAtomNumbers() );
+     164          12 :       if( drmsd_type=="DRMSD" ) {
+     165         102 :         for(unsigned i=0; i<atoms.size()-1; ++i) {
+     166          92 :           std::string istr; Tools::convert( atoms[i].serial(), istr );
+     167         671 :           for(unsigned j=i+1; j<atoms.size(); ++j) {
+     168         579 :             std::string jstr; Tools::convert( atoms[j].serial(), jstr );
+     169         579 :             double distance = delta( pos[i], pos[j] ).modulo();
+     170         579 :             if( distance < ucut && distance > lcut ) {
+     171         386 :               std::string num; Tools::convert( nn, num ); nn++;
+     172             :               // Add this pair to list of pairs
+     173         386 :               upairs.push_back( std::pair<unsigned,unsigned>(i,j) );
+     174             :               // Add this distance to list of reference values
+     175         386 :               std::string dstr; Tools::convert( distance, dstr ); refvals.push_back( dstr );
+     176             :               // Calculate this distance
+     177         694 :               if( nframes==1 ) allpairs += " ATOMS" + num + "=" + istr + "," + jstr;
+     178         156 :               else readInputLine( getShortcutLabel() + "_d" + num + ": DISTANCE ATOMS=" + istr + "," + jstr + " " + pbc_str );
+     179             :             }
+     180             :           }
+     181             :         }
+     182             :       } else {
+     183           2 :         unsigned nblocks = mypdb.getNumberOfAtomBlocks(); std::vector<unsigned> blocks( 1 + nblocks );
+     184           2 :         if( nblocks==1 ) { blocks[0]=0; blocks[1]=atoms.size(); }
+     185           6 :         else { blocks[0]=0; for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=mypdb.getAtomBlockEnds()[i]; }
+     186           2 :         if( drmsd_type=="INTRA-DRMSD" ) {
+     187           3 :           for(unsigned i=0; i<nblocks; ++i) {
+     188           7 :             for(unsigned iatom=blocks[i]+1; iatom<blocks[i+1]; ++iatom) {
+     189           5 :               std::string istr; Tools::convert( atoms[iatom].serial(), istr );
+     190          14 :               for(unsigned jatom=blocks[i]; jatom<iatom; ++jatom) {
+     191           9 :                 std::string jstr; Tools::convert( atoms[jatom].serial(), jstr );
+     192           9 :                 double distance = delta( pos[iatom], pos[jatom] ).modulo();
+     193           9 :                 if(distance < ucut && distance > lcut ) {
+     194           9 :                   std::string num; Tools::convert( nn, num ); nn++;
+     195             :                   // Add this pair to list of pairs
+     196           9 :                   upairs.push_back( std::pair<unsigned,unsigned>(iatom,jatom) );
+     197             :                   // Add this distance to list of reference values
+     198           9 :                   std::string dstr; Tools::convert( distance, dstr ); refvals.push_back( dstr );
+     199             :                   // Calculate this distance
+     200          18 :                   if( nframes==1 ) allpairs += " ATOMS" + num + "=" + istr + "," + jstr;
+     201           0 :                   else readInputLine( getShortcutLabel() + "_d" + num + ": DISTANCE ATOMS=" + istr + "," + jstr + " " + pbc_str );
+     202             :                 }
+     203             :               }
+     204             :             }
+     205             :           }
+     206           1 :         } else if( drmsd_type=="INTER-DRMSD" ) {
+     207           2 :           for(unsigned i=1; i<nblocks; ++i) {
+     208           2 :             for(unsigned j=0; j<i; ++j) {
+     209           4 :               for(unsigned iatom=blocks[i]; iatom<blocks[i+1]; ++iatom) {
+     210           3 :                 std::string istr; Tools::convert( atoms[iatom].serial(), istr );
+     211          15 :                 for(unsigned jatom=blocks[j]; jatom<blocks[j+1]; ++jatom) {
+     212          12 :                   std::string jstr; Tools::convert( atoms[jatom].serial(), jstr );
+     213          12 :                   double distance = delta( pos[iatom], pos[jatom] ).modulo();
+     214          12 :                   if(distance < ucut && distance > lcut ) {
+     215          12 :                     std::string num; Tools::convert( nn, num ); nn++;
+     216             :                     // Add this pair to list of pairs
+     217          12 :                     upairs.push_back( std::pair<unsigned,unsigned>(iatom,jatom) );
+     218             :                     // Add this distance to list of reference values
+     219          12 :                     std::string dstr; Tools::convert( distance, dstr ); refvals.push_back( dstr );
+     220             :                     // Calculate this distance
+     221          24 :                     if( nframes==1 ) allpairs += " ATOMS" + num + "=" + istr + "," + jstr;
+     222           0 :                     else readInputLine( getShortcutLabel() + "_d" + num + ": DISTANCE ATOMS=" + istr + "," + jstr + " " + pbc_str );
+     223             :                   }
+     224             :                 }
+     225             :               }
+     226             :             }
+     227             :           }
+     228           0 :         } else plumed_merror( drmsd_type + " is not valid input to TYPE keyword");
+     229             :       }
+     230             :       // This is for every subsequent frame
+     231             :     } else {
+     232        3239 :       for(unsigned i=0; i<refvals.size(); ++i) {
+     233        3198 :         std::string dstr; Tools::convert( delta( pos[upairs[i].first], pos[upairs[i].second] ).modulo(), dstr );
+     234        6396 :         refvals[i] += "," + dstr;
+     235             :       }
+     236             :     }
+     237          53 :     n++;
+     238          54 :   }
+     239             :   // Now create values that hold all the reference distances
+     240          12 :   fclose(fp);
+     241             : 
+     242          12 :   if( nframes==1 ) {
+     243          22 :     readInputLine( getShortcutLabel() + "_d: DISTANCE" + allpairs + " " + pbc_str );
+     244         340 :     std::string refstr = refvals[0]; for(unsigned i=1; i<refvals.size(); ++i) refstr += "," + refvals[i];
+     245          22 :     readInputLine( getShortcutLabel() + "_ref: CONSTANT VALUES="  + refstr );
+     246          22 :     readInputLine( getShortcutLabel() + "_diffs: CUSTOM ARG=" + getShortcutLabel() + "_d," + getShortcutLabel() + "_ref FUNC=(x-y)*(x-y) PERIODIC=NO");
+     247          22 :     readInputLine( getShortcutLabel() + "_u: SUM ARG=" + getShortcutLabel() + "_diffs PERIODIC=NO");
+     248             :   } else {
+     249             :     std::string arg_str1, arg_str2;
+     250          79 :     for(unsigned i=0; i<refvals.size(); ++i ) {
+     251          78 :       std::string inum; Tools::convert( i+1, inum );
+     252         156 :       readInputLine( getShortcutLabel() + "_ref" + inum + ": CONSTANT VALUES=" + refvals[i] );
+     253          80 :       if( i==0 ) { arg_str1 = getShortcutLabel() + "_d" + inum; arg_str2 = getShortcutLabel() + "_ref" + inum; }
+     254         231 :       else { arg_str1 += "," + getShortcutLabel() + "_d" + inum; arg_str2 += "," + getShortcutLabel() + "_ref" + inum; }
+     255             :     }
+     256             :     // And calculate the euclidean distances between the true distances and the references
+     257           2 :     readInputLine( getShortcutLabel() + "_u: EUCLIDEAN_DISTANCE SQUARED ARG1=" + arg_str1 + " ARG2=" + arg_str2 );
+     258             :   }
+     259             :   // And final value
+     260          12 :   std::string nvals; Tools::convert( refvals.size(), nvals ); bool squared; parseFlag("SQUARED",squared);
+     261          15 :   if( squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_u FUNC=x/" + nvals + " PERIODIC=NO");
+     262             :   else {
+     263          18 :     readInputLine( getShortcutLabel() + "_2: CUSTOM ARG=" + getShortcutLabel() + "_u FUNC=(x/" + nvals + ") PERIODIC=NO");
+     264          18 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+     265             :   }
+     266          26 : }
+     267             : 
+     268             : }
+     269             : }
+     270             : 
+     271             : 
+
+
+
+ + + + +
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 000000000..900c89b67 --- /dev/null +++ b/coverage/colvar/DihedralCorrelation.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:446567.7 %
Date:2024-10-17 16:45:00Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar19DihedralCorrelation9calculateEv0
_ZN4PLMD6colvar19DihedralCorrelationC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar19DihedralCorrelation21getModeAndSetupValuesEPNS_15ActionWithValueE1
_ZN4PLMD6colvar19DihedralCorrelation13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE3
_ZN4PLMD6colvar19DihedralCorrelation11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE10
_ZN4PLMD6colvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
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 000000000..986e98368 --- /dev/null +++ b/coverage/colvar/DihedralCorrelation.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:446567.7 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE10
_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 000000000..d5083ee7e --- /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:446567.7 %
Date:2024-10-17 16:45:00Functions: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          10 : void DihedralCorrelation::registerKeywords( Keywords& keys ) {
+      88          10 :   Colvar::registerKeywords( keys ); keys.setDisplayName("DIHEDRAL_CORRELATION");
+      89          20 :   keys.add("atoms","ATOMS","the set of 8 atoms that are being used to calculate this quantity");
+      90          20 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      91          10 :   keys.setValueDescription("the DIHEDRAL_CORRELATION for these atoms");
+      92          10 : }
+      93             : 
+      94           0 : DihedralCorrelation::DihedralCorrelation(const ActionOptions&ao):
+      95             :   PLUMED_COLVAR_INIT(ao),
+      96           0 :   pbc(true),
+      97           0 :   value(1),
+      98           0 :   derivs(1),
+      99           0 :   virial(1)
+     100             : {
+     101           0 :   derivs[0].resize(8); std::vector<AtomNumber> atoms;
+     102           0 :   parseAtomList(-1,atoms,this);
+     103           0 :   if( atoms.size()!=8 ) error("Number of specified atoms should be 8");
+     104             : 
+     105           0 :   bool nopbc=!pbc;
+     106           0 :   parseFlag("NOPBC",nopbc);
+     107           0 :   pbc=!nopbc;
+     108             : 
+     109           0 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     110           0 :   else    log.printf("  without periodic boundary conditions\n");
+     111           0 : }
+     112             : 
+     113           3 : void DihedralCorrelation::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     114           3 :   aa->parseAtomList("ATOMS",num,t);
+     115           3 :   if( num<0 && t.size()!=8 ) aa->error("Number of specified atoms should be 8");
+     116           3 :   if( t.size()==8 ) {
+     117           2 :     aa->log.printf("  correlation between dihedral angle for atoms %d %d %d %d and atoms %d %d %d %d\n",
+     118             :                    t[0].serial(),t[1].serial(),t[2].serial(),t[3].serial(),t[4].serial(),t[5].serial(),t[6].serial(),t[7].serial());
+     119             :   }
+     120           3 : }
+     121             : 
+     122           1 : unsigned DihedralCorrelation::getModeAndSetupValues( ActionWithValue* av ) {
+     123           2 :   av->addValueWithDerivatives(); av->setNotPeriodic(); return 0;
+     124             : }
+     125             : 
+     126           0 : void DihedralCorrelation::calculate() {
+     127             : 
+     128           0 :   if(pbc) makeWhole();
+     129           0 :   calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     130           0 :   setValue( value[0] );
+     131           0 :   for(unsigned i=0; i<derivs[0].size(); ++i) setAtomsDerivatives( i, derivs[0][i] );
+     132           0 :   setBoxDerivatives( virial[0] );
+     133           0 : }
+     134             : 
+     135          10 : void DihedralCorrelation::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     136             :                                        const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     137             :                                        std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     138          10 :   const Vector d10=delta(pos[1],pos[0]);
+     139          10 :   const Vector d11=delta(pos[2],pos[1]);
+     140          10 :   const Vector d12=delta(pos[3],pos[2]);
+     141             : 
+     142          10 :   Vector dd10,dd11,dd12;
+     143             :   PLMD::Torsion t1;
+     144          10 :   const double phi1  = t1.compute(d10,d11,d12,dd10,dd11,dd12);
+     145             : 
+     146          10 :   const Vector d20=delta(pos[5],pos[4]);
+     147          10 :   const Vector d21=delta(pos[6],pos[5]);
+     148          10 :   const Vector d22=delta(pos[7],pos[6]);
+     149             : 
+     150          10 :   Vector dd20,dd21,dd22;
+     151             :   PLMD::Torsion t2;
+     152          10 :   const double phi2 = t2.compute( d20, d21, d22, dd20, dd21, dd22 );
+     153             : 
+     154             :   // Calculate value
+     155          10 :   const double diff = phi2 - phi1;
+     156          10 :   vals[0] = 0.5*(1.+std::cos(diff));
+     157             :   // Derivatives wrt phi1
+     158          10 :   const double dval = 0.5*std::sin(diff);
+     159          10 :   dd10 *= dval;
+     160          10 :   dd11 *= dval;
+     161          10 :   dd12 *= dval;
+     162             :   // And add
+     163          10 :   derivs[0][0]=dd10;
+     164          10 :   derivs[0][1]=dd11-dd10;
+     165          10 :   derivs[0][2]=dd12-dd11;
+     166          10 :   derivs[0][3]=-dd12;
+     167             :   // Derivative wrt phi2
+     168          10 :   dd20 *= -dval;
+     169          10 :   dd21 *= -dval;
+     170          10 :   dd22 *= -dval;
+     171             :   // And add
+     172          10 :   derivs[0][4]=dd20;
+     173          10 :   derivs[0][5]=dd21-dd20;
+     174          10 :   derivs[0][6]=dd22-dd21;
+     175          10 :   derivs[0][7]=-dd22;
+     176          10 :   virial[0] = -(extProduct(d10,dd10)+extProduct(d11,dd11)+extProduct(d12,dd12)) - (extProduct(d20,dd20)+extProduct(d21,dd21)+extProduct(d22,dd22));
+     177          10 : }
+     178             : 
+     179             : }
+     180             : }
+
+
+
+ + + + +
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 000000000..8af8e031c --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - colvar/Dimer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dimer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:839092.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..49a102786 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - colvar/Dimer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dimer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:839092.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..59c379454 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.gcov.html @@ -0,0 +1,394 @@ + + + + + + + LCOV - plumed test coverage - colvar/Dimer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dimer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:839092.2 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("the dimer interaction energy");
+     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 000000000..3756d5945 --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Dipole.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dipole.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:848598.8 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE58
_ZN4PLMD6colvar6Dipole21getModeAndSetupValuesEPNS_15ActionWithValueE61
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE192
_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 000000000..a5f1dbe30 --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Dipole.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dipole.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:848598.8 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE192
_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 000000000..46552e0c0 --- /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:848598.8 %
Date:2024-10-17 16:45:00Functions: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         192 : void Dipole::registerKeywords(Keywords& keys) {
+     109         192 :   Colvar::registerKeywords(keys); keys.setDisplayName("DIPOLE");
+     110         384 :   keys.add("atoms","GROUP","the group of atoms we are calculating the dipole moment for");
+     111         384 :   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         384 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the dipole");
+     113         384 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the dipole");
+     114         384 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the dipole");
+     115         384 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     116         192 :   keys.setValueDescription("the DIPOLE for these atoms");
+     117         192 : }
+     118             : 
+     119          58 : Dipole::Dipole(const ActionOptions&ao):
+     120             :   PLUMED_COLVAR_INIT(ao),
+     121          58 :   components(false),
+     122          58 :   value(1),
+     123           0 :   derivs(1),
+     124          58 :   virial(1)
+     125             : {
+     126          58 :   parseAtomList(-1,ga_lista,this); charges.resize(ga_lista.size());
+     127          58 :   components=(getModeAndSetupValues(this)==1);
+     128          58 :   if( components ) {
+     129           4 :     value.resize(3); derivs.resize(3); virial.resize(3);
+     130           4 :     valuex=getPntrToComponent("x");
+     131           4 :     valuey=getPntrToComponent("y");
+     132           4 :     valuez=getPntrToComponent("z");
+     133             :   }
+     134         124 :   for(unsigned i=0; i<derivs.size(); ++i) derivs[i].resize( ga_lista.size() );
+     135          58 :   parseFlag("NOPBC",nopbc);
+     136          58 :   checkRead();
+     137             : 
+     138          58 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     139          20 :   else      log.printf("  using periodic boundary conditions\n");
+     140             : 
+     141          58 :   requestAtoms(ga_lista);
+     142          58 : }
+     143             : 
+     144         576 : void Dipole::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     145        1152 :   aa->parseAtomList("GROUP",num,t);
+     146         576 :   if( t.size()>0 ) {
+     147         573 :     aa->log.printf("  of %u atoms\n",static_cast<unsigned>(t.size()));
+     148        2479 :     for(unsigned int i=0; i<t.size(); ++i) {
+     149        1906 :       aa->log.printf("  %d", t[i].serial());
+     150             :     }
+     151         573 :     aa->log.printf("  \n");
+     152             :   }
+     153         576 : }
+     154             : 
+     155          61 : unsigned Dipole::getModeAndSetupValues( ActionWithValue* av ) {
+     156          61 :   bool c; av->parseFlag("COMPONENTS",c);
+     157          61 :   if( c ) {
+     158          12 :     av->addComponentWithDerivatives("x"); av->componentIsNotPeriodic("x");
+     159          12 :     av->addComponentWithDerivatives("y"); av->componentIsNotPeriodic("y");
+     160          12 :     av->addComponentWithDerivatives("z"); av->componentIsNotPeriodic("z");
+     161           6 :     return 1;
+     162             :   }
+     163         110 :   av->addValueWithDerivatives(); av->setNotPeriodic(); return 0;
+     164             : }
+     165             : 
+     166             : // calculator
+     167         943 : void Dipole::calculate()
+     168             : {
+     169         943 :   if(!nopbc) makeWhole();
+     170             :   unsigned N=getNumberOfAtoms();
+     171        7398 :   for(unsigned i=0; i<N; ++i) charges[i]=getCharge(i);
+     172             : 
+     173         943 :   if(!components) {
+     174         788 :     calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     175        6313 :     for(unsigned i=0; i<N; i++) setAtomsDerivatives(i,derivs[0][i]);
+     176         788 :     setBoxDerivatives(virial[0]);
+     177         788 :     setValue(value[0]);
+     178             :   } else {
+     179         155 :     calculateCV( 1, masses, charges, getPositions(), value, derivs, virial, this );
+     180        1085 :     for(unsigned i=0; i<N; i++) {
+     181         930 :       setAtomsDerivatives(valuex,i,derivs[0][i]);
+     182         930 :       setAtomsDerivatives(valuey,i,derivs[1][i]);
+     183         930 :       setAtomsDerivatives(valuez,i,derivs[2][i]);
+     184             :     }
+     185         155 :     setBoxDerivatives(valuex,virial[0]);
+     186         155 :     setBoxDerivatives(valuey,virial[1]);
+     187         155 :     setBoxDerivatives(valuez,virial[2]);
+     188         155 :     valuex->set(value[0]);
+     189         155 :     valuey->set(value[1]);
+     190         155 :     valuez->set(value[2]);
+     191             :   }
+     192         943 : }
+     193             : 
+     194        4029 : void Dipole::calculateCV( const unsigned& mode, const std::vector<double>& masses, std::vector<double>& charges,
+     195             :                           const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     196             :                           std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     197        4029 :   unsigned N=pos.size(); double ctot=0.;
+     198       19802 :   for(unsigned i=0; i<N; ++i) ctot += charges[i];
+     199        4029 :   ctot/=(double)N;
+     200             : 
+     201        4029 :   Vector dipje;
+     202       19802 :   for(unsigned i=0; i<N; ++i) {
+     203       15773 :     charges[i]-=ctot; dipje += charges[i]*pos[i];
+     204             :   }
+     205             : 
+     206        4029 :   if( mode==1 ) {
+     207       13419 :     for(unsigned i=0; i<N; i++) {
+     208       10188 :       derivs[0][i]=charges[i]*Vector(1.0,0.0,0.0);
+     209       10188 :       derivs[1][i]=charges[i]*Vector(0.0,1.0,0.0);
+     210       10188 :       derivs[2][i]=charges[i]*Vector(0.0,0.0,1.0);
+     211             :     }
+     212       12924 :     for(unsigned i=0; i<3; ++i ) vals[i] = dipje[i];
+     213             :   } else {
+     214         798 :     vals[0] = dipje.modulo();
+     215         798 :     double idip = 1./vals[0];
+     216        6383 :     for(unsigned i=0; i<N; i++) {
+     217        5585 :       double dfunc=charges[i]*idip;
+     218        5585 :       derivs[0][i] = dfunc*dipje;
+     219             :     }
+     220             :   }
+     221        4029 :   setBoxDerivativesNoPbc( pos, derivs, virial );
+     222        4029 : }
+     223             : 
+     224             : }
+     225             : }
+
+
+
+ + + + +
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 000000000..62b49f30f --- /dev/null +++ b/coverage/colvar/Distance.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Distance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Distance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:120120100.0 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ColvarFake9calculateEv0
_ZN4PLMD6colvar10ColvarFakeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar10ColvarFake29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_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 000000000..a1a6271a5 --- /dev/null +++ b/coverage/colvar/Fake.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:303878.9 %
Date:2024-10-17 16:45:00Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ColvarFake16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD6colvar10ColvarFake9calculateEv0
_ZN4PLMD6colvar10ColvarFakeC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar10ColvarFakeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar10ColvarFake29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
+
+
+ + + +
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 000000000..87ddbc02d --- /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:303878.9 %
Date:2024-10-17 16:45:00Functions: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 "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           0 :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override { plumed_error(); }
+      47             : // active methods:
+      48             :   void calculate() override;
+      49             : };
+      50             : 
+      51             : PLUMED_REGISTER_ACTION(ColvarFake,"FAKE")
+      52             : 
+      53          19 : void ColvarFake::registerKeywords( Keywords& keys ) {
+      54          19 :   Colvar::registerKeywords( keys );
+      55          38 :   keys.add("atoms","ATOMS","the fake atom index, a number is enough");
+      56          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 ");
+      57          19 :   keys.use("PERIODIC");
+      58          38 :   keys.add("optional","COMPONENTS","additional components that this variable is supposed to have. Periodicity is ruled by PERIODIC keyword ");
+      59          19 :   useCustomisableComponents(keys);
+      60          19 : }
+      61             : 
+      62          17 : ColvarFake::ColvarFake(const ActionOptions&ao):
+      63          17 :   PLUMED_COLVAR_INIT(ao)
+      64             : {
+      65             :   std::vector<AtomNumber> atoms;
+      66          34 :   parseAtomList("ATOMS",atoms);
+      67             : 
+      68             :   std::vector<std::string> comps;
+      69             :   // multiple components for this variable
+      70          34 :   parseVector("COMPONENTS",comps);
+      71          17 :   if(comps.size()!=0) {
+      72           2 :     for(unsigned i=0; i<comps.size(); i++) {
+      73           2 :       addComponentWithDerivatives(comps[i]);
+      74             :     }
+      75             :     // periodicity
+      76             :   } else {
+      77             :     // only one component for this variable
+      78          32 :     addValueWithDerivatives();
+      79             :   }
+      80             :   std::vector<std::string> period;
+      81          34 :   parseVector("PERIODIC",period);
+      82          17 :   if(period.size()!=0) {
+      83          17 :     plumed_massert(static_cast<unsigned>(getNumberOfComponents()*2)==period.size(),"the periodicty should coincide with the number of components");
+      84          17 :     if(comps.size()!=0) {
+      85           2 :       for(int i=0; i<getNumberOfComponents(); i++) {
+      86           1 :         std::string pp=comps[i];
+      87           1 :         if(period[i*2]!="none" && period[i*2+1]!="none" ) {
+      88           1 :           componentIsPeriodic(pp,period[i*2],period[i*2+1]);
+      89             :         } else {
+      90           0 :           componentIsNotPeriodic(pp);
+      91             :         }
+      92             :       }
+      93             :     } else {
+      94          29 :       if(period[0]!="none" && period[1]!="none" ) {
+      95          13 :         setPeriodic(period[0],period[1]);
+      96             :       } else {
+      97           3 :         setNotPeriodic();
+      98             :       }
+      99             :     }
+     100             :   } else {
+     101           0 :     if(comps.size()!=0) {
+     102           0 :       for(int i=0; i<getNumberOfComponents(); i++) {
+     103           0 :         componentIsNotPeriodic(getPntrToComponent(i)->getName());
+     104             :       }
+     105             :     } else {
+     106           0 :       setNotPeriodic();
+     107             :     }
+     108             :   }
+     109          17 :   checkRead();
+     110          17 :   requestAtoms(atoms);
+     111             : 
+     112          34 : }
+     113             : 
+     114             : 
+     115             : // calculator
+     116           0 : void ColvarFake::calculate() {
+     117           0 :   plumed_merror("you should never have got here");
+     118             : }
+     119             : 
+     120             : }
+     121             : }
+     122             : 
+     123             : 
+     124             : 
+
+
+
+ + + + +
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 000000000..d692e71cb --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/GHBFIX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GHBFIX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7777100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..2b351d1ec --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/GHBFIX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GHBFIX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7777100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..01efbe454 --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.gcov.html @@ -0,0 +1,294 @@ + + + + + + + LCOV - plumed test coverage - colvar/GHBFIX.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GHBFIX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7777100.0 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the GHBFIX interaction energy between the atoms in GROUPA and GROUPB");
+      96           3 : }
+      97             : 
+      98           1 : GHBFIX::GHBFIX(const ActionOptions&ao):
+      99             :   Action(ao),
+     100           1 :   CoordinationBase(ao)
+     101             : {
+     102             :   std::string types;
+     103             :   std::string params;
+     104           1 :   std::string energy_units ="plumed" ;
+     105             : 
+     106           1 :   parse("D_MAX",dmax);
+     107           1 :   dmax_squared = dmax*dmax;
+     108           1 :   parse("D_0",d0);
+     109           1 :   parse("C",c);
+     110           1 :   parse("TYPES",types);
+     111           1 :   parse("PARAMS",params);
+     112           1 :   parse("ENERGY_UNITS",energy_units);
+     113             : 
+     114           1 :   dmax2 = dmax-d0;
+     115             : 
+     116           1 :   A = (-c*dmax2*dmax2)/((1-c)*dmax2*dmax2);
+     117           1 :   B = (2*dmax2)/((1-c)*dmax2*dmax2);
+     118           1 :   C = -1/((1-c)*dmax2*dmax2);
+     119           1 :   D = 1/(c*dmax2*dmax2);
+     120             : 
+     121             :   std::map<std::string,unsigned> MapTypesTable;
+     122             : 
+     123             :   //typesTable
+     124           1 :   IFile typesfile;
+     125           1 :   typesfile.link(*this);
+     126           1 :   typesfile.open(types);
+     127             :   std::string itype;
+     128           6 :   while(typesfile.scanField("itype",itype).scanField()) {
+     129           2 :     plumed_assert(itype.empty()==false)<<"itype is empty";
+     130             : 
+     131           2 :     if (MapTypesTable.empty()) {
+     132           1 :       MapTypesTable.insert({itype, 0});
+     133             :     }
+     134             :     else if (MapTypesTable.count(itype) == 0) {
+     135             :       unsigned currentMax = 0;
+     136           2 :       for(auto it = MapTypesTable.cbegin(); it != MapTypesTable.cend(); ++it ) {
+     137           1 :         if (it ->second > currentMax) {
+     138             :           currentMax = it->second;
+     139             :         }
+     140             :       }
+     141           2 :       MapTypesTable.insert({itype, currentMax+1});
+     142             :     }
+     143             : 
+     144           2 :     typesTable.push_back(MapTypesTable[itype]);
+     145             :   }
+     146             : 
+     147           1 :   n = (int)*std::max_element(std::begin(typesTable), std::end(typesTable));
+     148           1 :   n+=1;
+     149             : 
+     150             :   //scalingParameters
+     151           1 :   etas.resize(n*n,0.0);
+     152           1 :   IFile etafile;
+     153           1 :   etafile.open(params);
+     154             :   std::string it,jt;
+     155             :   double eta;
+     156          14 :   while(etafile.scanField("itype",it).scanField("jtype",jt).scanField("eta",eta).scanField()) {
+     157           6 :     plumed_assert(it.empty()==false)<<"itype is empty";
+     158           6 :     plumed_assert(jt.empty()==false)<<"jtype is empty";
+     159           6 :     etas[n*MapTypesTable[it]+MapTypesTable[jt]]=eta;
+     160             :   }
+     161             : 
+     162           1 :   if(energy_units!="plumed") {
+     163           1 :     Units units;
+     164           1 :     units.setEnergy(energy_units);
+     165           5 :     for(auto i=0; i<etas.size(); i++) etas[i]*=units.getEnergy()/getUnits().getEnergy();
+     166           1 :   }
+     167             : 
+     168           3 : }
+     169             : 
+     170             : 
+     171         150 : double GHBFIX::pairing(double distance2,double&dfunc,unsigned i,unsigned j)const {
+     172             : 
+     173         150 :   const auto i1=getAbsoluteIndex(i).index();
+     174         150 :   plumed_assert(i1<typesTable.size())<<"your types table only covers "<<typesTable.size()<<" atoms, but you are trying to access atom number "<<(i1+1);
+     175         150 :   const auto t1=typesTable[i1];
+     176             : 
+     177         150 :   const auto i2=getAbsoluteIndex(j).index();
+     178         150 :   plumed_assert(i2<typesTable.size())<<"your types table only covers "<<typesTable.size()<<" atoms, but you are trying to access atom number "<<(i2+1);
+     179         150 :   const auto t2=typesTable[i2];
+     180             : 
+     181         150 :   const double scale=etas[n*t1+t2];
+     182             : 
+     183             :   double result;
+     184         150 :   if(distance2>dmax_squared) {
+     185             :     result=0.;
+     186           1 :     dfunc=0.0;
+     187           1 :     return result;
+     188             :   }
+     189         149 :   double distance=std::sqrt(distance2);
+     190         149 :   const double rdist = (distance-d0);
+     191             : 
+     192         149 :   if(rdist<=0.) {
+     193             :     result=-1.;
+     194         100 :     dfunc=0.0;
+     195             :   } else {
+     196             :     result=-1.;
+     197          49 :     dfunc=0.0;
+     198             : 
+     199          49 :     if (rdist > c*dmax2) {
+     200           9 :       result+=(A + B*rdist + C*rdist*rdist);
+     201           9 :       dfunc+=B+2*C*rdist;
+     202          40 :     } else if (rdist > 0.0) {
+     203          40 :       result+=D*(rdist*rdist);
+     204          40 :       dfunc+=2*D*rdist;
+     205             :     }
+     206             : 
+     207          49 :     dfunc/=distance;
+     208             :   }
+     209             : 
+     210         149 :   result*=scale;
+     211         149 :   dfunc*=scale;
+     212             : 
+     213         149 :   return result;
+     214             : }
+     215             : 
+     216             : }
+     217             : 
+     218             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.func-sort-c.html b/coverage/colvar/Gyration.cpp.func-sort-c.html new file mode 100644 index 000000000..3af081b20 --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:14318477.7 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8GyrationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8GyrationC1ERKNS_13ActionOptionsE112
_ZN4PLMD6colvar8Gyration16registerKeywordsERNS_8KeywordsE224
_ZN4PLMD6colvar8Gyration9calculateEv1238
+
+
+ + + +
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 000000000..d9ce167f9 --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:14318477.7 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16GyrationShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16GyrationShortcutC1ERKNS_13ActionOptionsE116
_ZN4PLMD6colvar16GyrationShortcut16registerKeywordsERNS_8KeywordsE122
+
+
+ + + +
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 000000000..997ea740b --- /dev/null +++ b/coverage/colvar/GyrationShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:519255.4 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16GyrationShortcut16registerKeywordsERNS_8KeywordsE122
_ZN4PLMD6colvar16GyrationShortcutC1ERKNS_13ActionOptionsE116
_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 000000000..bd8ada33d --- /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:519255.4 %
Date:2024-10-17 16:45:00Functions: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         122 : void GyrationShortcut::registerKeywords( Keywords& keys ) {
+      57         122 :   ActionShortcut::registerKeywords( keys );
+      58         244 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the Gyration Tensor for");
+      59         244 :   keys.add("compulsory","TYPE","RADIUS","The type of calculation relative to the Gyration Tensor you want to perform");
+      60         244 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      61         244 :   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         244 :   keys.addFlag("PHASES",false,"use trigonometric phases when computing position of center of mass");
+      66         244 :   keys.addFlag("MASS",false,"calculate the center of mass");
+      67         244 :   keys.addFlag("MASS_WEIGHTED",false,"set the masses of all the atoms equal to one");
+      68         244 :   keys.addFlag("UNORMALIZED",false,"do not divide by the sum of the weights");
+      69         122 :   keys.setValueDescription("the radius that was computed from the weights");
+      70         366 :   keys.addActionNameSuffix("_FAST"); keys.needsAction("CENTER"); keys.needsAction("CONSTANT");
+      71         366 :   keys.needsAction("ONES"); keys.needsAction("MASS"); keys.needsAction("DISTANCE");
+      72         244 :   keys.needsAction("COVARIANCE_MATRIX"); keys.needsAction("SELECT_COMPONENTS");
+      73         366 :   keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("DIAGONALIZE");
+      74         122 : }
+      75             : 
+      76         116 : GyrationShortcut::GyrationShortcut(const ActionOptions& ao):
+      77             :   Action(ao),
+      78         116 :   ActionShortcut(ao)
+      79             : {
+      80         348 :   bool usemass, phases; parseFlag("MASS",usemass); parseFlag("PHASES",phases);
+      81         232 :   std::vector<std::string> str_weights; parseVector("WEIGHTS",str_weights); std::string wflab;
+      82         116 :   if( !phases ) {
+      83         115 :     if( usemass || str_weights.size()==0 || (str_weights.size()==1 && str_weights[0]=="@Masses") ) {
+      84             :       std::string wt_str;
+      85         112 :       if( str_weights.size()>0 ) {
+      86           0 :         wt_str="WEIGHTS=" + str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) wt_str += "," + str_weights[i];
+      87             :       }
+      88         112 :       if( usemass || (str_weights.size()==1 && str_weights[0]=="@Masses") ) wt_str = "MASS";
+      89         232 :       readInputLine( getShortcutLabel() + ": GYRATION_FAST " + wt_str + " " + convertInputLineToString() );
+      90             :       return;
+      91             :     }
+      92             :   }
+      93           4 :   if( usemass ) { str_weights.resize(1); str_weights[0]="@Masses"; }
+      94          10 :   log<<"  Bibliography "<<plumed.cite("JiriÌ Vymetal and JiriÌ Vondrasek, J. Phys. Chem. A 115, 11455 (2011)")<<"\n";
+      95             :   // Read in the atoms involved
+      96           8 :   std::vector<std::string> atoms; parseVector("ATOMS",atoms); Tools::interpretRanges(atoms);
+      97          12 :   std::string gtype, atlist=atoms[0]; for(unsigned i=1; i<atoms.size(); ++i) atlist += "," + atoms[i];
+      98           8 :   bool nopbc; parseFlag("NOPBC",nopbc); std::string pbcstr; if(nopbc) pbcstr = " NOPBC";
+      99           4 :   std::string phasestr; if(phases) phasestr = " PHASES";
+     100             :   // Create the geometric center of the molecule
+     101           4 :   std::string weights_str=" WEIGHTS=" + str_weights[0];
+     102           8 :   for(unsigned i=1; i<str_weights.size(); ++i) weights_str += "," + str_weights[i];
+     103           8 :   readInputLine( getShortcutLabel() + "_cent: CENTER ATOMS=" + atlist + pbcstr + phasestr + weights_str );
+     104           4 :   if( str_weights.size()==0 ) {
+     105           0 :     wflab = getShortcutLabel() + "_w"; std::string str_natoms; Tools::convert( atoms.size(), str_natoms );
+     106           0 :     readInputLine( getShortcutLabel() + "_w: ONES SIZE=" + str_natoms );
+     107           6 :   } else if( str_weights.size()==1 && str_weights[0]=="@Masses" ) {
+     108           0 :     wflab = getShortcutLabel() + "_m";
+     109           0 :     readInputLine( getShortcutLabel() + "_m: MASS ATOMS=" + atlist );
+     110           4 :   } else if( str_weights.size()>1 ) {
+     111           6 :     std::string vals=str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) vals += "," + str_weights[i];
+     112           6 :     readInputLine( getShortcutLabel() + "_w: CONSTANT VALUES=" + vals ); wflab=getShortcutLabel() + "_w";
+     113             :   } else {
+     114           2 :     plumed_assert( str_weights.size()==1 ); wflab = getShortcutLabel() + "_cent_w";
+     115           2 :     ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( wflab );
+     116           2 :     if( !av ) { wflab = str_weights[0]; }
+     117             :   }
+     118             :   // Check for normalisation
+     119           8 :   bool unorm; parseFlag("UNORMALIZED",unorm);
+     120             :   // Find out the type
+     121           4 :   if( getName()!="GYRATION_TENSOR" ) {
+     122           0 :     parse("TYPE",gtype);
+     123           0 :     if( gtype!="RADIUS" && gtype!="TRACE" && gtype!="GTPC_1" && gtype!="GTPC_2" && gtype!="GTPC_3" && gtype!="ASPHERICITY" && gtype!="ACYLINDRICITY"
+     124           0 :         && gtype!= "KAPPA2" && gtype!="RGYR_1" && gtype!="RGYR_2" && gtype!="RGYR_3" ) error("type " + gtype + " is invalid");
+     125             :     // Check if we need to calculate the unormlised radius
+     126           0 :     if( gtype=="TRACE" || gtype=="KAPPA2" ) unorm=true;
+     127             :   }
+     128             :   // Compute all the vectors separating all the positions from the center
+     129           4 :   std::string distance_act = getShortcutLabel() + "_dists: DISTANCE COMPONENTS" + pbcstr;
+     130          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]; }
+     131           4 :   readInputLine( distance_act );
+     132             :   // And calculate the covariance
+     133           4 :   std::string norm_str; if( unorm ) norm_str = " UNORMALIZED";
+     134           4 :   if( getName()=="GYRATION_TENSOR" ) {
+     135           8 :     readInputLine( getShortcutLabel() + ": COVARIANCE_MATRIX ARG=" + getShortcutLabel() + "_dists.x," + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_dists.z WEIGHTS=" + wflab + norm_str );
+     136             :     return;
+     137             :   }
+     138           0 :   readInputLine( getShortcutLabel() + "_tensor: COVARIANCE_MATRIX ARG=" + getShortcutLabel() + "_dists.x," + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_dists.z WEIGHTS=" + wflab + norm_str );
+     139             :   // Pick out the diagonal elements
+     140           0 :   readInputLine( getShortcutLabel() + "_diag_elements: SELECT_COMPONENTS ARG=" + getShortcutLabel() + "_tensor COMPONENTS=1.1,2.2,3.3");
+     141           0 :   if( gtype=="RADIUS") {
+     142             :     // And now we need the average trace for the gyration radius
+     143           0 :     readInputLine( getShortcutLabel() + "_trace: SUM ARG=" + getShortcutLabel() + "_diag_elements PERIODIC=NO");
+     144             :     // Square root the radius
+     145           0 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_trace FUNC=sqrt(x) PERIODIC=NO");
+     146           0 :   } else if( gtype=="TRACE" ) {
+     147             :     // Compte the trace of the gyration tensor
+     148           0 :     readInputLine( getShortcutLabel() + "_trace: SUM ARG=" + getShortcutLabel() + "_diag_elements PERIODIC=NO");
+     149             :     // And double it
+     150           0 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_trace FUNC=2*x PERIODIC=NO");
+     151             :   } else {
+     152             :     // Diagonalize the gyration tensor
+     153           0 :     readInputLine( getShortcutLabel() + "_diag: DIAGONALIZE ARG=" + getShortcutLabel() + "_tensor VECTORS=all" );
+     154           0 :     if( gtype.find("GTPC")!=std::string::npos ) {
+     155           0 :       std::size_t und=gtype.find_first_of("_"); if( und==std::string::npos ) error( gtype + " is not a valid type for gyration radius");
+     156           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");
+     157             :       // Now get the appropriate eigenvalue
+     158           0 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-" + num + " FUNC=sqrt(x) PERIODIC=NO");
+     159           0 :     } else if( gtype.find("RGYR")!=std::string::npos ) {
+     160           0 :       std::size_t und=gtype.find_first_of("_"); if( und==std::string::npos ) error( gtype + " is not a valid type for gyration radius");
+     161           0 :       unsigned ind; Tools::convert( gtype.substr(und+1), ind );
+     162             :       // Now get the appropriate quantity
+     163           0 :       if( ind==3 ) {
+     164           0 :         readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-2 FUNC=sqrt(x+y) PERIODIC=NO");
+     165           0 :       } else if( ind==2 ) {
+     166           0 :         readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-3 FUNC=sqrt(x+y) PERIODIC=NO");
+     167           0 :       } else if( ind==1 ) {
+     168           0 :         readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=sqrt(x+y) PERIODIC=NO");
+     169           0 :       } else error( gtype + " is not a valid type for gyration radius");
+     170           0 :     } else if( gtype=="ASPHERICITY" ) {
+     171           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" );
+     172           0 :     } else if( gtype=="ACYLINDRICITY" ) {
+     173           0 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=sqrt(x-y) PERIODIC=NO" );
+     174           0 :     } else if( gtype=="KAPPA2" ) {
+     175           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" );
+     176           0 :       readInputLine( getShortcutLabel() + "_denom: CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=x+y+z PERIODIC=NO" );
+     177           0 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=1-3*(x/(y*y)) PERIODIC=NO");
+     178           0 :     } else error( gtype + " is not a valid type for gyration radius");
+     179             :   }
+     180         124 : }
+     181             : 
+     182             : }
+     183             : }
+
+
+
+ + + + +
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 000000000..4f1e6a0d7 --- /dev/null +++ b/coverage/colvar/MultiColvarTemplate.h.func-sort-c.html @@ -0,0 +1,360 @@ + + + + + + + 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:929497.9 %
Date:2024-10-17 16:45:00Functions: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_19DihedralCorrelationEE22getNumberOfDerivativesEv3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23addValueWithDerivativesERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE9calculateEv5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE22getNumberOfDerivativesEv6
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE6
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE11performTaskERKjRNS_10MultiValueE10
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE9calculateEv11
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEC1ERKNS_13ActionOptionsE12
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE9calculateEv15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE9calculateEv16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23addValueWithDerivativesERKSt6vectorIjSaIjEE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE9calculateEv18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_22
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE22getNumberOfDerivativesEv38
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE22getNumberOfDerivativesEv48
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE48
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE9calculateEv54
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE23addValueWithDerivativesERKSt6vectorIjSaIjEE62
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE9calculateEv84
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_84
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE22getNumberOfDerivativesEv105
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEEC1ERKNS_13ActionOptionsE108
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE22getNumberOfDerivativesEv128
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE138
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE11performTaskERKjRNS_10MultiValueE176
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE222
_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 000000000..a371ae0af --- /dev/null +++ b/coverage/colvar/MultiColvarTemplate.h.func.html @@ -0,0 +1,360 @@ + + + + + + + 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:929497.9 %
Date:2024-10-17 16:45:00Functions:657290.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE22getNumberOfDerivativesEv38
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23addValueWithDerivativesERKSt6vectorIjSaIjEE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE9calculateEv18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE22getNumberOfDerivativesEv3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE23addValueWithDerivativesERKSt6vectorIjSaIjEE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE9calculateEv5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE22getNumberOfDerivativesEv2
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23addValueWithDerivativesERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE9calculateEv15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE22getNumberOfDerivativesEv105
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_22
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE9calculateEv11
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE22getNumberOfDerivativesEv6
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE23addValueWithDerivativesERKSt6vectorIjSaIjEE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE6
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE9calculateEv16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE22getNumberOfDerivativesEv128
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE9calculateEv84
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE222
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE22getNumberOfDerivativesEv553
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE23addValueWithDerivativesERKSt6vectorIjSaIjEE62
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_15596
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE138
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE9calculateEv15253
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEEC1ERKNS_13ActionOptionsE108
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE22getNumberOfDerivativesEv729
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_12212
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE9calculateEv7229
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE16registerKeywordsERNS_8KeywordsE26
_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 000000000..a744f9eb6 --- /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:929497.9 %
Date:2024-10-17 16:45:00Functions: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         426 : void MultiColvarTemplate<T>::registerKeywords(Keywords& keys ) {
+      54         426 :   T::registerKeywords( keys );
+      55         426 :   unsigned nkeys = keys.size();
+      56        3906 :   for(unsigned i=0; i<nkeys; ++i) {
+      57        7660 :     if( keys.style( keys.get(i), "atoms" ) ) keys.reset_style( keys.get(i), "numbered" );
+      58             :   }
+      59        1164 :   if( keys.outputComponentExists(".#!value") ) keys.setValueDescription("the " + keys.getDisplayName() + " for each set of specified atoms");
+      60         426 : }
+      61             : 
+      62             : template <class T>
+      63         201 : MultiColvarTemplate<T>::MultiColvarTemplate(const ActionOptions&ao):
+      64             :   Action(ao),
+      65             :   ActionWithVector(ao),
+      66         201 :   mode(0),
+      67         201 :   usepbc(true),
+      68         201 :   wholemolecules(false)
+      69             : {
+      70             :   std::vector<AtomNumber> all_atoms;
+      71         571 :   if( getName()=="POSITION_VECTOR" || getName()=="MASS_VECTOR" || getName()=="CHARGE_VECTOR" ) parseAtomList( "ATOMS", all_atoms );
+      72         201 :   if( all_atoms.size()>0 ) {
+      73          57 :     ablocks.resize(1); ablocks[0].resize( all_atoms.size() );
+      74        8109 :     for(unsigned i=0; i<all_atoms.size(); ++i) ablocks[0][i] = i;
+      75             :   } else {
+      76             :     std::vector<AtomNumber> t;
+      77       32324 :     for(int i=1;; ++i ) {
+      78       32324 :       T::parseAtomList( i, t, this );
+      79       32324 :       if( t.empty() ) break;
+      80             : 
+      81       32180 :       if( i==1 ) { ablocks.resize(t.size()); }
+      82       32180 :       if( t.size()!=ablocks.size() ) {
+      83           0 :         std::string ss; Tools::convert(i,ss);
+      84           0 :         error("ATOMS" + ss + " keyword has the wrong number of atoms");
+      85             :       }
+      86       98848 :       for(unsigned j=0; j<ablocks.size(); ++j) {
+      87       66668 :         ablocks[j].push_back( ablocks.size()*(i-1)+j ); all_atoms.push_back( t[j] );
+      88             :       }
+      89       32180 :       t.resize(0);
+      90             :     }
+      91             :   }
+      92         201 :   if( all_atoms.size()==0 ) error("No atoms have been specified");
+      93         201 :   requestAtoms(all_atoms);
+      94         402 :   if( keywords.exists("NOPBC") ) {
+      95         201 :     bool nopbc=!usepbc; parseFlag("NOPBC",nopbc);
+      96         201 :     usepbc=!nopbc;
+      97             :   }
+      98         402 :   if( keywords.exists("WHOLEMOLECULES") ) {
+      99          41 :     parseFlag("WHOLEMOLECULES",wholemolecules);
+     100          41 :     if( wholemolecules ) usepbc=false;
+     101             :   }
+     102         201 :   if( usepbc ) log.printf("  using periodic boundary conditions\n");
+     103          34 :   else    log.printf("  without periodic boundary conditions\n");
+     104             : 
+     105             :   // Setup the values
+     106         201 :   mode = T::getModeAndSetupValues( this );
+     107         201 : }
+     108             : 
+     109             : template <class T>
+     110        1612 : unsigned MultiColvarTemplate<T>::getNumberOfDerivatives() {
+     111        1612 :   return 3*getNumberOfAtoms()+9;
+     112             : }
+     113             : 
+     114             : template <class T>
+     115       22685 : void MultiColvarTemplate<T>::calculate() {
+     116       22685 :   runAllTasks();
+     117       22685 : }
+     118             : 
+     119             : template <class T>
+     120          99 : void MultiColvarTemplate<T>::addValueWithDerivatives( const std::vector<unsigned>& shape ) {
+     121          99 :   std::vector<unsigned> s(1); s[0]=ablocks[0].size(); addValue( s );
+     122          99 : }
+     123             : 
+     124             : template <class T>
+     125         318 : void MultiColvarTemplate<T>::addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape ) {
+     126         318 :   std::vector<unsigned> s(1); s[0]=ablocks[0].size(); addComponent( name, s );
+     127         318 : }
+     128             : 
+     129             : template <class T>
+     130       28091 : void MultiColvarTemplate<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     131       28091 :   if( wholemolecules ) makeWhole();
+     132       28091 :   ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     133       28091 : }
+     134             : 
+     135             : template <class T>
+     136      490140 : void MultiColvarTemplate<T>::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+     137             :   // Retrieve the positions
+     138             :   std::vector<Vector> & fpositions( myvals.getFirstAtomVector() );
+     139      490140 :   if( fpositions.size()!=ablocks.size() ) fpositions.resize( ablocks.size() );
+     140     1334749 :   for(unsigned i=0; i<ablocks.size(); ++i) fpositions[i] = getPosition( ablocks[i][task_index] );
+     141             :   // If we are using pbc make whole
+     142      490140 :   if( usepbc ) {
+     143      233347 :     if( fpositions.size()==1 ) {
+     144       57816 :       fpositions[0]=pbcDistance(Vector(0.0,0.0,0.0),getPosition( ablocks[0][task_index] ) );
+     145             :     } else {
+     146      418629 :       for(unsigned j=0; j<fpositions.size()-1; ++j) {
+     147      214190 :         const Vector & first (fpositions[j]); Vector & second (fpositions[j+1]);
+     148      214190 :         second=first+pbcDistance(first,second);
+     149             :       }
+     150             :     }
+     151      256793 :   } else if( fpositions.size()==1 ) fpositions[0]=delta(Vector(0.0,0.0,0.0),getPosition( ablocks[0][task_index] ) );
+     152             :   // Retrieve the masses and charges
+     153      490140 :   myvals.resizeTemporyVector(2);
+     154             :   std::vector<double> & mass( myvals.getTemporyVector(0) );
+     155             :   std::vector<double> & charge( myvals.getTemporyVector(1) );
+     156      490140 :   if( mass.size()!=ablocks.size() ) { mass.resize(ablocks.size()); charge.resize(ablocks.size()); }
+     157     1334749 :   for(unsigned i=0; i<ablocks.size(); ++i) { mass[i]=getMass( ablocks[i][task_index] ); charge[i]=getCharge( ablocks[i][task_index] ); }
+     158             :   // Make some space to store various things
+     159      490140 :   std::vector<double> values( getNumberOfComponents() );
+     160             :   std::vector<Tensor> & virial( myvals.getFirstAtomVirialVector() );
+     161             :   std::vector<std::vector<Vector> > & derivs( myvals.getFirstAtomDerivativeVector() );
+     162      490140 :   if( derivs.size()!=values.size() ) { derivs.resize( values.size() ); virial.resize( values.size() ); }
+     163     1478457 :   for(unsigned i=0; i<derivs.size(); ++i) {
+     164      988317 :     if( derivs[i].size()<ablocks.size() ) derivs[i].resize( ablocks.size() );
+     165             :   }
+     166             :   // Calculate the CVs using the method in the Colvar
+     167      490140 :   T::calculateCV( mode, mass, charge, fpositions, values, derivs, virial, this );
+     168     1478457 :   for(unsigned i=0; i<values.size(); ++i) myvals.setValue( getConstPntrToComponent(i)->getPositionInStream(), values[i] );
+     169             :   // Finish if there are no derivatives
+     170      490140 :   if( doNotCalculateDerivatives() ) return;
+     171             : 
+     172             :   // Now transfer the derivatives to the underlying MultiValue
+     173      868925 :   for(unsigned i=0; i<ablocks.size(); ++i) {
+     174      547918 :     unsigned base=3*ablocks[i][task_index];
+     175     1456521 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     176      908603 :       unsigned jval=getConstPntrToComponent(j)->getPositionInStream();
+     177      908603 :       myvals.addDerivative( jval, base + 0, derivs[j][i][0] );
+     178      908603 :       myvals.addDerivative( jval, base + 1, derivs[j][i][1] );
+     179      908603 :       myvals.addDerivative( jval, base + 2, derivs[j][i][2] );
+     180             :     }
+     181             :     // Check for duplicated indices during update to avoid double counting
+     182             :     bool newi=true;
+     183      787032 :     for(unsigned j=0; j<i; ++j) {
+     184      239114 :       if( ablocks[j][task_index]==ablocks[i][task_index] ) { newi=false; break; }
+     185             :     }
+     186      547918 :     if( !newi ) continue;
+     187     1456521 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     188      908603 :       unsigned jval=getConstPntrToComponent(j)->getPositionInStream();
+     189      908603 :       myvals.updateIndex( jval, base );
+     190      908603 :       myvals.updateIndex( jval, base + 1 );
+     191      908603 :       myvals.updateIndex( jval, base + 2 );
+     192             :     }
+     193             :   }
+     194      321007 :   unsigned nvir=3*getNumberOfAtoms();
+     195      913213 :   for(int j=0; j<getNumberOfComponents(); ++j) {
+     196      592206 :     unsigned jval=getConstPntrToComponent(j)->getPositionInStream();
+     197     2368824 :     for(unsigned i=0; i<3; ++i) {
+     198     7106472 :       for(unsigned k=0; k<3; ++k) {
+     199     5329854 :         myvals.addDerivative( jval, nvir + 3*i + k, virial[j][i][k] );
+     200     5329854 :         myvals.updateIndex( jval, nvir + 3*i + k );
+     201             :       }
+     202             :     }
+     203             :   }
+     204             : }
+     205             : 
+     206             : }
+     207             : }
+     208             : #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 000000000..1e971dcae --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:515691.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..34e1f8b9d --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:515691.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..115854bab --- /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:515691.1 %
Date:2024-10-17 16:45:00Functions: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           3 :   keys.setValueDescription("the sum of the multiple RMSD distances");
+      62           9 :   keys.needsAction("CONSTANT"); keys.needsAction("WHOLEMOLECULES"); keys.needsAction("POSITION");
+      63          12 :   keys.needsAction("CONCATENATE"); keys.needsAction("RMSD_VECTOR"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      64           3 : }
+      65             : 
+      66           1 : MultiRMSD::MultiRMSD(const ActionOptions& ao):
+      67             :   Action(ao),
+      68           1 :   ActionShortcut(ao)
+      69             : {
+      70           2 :   warning("this action is depracated.  look at the log to see how it is implemented using the new syntax");
+      71           2 :   std::string type; parse("TYPE",type); bool nopbc; parseFlag("NOPBC",nopbc);
+      72           1 :   std::size_t dash=type.find_first_of("-");
+      73           1 :   if( dash!=std::string::npos ) {
+      74           2 :     if( type.substr(0,dash)=="MULTI" ) warning("MULTI is deprecated.  You can just use OPTIMAL/SIMPLE");
+      75           0 :     else error("cannot understand type " + type );
+      76           2 :     type = type.substr(dash+1);
+      77             :   }
+      78           2 :   std::string reference; parse("REFERENCE",reference); PDB pdb;
+      79           1 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) ) error("missing input file " + reference );
+      80             : 
+      81           1 :   unsigned nblocks =  pdb.getNumberOfAtomBlocks();
+      82           1 :   if( nblocks<2 ) error("multidomain RMSD only has one block of atoms");
+      83           1 :   std::string num; std::vector<unsigned> blocks( nblocks+1 ); blocks[0]=0;
+      84           3 :   for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      85             : 
+      86           3 :   for(unsigned i=1; i<=nblocks; ++i) {
+      87             :     // Setup a constant
+      88           2 :     double asum=0; std::string bnum; Tools::convert( i, bnum );
+      89          17 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) asum += pdb.getOccupancy()[j];
+      90           2 :     Vector center; center.zero();
+      91          17 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) center += ( pdb.getOccupancy()[j] / asum )*pdb.getPositions()[j];
+      92             :     std::vector<double> vals;
+      93           8 :     for(unsigned k=0; k<3; ++k) {
+      94          51 :       for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) vals.push_back( pdb.getPositions()[j][k] - center[k] );
+      95             :     }
+      96           2 :     std::string valstr; Tools::convert( vals[0], valstr );
+      97          45 :     for(unsigned i=1; i<vals.size(); ++i) { std::string rnum; Tools::convert( vals[i], rnum ); valstr += "," + rnum; }
+      98             :     // Create the reference value
+      99           4 :     readInputLine( getShortcutLabel() + "_ref" + bnum + ": CONSTANT VALUES=" + valstr );
+     100             :     // Do whole molecules
+     101           2 :     if( !nopbc ) {
+     102           0 :       std::string num; Tools::convert( pdb.getAtomNumbers()[blocks[i-1]].serial(), num ); std::string wm_line = "WHOLEMOLECULES ENTITY0=" + num;
+     103           0 :       for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getAtomNumbers()[j].serial(), num ); wm_line += "," + num; }
+     104           0 :       readInputLine( wm_line );
+     105             :     }
+     106             :     // Get the positions of the atoms in this block
+     107           4 :     std::string num; Tools::convert( pdb.getAtomNumbers()[blocks[i-1]].serial(), num ); std::string pos_line = getShortcutLabel() + "_cpos" + bnum + ": POSITION NOPBC ATOMS=" + num;
+     108          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getAtomNumbers()[j].serial(), num ); pos_line += "," + num; }
+     109           2 :     readInputLine( pos_line );
+     110             :     // Concatenate the positiosn together
+     111           4 :     readInputLine( getShortcutLabel() + "_pos" + bnum + ": CONCATENATE ARG=" + getShortcutLabel() + "_cpos" + bnum + ".x," + getShortcutLabel() + "_cpos" + bnum + ".y," + getShortcutLabel() + "_cpos" + bnum + ".z");
+     112             :     // Computer the RMSD for this block
+     113           4 :     std::string rmsd_line = getShortcutLabel() + "_rmsd" + bnum + ": RMSD_VECTOR SQUARED ARG=" + getShortcutLabel() + "_pos" + bnum + "," + getShortcutLabel() + "_ref" + bnum;
+     114             :     // Now align
+     115           4 :     Tools::convert( pdb.getOccupancy()[blocks[i-1]], num ); rmsd_line += " ALIGN=" + num;
+     116          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getOccupancy()[j], num ); rmsd_line += "," + num; }
+     117             :     // And displace
+     118           4 :     Tools::convert( pdb.getBeta()[blocks[i-1]], num ); rmsd_line += " DISPLACE=" + num;
+     119          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getBeta()[j], num ); rmsd_line += "," + num; }
+     120           4 :     readInputLine( rmsd_line + " TYPE=" + type );
+     121             :   }
+     122           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; }
+     123           1 :   bool squared; parseFlag("SQUARED",squared);
+     124           1 :   if( !squared ) {
+     125           2 :     readInputLine( getShortcutLabel() + "_2: COMBINE ARG=" + argstr + " PERIODIC=NO");
+     126           2 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+     127           0 :   } else readInputLine( getShortcutLabel() + ": COMBINE ARG=" + argstr + " PERIODIC=NO");
+     128           2 : }
+     129             : 
+     130             : }
+     131             : }
+
+
+
+ + + + +
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 000000000..b5aeeebd3 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..93677ddf8 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..32a6d7063 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.gcov.html @@ -0,0 +1,342 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c54822ba7 --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1919100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..5c15d1c87 --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1919100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3cb742ec8 --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.gcov.html @@ -0,0 +1,204 @@ + + + + + + + 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:1919100.0 %
Date:2024-10-17 16:45:00Functions: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          32 :   keys.addOutputComponent("sss","default","the position on the path");
+     103          32 :   keys.addOutputComponent("zzz","default","the distance from the path");
+     104          16 : }
+     105             : 
+     106          14 : PathMSD::PathMSD(const ActionOptions&ao):
+     107          14 :   Action(ao),PathMSDBase(ao)
+     108             : {
+     109          14 :   checkRead();
+     110             : 
+     111          14 :   log<<"  Bibliography "
+     112          28 :      <<plumed.cite("Branduardi, Gervasio, Parrinello J. Chem. Phys. 126, 054103 (2007)")
+     113          28 :      <<"\n";
+     114             :   // no need to read anything
+     115          42 :   addComponentWithDerivatives("sss"); componentIsNotPeriodic("sss");
+     116          28 :   addComponentWithDerivatives("zzz"); componentIsNotPeriodic("zzz");
+     117          14 :   requestAtoms(pdbv[0].getAtomNumbers());
+     118             : 
+     119          14 :   double i=1.;
+     120         634 :   for(unsigned it=0 ; it<nframes ; ++it) {
+     121         620 :     std::vector<double> v; v.push_back(i);
+     122         620 :     indexvec.push_back(v); i+=1.;
+     123             :   }
+     124          14 : }
+     125             : 
+     126             : }
+     127             : 
+     128             : }
+
+
+
+ + + + +
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 000000000..910e5b0b9 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18018497.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..9eedeb959 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18018497.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..3613624c8 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.gcov.html @@ -0,0 +1,413 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e6f2da5a8 --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..6fb0366ea --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..2c27ae591 --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.gcov.html @@ -0,0 +1,177 @@ + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..a04d9fc1d --- /dev/null +++ b/coverage/colvar/Plane.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5Plane9calculateEv0
_ZN4PLMD6colvar5PlaneC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5PlaneC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5Plane21getModeAndSetupValuesEPNS_15ActionWithValueE1
_ZN4PLMD6colvar5Plane13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE9
_ZN4PLMD6colvar5Plane16registerKeywordsERNS_8KeywordsE10
_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 000000000..1efa67ccd --- /dev/null +++ b/coverage/colvar/Plane.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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_8KeywordsE10
_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 000000000..9bb4e64e2 --- /dev/null +++ b/coverage/colvar/Plane.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + 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-10-17 16:45:00Functions: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          10 : void Plane::registerKeywords( Keywords& keys ) {
+      87          10 :   Colvar::registerKeywords( keys ); keys.setDisplayName("PLANE");
+      88          20 :   keys.add("atoms","ATOMS","the three or four atoms whose plane we are computing");
+      89          20 :   keys.addOutputComponent("x","default","the x-component of the vector that is normal to the plane containing the atoms");
+      90          20 :   keys.addOutputComponent("y","default","the y-component of the vector that is normal to the plane containing the atoms");
+      91          20 :   keys.addOutputComponent("z","default","the z-component of the vector that is normal to the plane containing the atoms");
+      92          20 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      93          10 : }
+      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 000000000..732287ce3 --- /dev/null +++ b/coverage/colvar/Position.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Position.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Position.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8989100.0 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE94
_ZN4PLMD6colvar8Position13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE102
_ZN4PLMD6colvar8Position21getModeAndSetupValuesEPNS_15ActionWithValueE134
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE468
_ZN4PLMD6colvar8Position9calculateEv8078
_ZN4PLMD6colvar8Position11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE151422
+
+
+ + + +
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 000000000..d346ec688 --- /dev/null +++ b/coverage/colvar/Position.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Position.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Position.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8989100.0 %
Date:2024-10-17 16:45:00Functions: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_15ActionAtomisticE151422
_ZN4PLMD6colvar8Position13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE102
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE468
_ZN4PLMD6colvar8Position21getModeAndSetupValuesEPNS_15ActionWithValueE134
_ZN4PLMD6colvar8Position9calculateEv8078
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE94
_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 000000000..6a5baf6e1 --- /dev/null +++ b/coverage/colvar/Position.cpp.gcov.html @@ -0,0 +1,314 @@ + + + + + + + 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:8989100.0 %
Date:2024-10-17 16:45:00Functions: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         468 : void Position::registerKeywords( Keywords& keys ) {
+     118         468 :   Colvar::registerKeywords( keys ); keys.setDisplayName("POSITION");
+     119         936 :   keys.add("atoms","ATOM","the atom number");
+     120         936 :   keys.add("atoms","ATOMS","the atom numbers that you would like to use the positions of");
+     121         936 :   keys.addFlag("WHOLEMOLECULES",false,"if this is a vector of positions do you want to make the positions into a whole before");
+     122         936 :   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");
+     123         936 :   keys.addOutputComponent("x","default","the x-component of the atom position");
+     124         936 :   keys.addOutputComponent("y","default","the y-component of the atom position");
+     125         936 :   keys.addOutputComponent("z","default","the z-component of the atom position");
+     126         936 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the atom position");
+     127         936 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the atom position");
+     128         936 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the atom position");
+     129         936 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     130         468 : }
+     131             : 
+     132          94 : Position::Position(const ActionOptions&ao):
+     133             :   PLUMED_COLVAR_INIT(ao),
+     134          94 :   scaled_components(false),
+     135          94 :   pbc(true),
+     136          94 :   value(3),
+     137          95 :   derivs(3),
+     138         188 :   virial(3)
+     139             : {
+     140         376 :   for(unsigned i=0; i<3; ++i) derivs[i].resize(1);
+     141          94 :   std::vector<AtomNumber> atoms; parseAtomList(-1,atoms,this);
+     142          93 :   unsigned mode=getModeAndSetupValues(this);
+     143          93 :   if( mode==1 ) scaled_components=true;
+     144             : 
+     145          93 :   bool nopbc=!pbc;
+     146          94 :   parseFlag("NOPBC",nopbc);
+     147          93 :   pbc=!nopbc;
+     148          93 :   checkRead();
+     149             : 
+     150          93 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     151           5 :   else    log.printf("  without periodic boundary conditions\n");
+     152             : 
+     153          93 :   requestAtoms(atoms);
+     154          96 : }
+     155             : 
+     156         102 : void Position::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     157         204 :   aa->parseAtomList("ATOM",num,t);
+     158         102 :   if( t.size()==1 ) aa->log.printf("  for atom %d\n",t[0].serial());
+     159           3 :   else if( num<0 || t.size()!=0 ) aa->error("Number of specified atoms should be 1");
+     160         101 : }
+     161             : 
+     162         134 : unsigned Position::getModeAndSetupValues( ActionWithValue* av ) {
+     163         134 :   bool sc; av->parseFlag("SCALED_COMPONENTS",sc);
+     164         134 :   if(sc) {
+     165          45 :     av->addComponentWithDerivatives("a"); av->componentIsPeriodic("a","-0.5","+0.5");
+     166          45 :     av->addComponentWithDerivatives("b"); av->componentIsPeriodic("b","-0.5","+0.5");
+     167          45 :     av->addComponentWithDerivatives("c"); av->componentIsPeriodic("c","-0.5","+0.5");
+     168          15 :     return 1;
+     169             :   }
+     170         238 :   av->addComponentWithDerivatives("x"); av->componentIsNotPeriodic("x");
+     171         238 :   av->addComponentWithDerivatives("y"); av->componentIsNotPeriodic("y");
+     172         238 :   av->addComponentWithDerivatives("z"); av->componentIsNotPeriodic("z");
+     173         119 :   av->log<<"  WARNING: components will not have the proper periodicity - see manual\n";
+     174             :   return 0;
+     175             : }
+     176             : 
+     177             : // calculator
+     178        8078 : void Position::calculate() {
+     179             : 
+     180        8078 :   std::vector<Vector> distance(1);
+     181        8078 :   if(pbc) {
+     182       16044 :     distance[0]=pbcDistance(Vector(0.0,0.0,0.0),getPosition(0));
+     183             :   } else {
+     184          56 :     distance[0]=delta(Vector(0.0,0.0,0.0),getPosition(0));
+     185             :   }
+     186             : 
+     187        8078 :   if(scaled_components) {
+     188          56 :     calculateCV( 1, masses, charges, distance, value, derivs, virial, this );
+     189          56 :     Value* valuea=getPntrToComponent("a");
+     190          56 :     Value* valueb=getPntrToComponent("b");
+     191          56 :     Value* valuec=getPntrToComponent("c");
+     192          56 :     setAtomsDerivatives (valuea,0,derivs[0][0]);
+     193          56 :     valuea->set(value[0]);
+     194          56 :     setAtomsDerivatives (valueb,0,derivs[1][0]);
+     195          56 :     valueb->set(value[1]);
+     196          56 :     setAtomsDerivatives (valuec,0,derivs[2][0]);
+     197          56 :     valuec->set(value[2]);
+     198             :   } else {
+     199        8022 :     calculateCV( 0, masses, charges, distance, value, derivs, virial, this );
+     200        8022 :     Value* valuex=getPntrToComponent("x");
+     201        8022 :     Value* valuey=getPntrToComponent("y");
+     202        8022 :     Value* valuez=getPntrToComponent("z");
+     203             : 
+     204        8022 :     setAtomsDerivatives (valuex,0,derivs[0][0]);
+     205        8022 :     setBoxDerivatives   (valuex,virial[0]);
+     206        8022 :     valuex->set(value[0]);
+     207             : 
+     208        8022 :     setAtomsDerivatives (valuey,0,derivs[1][0]);
+     209        8022 :     setBoxDerivatives   (valuey,virial[1]);
+     210        8022 :     valuey->set(value[1]);
+     211             : 
+     212        8022 :     setAtomsDerivatives (valuez,0,derivs[2][0]);
+     213        8022 :     setBoxDerivatives   (valuez,virial[2]);
+     214        8022 :     valuez->set(value[2]);
+     215             :   }
+     216        8078 : }
+     217             : 
+     218      151422 : void Position::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     219             :                             const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     220             :                             std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     221      151422 :   if( mode==1 ) {
+     222       10841 :     Vector d=aa->getPbc().realToScaled(pos[0]);
+     223       10841 :     vals[0]=Tools::pbc(d[0]); vals[1]=Tools::pbc(d[1]); vals[2]=Tools::pbc(d[2]);
+     224       10841 :     derivs[0][0]=matmul(aa->getPbc().getInvBox(),Vector(+1,0,0));
+     225       10841 :     derivs[1][0]=matmul(aa->getPbc().getInvBox(),Vector(0,+1,0));
+     226       10841 :     derivs[2][0]=matmul(aa->getPbc().getInvBox(),Vector(0,0,+1));
+     227             :   } else {
+     228      562324 :     for(unsigned i=0; i<3; ++i) vals[i]=pos[0][i];
+     229      140581 :     derivs[0][0]=Vector(+1,0,0); derivs[1][0]=Vector(0,+1,0); derivs[2][0]=Vector(0,0,+1);
+     230      140581 :     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));
+     231             :   }
+     232      151422 : }
+     233             : 
+     234             : }
+     235             : }
+     236             : 
+     237             : 
+     238             : 
+
+
+
+ + + + +
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 000000000..56943e099 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/ProjectionOnAxis.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ProjectionOnAxis.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606395.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..52b798512 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/ProjectionOnAxis.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ProjectionOnAxis.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606395.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..4b4534813 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.gcov.html @@ -0,0 +1,246 @@ + + + + + + + LCOV - plumed test coverage - colvar/ProjectionOnAxis.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ProjectionOnAxis.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606395.2 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the projection along the axis");
+      88           3 : }
+      89             : 
+      90           1 : ProjectionOnAxis::ProjectionOnAxis(const ActionOptions&ao):
+      91             :   PLUMED_COLVAR_INIT(ao),
+      92           1 :   pbc(true)
+      93             : {
+      94             :   std::vector<AtomNumber> axis_atoms;
+      95           2 :   parseAtomList("AXIS_ATOMS",axis_atoms);
+      96           1 :   if( axis_atoms.size()!=2 ) error("There should only be two atoms specified to AXIS_ATOMS keyword");
+      97             :   std::vector<AtomNumber> atom;
+      98           2 :   parseAtomList("ATOM",atom);
+      99           1 :   if( atom.size()!=1 ) error("There should only be one atom specified to ATOM keyword");
+     100           1 :   log.printf("  calculating projection of vector connecting atom %d and atom %d on vector connecting atom %d and atom %d \n",
+     101             :              axis_atoms[0].serial(), atom[0].serial(), axis_atoms[0].serial(), axis_atoms[1].serial() );
+     102           1 :   bool nopbc=!pbc;
+     103           1 :   parseFlag("NOPBC",nopbc);
+     104           1 :   pbc=!nopbc;
+     105             : 
+     106           1 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     107           0 :   else    log.printf("  not using periodic boundary conditions\n");
+     108             : 
+     109             :   // Add values to store data
+     110           3 :   addComponentWithDerivatives("proj"); componentIsNotPeriodic("proj");
+     111           3 :   addComponentWithDerivatives("ext"); componentIsNotPeriodic("ext");
+     112             :   // Get all the atom positions
+     113           1 :   axis_atoms.push_back( atom[0] );
+     114           1 :   requestAtoms(axis_atoms);
+     115           1 :   checkRead();
+     116           1 : }
+     117             : 
+     118             : // Calculator
+     119          25 : void ProjectionOnAxis::calculate() {
+     120             : 
+     121          25 :   Vector rik, rjk;
+     122          25 :   if( pbc ) {
+     123          25 :     rik = pbcDistance( getPosition(2), getPosition(0) );
+     124          25 :     rjk = pbcDistance( getPosition(2), getPosition(1) );
+     125             :   } else {
+     126           0 :     rik = delta( getPosition(2), getPosition(0) );
+     127           0 :     rjk = delta( getPosition(2), getPosition(1) );
+     128             :   }
+     129          25 :   Vector rij = delta( rik, rjk ); double dij = rij.modulo();
+     130          25 :   Vector nij = (1.0/dij)*rij; Tensor dij_a1;
+     131             :   // Derivative of director connecting atom1 - atom2 wrt the position of atom 1
+     132          25 :   dij_a1(0,0) = ( -(nij[1]*nij[1]+nij[2]*nij[2])/dij );   // dx/dx
+     133          25 :   dij_a1(0,1) = (  nij[0]*nij[1]/dij );                   // dx/dy
+     134          25 :   dij_a1(0,2) = (  nij[0]*nij[2]/dij );                   // dx/dz
+     135          25 :   dij_a1(1,0) = (  nij[1]*nij[0]/dij );                   // dy/dx
+     136          25 :   dij_a1(1,1) = ( -(nij[0]*nij[0]+nij[2]*nij[2])/dij );   // dy/dy
+     137          25 :   dij_a1(1,2) = (  nij[1]*nij[2]/dij );
+     138          25 :   dij_a1(2,0) = (  nij[2]*nij[0]/dij );
+     139          25 :   dij_a1(2,1) = (  nij[2]*nij[1]/dij );
+     140          25 :   dij_a1(2,2) = ( -(nij[1]*nij[1]+nij[0]*nij[0])/dij );
+     141             : 
+     142             :   // Calculate dot product and derivatives
+     143          25 :   double d = dotProduct( -rik, nij );
+     144          25 :   Vector dd1 = matmul(-rik, dij_a1) - nij;
+     145          25 :   Vector dd2 = matmul(rik, dij_a1);
+     146          25 :   Vector dd3 = nij;
+     147          50 :   Value* pval=getPntrToComponent("proj"); pval->set( d );
+     148          25 :   setAtomsDerivatives( pval, 0, dd1 );
+     149          25 :   setAtomsDerivatives( pval, 1, dd2 );
+     150          25 :   setAtomsDerivatives( pval, 2, dd3 );
+     151          25 :   setBoxDerivatives( pval, -Tensor( rik, dd1 ) - Tensor( rjk, dd2 ) );
+     152             :   // Calculate derivatives of perpendicular distance from axis
+     153          25 :   double c = std::sqrt( rik.modulo2() - d*d ); double invc = (1.0/c);
+     154             :   // Calculate derivatives of the other thing
+     155          25 :   Vector der1 = invc*(rik - d*dd1);
+     156          25 :   Vector der2 = invc*(-d*dd2);
+     157          25 :   Vector der3 = invc*(-rik - d*dd3);
+     158             : 
+     159          50 :   Value* cval=getPntrToComponent("ext"); cval->set( c );
+     160          25 :   setAtomsDerivatives( cval, 0, der1 );
+     161          25 :   setAtomsDerivatives( cval, 1, der2 );
+     162          25 :   setAtomsDerivatives( cval, 2, der3 );
+     163          25 :   setBoxDerivatives( cval, -Tensor( rik, der1 ) - Tensor( rjk, der2 ) );
+     164          25 : }
+     165             : 
+     166             : }
+     167             : }
+     168             : 
+     169             : 
+     170             : 
+
+
+
+ + + + +
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 000000000..acb394b42 --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar11PropertyMap29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_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 000000000..c0780ad5c --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMap16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD6colvar11PropertyMapC1ERKNS_13ActionOptionsE11
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar11PropertyMap29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
+
+
+ + + +
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 000000000..b01ef1f92 --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions: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 "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             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(PropertyMap,"PROPERTYMAP")
+      99             : 
+     100          13 : void PropertyMap::registerKeywords(Keywords& keys) {
+     101          13 :   PathMSDBase::registerKeywords(keys);
+     102          26 :   keys.add("compulsory","PROPERTY","the property to be used in the indexing: this goes in the REMARK field of the reference");
+     103          26 :   keys.addOutputComponent("zzz","default","the minimum distance from the reference points");
+     104          13 :   ActionWithValue::useCustomisableComponents(keys);
+     105          13 : }
+     106             : 
+     107          11 : PropertyMap::PropertyMap(const ActionOptions&ao):
+     108             :   Action(ao),
+     109          11 :   PathMSDBase(ao)
+     110             : {
+     111             :   // this is the only additional keyword needed
+     112          11 :   parseVector("PROPERTY",labels);
+     113          11 :   checkRead();
+     114          11 :   log<<"  Bibliography "
+     115          22 :      <<plumed.cite("Spiwok V, Kralova B  J. Chem. Phys. 135,  224504 (2011)")
+     116          22 :      <<"\n";
+     117          11 :   if(labels.size()==0) {
+     118             :     const std::size_t buflen=500;
+     119             :     char buf[buflen];
+     120             :     std::snprintf(buf,buflen,"Need to specify PROPERTY with this action\n");
+     121           0 :     plumed_merror(buf);
+     122             :   } else {
+     123          33 :     for(unsigned i=0; i<labels.size(); i++) {
+     124          22 :       log<<" found custom propety to be found in the REMARK line: "<<labels[i].c_str()<<"\n";
+     125          44 :       addComponentWithDerivatives(labels[i]); componentIsNotPeriodic(labels[i]);
+     126             :     }
+     127             :     // add distance anyhow
+     128          22 :     addComponentWithDerivatives("zzz"); componentIsNotPeriodic("zzz");
+     129             :     //reparse the REMARK field and pick the index
+     130         473 :     for(unsigned i=0; i<pdbv.size(); i++) {
+     131             :       // now look for X=1.34555 Y=5.6677
+     132             :       std::vector<double> labelvals;
+     133        1386 :       for(unsigned j=0; j<labels.size(); j++) {
+     134         924 :         std::vector<double> val(1);
+     135         924 :         if( pdbv[i].getArgumentValue(labels[j],val) ) {labelvals.push_back(val[0]);}
+     136             :         else {
+     137             :           const std::size_t buflen=500;
+     138             :           char buf[buflen];
+     139             :           std::snprintf(buf,buflen,"PROPERTY LABEL \" %s \" NOT FOUND IN REMARK FOR FRAME %u \n",labels[j].c_str(),i);
+     140           0 :           plumed_merror(buf);
+     141             :         };
+     142             :       }
+     143         462 :       indexvec.push_back(labelvals);
+     144             :     }
+     145             :   }
+     146          11 :   requestAtoms(pdbv[0].getAtomNumbers());
+     147             : 
+     148          11 : }
+     149             : 
+     150           0 : std::string PropertyMap::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     151           0 :   return "the projection of the instanenous position in CV space on the coordinate " + cname + " that is defined in the reference file";
+     152             : }
+     153             : 
+     154             : }
+     155             : }
+     156             : 
+     157             : 
+
+
+
+ + + + +
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 000000000..154a21cc2 --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..654f31b7e --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4fdb65f6a --- /dev/null +++ b/coverage/colvar/Puckering.cpp.gcov.html @@ -0,0 +1,496 @@ + + + + + + + LCOV - plumed test coverage - colvar/Puckering.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Puckering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22822999.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..7378f692b --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:414297.6 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE81
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE163
_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 000000000..922e11fe0 --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:414297.6 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE163
_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 000000000..ee42e906f --- /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:414297.6 %
Date:2024-10-17 16:45:00Functions: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         163 : void RMSD::registerKeywords(Keywords& keys) {
+     170         163 :   Colvar::registerKeywords(keys); keys.setDisplayName("RMSD");
+     171         326 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     172         326 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+     173         326 :   keys.addFlag("SQUARED",false," This should be set if you want mean squared displacement instead of RMSD ");
+     174         163 :   keys.setValueDescription("the RMSD between the instantaneous structure and the reference structure that was input");
+     175         163 : }
+     176             : 
+     177          81 : RMSD::RMSD(const ActionOptions&ao):
+     178             :   PLUMED_COLVAR_INIT(ao),
+     179          81 :   squared(false),
+     180          81 :   nopbc(false)
+     181             : {
+     182             :   std::string reference;
+     183         163 :   parse("REFERENCE",reference);
+     184             :   std::string type;
+     185          81 :   type.assign("SIMPLE");
+     186          81 :   parse("TYPE",type);
+     187          81 :   parseFlag("SQUARED",squared);
+     188          81 :   parseFlag("NOPBC",nopbc);
+     189          81 :   checkRead();
+     190             : 
+     191         163 :   addValueWithDerivatives(); setNotPeriodic();
+     192          81 :   PDB pdb;
+     193             : 
+     194             :   // read everything in ang and transform to nm if we are not in natural units
+     195          81 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     196           0 :     error("missing input file " + reference );
+     197          81 :   myrmsd.set( pdb, type, true, true );
+     198             : 
+     199          81 :   std::vector<AtomNumber> atoms( pdb.getAtomNumbers() );
+     200          81 :   requestAtoms( atoms ); der.resize( atoms.size() );
+     201             : 
+     202          80 :   log.printf("  reference from file %s\n",reference.c_str());
+     203          80 :   log.printf("  which contains %d atoms\n",getNumberOfAtoms());
+     204          80 :   log.printf("  with indices : ");
+     205        3867 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     206        3787 :     if(i%25==0) log<<"\n";
+     207        3787 :     log.printf("%d ",atoms[i].serial());
+     208             :   }
+     209          80 :   log.printf("\n");
+     210          80 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     211          80 :   if(squared)log.printf("  chosen to use SQUARED option for MSD instead of RMSD\n");
+     212          80 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     213          19 :   else      log.printf("  using periodic boundary conditions\n");
+     214         164 : }
+     215             : 
+     216             : 
+     217             : // calculator
+     218       40516 : void RMSD::calculate() {
+     219       40516 :   if(!nopbc) makeWhole();
+     220       40516 :   double r=myrmsd.calculate( getPositions(), der, squared );
+     221             : 
+     222       40516 :   setValue(r);
+     223    14617897 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives( i, der[i] );
+     224       40516 :   setBoxDerivativesNoPbc();
+     225       40516 : }
+     226             : 
+     227             : }
+     228             : }
+     229             : 
+     230             : 
+     231             : 
+
+
+
+ + + + +
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 000000000..f620647ea --- /dev/null +++ b/coverage/colvar/RMSDShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:5353100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12RMSDShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12RMSDShortcutC1ERKNS_13ActionOptionsE104
_ZN4PLMD6colvar12RMSDShortcut16registerKeywordsERNS_8KeywordsE118
+
+
+ + + +
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 000000000..7e79e7dc8 --- /dev/null +++ b/coverage/colvar/RMSDShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:5353100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12RMSDShortcut16registerKeywordsERNS_8KeywordsE118
_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 000000000..808271229 --- /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:5353100.0 %
Date:2024-10-17 16:45:00Functions: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         118 : void RMSDShortcut::registerKeywords(Keywords& keys) {
+      40         118 :   ActionShortcut::registerKeywords( keys );
+      41         236 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV");
+      42         236 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+      43         236 :   keys.addFlag("SQUARED",false," This should be setted if you want MSD instead of RMSD ");
+      44         236 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      45         236 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
+      46         236 :   keys.addFlag("DISPLACEMENT",false,"Calculate the vector of displacements instead of the length of this vector");
+      47         236 :   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         118 :   keys.setValueDescription("the RMSD distance between the instaneous structure and the reference structure/s that were input");
+      49         236 :   keys.addActionNameSuffix("_SCALAR"); keys.addActionNameSuffix("_VECTOR");
+      50         236 :   keys.needsAction("PDB2CONSTANT"); keys.needsAction("WHOLEMOLECULES");
+      51         236 :   keys.needsAction("POSITION"); keys.needsAction("CONCATENATE");
+      52         118 : }
+      53             : 
+      54         104 : RMSDShortcut::RMSDShortcut(const ActionOptions& ao):
+      55             :   Action(ao),
+      56         104 :   ActionShortcut(ao)
+      57             : {
+      58         208 :   bool disp; parseFlag("DISPLACEMENT",disp);
+      59         106 :   std::string reference; parse("REFERENCE",reference);
+      60             :   // Read the reference pdb file
+      61         106 :   PDB pdb; if( !pdb.read(reference,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength()) ) plumed_merror("missing file " + reference );
+      62         103 :   unsigned frame; parse("NUMBER",frame); unsigned nf=1;
+      63         103 :   if( frame==0 ) {
+      64          94 :     FILE* fp=std::fopen(reference.c_str(),"r"); bool do_read=true; nf=0;
+      65         561 :     while ( do_read ) {
+      66         495 :       PDB mypdb; do_read=mypdb.readFromFilepointer(fp,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength());
+      67         495 :       if( !do_read && nf>0 ) break ;
+      68         467 :       nf++;
+      69         495 :     }
+      70             :   }
+      71         103 :   bool nopbc; parseFlag("NOPBC",nopbc);
+      72             :   // Now create the RMSD object
+      73         103 :   std::string rmsd_line = getShortcutLabel() + ": ";
+      74         103 :   if( nf==1 && !disp ) {
+      75         162 :     rmsd_line += "RMSD_SCALAR REFERENCE=" + reference; if(nopbc) rmsd_line += " NOPBC";
+      76             :   } else {
+      77          22 :     std::string ffnum; Tools::convert( frame, ffnum );
+      78          44 :     readInputLine( getShortcutLabel() + "_ref: PDB2CONSTANT REFERENCE=" + reference + " NUMBER=" + ffnum );
+      79          22 :     std::vector<AtomNumber> anum( pdb.getAtomNumbers() );
+      80          22 :     if( !nopbc ) {
+      81          20 :       std::string num; Tools::convert( anum[0].serial(), num ); std::string wm_line = "WHOLEMOLECULES ENTITY0=" + num;
+      82         196 :       for(unsigned i=1; i<anum.size(); ++i) { Tools::convert( anum[i].serial(), num ); wm_line += "," + num; }
+      83          20 :       readInputLine( wm_line );
+      84             :     }
+      85          22 :     std::string num; Tools::convert( anum[0].serial(), num ); std::string pos_line = getShortcutLabel() + "_cpos: POSITION NOPBC ATOMS=" + num;
+      86         210 :     for(unsigned i=1; i<anum.size(); ++i) { Tools::convert( anum[i].serial(), num ); pos_line += "," + num; }
+      87          22 :     readInputLine( pos_line );
+      88             :     // Concatenate the three positions together
+      89          44 :     readInputLine( getShortcutLabel() + "_pos: CONCATENATE ARG=" + getShortcutLabel() + "_cpos.x," + getShortcutLabel() + "_cpos.y," + getShortcutLabel() + "_cpos.z");
+      90          44 :     rmsd_line += "RMSD_VECTOR ARG=" + getShortcutLabel() + "_pos," + getShortcutLabel() + "_ref";
+      91          22 :     if( disp ) rmsd_line += " DISPLACEMENT";
+      92             :     // Now align
+      93          22 :     std::vector<double> align( pdb.getOccupancy() ); Tools::convert( align[0], num ); rmsd_line += " ALIGN=" + num;
+      94         210 :     for(unsigned i=1; i<align.size(); ++i) { Tools::convert( align[i], num ); rmsd_line += "," + num; }
+      95             :     // And displace
+      96          22 :     std::vector<double> displace( pdb.getBeta() ); Tools::convert( displace[0], num ); rmsd_line += " DISPLACE=" + num;
+      97         210 :     for(unsigned i=1; i<displace.size(); ++i) { Tools::convert( displace[i], num ); rmsd_line += "," + num; }
+      98             :   }
+      99             :   // And create the RMSD object
+     100         103 :   bool numder; parseFlag("NUMERICAL_DERIVATIVES",numder);
+     101         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");
+     102         207 :   bool squared; parseFlag("SQUARED",squared); if(squared) rmsd_line += " SQUARED";
+     103         310 :   std::string tt; parse("TYPE",tt); readInputLine( rmsd_line + " TYPE=" + tt );
+     104         210 : }
+     105             : 
+     106             : }
+     107             : }
+
+
+
+ + + + +
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 000000000..795241f2b --- /dev/null +++ b/coverage/colvar/RMSDVector.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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:16216697.6 %
Date:2024-10-17 16:45:00Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10RMSDVectorC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar10RMSDVectorC1ERKNS_13ActionOptionsE49
_ZN4PLMD6colvar10RMSDVector16registerKeywordsERNS_8KeywordsE81
_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 000000000..f88c08757 --- /dev/null +++ b/coverage/colvar/RMSDVector.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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:16216697.6 %
Date:2024-10-17 16:45:00Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10RMSDVector16registerKeywordsERNS_8KeywordsE81
_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 000000000..800888e16 --- /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:16216697.6 %
Date:2024-10-17 16:45:00Functions: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          81 : void RMSDVector::registerKeywords(Keywords& keys) {
+      43         162 :   ActionWithVector::registerKeywords(keys); keys.use("ARG"); keys.setDisplayName("RMSD");
+      44         162 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+      45         162 :   keys.add("compulsory","ALIGN","1.0","the weights to use when aligning to the reference structure");
+      46         162 :   keys.add("compulsory","DISPLACE","1.0","the weights to use when calculating the displacement from the reference structure");
+      47         162 :   keys.addFlag("SQUARED",false," This should be set if you want mean squared displacement instead of RMSD ");
+      48         162 :   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         162 :   keys.addFlag("DISPLACEMENT",false,"Calculate the vector of displacements instead of the length of this vector");
+      50         162 :   keys.addOutputComponent("disp","DISPLACEMENT","the vector of displacements for the atoms");
+      51         162 :   keys.addOutputComponent("dist","DISPLACEMENT","the RMSD distance the atoms have moved");
+      52          81 :   keys.setValueDescription("a vector containing the RMSD between the instantaneous structure and each of the reference structures that were input");
+      53          81 : }
+      54             : 
+      55          49 : RMSDVector::RMSDVector(const ActionOptions&ao):
+      56             :   Action(ao),
+      57             :   ActionWithVector(ao),
+      58          49 :   firststep(true)
+      59             : {
+      60          49 :   if( getPntrToArgument(0)->getRank()!=1 ) error("first argument should be vector");
+      61          49 :   if( getPntrToArgument(1)->getRank()<1 ) error("second argument should be matrix or a vector");
+      62          49 :   if( getPntrToArgument(1)->getRank()==1 ) {
+      63           7 :     if( getPntrToArgument(0)->getNumberOfValues()!=getPntrToArgument(1)->getNumberOfValues() ) error("mismatch between sizes of input vectors");
+      64          42 :   } else if( getPntrToArgument(1)->getRank()==2 ) {
+      65          42 :     if( getPntrToArgument(0)->getNumberOfValues()!=getPntrToArgument(1)->getShape()[1] ) error("mismatch between sizes of input vectors");
+      66             :   }
+      67          49 :   if( getPntrToArgument(0)->getNumberOfValues()%3!=0 ) error("number of components in input arguments should be multiple of three");
+      68             : 
+      69          49 :   unsigned natoms = getPntrToArgument(0)->getNumberOfValues() / 3;
+      70          98 :   type.assign("SIMPLE"); parse("TYPE",type); parseFlag("SQUARED",squared);
+      71          49 :   align.resize( natoms ); parseVector("ALIGN",align);
+      72          49 :   displace.resize( natoms ); parseVector("DISPLACE",displace);
+      73          98 :   bool unorm=false; parseFlag("UNORMALIZED",unorm); norm_weights=!unorm;
+      74          49 :   double wa=0, wd=0; sqrtdisplace.resize( displace.size() );
+      75         630 :   for(unsigned i=0; i<align.size(); ++i) { wa+=align[i]; wd+=displace[i]; }
+      76             : 
+      77          49 :   if( wa>epsilon ) {
+      78          49 :     double iwa = 1. / wa;
+      79         630 :     for(unsigned i=0; i<align.size(); ++i) align[i] *= iwa;
+      80             :   } else {
+      81           0 :     double iwa = 1. / natoms;
+      82           0 :     for(unsigned i=0; i<align.size(); ++i) align[i] = iwa;
+      83             :   }
+      84          49 :   if( wd>epsilon ) {
+      85          49 :     if( !norm_weights ) { wd = 1; } double iwd = 1. / wd;
+      86         630 :     for(unsigned i=0; i<align.size(); ++i) displace[i] *= iwd;
+      87             :   } else {
+      88           0 :     double iwd = 1. / natoms;
+      89           0 :     for(unsigned i=0; i<align.size(); ++i) displace[i] = iwd;
+      90             :   }
+      91         630 :   for(unsigned i=0; i<align.size(); ++i) sqrtdisplace[i] = sqrt(displace[i]);
+      92             : 
+      93          49 :   parseFlag("DISPLACEMENT",displacement);
+      94          49 :   if( displacement && (getPntrToArgument(1)->getRank()==1 || getPntrToArgument(1)->getShape()[0]<=1) ) {
+      95          78 :     addComponentWithDerivatives("dist"); componentIsNotPeriodic("dist");
+      96          26 :     std::vector<unsigned> shape( 1, getPntrToArgument(0)->getNumberOfValues() );
+      97          78 :     addComponent( "disp", shape ); getPntrToComponent(1)->buildDataStore(); componentIsNotPeriodic("disp");
+      98          23 :   } else if( displacement ) {
+      99           2 :     std::vector<unsigned> shape( 1, getPntrToArgument(1)->getShape()[0] );
+     100           4 :     addComponent( "dist", shape ); getPntrToComponent(0)->buildDataStore();
+     101           2 :     componentIsNotPeriodic("dist");
+     102           2 :     shape.resize(2); shape[0] = getPntrToArgument(1)->getShape()[0]; shape[1] = getPntrToArgument(0)->getNumberOfValues();
+     103           4 :     addComponent( "disp", shape ); getPntrToComponent(1)->buildDataStore(); getPntrToComponent(1)->reshapeMatrixStore( shape[1] );
+     104           4 :     componentIsNotPeriodic("disp");
+     105          21 :   } else if( (getPntrToArgument(1)->getRank()==1 || getPntrToArgument(1)->getShape()[0]==1) ) {
+     106          26 :     addValue(); setNotPeriodic();
+     107             :   } else {
+     108           8 :     std::vector<unsigned> shape( 1, getPntrToArgument(1)->getShape()[0] );
+     109           8 :     addValue( shape ); setNotPeriodic();
+     110             :   }
+     111          49 :   if( getPntrToArgument(1)->getRank()==1 || getPntrToArgument(1)->getNumberOfValues()==0 ) myrmsd.resize(1);
+     112          42 :   else myrmsd.resize( getPntrToArgument(1)->getShape()[0] );
+     113             : 
+     114          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",
+     115             :         natoms, getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str() );
+     116          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",
+     117             :                     getPntrToArgument(1)->getShape()[0], natoms, getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str() );
+     118          49 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     119          49 :   if(squared)log.printf("  chosen to use SQUARED option for MSD instead of RMSD\n");
+     120          21 :   else      log.printf("  using periodic boundary conditions\n");
+     121          49 : }
+     122             : 
+     123         804 : unsigned RMSDVector::getNumberOfDerivatives() {
+     124         804 :   return getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();
+     125             : }
+     126             : 
+     127       10631 : void RMSDVector::setReferenceConfigurations() {
+     128       10631 :   unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     129       10631 :   Vector center; std::vector<Vector> pos( natoms );
+     130       22578 :   for(unsigned jconf=0; jconf<myrmsd.size(); ++jconf) {
+     131       11947 :     center.zero();
+     132      172431 :     for(unsigned i=0; i<pos.size(); ++i) {
+     133      641936 :       for(unsigned j=0; j<3; ++j) pos[i][j] = getPntrToArgument(1)->get( (3*jconf+j)*pos.size() + i );
+     134      160484 :       center+=pos[i]*align[i];
+     135             :     }
+     136      172431 :     for(unsigned i=0; i<pos.size(); ++i) pos[i] -= center;
+     137       11947 :     myrmsd[jconf].clear(); myrmsd[jconf].set(align,displace,pos,type,true,norm_weights);
+     138             :   }
+     139       10631 : }
+     140             : 
+     141      192996 : double RMSDVector::calculateRMSD( const unsigned& current, std::vector<Vector>& pos, std::vector<Vector>& der, std::vector<Vector>& direction ) const {
+     142      192996 :   unsigned natoms = pos.size();
+     143     2704147 :   for(unsigned i=0; i<natoms; ++i) {
+     144    10044604 :     for(unsigned j=0; j<3; ++j) pos[i][j] = getPntrToArgument(0)->get( j*natoms + i );
+     145             :   }
+     146             : 
+     147      192996 :   if( displacement && type=="SIMPLE" ) {
+     148         646 :     const Value* myval = getConstPntrToComponent(1);
+     149         646 :     double r = myrmsd[current].simpleAlignment( align, displace, pos, myrmsd[current].getReference(), der, direction, squared );
+     150         646 :     if( !doNotCalculateDerivatives() && myval->forcesWereAdded() ) {
+     151          33 :       Vector comforce; comforce.zero();
+     152         187 :       for(unsigned i=0; i<natoms; i++) {
+     153         616 :         for(unsigned k=0; k<3; ++k) comforce[k] += align[i]*myval->getForce( (3*current+k)*natoms + i);
+     154             :       }
+     155         187 :       for(unsigned i=0; i<natoms; i++) {
+     156         616 :         for(unsigned k=0; k<3; ++k) direction[i][k] = myval->getForce( (3*current+k)*natoms + i ) - comforce[k];
+     157             :       }
+     158             :     }
+     159         646 :     return r;
+     160      192350 :   } else if( displacement ) {
+     161       55589 :     const Value* myval = getConstPntrToComponent(1);
+     162      111178 :     Tensor rot; Matrix<std::vector<Vector> > DRotDPos(3,3); std::vector<Vector> centeredpos( natoms ), centeredreference( natoms );
+     163       55589 :     double r = myrmsd[current].calc_PCAelements( pos, der, rot, DRotDPos, direction, centeredpos, centeredreference, squared ); std::vector<Vector> ref( myrmsd[current].getReference() );
+     164       55589 :     if( !doNotCalculateDerivatives() && myval->forcesWereAdded() ) {
+     165        1671 :       Tensor trot=rot.transpose(); double prefactor = 1 / static_cast<double>( natoms ); Vector v1; v1.zero();
+     166       22573 :       for(unsigned n=0; n<natoms; n++) {
+     167       83608 :         Vector ff; for(unsigned k=0; k<3; ++k ) ff[k] = myval->getForce( (3*current+k)*natoms + n );
+     168       20902 :         v1+=prefactor*matmul(trot,ff);
+     169             :       }
+     170             :       // Notice that we use centreredreference here to accumulate the true forces
+     171       22573 :       for(unsigned n=0; n<natoms; n++) {
+     172       83608 :         Vector ff; for(unsigned k=0; k<3; ++k ) ff[k] = myval->getForce( (3*current+k)*natoms + n );
+     173       20902 :         centeredreference[n] = sqrtdisplace[n]*( matmul(trot,ff) - v1 );
+     174             :       }
+     175        6684 :       for(unsigned a=0; a<3; a++) {
+     176       20052 :         for(unsigned b=0; b<3; b++) {
+     177      203157 :           double tmp1=0.; for(unsigned m=0; m<natoms; m++) tmp1+=centeredpos[m][b]*myval->getForce( (3*current+a)*natoms + m );
+     178      203157 :           for(unsigned i=0; i<natoms; i++) centeredreference[i] += sqrtdisplace[i]*tmp1*DRotDPos[a][b][i];
+     179             :         }
+     180             :       }
+     181             :       // Now subtract the current force and add on the true force
+     182       22573 :       for(unsigned n=0; n<natoms; n++) {
+     183       83608 :         for(unsigned k=0; k<3; ++k) direction[n][k] = centeredreference[n][k];
+     184             :       }
+     185             :     } else {
+     186      759226 :       for(unsigned i=0; i<direction.size(); ++i) direction[i] = sqrtdisplace[i]*( direction[i] - ref[i] );
+     187             :     }
+     188             :     return r;
+     189             :   }
+     190      136761 :   return myrmsd[current].calculate( pos, der, squared );
+     191             : }
+     192             : 
+     193             : // calculator
+     194       17182 : void RMSDVector::calculate() {
+     195       17182 :   if( firststep || !getPntrToArgument(1)->isConstant() ) { setReferenceConfigurations(); firststep=false; }
+     196             : 
+     197       17182 :   if( getPntrToComponent(0)->getRank()==0 ) {
+     198       11796 :     unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     199       11796 :     std::vector<Vector> pos( natoms ), der( natoms ), direction( natoms );
+     200       11796 :     double r = calculateRMSD( 0, pos, der, direction );
+     201             : 
+     202       11796 :     getPntrToComponent(0)->set( r );
+     203       11796 :     if( getNumberOfComponents()==2 ) {
+     204       11775 :       Value* mydisp = getPntrToComponent(1);
+     205      168204 :       for(unsigned i=0; i<natoms; i++) {
+     206      625716 :         for(unsigned j=0; j<3; ++j ) mydisp->set( j*natoms+i, direction[i][j] );
+     207             :       }
+     208             :     }
+     209       11796 :     if( doNotCalculateDerivatives() ) return;
+     210             : 
+     211         612 :     Value* myval = getPntrToComponent(0);
+     212        7472 :     for(unsigned i=0; i<natoms; i++) {
+     213       27440 :       for(unsigned j=0; j<3; ++j ) myval->setDerivative( j*natoms+i, der[i][j] );
+     214             :     }
+     215        5386 :   } else runAllTasks();
+     216             : }
+     217             : 
+     218      160524 : bool RMSDVector::checkForTaskForce( const unsigned& itask, const Value* myval ) const {
+     219      160524 :   if( myval->getRank()<2 ) return ActionWithVector::checkForTaskForce( itask, myval );
+     220       22932 :   unsigned nelements = myval->getShape()[1], startr = itask*nelements;
+     221      874692 :   for(unsigned j=0; j<nelements; ++j ) {
+     222      852852 :     if( fabs( myval->getForce( startr + j ) )>epsilon ) return true;
+     223             :   }
+     224             :   return false;
+     225             : }
+     226             : 
+     227       17162 : void RMSDVector::apply() {
+     228       17162 :   if( doNotCalculateDerivatives() ) return;
+     229             : 
+     230        4980 :   if( getPntrToComponent(0)->getRank()==0 ) {
+     231         612 :     std::vector<double> forces( getNumberOfDerivatives(), 0 );
+     232         612 :     bool wasforced = getPntrToComponent(0)->applyForce( forces );
+     233             : 
+     234         612 :     if( getNumberOfComponents()==2 && getPntrToComponent(1)->forcesWereAdded() ) {
+     235         612 :       unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     236         612 :       std::vector<Vector> pos( natoms ), der( natoms ), direction( natoms );
+     237         612 :       double r = calculateRMSD( 0, pos, der, direction );
+     238        7472 :       for(unsigned i=0; i<natoms; ++i) {
+     239       27440 :         for(unsigned j=0; j<3; ++j ) forces[j*natoms+i] += direction[i][j];
+     240             :       }
+     241             :       wasforced=true;
+     242             :     }
+     243         612 :     if( wasforced ) { unsigned ss=0; addForcesOnArguments( 0, forces, ss, getLabel() ); }
+     244        4368 :   } else ActionWithVector::apply();
+     245             : }
+     246             : 
+     247      180588 : void RMSDVector::performTask( const unsigned& current, MultiValue& myvals ) const {
+     248      180588 :   unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     249             :   std::vector<Vector>& pos( myvals.getFirstAtomVector() );
+     250             :   std::vector<std::vector<Vector> > & allder( myvals.getFirstAtomDerivativeVector() );
+     251      180588 :   if( allder.size()!=2 ) allder.resize(2);
+     252             :   std::vector<Vector>& der( allder[0] ); std::vector<Vector>& direction( allder[1] );
+     253      180588 :   if( pos.size()!=natoms ) { pos.resize( natoms ); der.resize( natoms ); direction.resize( natoms ); }
+     254     2528232 :   for(unsigned i=0; i<pos.size(); ++i) {
+     255     9390576 :     for(unsigned j=0; j<3; ++j) pos[i][j] = getPntrToArgument(0)->get( j*natoms + i );
+     256             :   }
+     257      180588 :   double r = calculateRMSD( current, pos, der, direction );
+     258      180588 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+     259      180588 :   myvals.setValue( ostrn, r );
+     260             : 
+     261      180588 :   if( doNotCalculateDerivatives() ) return;
+     262             : 
+     263     1929648 :   for(unsigned i=0; i<natoms; i++) {
+     264     7167264 :     for(unsigned j=0; j<3; ++j ) { myvals.addDerivative( ostrn, j*natoms+i, der[i][j] ); myvals.updateIndex( ostrn, j*natoms+i ); }
+     265             :   }
+     266             : }
+     267             : 
+     268      202902 : void RMSDVector::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     269             :                                     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     270      202902 :   if( getConstPntrToComponent(valindex)->getRank()==1 ) { ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer ); return; }
+     271             :   const std::vector<Vector>& direction( myvals.getConstFirstAtomDerivativeVector()[1] );
+     272       42756 :   unsigned natoms = direction.size(); unsigned vindex = bufstart + 3*code*natoms;
+     273      598584 :   for(unsigned i=0; i<natoms; ++i) {
+     274     2223312 :     for(unsigned j=0; j<3; ++j ) buffer[vindex + j*natoms + i] += direction[i][j];
+     275             :   }
+     276             : }
+     277             : 
+     278       20442 : void RMSDVector::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     279       20442 :   if( myval->getRank()==1 ) { ActionWithVector::gatherForcesOnStoredValue( myval, itask, myvals, forces ); return; }
+     280        1092 :   const std::vector<Vector>& direction( myvals.getConstFirstAtomDerivativeVector()[1] ); unsigned natoms = direction.size();
+     281       15288 :   for(unsigned i=0; i<natoms; ++i) {
+     282       56784 :     for(unsigned j=0; j<3; ++j ) forces[j*natoms+i] += direction[i][j];
+     283             :   }
+     284             : }
+     285             : 
+     286             : 
+     287             : }
+     288             : }
+     289             : 
+     290             : 
+     291             : 
+
+
+
+ + + + +
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 000000000..3638833da --- /dev/null +++ b/coverage/colvar/SelectMassCharge.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:233860.5 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE84
_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 000000000..9eb1ae16e --- /dev/null +++ b/coverage/colvar/SelectMassCharge.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:233860.5 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE84
_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 000000000..24676f8f6 --- /dev/null +++ b/coverage/colvar/SelectMassCharge.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + 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:233860.5 %
Date:2024-10-17 16:45:00Functions: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          84 : void SelectMassCharge::registerKeywords( Keywords& keys ) {
+     108          84 :   Colvar::registerKeywords( keys );
+     109         168 :   keys.add("atoms","ATOM","the atom number");
+     110         168 :   keys.add("atoms","ATOMS","the atom numbers that you would like to store the masses and charges of");
+     111         168 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     112          84 :   std::string acname = keys.getDisplayName(); std::size_t und = acname.find("_SCALAR");
+     113          84 :   if( und==std::string::npos ) und = acname.find("_VECTOR");
+     114         252 :   keys.setDisplayName( acname.substr(0,und) ); keys.setValueDescription("the " + keys.getDisplayName() + " of the atom");
+     115          84 : }
+     116             : 
+     117           0 : SelectMassCharge::SelectMassCharge(const ActionOptions&ao):
+     118           0 :   PLUMED_COLVAR_INIT(ao)
+     119             : {
+     120           0 :   std::vector<AtomNumber> atoms; parseAtomList(-1,atoms,this);
+     121           0 :   unsigned mode=getModeAndSetupValues(this);
+     122           0 :   requestAtoms(atoms);
+     123           0 : }
+     124             : 
+     125           0 : void SelectMassCharge::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     126           0 :   aa->parseAtomList("ATOM",num,t);
+     127           0 :   if( t.size()==1 ) aa->log.printf("  for atom %d\n",t[0].serial());
+     128           0 :   else if( num<0 || t.size()!=0 ) aa->error("Number of specified atoms should be 1");
+     129           0 : }
+     130             : 
+     131          18 : unsigned SelectMassCharge::getModeAndSetupValues( ActionWithValue* av ) {
+     132          36 :   av->addValueWithDerivatives(); av->setNotPeriodic(); bool constant=true;
+     133          18 :   ActionAtomistic* aa=dynamic_cast<ActionAtomistic*>( av ); plumed_assert( aa );
+     134        5162 :   for(unsigned i=0; i<aa->getNumberOfAtoms(); ++i) {
+     135        5144 :     std::pair<std::size_t,std::size_t> p = aa->getValueIndices( aa->getAbsoluteIndex(i) );
+     136        5144 :     if( av->getName().find("MASS")!=std::string::npos && !aa->masv[p.first]->isConstant() ) constant=false;
+     137        5144 :     if( av->getName().find("CHARGE")!=std::string::npos && !aa->chargev[p.first]->isConstant() ) constant=false;
+     138             :   }
+     139          18 :   if( !constant ) av->error("cannot deal with non-constant " + av->getName() + " values");
+     140          18 :   (av->copyOutput(0))->setConstant();
+     141          18 :   return 0;
+     142             : }
+     143             : 
+     144             : // calculator
+     145           0 : void SelectMassCharge::calculate() {
+     146           0 :   std::vector<double> masses(1), charges(1), vals(1);
+     147             :   std::vector<Vector> pos; std::vector<std::vector<Vector> > derivs; std::vector<Tensor> virial;
+     148           0 :   calculateCV( 0, masses, charges, pos, vals, derivs, virial, this ); setValue( vals[0] );
+     149           0 : }
+     150             : 
+     151        5144 : void SelectMassCharge::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     152             :                                     const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     153             :                                     std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     154        5144 :   if( aa->getName().find("MASSES")!=std::string::npos ) vals[0]=masses[0];
+     155        5144 :   else if( aa->chargesWereSet ) vals[0]=charges[0];
+     156        5144 : }
+     157             : 
+     158             : }
+     159             : }
+     160             : 
+     161             : 
+     162             : 
+
+
+
+ + + + +
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 000000000..45e867e46 --- /dev/null +++ b/coverage/colvar/Template.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/Template.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Template.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:83522.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..6501b12eb --- /dev/null +++ b/coverage/colvar/Template.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/Template.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Template.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:83522.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..78ef6ecf1 --- /dev/null +++ b/coverage/colvar/Template.cpp.gcov.html @@ -0,0 +1,191 @@ + + + + + + + LCOV - plumed test coverage - colvar/Template.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Template.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:83522.9 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("a description of the value that is computed by this colvar should be included here");
+      68           2 : }
+      69             : 
+      70           0 : Template::Template(const ActionOptions&ao):
+      71             :   PLUMED_COLVAR_INIT(ao),
+      72           0 :   pbc(true)
+      73             : {
+      74             :   std::vector<AtomNumber> atoms;
+      75           0 :   parseAtomList("ATOMS",atoms);
+      76           0 :   if(atoms.size()!=2)
+      77           0 :     error("Number of specified atoms should be 2");
+      78           0 :   bool nopbc=!pbc;
+      79           0 :   parseFlag("NOPBC",nopbc);
+      80           0 :   pbc=!nopbc;
+      81           0 :   checkRead();
+      82             : 
+      83           0 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+      84           0 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+      85           0 :   else    log.printf("  without periodic boundary conditions\n");
+      86             : 
+      87           0 :   addValueWithDerivatives(); setNotPeriodic();
+      88             : 
+      89           0 :   requestAtoms(atoms);
+      90           0 : }
+      91             : 
+      92             : 
+      93             : // calculator
+      94           0 : void Template::calculate() {
+      95             : 
+      96           0 :   Vector distance;
+      97           0 :   if(pbc) {
+      98           0 :     distance=pbcDistance(getPosition(0),getPosition(1));
+      99             :   } else {
+     100           0 :     distance=delta(getPosition(0),getPosition(1));
+     101             :   }
+     102           0 :   const double value=distance.modulo();
+     103           0 :   const double invvalue=1.0/value;
+     104             : 
+     105           0 :   setAtomsDerivatives(0,-invvalue*distance);
+     106           0 :   setAtomsDerivatives(1,invvalue*distance);
+     107           0 :   setBoxDerivatives  (-invvalue*Tensor(distance,distance));
+     108           0 :   setValue           (value);
+     109           0 : }
+     110             : 
+     111             : }
+     112             : }
+     113             : 
+     114             : 
+     115             : 
+
+
+
+ + + + +
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 000000000..ad1dfdf8f --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10010298.0 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE671
_ZN4PLMD6colvar7Torsion21getModeAndSetupValuesEPNS_15ActionWithValueE684
_ZN4PLMD6colvar7Torsion13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE774
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE2070
_ZN4PLMD6colvar7Torsion9calculateEv35723
_ZN4PLMD6colvar7Torsion11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE36502
+
+
+ + + +
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 000000000..aa37bcfef --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - colvar/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10010298.0 %
Date:2024-10-17 16:45:00Functions: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_15ActionAtomisticE36502
_ZN4PLMD6colvar7Torsion13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE774
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE2070
_ZN4PLMD6colvar7Torsion21getModeAndSetupValuesEPNS_15ActionWithValueE684
_ZN4PLMD6colvar7Torsion9calculateEv35723
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE671
_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 000000000..e36681cb4 --- /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:10010298.0 %
Date:2024-10-17 16:45:00Functions: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        2070 : void Torsion::registerKeywords(Keywords& keys) {
+     135        2070 :   Colvar::registerKeywords( keys ); keys.setDisplayName("TORSION");
+     136        4140 :   keys.add("atoms-1","ATOMS","the four atoms involved in the torsional angle");
+     137        4140 :   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        4140 :   keys.add("atoms-2","VECTORA","two atoms that define a vector.  You can use this in combination with VECTOR2 and AXIS");
+     139        4140 :   keys.add("atoms-2","VECTORB","two atoms that define a vector.  You can use this in combination with VECTOR1 and AXIS");
+     140        4140 :   keys.add("atoms-3","VECTOR1","two atoms that define a vector.  You can use this in combination with VECTOR2 and AXIS");
+     141        4140 :   keys.add("atoms-3","VECTOR2","two atoms that define a vector.  You can use this in combination with VECTOR1 and AXIS");
+     142        4140 :   keys.addFlag("COSINE",false,"calculate cosine instead of dihedral");
+     143        4140 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     144        2070 :   keys.setValueDescription("the TORSION involving these atoms");
+     145        2070 : }
+     146             : 
+     147         671 : Torsion::Torsion(const ActionOptions&ao):
+     148             :   PLUMED_COLVAR_INIT(ao),
+     149         671 :   pbc(true),
+     150         671 :   do_cosine(false),
+     151         671 :   value(1),
+     152         673 :   derivs(1),
+     153        1342 :   virial(1)
+     154             : {
+     155         671 :   derivs[0].resize(6); std::vector<AtomNumber> atoms;
+     156        1342 :   std::vector<AtomNumber> v1; ActionAtomistic::parseAtomList("VECTOR1",v1);
+     157         671 :   if( v1.size()>0 ) {
+     158           4 :     std::vector<AtomNumber> v2; ActionAtomistic::parseAtomList("VECTOR2",v2);
+     159           4 :     std::vector<AtomNumber> axis; ActionAtomistic::parseAtomList("AXIS",axis);
+     160           2 :     if( !(v1.size()==2 && v2.size()==2 && axis.size()==2)) error("VECTOR1, VECTOR2 and AXIS should specify 2 atoms each");
+     161           2 :     atoms.resize(6);
+     162           2 :     atoms[0]=v1[1];
+     163           2 :     atoms[1]=v1[0];
+     164           2 :     atoms[2]=axis[0];
+     165           2 :     atoms[3]=axis[1];
+     166           2 :     atoms[4]=v2[0];
+     167           2 :     atoms[5]=v2[1];
+     168           2 :     log.printf("  between lines %d-%d and %d-%d, projected on the plane orthogonal to line %d-%d\n",
+     169             :                v1[0].serial(),v1[1].serial(),v2[0].serial(),v2[1].serial(),axis[0].serial(),axis[1].serial());
+     170         669 :   } else parseAtomList(-1,atoms,this);
+     171         670 :   unsigned mode=getModeAndSetupValues(this);
+     172         670 :   if( mode==1 ) do_cosine=true;
+     173             : 
+     174         670 :   bool nopbc=!pbc;
+     175         672 :   parseFlag("NOPBC",nopbc);
+     176         670 :   pbc=!nopbc;
+     177         670 :   checkRead();
+     178             : 
+     179         669 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     180         112 :   else    log.printf("  without periodic boundary conditions\n");
+     181         669 :   requestAtoms(atoms);
+     182         675 : }
+     183             : 
+     184         774 : void Torsion::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     185             :   std::vector<AtomNumber> v1,v2,axis;
+     186         774 :   aa->parseAtomList("ATOMS",num,t);
+     187         774 :   aa->parseAtomList("VECTORA",num,v1);
+     188         774 :   aa->parseAtomList("VECTORB",num,v2);
+     189        1548 :   aa->parseAtomList("AXIS",num,axis);
+     190             : 
+     191         774 :   if(t.size()==4) {
+     192         727 :     if(!(v1.empty() && v2.empty() && axis.empty()))
+     193           0 :       aa->error("ATOMS keyword is not compatible with VECTORA, VECTORB and AXIS keywords");
+     194         727 :     aa->log.printf("  between atoms %d %d %d %d\n",t[0].serial(),t[1].serial(),t[2].serial(),t[3].serial());
+     195         727 :     t.resize(6);
+     196         727 :     t[5]=t[3];
+     197         727 :     t[4]=t[2];
+     198         727 :     t[3]=t[2];
+     199         727 :     t[2]=t[1];
+     200          47 :   } else if(t.empty()) {
+     201          46 :     if( num>0 && v1.empty() && v2.empty() && axis.empty() ) return;
+     202          32 :     if(!(v1.size()==2 && v2.size()==2 && axis.size()==2))
+     203           0 :       aa->error("VECTORA, VECTORB and AXIS should specify 2 atoms each");
+     204          32 :     aa->log.printf("  between lines %d-%d and %d-%d, projected on the plane orthogonal to line %d-%d\n",
+     205             :                    v1[0].serial(),v1[1].serial(),v2[0].serial(),v2[1].serial(),axis[0].serial(),axis[1].serial());
+     206          32 :     t.resize(6);
+     207          32 :     t[0]=v1[1];
+     208          32 :     t[1]=v1[0];
+     209          32 :     t[2]=axis[0];
+     210          32 :     t[3]=axis[1];
+     211          32 :     t[4]=v2[0];
+     212          32 :     t[5]=v2[1];
+     213           2 :   } else if( t.size()!=4 ) aa->error("ATOMS should specify 4 atoms");
+     214             : }
+     215             : 
+     216         684 : unsigned Torsion::getModeAndSetupValues( ActionWithValue* av ) {
+     217         684 :   bool do_cos; av->parseFlag("COSINE",do_cos);
+     218         684 :   if(do_cos) av->log.printf("  calculating cosine instead of torsion\n");
+     219             : 
+     220         684 :   av->addValueWithDerivatives();
+     221        1364 :   if(!do_cos) { av->setPeriodic("-pi","pi"); return 0; }
+     222           4 :   av->setNotPeriodic(); return 1;
+     223             : }
+     224             : 
+     225             : // calculator
+     226       35723 : void Torsion::calculate() {
+     227       35723 :   if(pbc) makeWhole();
+     228       35723 :   if(do_cosine) calculateCV( 1, masses, charges, getPositions(), value, derivs, virial, this );
+     229       35708 :   else calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     230      250061 :   for(unsigned i=0; i<6; ++i) setAtomsDerivatives(i,derivs[0][i] );
+     231       35723 :   setValue(value[0]); setBoxDerivatives( virial[0] );
+     232       35723 : }
+     233             : 
+     234       36502 : void Torsion::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     235             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     236             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     237       36502 :   Vector d0=delta(pos[1],pos[0]);
+     238       36502 :   Vector d1=delta(pos[3],pos[2]);
+     239       36502 :   Vector d2=delta(pos[5],pos[4]);
+     240       36502 :   Vector dd0,dd1,dd2;
+     241             :   PLMD::Torsion t;
+     242       36502 :   vals[0] = t.compute(d0,d1,d2,dd0,dd1,dd2);
+     243       36502 :   if(mode==1) {
+     244          30 :     dd0 *= -std::sin(vals[0]);
+     245          30 :     dd1 *= -std::sin(vals[0]);
+     246          30 :     dd2 *= -std::sin(vals[0]);
+     247          30 :     vals[0] = std::cos(vals[0]);
+     248             :   }
+     249       36502 :   derivs[0][0] = dd0;
+     250       36502 :   derivs[0][1] = -dd0;
+     251       36502 :   derivs[0][2] = dd1;
+     252       36502 :   derivs[0][3] = -dd1;
+     253       36502 :   derivs[0][4] = dd2;
+     254       36502 :   derivs[0][5] = -dd2;
+     255       36502 :   setBoxDerivativesNoPbc( pos, derivs, virial );
+     256       36502 : }
+     257             : 
+     258             : }
+     259             : }
+     260             : 
+     261             : 
+     262             : 
+
+
+
+ + + + +
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 000000000..2a35bf7a8 --- /dev/null +++ b/coverage/colvar/Volume.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE15
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE20
_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 000000000..6a65ff9b2 --- /dev/null +++ b/coverage/colvar/Volume.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE20
_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 000000000..75d1bd48f --- /dev/null +++ b/coverage/colvar/Volume.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-10-17 16:45:00Functions: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          20 : void Volume::registerKeywords( Keywords& keys ) {
+      67          20 :   Action::registerKeywords( keys );
+      68          20 :   ActionWithValue::registerKeywords( keys );
+      69          20 :   ActionAtomistic::registerKeywords( keys );
+      70          20 :   keys.setValueDescription("the volume of simulation box");
+      71          20 : }
+      72             : 
+      73             : 
+      74             : // calculator
+      75         163 : void Volume::calculate() {
+      76             : 
+      77         163 :   double v=getBox().determinant();
+      78         163 :   setBoxDerivatives(-v*Tensor::identity());
+      79         163 :   setValue         (v);
+      80         163 : }
+      81             : 
+      82             : }
+      83             : }
+      84             : 
+      85             : 
+      86             : 
+
+
+
+ + + + +
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 000000000..09fca2271 --- /dev/null +++ b/coverage/colvar/index-sort-f.html @@ -0,0 +1,463 @@ + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2722296891.7 %
Date:2024-10-17 16:45:00Functions:21627578.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Template.cpp +
22.9%22.9%
+
22.9 %8 / 3525.0 %1 / 4
Fake.cpp +
78.9%78.9%
+
78.9 %30 / 3840.0 %2 / 5
SelectMassCharge.cpp +
60.5%60.5%
+
60.5 %23 / 3842.9 %3 / 7
PropertyMap.cpp +
86.2%86.2%
+
86.2 %25 / 2950.0 %2 / 4
DihedralCorrelation.cpp +
67.7%67.7%
+
67.7 %44 / 6557.1 %4 / 7
Plane.cpp +
65.7%65.7%
+
65.7 %46 / 7057.1 %4 / 7
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %92 / 9362.5 %5 / 8
ExtraCV.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
GyrationShortcut.cpp +
55.4%55.4%
+
55.4 %51 / 9266.7 %2 / 3
DRMSD.cpp +
97.0%97.0%
+
97.0 %98 / 10166.7 %2 / 3
MultiRMSD.cpp +
91.1%91.1%
+
91.1 %51 / 5666.7 %2 / 3
RMSDShortcut.cpp +
100.0%
+
100.0 %53 / 5366.7 %2 / 3
PathMSD.cpp +
100.0%
+
100.0 %19 / 1966.7 %2 / 3
ERMSD.cpp +
98.1%98.1%
+
98.1 %51 / 5275.0 %3 / 4
GHBFIX.cpp +
100.0%
+
100.0 %77 / 7775.0 %3 / 4
Coordination.cpp +
100.0%
+
100.0 %30 / 3075.0 %3 / 4
RMSD.cpp +
97.6%97.6%
+
97.6 %41 / 4275.0 %3 / 4
DHEnergy.cpp +
94.1%94.1%
+
94.1 %32 / 3475.0 %3 / 4
Gyration.cpp +
77.7%77.7%
+
77.7 %143 / 18475.0 %3 / 4
Volume.cpp +
100.0%
+
100.0 %17 / 1775.0 %3 / 4
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %60 / 6375.0 %3 / 4
Cell.cpp +
100.0%
+
100.0 %34 / 3475.0 %3 / 4
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
Dimer.cpp +
92.2%92.2%
+
92.2 %83 / 9080.0 %4 / 5
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
Torsion.cpp +
98.0%98.0%
+
98.0 %100 / 10285.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %120 / 12085.7 %6 / 7
Dipole.cpp +
98.8%98.8%
+
98.8 %84 / 8585.7 %6 / 7
Angle.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
Position.cpp +
100.0%
+
100.0 %89 / 8985.7 %6 / 7
EEFSolv.cpp +
94.3%94.3%
+
94.3 %230 / 24487.5 %7 / 8
MultiColvarTemplate.h +
97.9%97.9%
+
97.9 %92 / 9490.3 %65 / 72
RMSDVector.cpp +
97.6%97.6%
+
97.6 %162 / 16691.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 000000000..3c3810d98 --- /dev/null +++ b/coverage/colvar/index-sort-l.html @@ -0,0 +1,463 @@ + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2722296891.7 %
Date:2024-10-17 16:45:00Functions:21627578.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Template.cpp +
22.9%22.9%
+
22.9 %8 / 3525.0 %1 / 4
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
GyrationShortcut.cpp +
55.4%55.4%
+
55.4 %51 / 9266.7 %2 / 3
SelectMassCharge.cpp +
60.5%60.5%
+
60.5 %23 / 3842.9 %3 / 7
Plane.cpp +
65.7%65.7%
+
65.7 %46 / 7057.1 %4 / 7
DihedralCorrelation.cpp +
67.7%67.7%
+
67.7 %44 / 6557.1 %4 / 7
Gyration.cpp +
77.7%77.7%
+
77.7 %143 / 18475.0 %3 / 4
Fake.cpp +
78.9%78.9%
+
78.9 %30 / 3840.0 %2 / 5
PropertyMap.cpp +
86.2%86.2%
+
86.2 %25 / 2950.0 %2 / 4
MultiRMSD.cpp +
91.1%91.1%
+
91.1 %51 / 5666.7 %2 / 3
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
Dimer.cpp +
92.2%92.2%
+
92.2 %83 / 9080.0 %4 / 5
DHEnergy.cpp +
94.1%94.1%
+
94.1 %32 / 3475.0 %3 / 4
EEFSolv.cpp +
94.3%94.3%
+
94.3 %230 / 24487.5 %7 / 8
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %60 / 6375.0 %3 / 4
DRMSD.cpp +
97.0%97.0%
+
97.0 %98 / 10166.7 %2 / 3
RMSDVector.cpp +
97.6%97.6%
+
97.6 %162 / 16691.7 %11 / 12
RMSD.cpp +
97.6%97.6%
+
97.6 %41 / 4275.0 %3 / 4
MultiColvarTemplate.h +
97.9%97.9%
+
97.9 %92 / 9490.3 %65 / 72
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
ERMSD.cpp +
98.1%98.1%
+
98.1 %51 / 5275.0 %3 / 4
Angle.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
Torsion.cpp +
98.0%98.0%
+
98.0 %100 / 10285.7 %6 / 7
Dipole.cpp +
98.8%98.8%
+
98.8 %84 / 8585.7 %6 / 7
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %92 / 9362.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 %12 / 1266.7 %2 / 3
Volume.cpp +
100.0%
+
100.0 %17 / 1775.0 %3 / 4
PathMSD.cpp +
100.0%
+
100.0 %19 / 1966.7 %2 / 3
ColvarShortcut.h +
100.0%
+
100.0 %21 / 21100.0 %18 / 18
Coordination.cpp +
100.0%
+
100.0 %30 / 3075.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
Cell.cpp +
100.0%
+
100.0 %34 / 3475.0 %3 / 4
RMSDShortcut.cpp +
100.0%
+
100.0 %53 / 5366.7 %2 / 3
GHBFIX.cpp +
100.0%
+
100.0 %77 / 7775.0 %3 / 4
Position.cpp +
100.0%
+
100.0 %89 / 8985.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %120 / 12085.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 000000000..a46996a5e --- /dev/null +++ b/coverage/colvar/index.html @@ -0,0 +1,463 @@ + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2722296891.7 %
Date:2024-10-17 16:45:00Functions:21627578.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Angle.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
Cell.cpp +
100.0%
+
100.0 %34 / 3475.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 %30 / 3075.0 %3 / 4
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %92 / 9362.5 %5 / 8
DHEnergy.cpp +
94.1%94.1%
+
94.1 %32 / 3475.0 %3 / 4
DRMSD.cpp +
97.0%97.0%
+
97.0 %98 / 10166.7 %2 / 3
DihedralCorrelation.cpp +
67.7%67.7%
+
67.7 %44 / 6557.1 %4 / 7
Dimer.cpp +
92.2%92.2%
+
92.2 %83 / 9080.0 %4 / 5
Dipole.cpp +
98.8%98.8%
+
98.8 %84 / 8585.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %120 / 12085.7 %6 / 7
EEFSolv.cpp +
94.3%94.3%
+
94.3 %230 / 24487.5 %7 / 8
ERMSD.cpp +
98.1%98.1%
+
98.1 %51 / 5275.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
ExtraCV.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
Fake.cpp +
78.9%78.9%
+
78.9 %30 / 3840.0 %2 / 5
GHBFIX.cpp +
100.0%
+
100.0 %77 / 7775.0 %3 / 4
Gyration.cpp +
77.7%77.7%
+
77.7 %143 / 18475.0 %3 / 4
GyrationShortcut.cpp +
55.4%55.4%
+
55.4 %51 / 9266.7 %2 / 3
MultiColvarTemplate.h +
97.9%97.9%
+
97.9 %92 / 9490.3 %65 / 72
MultiRMSD.cpp +
91.1%91.1%
+
91.1 %51 / 5666.7 %2 / 3
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
PathMSD.cpp +
100.0%
+
100.0 %19 / 1966.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 %89 / 8985.7 %6 / 7
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %60 / 6375.0 %3 / 4
PropertyMap.cpp +
86.2%86.2%
+
86.2 %25 / 2950.0 %2 / 4
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
RMSD.cpp +
97.6%97.6%
+
97.6 %41 / 4275.0 %3 / 4
RMSDShortcut.cpp +
100.0%
+
100.0 %53 / 5366.7 %2 / 3
RMSDVector.cpp +
97.6%97.6%
+
97.6 %162 / 16691.7 %11 / 12
SelectMassCharge.cpp +
60.5%60.5%
+
60.5 %23 / 3842.9 %3 / 7
Template.cpp +
22.9%22.9%
+
22.9 %8 / 3525.0 %1 / 4
Torsion.cpp +
98.0%98.0%
+
98.0 %100 / 10285.7 %6 / 7
Volume.cpp +
100.0%
+
100.0 %17 / 1775.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 000000000..0fa7edf92 --- /dev/null +++ b/coverage/config/Config.inc.func-sort-c.html @@ -0,0 +1,176 @@ + + + + + + + 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:107313.7 %
Date:2024-10-17 16:45:00Functions:42615.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv0
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev0
_ZN4PLMD6config13getVersionGitB5cxx11Ev0
_ZN4PLMD6config14getLibraryPathB5cxx11Ev0
_ZN4PLMD6config14plumed_htmldirEv0
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev0
_ZN4PLMD6config17plumed_includedirEv0
_ZN4PLMD6config18getCompilationDateB5cxx11Ev0
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev0
_ZN4PLMD6config19plumed_program_nameEv0
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config10getVersionB5cxx11Ev1
_ZN4PLMD6config14getVersionLongB5cxx11Ev1
_ZN4PLMD6config11plumed_rootEv440
_ZN4PLMD6config13getPlumedRootB5cxx11Ev440
+
+
+ + + +
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 000000000..76ac324d8 --- /dev/null +++ b/coverage/config/Config.inc.func.html @@ -0,0 +1,176 @@ + + + + + + + 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:107313.7 %
Date:2024-10-17 16:45:00Functions:42615.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev1
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv0
_ZN4PLMD6config11plumed_rootEv440
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev0
_ZN4PLMD6config13getPlumedRootB5cxx11Ev440
_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 000000000..4886baffe --- /dev/null +++ b/coverage/config/Config.inc.gcov.html @@ -0,0 +1,289 @@ + + + + + + + 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:107313.7 %
Date:2024-10-17 16:45:00Functions:42615.4 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config10getVersionB5cxx11Ev4
_ZN4PLMD6config11getMakefileB5cxx11Ev40
_ZN4PLMD6config17plumed_includedirEv928
_ZN4PLMD6config13getEnvCommandB5cxx11Ev929
_ZN4PLMD6config14plumed_htmldirEv929
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev929
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev929
_ZN4PLMD6config19plumed_program_nameEv929
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev929
_ZN4PLMD6config13getVersionGitB5cxx11Ev1286
_ZN4PLMD6config14getLibraryPathB5cxx11Ev1286
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1286
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1286
_ZN4PLMD6config12plumed_soextEv1544
_ZN4PLMD6config8getSoExtB5cxx11Ev1544
_ZN4PLMD6config14getVersionLongB5cxx11Ev2242
_ZN4PLMD6config11isInstalledEv3578
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4645
_ZN4PLMD6config11plumed_rootEv9187
_ZN4PLMD6config13getPlumedRootB5cxx11Ev9187
+
+
+ + + +
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 000000000..1fb046ec8 --- /dev/null +++ b/coverage/config/ConfigInstall.inc.func.html @@ -0,0 +1,176 @@ + + + + + + + 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:577378.1 %
Date:2024-10-17 16:45:00Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev4
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev40
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv3578
_ZN4PLMD6config11plumed_rootEv9187
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4645
_ZN4PLMD6config12plumed_soextEv1544
_ZN4PLMD6config13getEnvCommandB5cxx11Ev929
_ZN4PLMD6config13getPlumedRootB5cxx11Ev9187
_ZN4PLMD6config13getVersionGitB5cxx11Ev1286
_ZN4PLMD6config14getLibraryPathB5cxx11Ev1286
_ZN4PLMD6config14getVersionLongB5cxx11Ev2242
_ZN4PLMD6config14plumed_htmldirEv929
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev929
_ZN4PLMD6config17plumed_includedirEv928
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1286
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1286
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev929
_ZN4PLMD6config19plumed_program_nameEv929
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev929
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev1544
_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 000000000..f9559ac97 --- /dev/null +++ b/coverage/config/ConfigInstall.inc.gcov.html @@ -0,0 +1,289 @@ + + + + + + + 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:577378.1 %
Date:2024-10-17 16:45:00Functions:202676.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             : 
+      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             : namespace {
+      33             : /// local tool that, given a string, returns a new string which is:
+      34             : /// - enclosed in single quotes (')
+      35             : /// - with all single quotes escaped
+      36        4645 : std::string escapeForSingleQuote(const std::string& input) {
+      37             :   std::string escaped;
+      38       92905 :   for (char c : input) {
+      39       88260 :     if (c == '\'') {
+      40             :       escaped += "'\\''";
+      41             :     } else {
+      42       88260 :       escaped += c;
+      43             :     }
+      44             :   }
+      45        9290 :   return "'" + escaped + "'";
+      46             : }
+      47             : }
+      48             : 
+      49             : // This is a fix to allow conda to correctly replace paths in binary files.
+      50             : // These functions should not be static or they will be optimized away!
+      51        9187 : const char* plumed_root() {return "/home/runner/opt/lib/plumed";}
+      52        1544 : const char* plumed_soext() {return "so";}
+      53         929 : const char* plumed_htmldir() {return "/home/runner/opt/share/doc/plumed";}
+      54         928 : const char* plumed_includedir() {return "/home/runner/opt/include";}
+      55         929 : const char* plumed_program_name() {return "plumed";}
+      56             : 
+      57        1544 : std::string getSoExt() {
+      58        1544 :   return plumed_soext();
+      59             : }
+      60             : 
+      61        3578 : bool isInstalled() {
+      62        3578 :   return true;
+      63             : }
+      64             : 
+      65        9187 : std::string getPlumedRoot() {
+      66        9187 :   char *env = std::getenv("PLUMED_ROOT");
+      67             :   std::string ss;
+      68        9187 :   if( env == NULL) {
+      69        9187 :     ss=plumed_root();
+      70             :   } else {
+      71           0 :     ss=std::string( env );
+      72             :   }
+      73        9187 :   return ss;
+      74             : }
+      75             : 
+      76         929 : std::string getPlumedHtmldir() {
+      77         929 :   if(!isInstalled()) return getPlumedRoot();
+      78         929 :   char *env = std::getenv("PLUMED_HTMLDIR");
+      79             :   std::string ss;
+      80         929 :   if( env == NULL) {
+      81         929 :     ss=plumed_htmldir();
+      82             :   } else {
+      83           0 :     ss=std::string( env );
+      84             :   }
+      85             :   return ss;
+      86             : }
+      87             : 
+      88         929 : std::string getPlumedIncludedir() {
+      89         929 :   if(!isInstalled()) return getPlumedRoot()+"/src/include";
+      90         929 :   char *env = std::getenv("PLUMED_INCLUDEDIR");
+      91             :   std::string ss;
+      92         929 :   if( env == NULL) {
+      93         928 :     ss=plumed_includedir();
+      94             :   } else {
+      95           2 :     ss=std::string( env );
+      96             :   }
+      97             :   return ss;
+      98             : }
+      99             : 
+     100         929 : std::string getPlumedProgramName() {
+     101         929 :   if(!isInstalled()) return "plumed";
+     102         929 :   char *env = std::getenv("PLUMED_PROGRAM_NAME");
+     103             :   std::string ss;
+     104         929 :   if( env == NULL) {
+     105         929 :     ss=plumed_program_name();
+     106             :   } else {
+     107           0 :     ss=std::string( env );
+     108             :   }
+     109             :   return ss;
+     110             : }
+     111             : 
+     112         929 : std::string getEnvCommand() {
+     113        1858 :   return "env PLUMED_ROOT="+escapeForSingleQuote(getPlumedRoot())+
+     114        3716 :          " PLUMED_VERSION="+escapeForSingleQuote(getVersionLong())+
+     115        3716 :          " PLUMED_HTMLDIR="+escapeForSingleQuote(getPlumedHtmldir())+
+     116        3716 :          " PLUMED_INCLUDEDIR="+escapeForSingleQuote(getPlumedIncludedir())+
+     117        3716 :          " PLUMED_PROGRAM_NAME="+escapeForSingleQuote(getPlumedProgramName())+
+     118        2787 :          " PLUMED_IS_INSTALLED='"+(true?"yes":"no")+"'";
+     119             : }
+     120             : 
+     121           4 : std::string getVersion() {
+     122           4 :   return PLUMED_VERSION_SHORT;
+     123             : }
+     124             : 
+     125        2242 : std::string getVersionLong() {
+     126        2242 :   return PLUMED_VERSION_LONG;
+     127             : }
+     128             : 
+     129        1286 : std::string getVersionGit() {
+     130        1286 :   return PLUMED_VERSION_GIT;
+     131             : }
+     132             : 
+     133          40 : std::string getMakefile() {
+     134             :   static const unsigned char confu [] = {
+     135             : #include "Makefile.conf.xxd"
+     136             :     , 0x00
+     137             :   };
+     138             :   auto conf=(char*)confu;
+     139          40 :   return std::string(conf,conf+std::strlen(conf));
+     140             : }
+     141             : 
+     142           0 : bool hasMatheval() {
+     143             : #ifdef __PLUMED_HAS_MATHEVAL
+     144             :   return true;
+     145             : #else
+     146           0 :   return false;
+     147             : #endif
+     148             : }
+     149             : 
+     150           0 : bool hasDlopen() {
+     151             : #ifdef __PLUMED_HAS_DLOPEN
+     152           0 :   return true;
+     153             : #else
+     154             :   return false;
+     155             : #endif
+     156             : }
+     157             : 
+     158           0 : bool hasCregex() {
+     159             : #ifdef __PLUMED_HAS_CREGEX
+     160             :   return true;
+     161             : #else
+     162           0 :   return false;
+     163             : #endif
+     164             : }
+     165             : 
+     166           0 : bool hasMolfile() {
+     167             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     168           0 :   return true;
+     169             : #else
+     170             :   return false;
+     171             : #endif
+     172             : }
+     173             : 
+     174           0 : bool hasExternalMolfile() {
+     175             : #ifdef __PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS
+     176             :   return true;
+     177             : #else
+     178           0 :   return false;
+     179             : #endif
+     180             : }
+     181             : 
+     182           0 : bool hasZlib() {
+     183             : #ifdef __PLUMED_HAS_ZLIB
+     184           0 :   return true;
+     185             : #else
+     186             :   return false;
+     187             : #endif
+     188             : }
+     189             : 
+     190        1286 : std::string getCompilationDate() {
+     191        1286 :   return __DATE__;
+     192             : }
+     193             : 
+     194        1286 : std::string getCompilationTime() {
+     195        1286 :   return __TIME__;
+     196             : }
+     197             : 
+     198        1286 : std::string getLibraryPath() {
+     199             : #ifdef __PLUMED_HAS_DLADDR
+     200             :   Dl_info info;
+     201        1286 :   if(dladdr((void*)getLibraryPath,&info)) {
+     202        1286 :     return info.dli_fname;
+     203             :   } else {
+     204           0 :     return "";
+     205             :   }
+     206             : #endif
+     207             : 
+     208             : }
+     209             : 
+     210             : 
+     211             : }
+     212             : }
+     213             : 
+
+
+
+ + + + +
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 000000000..5e4141708 --- /dev/null +++ b/coverage/config/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:6714645.9 %
Date:2024-10-17 16:45:00Functions:245246.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
13.7%13.7%
+
13.7 %10 / 7315.4 %4 / 26
ConfigInstall.inc +
78.1%78.1%
+
78.1 %57 / 7376.9 %20 / 26
+
+
+ + + + +
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 000000000..5d28461b6 --- /dev/null +++ b/coverage/config/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:6714645.9 %
Date:2024-10-17 16:45:00Functions:245246.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
13.7%13.7%
+
13.7 %10 / 7315.4 %4 / 26
ConfigInstall.inc +
78.1%78.1%
+
78.1 %57 / 7376.9 %20 / 26
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/index.html b/coverage/config/index.html new file mode 100644 index 000000000..94f415d2c --- /dev/null +++ b/coverage/config/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:6714645.9 %
Date:2024-10-17 16:45:00Functions:245246.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
13.7%13.7%
+
13.7 %10 / 7315.4 %4 / 26
ConfigInstall.inc +
78.1%78.1%
+
78.1 %57 / 7376.9 %20 / 26
+
+
+ + + + +
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 000000000..6e7343a6e --- /dev/null +++ b/coverage/contour/ContourFindingBase.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7contour18ContourFindingBase16setupOnFirstStepEb3
_ZN4PLMD7contour18ContourFindingBaseC2ERKNS_13ActionOptionsE4
_ZN4PLMD7contour18ContourFindingBase16registerKeywordsERNS_8KeywordsE11
+
+
+ + + +
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 000000000..0daa1252f --- /dev/null +++ b/coverage/contour/ContourFindingBase.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour18ContourFindingBase16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7contour18ContourFindingBase16setupOnFirstStepEb3
_ZN4PLMD7contour18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7contour18ContourFindingBaseC2ERKNS_13ActionOptionsE4
+
+
+ + + +
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 000000000..6954dab8b --- /dev/null +++ b/coverage/contour/ContourFindingBase.cpp.gcov.html @@ -0,0 +1,123 @@ + + + + + + + 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-10-17 16:45:00Functions: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          11 : void ContourFindingBase::registerKeywords( Keywords& keys ) {
+      28          11 :   gridtools::ActionWithGrid::registerKeywords( keys ); keys.use("ARG");
+      29          22 :   keys.add("compulsory","CONTOUR","the value we would like to draw the contour at in the space");
+      30          11 :   gridtools::EvaluateGridFunction gg; gg.registerKeywords(keys);
+      31          11 : }
+      32             : 
+      33           4 : ContourFindingBase::ContourFindingBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionWithGrid(ao),
+      36           4 :   mymin(this)
+      37             : {
+      38           8 :   parse("CONTOUR",contour); function.read( this );
+      39           4 :   log.printf("  calculating dividing surface along which function equals %f \n", contour);
+      40           4 : }
+      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 000000000..a2b66d433 --- /dev/null +++ b/coverage/contour/ContourFindingBase.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..27443e554 --- /dev/null +++ b/coverage/contour/ContourFindingBase.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..872e5c72f --- /dev/null +++ b/coverage/contour/ContourFindingBase.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e1352bb5c --- /dev/null +++ b/coverage/contour/DistanceFromContour.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ac1282f44 --- /dev/null +++ b/coverage/contour/DistanceFromContour.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d1491f865 --- /dev/null +++ b/coverage/contour/DistanceFromContour.cpp.gcov.html @@ -0,0 +1,322 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..125876298 --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6ee292bef --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fab84cfee --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..eb826f65a --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7686216a3 --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d8b4db7e2 --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.h.gcov.html @@ -0,0 +1,155 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..182269020 --- /dev/null +++ b/coverage/contour/DistanceFromSphericalContour.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..173003b59 --- /dev/null +++ b/coverage/contour/DistanceFromSphericalContour.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ae0546a1c --- /dev/null +++ b/coverage/contour/DistanceFromSphericalContour.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..001e82868 --- /dev/null +++ b/coverage/contour/DumpContour.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f07e96c09 --- /dev/null +++ b/coverage/contour/DumpContour.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..aaec775c3 --- /dev/null +++ b/coverage/contour/DumpContour.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..434faae36 --- /dev/null +++ b/coverage/contour/FindContour.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:565896.6 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour11FindContour22getNumberOfDerivativesEv0
_ZN4PLMD7contour11FindContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD7contour11FindContour22setupValuesOnFirstStepEv1
_ZN4PLMD7contour11FindContour16getNumberOfTasksERj2
_ZN4PLMD7contour11FindContour19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE2
_ZN4PLMD7contour11FindContourC1ERKNS_13ActionOptionsE2
_ZNK4PLMD7contour11FindContour29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE3
_ZN4PLMD7contour11FindContour16registerKeywordsERNS_8KeywordsE5
_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 000000000..d931eab12 --- /dev/null +++ b/coverage/contour/FindContour.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:565896.6 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour11FindContour16getNumberOfTasksERj2
_ZN4PLMD7contour11FindContour16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD7contour11FindContour19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE2
_ZN4PLMD7contour11FindContour22getNumberOfDerivativesEv0
_ZN4PLMD7contour11FindContour22setupValuesOnFirstStepEv1
_ZN4PLMD7contour11FindContourC1ERKNS_13ActionOptionsE2
_ZN4PLMD7contour11FindContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7contour11FindContour11performTaskERKjRNS_10MultiValueE1108
_ZNK4PLMD7contour11FindContour15checkTaskStatusERKjRi32928
_ZNK4PLMD7contour11FindContour29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE3
+
+
+ + + +
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 000000000..04cdc0e92 --- /dev/null +++ b/coverage/contour/FindContour.cpp.gcov.html @@ -0,0 +1,267 @@ + + + + + + + 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:565896.6 %
Date:2024-10-17 16:45:00Functions:81080.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 "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           5 : void FindContour::registerKeywords( Keywords& keys ) {
+      95           5 :   ContourFindingBase::registerKeywords( keys ); ActionWithValue::useCustomisableComponents(keys);
+      96             : // We want a better way of doing this bit
+      97          10 :   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           5 : }
+      99             : 
+     100           2 : FindContour::FindContour(const ActionOptions&ao):
+     101             :   Action(ao),
+     102           2 :   ContourFindingBase(ao)
+     103             : {
+     104           2 :   parse("BUFFER",gbuffer);
+     105           2 :   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           2 :   checkRead();
+     107             : 
+     108           2 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     109           2 :   std::vector<std::string> argn( ag->getGridCoordinateNames() );
+     110             : 
+     111           2 :   std::vector<unsigned> shape(1); shape[0]=0;
+     112           8 :   for(unsigned i=0; i<argn.size(); ++i ) {
+     113           6 :     addComponent( argn[i], shape ); componentIsNotPeriodic( argn[i] ); getPntrToComponent(i)->buildDataStore();
+     114             :   }
+     115             :   // Check for task reduction
+     116           2 :   updateTaskListReductionStatus();
+     117           2 : }
+     118             : 
+     119           3 : std::string FindContour::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     120           6 :   return "a vector of coordinates for the contour along the " + cname + " direction";
+     121             : }
+     122             : 
+     123           1 : void FindContour::setupValuesOnFirstStep() {
+     124           1 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getRank()*getPntrToArgument(0)->getNumberOfValues();
+     125           4 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setShape( shape );
+     126           1 :   active_cells.resize( shape[0] );
+     127           1 : }
+     128             : 
+     129           0 : unsigned FindContour::getNumberOfDerivatives() {
+     130           0 :   return 0;
+     131             : }
+     132             : 
+     133           2 : void FindContour::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     134           2 :   task_reducing_actions.push_back(this);
+     135           2 : }
+     136             : 
+     137           2 : void FindContour::getNumberOfTasks( unsigned& ntasks ) {
+     138           2 :   ntasks = active_cells.size();
+     139             : 
+     140             :   Value* gval=getPntrToArgument(0);
+     141           2 :   unsigned npoints = gval->getNumberOfValues();
+     142           2 :   std::vector<unsigned> ind( gval->getRank() );
+     143           2 :   std::vector<unsigned> ones( gval->getRank(), 1 );
+     144           2 :   std::vector<unsigned> nbin( getInputGridObject().getNbin( false ) );
+     145             :   unsigned num_neighbours; std::vector<unsigned> neighbours;
+     146             : 
+     147             :   std::fill( active_cells.begin(), active_cells.end(), 0 );
+     148       10978 :   for(unsigned i=0; i<npoints; ++i) {
+     149             :     // Get the index of the current grid point
+     150       10976 :     getInputGridObject().getIndices( i, ind );
+     151       10976 :     getInputGridObject().getNeighbors( ind, ones, num_neighbours, neighbours );
+     152             :     // Get the value of a point on the grid
+     153       10976 :     double val1=gval->get( i ) - contour;
+     154             :     bool edge=false;
+     155       43904 :     for(unsigned j=0; j<gval->getRank(); ++j) {
+     156             :       // Make sure we don't search at the edge of the grid
+     157       32928 :       if( !getInputGridObject().isPeriodic(j) && (ind[j]+1)==nbin[j] ) continue;
+     158       32928 :       else if( (ind[j]+1)==nbin[j] ) { edge=true; ind[j]=0; }
+     159       30968 :       else ind[j]+=1;
+     160       32928 :       double val2=gval->get( getInputGridObject().getIndex(ind) ) - contour;
+     161       32928 :       if( val1*val2<0 ) active_cells[gval->getRank()*i + j] = 1;
+     162       32928 :       if( getInputGridObject().isPeriodic(j) && edge ) { edge=false; ind[j]=nbin[j]-1; }
+     163       30968 :       else ind[j]-=1;
+     164             :     }
+     165             :   }
+     166           2 : }
+     167             : 
+     168       32928 : int FindContour::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+     169       32928 :   if( active_cells[taskno]>0 ) return 1;
+     170             :   return 0;
+     171             : }
+     172             : 
+     173        1108 : void FindContour::performTask( const unsigned& current, MultiValue& myvals ) const {
+     174             :   // Retrieve the initial grid point coordinates
+     175        1108 :   unsigned gpoint = std::floor( current / getPntrToArgument(0)->getRank() );
+     176        1108 :   std::vector<double> point( getPntrToArgument(0)->getRank() );
+     177        1108 :   getInputGridObject().getGridPointCoordinates( gpoint, point );
+     178             : 
+     179             :   // Retrieve the direction we are searching for the contour
+     180        1108 :   unsigned gdir = current%(getPntrToArgument(0)->getRank() );
+     181        1108 :   std::vector<double> direction( getPntrToArgument(0)->getRank(), 0 );
+     182        1108 :   direction[gdir] = 0.999999999*getInputGridObject().getGridSpacing()[gdir];
+     183             : 
+     184             :   // Now find the contour
+     185             :   findContour( direction, point );
+     186             :   // And transfer to the store data vessel
+     187        4432 :   for(unsigned i=0; i<getPntrToArgument(0)->getRank(); ++i) myvals.setValue( getConstPntrToComponent(i)->getPositionInStream(), point[i] );
+     188        1108 : }
+     189             : 
+     190             : }
+     191             : }
+
+
+
+ + + + +
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 000000000..cd54a64c1 --- /dev/null +++ b/coverage/contour/FindContour.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..56f29f0e2 --- /dev/null +++ b/coverage/contour/FindContour.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..31f1c29b5 --- /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-10-17 16:45:00Functions: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             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      39             :   void setupValuesOnFirstStep() override;
+      40             :   unsigned getNumberOfDerivatives() override ;
+      41             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) override ;
+      42             :   void getNumberOfTasks( unsigned& ntasks ) override ;
+      43             :   int checkTaskStatus( const unsigned& taskno, int& flag ) const override ;
+      44           0 :   std::vector<std::string> getGridCoordinateNames() const override { plumed_error(); }
+      45           0 :   const gridtools::GridCoordinatesObject& getGridCoordinatesObject() const override { plumed_error(); }
+      46             :   void performTask( const unsigned& current, MultiValue& myvals ) const override;
+      47             : };
+      48             : 
+      49             : }
+      50             : }
+      51             : #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 000000000..b7055421d --- /dev/null +++ b/coverage/contour/FindContourSurface.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:747796.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..e2dfc7127 --- /dev/null +++ b/coverage/contour/FindContourSurface.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:747796.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..9c4d87053 --- /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:747796.1 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("a grid containing the location of the points in the Willard-Chandler surface along the chosen direction");
+     114           3 : }
+     115             : 
+     116           1 : FindContourSurface::FindContourSurface(const ActionOptions&ao):
+     117             :   Action(ao),
+     118             :   ContourFindingBase(ao),
+     119           1 :   ones(getPntrToArgument(0)->getRank(),1)
+     120             : {
+     121           1 :   if( getPntrToArgument(0)->getRank()<2 ) error("cannot find dividing surface if input grid is one dimensional");
+     122             : 
+     123           1 :   std::string dir; parse("SEARCHDIR",dir);
+     124           1 :   log.printf("  calculating location of contour on %d dimensional grid \n", getPntrToArgument(0)->getRank()-1 );
+     125           1 :   checkRead();
+     126             : 
+     127             :   Value* gval=getPntrToArgument(0); unsigned n=0;
+     128           1 :   gdirs.resize( gval->getRank()-1 ); gnames.resize( getPntrToArgument(0)->getRank()-1 );
+     129             : 
+     130           1 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( gval->getPntrToAction() );
+     131           1 :   if( !ag ) error("input argument must be a grid");
+     132           2 :   if( getInputGridObject().getGridType()=="fibonacci") error("cannot search for contours in fibonacci grids");
+     133           1 :   std::vector<std::string> argn( ag->getGridCoordinateNames() );
+     134             : 
+     135           4 :   for(unsigned i=0; i<gval->getRank(); ++i) {
+     136           3 :     if( argn[i]==dir ) {
+     137           1 :       dir_n=i;
+     138             :     } else {
+     139           2 :       if( n==gdirs.size() ) error("could not find " + dir + " direction in input grid");
+     140           4 :       gdirs[n]=i; gnames[n]=argn[i]; n++;
+     141             :     }
+     142             :   }
+     143           1 :   if( n!=(gval->getRank()-1) ) error("output of grid is not understood");
+     144             : 
+     145           1 :   std::vector<bool> ipbc( getInputGridObject().getDimension()-1 );
+     146           3 :   for(unsigned i=0; i<gdirs.size(); ++i) ipbc[i] = getInputGridObject().isPeriodic(gdirs[i]);
+     147           2 :   gridcoords.setup( "flat", ipbc, 0, 0.0 );
+     148             : 
+     149             :   // Now add a value
+     150           1 :   std::vector<unsigned> shape( getInputGridObject().getDimension()-1 );
+     151           1 :   addValueWithDerivatives( shape ); setNotPeriodic();
+     152           1 :   getPntrToComponent(0)->buildDataStore();
+     153           2 : }
+     154             : 
+     155           1 : void FindContourSurface::setupValuesOnFirstStep() {
+     156           1 :   std::vector<double> fspacing; std::vector<unsigned> snbins( gridcoords.getDimension() );
+     157           1 :   std::vector<std::string> smin( gridcoords.getDimension() ), smax( gridcoords.getDimension() );
+     158           3 :   for(unsigned i=0; i<gdirs.size(); ++i) {
+     159           6 :     smin[i]=getInputGridObject().getMin()[gdirs[i]]; smax[i]=getInputGridObject().getMax()[gdirs[i]];
+     160           2 :     snbins[i]=getInputGridObject().getNbin(false)[gdirs[i]];
+     161             :   }
+     162           1 :   gridcoords.setBounds( smin, smax, snbins, fspacing );
+     163           2 :   getPntrToComponent(0)->setShape( gridcoords.getNbin(true) );
+     164             : 
+     165           1 :   std::vector<unsigned> find( gridcoords.getDimension() );
+     166           1 :   std::vector<unsigned> ind( gridcoords.getDimension() );
+     167         197 :   for(unsigned i=0; i<gridcoords.getNumberOfPoints(); ++i) {
+     168         196 :     find.assign( find.size(), 0 ); gridcoords.getIndices( i, ind );
+     169         588 :     for(unsigned j=0; j<gdirs.size(); ++j) find[gdirs[j]]=ind[j];
+     170             :   }
+     171             : 
+     172             :   // Set the direction in which to look for the contour
+     173           1 :   direction.resize( getInputGridObject().getDimension(), 0 );
+     174           1 :   direction[dir_n] = 0.999999999*getInputGridObject().getGridSpacing()[dir_n];
+     175           2 : }
+     176             : 
+     177           3 : unsigned FindContourSurface::getNumberOfDerivatives() {
+     178           3 :   return gridcoords.getDimension();
+     179             : }
+     180             : 
+     181           3 : std::vector<std::string> FindContourSurface::getGridCoordinateNames() const {
+     182           3 :   return gnames;
+     183             : }
+     184             : 
+     185           3 : const gridtools::GridCoordinatesObject& FindContourSurface::getGridCoordinatesObject() const {
+     186           3 :   return gridcoords;
+     187             : }
+     188             : 
+     189         588 : void FindContourSurface::performTask( const unsigned& current, MultiValue& myvals ) const {
+     190             :   std::vector<unsigned> neighbours; unsigned num_neighbours; unsigned nfound=0; double minv=0, minp;
+     191         588 :   std::vector<unsigned> bins_n( getInputGridObject().getNbin(false) ); unsigned shiftn=current;
+     192         588 :   std::vector<unsigned> ind( getInputGridObject().getDimension() ); std::vector<double> point( getInputGridObject().getDimension() );
+     193             : #ifndef DNDEBUG
+     194         588 :   std::vector<unsigned> oind( gridcoords.getDimension() ); gridcoords.getIndices( current, oind );
+     195             : #endif
+     196       16842 :   for(unsigned i=0; i<bins_n[dir_n]; ++i) {
+     197             : #ifndef DNDEBUG
+     198       16842 :     std::vector<unsigned> base_ind( getInputGridObject().getDimension() ); getInputGridObject().getIndices( shiftn, base_ind );
+     199       50526 :     for(unsigned j=0; j<gdirs.size(); ++j) plumed_dbg_assert( base_ind[gdirs[j]]==oind[j] );
+     200             : #endif
+     201             :     // Get the index of the current grid point
+     202       16842 :     getInputGridObject().getIndices( shiftn, ind );
+     203             :     // Exit if we are at the edge of the grid
+     204       16842 :     if( !getInputGridObject().isPeriodic(dir_n) && (ind[dir_n]+1)==bins_n[dir_n] ) {
+     205           0 :       shiftn += getInputGridObject().getStride()[dir_n]; continue;
+     206             :     }
+     207             : 
+     208             :     // Ensure points with inactive neighbours are ignored
+     209       16842 :     getInputGridObject().getNeighbors( ind, ones, num_neighbours, neighbours );
+     210             : 
+     211             :     // Now get the function value at two points
+     212       16842 :     double val1=getPntrToArgument(0)->get( shiftn ) - contour; double val2;
+     213       16842 :     if( (ind[dir_n]+1)==bins_n[dir_n] ) val2 = getPntrToArgument(0)->get( current ) - contour;
+     214       16842 :     else val2=getPntrToArgument(0)->get( shiftn + getInputGridObject().getStride()[dir_n] ) - contour;
+     215             : 
+     216             :     // Check if the minimum is bracketed
+     217       16842 :     if( val1*val2<0 ) {
+     218         588 :       getInputGridObject().getGridPointCoordinates( shiftn, point ); findContour( direction, point );
+     219         588 :       minp=point[dir_n]; nfound++; break;
+     220             :     }
+     221             : 
+     222             :     // This moves us on to the next point
+     223       16254 :     shiftn += getInputGridObject().getStride()[dir_n];
+     224             :   }
+     225             :   if( nfound==0 ) {
+     226           0 :     std::string num; Tools::convert( getStep(), num );
+     227           0 :     error("On step " + num + " failed to find required grid point");
+     228             :   }
+     229         588 :   myvals.setValue( getConstPntrToComponent(0)->getPositionInStream(), minp );
+     230         588 : }
+     231             : 
+     232         588 : void FindContourSurface::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     233             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     234         588 :   plumed_dbg_assert( valindex==0 ); unsigned istart = bufstart + (1+gridcoords.getDimension())*code;
+     235         588 :   unsigned valout = getConstPntrToComponent(0)->getPositionInStream(); buffer[istart] += myvals.get( valout );
+     236         588 : }
+     237             : 
+     238             : }
+     239             : }
+
+
+
+ + + + +
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 000000000..a2eef7f23 --- /dev/null +++ b/coverage/contour/FindSphericalContour.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:434889.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..1e3eae49f --- /dev/null +++ b/coverage/contour/FindSphericalContour.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:434889.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..17844f011 --- /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:434889.6 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("a grid on a Fibonacci sphere that describes the radial distance from the origin for the points on the Willard-Chandler surface");
+     137           3 : }
+     138             : 
+     139           1 : FindSphericalContour::FindSphericalContour(const ActionOptions&ao):
+     140             :   Action(ao),
+     141           1 :   ContourFindingBase(ao)
+     142             : {
+     143           1 :   if( getPntrToArgument(0)->getRank()!=3 ) error("input grid must be three dimensional");
+     144             : 
+     145           2 :   parse("NPOINTS",npoints); log.printf("  searching for %u points on dividing surface \n",npoints);
+     146           3 :   parse("INNER_RADIUS",min); parse("OUTER_RADIUS",max); parse("NBINS",nbins);
+     147           1 :   log.printf("  expecting to find dividing surface at radii between %f and %f \n",min,max);
+     148           1 :   log.printf("  looking for contour in windows of length %f \n", (max-min)/nbins);
+     149             :   // Set this here so the same set of grid points are used on every turn
+     150           1 :   std::vector<bool> ipbc( 3, false ); gridcoords.setup( "fibonacci", ipbc, npoints, 0.0 );
+     151             :   // Now create a value
+     152           1 :   std::vector<unsigned> shape( 3 ); shape[0]=npoints; shape[1]=shape[2]=1;
+     153           1 :   addValueWithDerivatives( shape ); setNotPeriodic();
+     154           1 :   getPntrToComponent(0)->buildDataStore(); checkRead();
+     155           1 : }
+     156             : 
+     157           2 : unsigned FindSphericalContour::getNumberOfDerivatives() {
+     158           2 :   return gridcoords.getDimension();
+     159             : }
+     160             : 
+     161           0 : std::vector<std::string> FindSphericalContour::getGridCoordinateNames() const {
+     162           0 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     163           0 :   plumed_assert( ag ); return ag->getGridCoordinateNames();
+     164             : }
+     165             : 
+     166           3 : const gridtools::GridCoordinatesObject& FindSphericalContour::getGridCoordinatesObject() const {
+     167           3 :   return gridcoords;
+     168             : }
+     169             : 
+     170         200 : void FindSphericalContour::performTask( const unsigned& current, MultiValue& myvals ) const {
+     171             :   // Generate contour point on inner sphere
+     172         200 :   std::vector<double> contour_point(3), direction(3), der(3), tmp(3);
+     173             :   // Retrieve this contour point from grid
+     174         200 :   gridcoords.getGridPointCoordinates( current, direction );
+     175             :   // Now setup contour point on inner sphere
+     176         800 :   for(unsigned j=0; j<3; ++j) {
+     177         600 :     contour_point[j] = min*direction[j];
+     178         600 :     direction[j] = (max-min)*direction[j] / static_cast<double>(nbins);
+     179             :   }
+     180             : 
+     181             :   bool found=false;
+     182         200 :   for(unsigned k=0; k<nbins; ++k) {
+     183         800 :     for(unsigned j=0; j<3; ++j) tmp[j] = contour_point[j] + direction[j];
+     184         200 :     double val1 = getDifferenceFromContour( contour_point, der );
+     185         200 :     double val2 = getDifferenceFromContour( tmp, der );
+     186         200 :     if( val1*val2<0 ) {
+     187             :       findContour( direction, contour_point );
+     188         800 :       double norm=0; for(unsigned j=0; j<3; ++j) norm += contour_point[j]*contour_point[j];
+     189         200 :       myvals.setValue( getConstPntrToComponent(0)->getPositionInStream(), sqrt(norm) ); found=true; break;
+     190             :     }
+     191           0 :     for(unsigned j=0; j<3; ++j) contour_point[j] = tmp[j];
+     192             :   }
+     193           0 :   if( !found ) error("range does not bracket the dividing surface");
+     194         200 : }
+     195             : 
+     196         200 : void FindSphericalContour::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     197             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     198         200 :   plumed_assert( valindex==0 ); unsigned istart = bufstart + (1+gridcoords.getDimension())*code;
+     199         200 :   unsigned valout = getConstPntrToComponent(0)->getPositionInStream(); buffer[istart] += myvals.get( valout );
+     200         200 : }
+     201             : 
+     202             : }
+     203             : }
+
+
+
+ + + + +
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 000000000..65082f843 --- /dev/null +++ b/coverage/contour/index-sort-f.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - contour + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contourHitTotalCoverage
Test:plumed test coverageLines:42145093.6 %
Date:2024-10-17 16:45:00Functions:496377.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
FindSphericalContour.cpp +
89.6%89.6%
+
89.6 %43 / 4877.8 %7 / 9
DistanceFromContour.cpp +
85.3%85.3%
+
85.3 %81 / 9580.0 %4 / 5
FindContour.cpp +
96.6%96.6%
+
96.6 %56 / 5880.0 %8 / 10
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 %74 / 7788.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 000000000..b6f17d7f4 --- /dev/null +++ b/coverage/contour/index-sort-l.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - contour + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contourHitTotalCoverage
Test:plumed test coverageLines:42145093.6 %
Date:2024-10-17 16:45:00Functions:496377.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.6%89.6%
+
89.6 %43 / 4877.8 %7 / 9
DistanceFromSphericalContour.cpp +
94.4%94.4%
+
94.4 %34 / 3660.0 %3 / 5
FindContourSurface.cpp +
96.1%96.1%
+
96.1 %74 / 7788.9 %8 / 9
FindContour.cpp +
96.6%96.6%
+
96.6 %56 / 5880.0 %8 / 10
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 000000000..e934aa909 --- /dev/null +++ b/coverage/contour/index.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - contour + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contourHitTotalCoverage
Test:plumed test coverageLines:42145093.6 %
Date:2024-10-17 16:45:00Functions:496377.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.6%96.6%
+
96.6 %56 / 5880.0 %8 / 10
FindContour.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
FindContourSurface.cpp +
96.1%96.1%
+
96.1 %74 / 7788.9 %8 / 9
FindSphericalContour.cpp +
89.6%89.6%
+
89.6 %43 / 4877.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 000000000..b75138e33 --- /dev/null +++ b/coverage/core/Action.cpp.func-sort-c.html @@ -0,0 +1,224 @@ + + + + + + + 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:17420784.1 %
Date:2024-10-17 16:45:00Functions:323884.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6ActionD0Ev0
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZNK4PLMD6Action12writeInGraphB5cxx11Ev44
_ZN4PLMD6Action5fopenEPKcS2_82
_ZN4PLMD6Action6fcloseEP8_IO_FILE99
_ZN4PLMD6Action6getkBTEv632
_ZNK4PLMD6Action13getKBoltzmannEv675
_ZNK4PLMD6Action6getCPTEv1095
_ZNK4PLMD6Action17usingNaturalUnitsEv2137
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2228
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4287
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZN4PLMD6ActionD2Ev51095
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE51096
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE51096
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE51098
_ZN4PLMD6Action6fflushEv60986
_ZN4PLMD6Action9checkReadEv67161
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE74043
_ZN4PLMD6Action19setupConstantValuesERKb95051
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb95605
_ZN4PLMD6Action19resetStoredTimestepEv100674
_ZN4PLMD6Action17clearDependenciesEv199627
_ZNK4PLMD6Action11getTimeStepEv217999
_ZN4PLMD6Action18checkForDependencyEPS0_571368
_ZN4PLMD6Action7prepareEv999973
_ZN4PLMD6Action13addDependencyEPS0_1263698
_ZNK4PLMD6Action11checkUpdateEv2519892
_ZNK4PLMD6Action7getTimeEv3667091
_ZN4PLMD6Action8activateEv5181986
_ZNK4PLMD6Action7getStepEv5396816
_ZNK4PLMD6Action8getUnitsEv15930476
+
+
+ + + +
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 000000000..b071db9c2 --- /dev/null +++ b/coverage/core/Action.cpp.func.html @@ -0,0 +1,224 @@ + + + + + + + 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:17420784.1 %
Date:2024-10-17 16:45:00Functions:323884.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE51096
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE51098
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action13addDependencyEPS0_1263698
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE74043
_ZN4PLMD6Action17clearDependenciesEv199627
_ZN4PLMD6Action18checkForDependencyEPS0_571368
_ZN4PLMD6Action19resetStoredTimestepEv100674
_ZN4PLMD6Action19setupConstantValuesERKb95051
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6Action5fopenEPKcS2_82
_ZN4PLMD6Action6fcloseEP8_IO_FILE99
_ZN4PLMD6Action6fflushEv60986
_ZN4PLMD6Action6getkBTEv632
_ZN4PLMD6Action7prepareEv999973
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4287
_ZN4PLMD6Action8activateEv5181986
_ZN4PLMD6Action9checkReadEv67161
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb95605
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2228
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE51096
_ZN4PLMD6ActionD0Ev0
_ZN4PLMD6ActionD2Ev51095
_ZNK4PLMD6Action11checkUpdateEv2519892
_ZNK4PLMD6Action11getTimeStepEv217999
_ZNK4PLMD6Action12writeInGraphB5cxx11Ev44
_ZNK4PLMD6Action13getKBoltzmannEv675
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZNK4PLMD6Action17usingNaturalUnitsEv2137
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28
_ZNK4PLMD6Action6getCPTEv1095
_ZNK4PLMD6Action7getStepEv5396816
_ZNK4PLMD6Action7getTimeEv3667091
_ZNK4PLMD6Action8getUnitsEv15930476
+
+
+ + + +
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 000000000..3ef5e3305 --- /dev/null +++ b/coverage/core/Action.cpp.gcov.html @@ -0,0 +1,444 @@ + + + + + + + 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:17420784.1 %
Date:2024-10-17 16:45:00Functions:323884.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 "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       51098 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
+      44       51098 :   plumed(p),
+      45       51098 :   line(l),
+      46       51098 :   keys(emptyKeys)
+      47             : {
+      48       51098 : }
+      49             : 
+      50       51096 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
+      51       51096 :   plumed(ao.plumed),
+      52       51096 :   line(ao.line),
+      53       51096 :   keys(keys)
+      54             : {
+      55       51096 : }
+      56             : 
+      57       74043 : void Action::registerKeywords( Keywords& keys ) {
+      58       74043 :   plumed_assert( keys.size()==0 );
+      59      148086 :   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      148086 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
+      61      148086 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
+      62      148086 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
+      63       74043 : }
+      64             : 
+      65       51096 : Action::Action(const ActionOptions&ao):
+      66       51096 :   name(ao.line[0]),
+      67       51096 :   line(ao.line),
+      68       51096 :   update_from(std::numeric_limits<double>::max()),
+      69       51096 :   update_until(std::numeric_limits<double>::max()),
+      70       51096 :   timestep(0),
+      71       51096 :   active(false),
+      72       51096 :   restart(ao.plumed.getRestart()),
+      73       51096 :   doCheckPoint(ao.plumed.getCPT()),
+      74       51096 :   never_activate(name=="CONSTANT"),
+      75       51096 :   plumed(ao.plumed),
+      76       51096 :   log(plumed.getLog()),
+      77       51096 :   comm(plumed.comm),
+      78       51096 :   multi_sim_comm(plumed.multi_sim_comm),
+      79      102192 :   keywords(ao.keys)
+      80             : {
+      81             :   // Retrieve the timestep and save it
+      82       51096 :   resetStoredTimestep();
+      83             : 
+      84             :   line.erase(line.begin());
+      85      102192 :   if( !keywords.exists("NO_ACTION_LOG") ) {
+      86       35737 :     log.printf("Action %s\n",name.c_str());
+      87       35737 :     if(ao.fullPath.length()>0) log<<"  from library: "<<ao.fullPath<<"\n";
+      88             :   }
+      89             : 
+      90       51096 :   if(comm.Get_rank()==0) {
+      91       37187 :     replica_index=multi_sim_comm.Get_rank();
+      92             :   }
+      93       51096 :   comm.Bcast(replica_index,0);
+      94             : 
+      95      153076 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
+      96       51096 :   if(label.length()==0) {
+      97        3123 :     std::string s; Tools::convert(plumed.getActionSet().size()-plumed.getActionSet().select<ActionForInterface*>().size(),s);
+      98        6246 :     label="@"+s;
+      99       47979 :   } else if ( label.find(".")!=std::string::npos ) warning("using full stop in an action label should be avaoided as . has a special meaning in PLUMED action labels");
+     100       51096 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
+     101      102192 :   if( !keywords.exists("NO_ACTION_LOG") ) log.printf("  with label %s\n",label.c_str());
+     102      104427 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
+     103      102192 :   if( !keywords.exists("NO_ACTION_LOG") && update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
+     104      104427 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
+     105      102192 :   if( !keywords.exists("NO_ACTION_LOG") && update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
+     106      102192 :   if ( keywords.exists("RESTART") ) {
+     107        2161 :     std::string srestart="AUTO";
+     108        2160 :     parse("RESTART",srestart);
+     109        2160 :     if( plumed.parseOnlyMode() ) restart=false;
+     110        2160 :     else if(srestart=="YES") restart=true;
+     111        1999 :     else if(srestart=="NO")  restart=false;
+     112        1977 :     else if(srestart=="AUTO") {
+     113             :       // do nothing, this is the default
+     114           2 :     } else error("RESTART should be either YES, NO, or AUTO");
+     115             :   }
+     116       51096 : }
+     117             : 
+     118      100674 : void Action::resetStoredTimestep() {
+     119      100674 :   ActionWithValue* ts = plumed.getActionSet().selectWithLabel<ActionWithValue*>("timestep");
+     120      100674 :   if( ts ) timestep = (ts->copyOutput(0))->get();
+     121      100674 : }
+     122             : 
+     123      102190 : Action::~Action() {
+     124       51095 :   if(files.size()!=0) {
+     125           0 :     std::cerr<<"WARNING: some files open in action "+getLabel()+" where not properly closed. This could lead to data loss!!\n";
+     126             :   }
+     127      102190 : }
+     128             : 
+     129          82 : FILE* Action::fopen(const char *path, const char *mode) {
+     130             :   bool write(false);
+     131         164 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
+     132             :   FILE* fp;
+     133          82 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
+     134          82 :   else      fp=plumed.fopen(path,mode);
+     135          81 :   files.insert(fp);
+     136          81 :   return fp;
+     137             : }
+     138             : 
+     139          99 : int Action::fclose(FILE*fp) {
+     140             :   files.erase(fp);
+     141          99 :   return plumed.fclose(fp);
+     142             : }
+     143             : 
+     144       60986 : void Action::fflush() {
+     145       60986 :   for(const auto & p : files) {
+     146           0 :     std::fflush(p);
+     147             :   }
+     148       60986 : }
+     149             : 
+     150           0 : std::string Action::getKeyword(const std::string& key) {
+     151             :   // Check keyword has been registered
+     152           0 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     153             : 
+     154             :   std::string outkey;
+     155           0 :   if( Tools::getKey(line,key,outkey ) ) return key + outkey;
+     156             : 
+     157           0 :   if( keywords.style(key,"compulsory") ) {
+     158           0 :     if( keywords.getDefaultValue(key,outkey) ) {
+     159           0 :       if( outkey.length()==0 ) error("keyword " + key + " has weird default value");
+     160           0 :       return key + "=" +  outkey;
+     161             :     } else {
+     162           0 :       error("keyword " + key + " is compulsory for this action");
+     163             :     }
+     164             :   }
+     165           0 :   return "";
+     166             : }
+     167             : 
+     168       95605 : void Action::parseFlag(const std::string&key,bool & t) {
+     169             :   // Check keyword has been registered
+     170       95605 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     171             :   // Check keyword is a flag
+     172      191210 :   if(!keywords.style(key,"nohtml")) {
+     173      191210 :     plumed_massert( keywords.style(key,"vessel") || keywords.style(key,"flag") || keywords.style(key,"hidden"), "keyword " + key + " is not a flag");
+     174             :   }
+     175             : 
+     176             :   // Read in the flag otherwise get the default value from the keywords object
+     177       95605 :   if(!Tools::parseFlag(line,key,t)) {
+     178      167706 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
+     179           0 :       t=false;
+     180       83853 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
+     181           0 :       log.printf("ERROR in action %s with label %s : flag %s has no default",name.c_str(),label.c_str(),key.c_str() );
+     182           0 :       plumed_error();
+     183             :     }
+     184             :   }
+     185       95605 : }
+     186             : 
+     187     1263698 : void Action::addDependency(Action*action) {
+     188             :   bool found=false;
+     189    40068859 :   for(const auto & d : after ) {
+     190    39068120 :     if( action==d ) { found=true; break; }
+     191             :   }
+     192     1263698 :   if( !found ) after.push_back(action);
+     193     1263698 : }
+     194             : 
+     195      571368 : bool Action::checkForDependency( Action* action ) {
+     196     1124742 :   for(const auto & d : after) {
+     197      563928 :     if( action==d ) { return true; }
+     198      557559 :     if( d->checkForDependency(action) ) { return true; }
+     199             :   }
+     200             :   return false;
+     201             : }
+     202             : 
+     203     5181986 : void Action::activate() {
+     204             : // This is set to true if actions are only need to be computed in setup (during checkRead)
+     205     5181986 :   if( never_activate ) return;
+     206             : // preparation step is called only the first time an Action is activated.
+     207             : // since it could change its dependences (e.g. in an ActionAtomistic which is
+     208             : // accessing to a virtual atom), this is done just before dependencies are
+     209             : // activated
+     210     5067620 :   if(!active) {
+     211     2619452 :     this->unlockRequests();
+     212     2619452 :     prepare();
+     213     2619452 :     this->lockRequests();
+     214             :   } else return;
+     215     6458656 :   for(const auto & p : after) p->activate();
+     216     2619452 :   active=true;
+     217             : }
+     218             : 
+     219        2228 : void Action::setOption(const std::string &s) {
+     220             : // This overloads the action and activate some options
+     221        2228 :   options.insert(s);
+     222        4370 :   for(const auto & p : after) p->setOption(s);
+     223        2228 : }
+     224             : 
+     225           0 : void Action::clearOptions() {
+     226             : // This overloads the action and activate some options
+     227             :   options.clear();
+     228           0 : }
+     229             : 
+     230             : 
+     231      199627 : void Action::clearDependencies() {
+     232             :   after.clear();
+     233      199627 : }
+     234             : 
+     235       67161 : void Action::checkRead() {
+     236       67161 :   if(!line.empty()) {
+     237           1 :     std::string msg="cannot understand the following words from the input line : ";
+     238           2 :     for(unsigned i=0; i<line.size(); i++) {
+     239           1 :       if(i>0) msg = msg + ", ";
+     240           2 :       msg = msg + line[i];
+     241             :     }
+     242           1 :     error(msg);
+     243             :   }
+     244       67160 :   setupConstantValues(false);
+     245       67160 : }
+     246             : 
+     247       95051 : void Action::setupConstantValues( const bool& have_atoms ) {
+     248       95051 :   if( have_atoms ) {
+     249             :     // This ensures that we switch off actions that only depend on constant when passed from the
+     250             :     // MD code on the first step
+     251       27891 :     ActionAtomistic* at = castToActionAtomistic();
+     252       27891 :     ActionWithValue* av = castToActionWithValue();
+     253       27891 :     if( at && av ) {
+     254       15913 :       never_activate=av->getNumberOfComponents()>0;
+     255       15960 :       for(unsigned i=0; i<av->getNumberOfComponents(); ++i) {
+     256       15913 :         if( !av->copyOutput(i)->isConstant() ) { never_activate=false; break; }
+     257             :       }
+     258             :     }
+     259             :   }
+     260       95051 :   ActionWithArguments* aa = castToActionWithArguments();
+     261      114029 :   if( aa && aa->getNumberOfArguments()>0 && getName()!="BIASVALUE" ) never_activate = aa->calculateConstantValues( have_atoms );
+     262       95051 : }
+     263             : 
+     264     5396816 : long long int Action::getStep()const {
+     265     5396816 :   return plumed.getStep();
+     266             : }
+     267             : 
+     268     3667091 : double Action::getTime()const {
+     269     3667091 :   return timestep*getStep();
+     270             : }
+     271             : 
+     272      217999 : double Action::getTimeStep()const {
+     273      217999 :   return timestep;
+     274             : }
+     275             : 
+     276         632 : double Action::getkBT() {
+     277         632 :   double temp=-1.0;
+     278        1882 :   if( keywords.exists("TEMP") ) parse("TEMP",temp);
+     279        1570 :   if(temp>=0.0 && keywords.style("TEMP","optional") ) return getKBoltzmann()*temp;
+     280         250 :   ActionForInterface* kb=plumed.getActionSet().selectWithLabel<ActionForInterface*>("kBT");
+     281         250 :   double kbt=0; if(kb) kbt=(kb->copyOutput(0))->get();
+     282         366 :   if( temp>=0 && keywords.style("TEMP","compulsory") ) {
+     283          58 :     double kB=getKBoltzmann();
+     284          58 :     if( kbt>0 && std::abs(kbt-kB*temp)>1e-4) {
+     285           0 :       std::string strt1, strt2; Tools::convert( temp, strt1 ); Tools::convert( kbt/kB, strt2 );
+     286           0 :       warning("using TEMP=" + strt1 + " while MD engine uses " + strt2 + "\n");
+     287             :     }
+     288          58 :     kbt = kB*temp;
+     289          58 :     plumed_massert(kbt>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     290             :     return kbt;
+     291             :   }
+     292             :   return kbt;
+     293             : }
+     294             : 
+     295           0 : void Action::exit(int c) {
+     296           0 :   plumed.exit(c);
+     297           0 : }
+     298             : 
+     299           0 : void Action::calculateNumericalDerivatives( ActionWithValue* a ) {
+     300           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");
+     301             : }
+     302             : 
+     303      999973 : void Action::prepare() {
+     304      999973 :   return;
+     305             : }
+     306             : 
+     307          28 : [[noreturn]] void Action::error( const std::string & msg ) const {
+     308          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() );
+     309          84 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
+     310             : }
+     311             : 
+     312        4287 : void Action::warning( const std::string & msg ) {
+     313        4287 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
+     314        4287 : }
+     315             : 
+     316           0 : void Action::calculateFromPDB( const PDB& pdb ) {
+     317           0 :   activate();
+     318           0 :   for(const auto & p : after) {
+     319           0 :     ActionWithValue*av=castToActionWithValue();
+     320           0 :     if(av) { av->clearInputForces(); av->clearDerivatives(); }
+     321           0 :     p->readAtomsFromPDB( pdb );
+     322           0 :     p->calculate();
+     323             :   }
+     324           0 :   readAtomsFromPDB( pdb );
+     325           0 :   calculate();
+     326           0 : }
+     327             : 
+     328       28109 : bool Action::getExchangeStep()const {
+     329       28109 :   return plumed.getExchangeStep();
+     330             : }
+     331             : 
+     332          40 : std::string Action::cite(const std::string&s) {
+     333          40 :   return plumed.cite(s);
+     334             : }
+     335             : 
+     336             : /// Check if action should be updated.
+     337     2519892 : bool Action::checkUpdate()const {
+     338     2519892 :   double t=getTime();
+     339     2519892 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
+     340         510 :   else return false;
+     341             : }
+     342             : 
+     343        1095 : bool Action::getCPT() const {
+     344        1095 :   return plumed.getCPT();
+     345             : }
+     346             : 
+     347    15930476 : const Units& Action::getUnits() const {
+     348    15930476 :   return plumed.getUnits();
+     349             : }
+     350             : 
+     351        2137 : bool Action::usingNaturalUnits() const {
+     352        2137 :   return plumed.usingNaturalUnits();
+     353             : }
+     354             : 
+     355         675 : double Action::getKBoltzmann() const {
+     356         675 :   if( usingNaturalUnits() ) return 1.0;
+     357         675 :   else return kBoltzmann/getUnits().getEnergy();
+     358             : }
+     359             : 
+     360          88 : std::string Action::writeInGraph() const {
+     361          44 :   std::string nam=getName();
+     362          44 :   std::size_t u=nam.find_last_of("_"); std::string sub=nam.substr(u+1);
+     363         118 :   if( sub=="SCALAR" || sub=="VECTOR" || sub=="GRID" ) return nam.substr(0,u);
+     364             :   return nam;
+     365             : }
+     366             : 
+     367             : }
+     368             : 
+
+
+
+ + + + +
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 000000000..b55776f3f --- /dev/null +++ b/coverage/core/Action.h.func-sort-c.html @@ -0,0 +1,224 @@ + + + + + + + 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:798494.0 %
Date:2024-10-17 16:45:00Functions:343889.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action13parseNumberedIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_0
_ZN4PLMD6Action15castToPbcActionEv0
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action21castToActionToGetDataEv0
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_12
_ZN4PLMD6Action19parseNumberedVectorIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE36
_ZN4PLMD6Action20castToActionShortcutEv100
_ZN4PLMD6Action5parseIxEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action24castToActionForInterfaceEv620
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1392
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1518
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5921
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_7658
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE7799
_ZN4PLMD6Action25castToDomainDecompositionEv7860
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE16368
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_28837
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE34268
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_39889
_ZN4PLMD6Action12runFinalJobsEv46124
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE58546
_ZN4PLMD6Action25castToActionWithArgumentsEv73954
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_96755
_ZN4PLMD6Action19parseNumberedVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE132501
_ZNK4PLMD6Action25checkNumericalDerivativesEv277082
_ZN4PLMD6Action21castToActionWithValueEv288638
_ZN4PLMD6Action6updateEv1270745
_ZN4PLMD6Action12lockRequestsEv1465590
_ZN4PLMD6Action14unlockRequestsEv1465590
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1851003
_ZN4PLMD6Action21castToActionAtomisticEv2154076
_ZNK4PLMD6Action19checkNeedsGradientsEv2609245
_ZN4PLMD6Action27castToActionWithVirtualAtomEv3387489
_ZN4PLMD6Action12beforeUpdateEv4103246
_ZN4PLMD6Action10deactivateEv4354925
_ZN4PLMD6Action21castToActionToPutDataEv7394247
+
+
+ + + +
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 000000000..5c51559e4 --- /dev/null +++ b/coverage/core/Action.h.func.html @@ -0,0 +1,224 @@ + + + + + + + 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:798494.0 %
Date:2024-10-17 16:45:00Functions:343889.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action10deactivateEv4354925
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE58546
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE16368
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE36
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE7799
_ZN4PLMD6Action12beforeUpdateEv4103246
_ZN4PLMD6Action12lockRequestsEv1465590
_ZN4PLMD6Action12runFinalJobsEv46124
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_39889
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1518
_ZN4PLMD6Action13parseNumberedIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_0
_ZN4PLMD6Action14unlockRequestsEv1465590
_ZN4PLMD6Action15castToPbcActionEv0
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE34268
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1392
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action19parseNumberedVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE132501
_ZN4PLMD6Action19parseNumberedVectorIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action20castToActionShortcutEv100
_ZN4PLMD6Action21castToActionAtomisticEv2154076
_ZN4PLMD6Action21castToActionToGetDataEv0
_ZN4PLMD6Action21castToActionToPutDataEv7394247
_ZN4PLMD6Action21castToActionWithValueEv288638
_ZN4PLMD6Action24castToActionForInterfaceEv620
_ZN4PLMD6Action25castToActionWithArgumentsEv73954
_ZN4PLMD6Action25castToDomainDecompositionEv7860
_ZN4PLMD6Action27castToActionWithVirtualAtomEv3387489
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_96755
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_28837
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_7658
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5921
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_12
_ZN4PLMD6Action5parseIxEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action6updateEv1270745
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1851003
_ZNK4PLMD6Action19checkNeedsGradientsEv2609245
_ZNK4PLMD6Action25checkNumericalDerivativesEv277082
+
+
+ + + +
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 000000000..ef97b32e1 --- /dev/null +++ b/coverage/core/Action.h.gcov.html @@ -0,0 +1,561 @@ + + + + + + + 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:798494.0 %
Date:2024-10-17 16:45:00Functions:343889.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_Action_h
+      23             : #define __PLUMED_core_Action_h
+      24             : #include <vector>
+      25             : #include <string>
+      26             : #include <set>
+      27             : #include "tools/Keywords.h"
+      28             : #include "tools/Tools.h"
+      29             : #include "tools/Units.h"
+      30             : #include "tools/Log.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class PDB;
+      35             : class PlumedMain;
+      36             : class Communicator;
+      37             : class ActionWithValue;
+      38             : class ActionWithArguments;
+      39             : class ActionAtomistic;
+      40             : class ActionWithVirtualAtom;
+      41             : class PbcAction;
+      42             : class ActionToGetData;
+      43             : class ActionToPutData;
+      44             : class DomainDecomposition;
+      45             : class ActionForInterface;
+      46             : class ActionShortcut;
+      47             : 
+      48             : /// This class is used to bring the relevant information to the Action constructor.
+      49             : /// Only Action and ActionRegister class can access to its content, which is
+      50             : /// kept private to other classes, and may change in the future.
+      51      102194 : 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       51096 :   }
+      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     1465590 :   virtual void lockRequests() {}
+     237     1465590 :   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     4103246 :   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     1270745 :   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       46124 :   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      277082 :   virtual bool checkNumericalDerivatives()const {return false;}
+     299             : 
+     300             : /// Check if the action needs gradient
+     301     2609245 :   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             : /// Set the timestep that is stored in the action to the correct value
+     333             :   void resetStoredTimestep();
+     334             : 
+     335             : /// Get the info on what to calculate
+     336             :   virtual std::string writeInGraph() const ;
+     337             : /// Specialized casts, to make PlumedMain run faster
+     338      288638 :   virtual ActionWithValue* castToActionWithValue() noexcept { return nullptr; }
+     339       73954 :   virtual ActionWithArguments* castToActionWithArguments() noexcept { return nullptr; }
+     340     2154076 :   virtual ActionAtomistic* castToActionAtomistic() noexcept { return nullptr; }
+     341     3387489 :   virtual ActionWithVirtualAtom* castToActionWithVirtualAtom() noexcept { return nullptr; }
+     342           0 :   virtual PbcAction* castToPbcAction() noexcept { return nullptr; }
+     343     7394247 :   virtual ActionToPutData* castToActionToPutData() noexcept { return nullptr; }
+     344           0 :   virtual ActionToGetData* castToActionToGetData() noexcept { return nullptr; }
+     345        7860 :   virtual DomainDecomposition* castToDomainDecomposition() noexcept { return nullptr; }
+     346         620 :   virtual ActionForInterface* castToActionForInterface() noexcept { return nullptr; }
+     347         100 :   virtual ActionShortcut* castToActionShortcut() noexcept { return nullptr; }
+     348             : };
+     349             : 
+     350             : /////////////////////
+     351             : // FAST INLINE METHODS
+     352             : 
+     353             : inline
+     354             : const std::string & Action::getLabel()const {
+     355   176422120 :   return label;
+     356             : }
+     357             : 
+     358             : inline
+     359             : const std::string & Action::getName()const {
+     360    20777932 :   return name;
+     361             : }
+     362             : 
+     363             : template<class T>
+     364      139292 : void Action::parse(const std::string&key,T&t) {
+     365             :   // Check keyword has been registered
+     366      139292 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     367             : 
+     368             :   // Now try to read the keyword
+     369             :   std::string def;
+     370      139292 :   bool present=Tools::findKeyword(line,key);
+     371      139292 :   bool found=Tools::parse(line,key,t,replica_index);
+     372      139295 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     373             : 
+     374             :   // If it isn't read and it is compulsory see if a default value was specified
+     375      247994 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     376       20343 :     if( keywords.getDefaultValue(key,def) ) {
+     377       14811 :       if( def.length()==0 || !Tools::convertNoexcept(def,t) ) {
+     378           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     379             :       }
+     380       29622 :       defaults += " " + key + "=" + def;
+     381       11064 :     } else if( keywords.style(key,"compulsory") ) {
+     382           3 :       error("keyword " + key + " is compulsory for this action");
+     383             :     }
+     384             :   }
+     385      139289 : }
+     386             : 
+     387             : template<class T>
+     388       41407 : bool Action::parseNumbered(const std::string&key, const int no, T&t) {
+     389             :   // Check keyword has been registered
+     390       41407 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     391       41407 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     392             : 
+     393             :   // Now try to read the keyword
+     394       41407 :   std::string num; Tools::convert(no,num);
+     395       82814 :   return Tools::parse(line,key+num,t,replica_index);
+     396             : }
+     397             : 
+     398             : template<class T>
+     399       82749 : void Action::parseVector(const std::string&key,std::vector<T>&t) {
+     400             :   // Check keyword has been registered
+     401       82749 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     402       82749 :   unsigned size=t.size(); bool skipcheck=false;
+     403       82749 :   if(size==0) skipcheck=true;
+     404             : 
+     405             :   // Now try to read the keyword
+     406             :   std::string def; T val;
+     407       82749 :   bool present=Tools::findKeyword(line,key);
+     408       82749 :   bool found=Tools::parseVector(line,key,t,replica_index);
+     409       82750 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     410             : 
+     411             :   // Check vectors size is correct (not if this is atoms or ARG)
+     412      165496 :   if( !keywords.style(key,"atoms") && found ) {
+     413             : //     bool skipcheck=false;
+     414             : //     if( keywords.style(key,"compulsory") ){ keywords.getDefaultValue(key,def); skipcheck=(def=="nosize"); }
+     415       51317 :     if( !skipcheck && t.size()!=size ) error("vector read in for keyword " + key + " has the wrong size");
+     416             :   }
+     417             : 
+     418             :   // If it isn't read and it is compulsory see if a default value was specified
+     419      113496 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     420        2945 :     if( keywords.getDefaultValue(key,def) ) {
+     421        2836 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
+     422           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     423             :       } else {
+     424        2836 :         if(t.size()>0) {
+     425        5338 :           for(unsigned i=0; i<t.size(); ++i) t[i]=val;
+     426        5338 :           defaults += " " + key + "=" + def; for(unsigned i=1; i<t.size(); ++i) defaults += "," + def;
+     427        2816 :         } else { t.push_back(val); defaults += " " + key + "=" + def; }
+     428             :       }
+     429         218 :     } else if( keywords.style(key,"compulsory") ) {
+     430           4 :       error("keyword " + key + " is compulsory for this action");
+     431             :     }
+     432       79800 :   } else if ( !found ) {
+     433       13794 :     t.resize(0);
+     434             :   }
+     435       82745 : }
+     436             : 
+     437             : template<class T>
+     438      168207 : bool Action::parseNumberedVector(const std::string&key, const int no, std::vector<T>&t) {
+     439      168207 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     440      168207 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     441             : 
+     442      168207 :   unsigned size=t.size(); bool skipcheck=false;
+     443      168207 :   if(size==0) skipcheck=true;
+     444      168207 :   std::string num; Tools::convert(no,num);
+     445      168207 :   bool present=Tools::findKeyword(line,key);
+     446      168207 :   bool found=Tools::parseVector(line,key+num,t,replica_index);
+     447      168207 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     448             : 
+     449      336414 :   if(  keywords.style(key,"compulsory") ) {
+     450         115 :     if (!skipcheck && found && t.size()!=size ) error("vector read in for keyword " + key + num + " has the wrong size");
+     451      168092 :   } else if ( !found ) {
+     452        1503 :     t.resize(0);
+     453             :   }
+     454      168207 :   return found;
+     455             : }
+     456             : 
+     457             : inline
+     458     4354925 : void Action::deactivate() {
+     459             :   options.clear();
+     460     4354925 :   active=false;
+     461     4354925 : }
+     462             : 
+     463             : inline
+     464             : bool Action::isActive()const {
+     465   225955735 :   return active;
+     466             : }
+     467             : 
+     468             : inline
+     469     1851003 : bool Action::isOptionOn(const std::string &s)const {
+     470     1851003 :   return options.count(s);
+     471             : }
+     472             : 
+     473             : inline
+     474             : bool Action::getRestart()const {
+     475        3997 :   return restart;
+     476             : }
+     477             : 
+     478             : inline
+     479             : std::string Action::getDefaultString() const {
+     480          32 :   return defaults;
+     481             : }
+     482             : 
+     483             : }
+     484             : #endif
+     485             : 
+
+
+
+ + + + +
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 000000000..11ec2c35b --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE161
+
+
+ + + +
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 000000000..436d0a706 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE161
+
+
+ + + +
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 000000000..12cc04e81 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.gcov.html @@ -0,0 +1,114 @@ + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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         161 : ActionAnyorder::ActionAnyorder(const ActionOptions&ao):
+      30         161 :   Action(ao)
+      31             : {
+      32         161 : }
+      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 000000000..7c7893e2d --- /dev/null +++ b/coverage/core/ActionAnyorder.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..f73eaac8a --- /dev/null +++ b/coverage/core/ActionAnyorder.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..de5101f6f --- /dev/null +++ b/coverage/core/ActionAnyorder.h.gcov.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-10-17 16:45:00Functions: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          97 : 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 000000000..cdeb6015c --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func-sort-c.html @@ -0,0 +1,184 @@ + + + + + + + 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:28730394.7 %
Date:2024-10-17 16:45:00Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZNK4PLMD15ActionAtomistic9getVirialEv6
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE28
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE156
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj240
_ZNK4PLMD15ActionAtomistic11getGradientERKjRNS_13VectorGenericILj3EEERSt3mapINS_10AtomNumberES4_St4lessIS7_ESaISt4pairIKS7_S4_EEE8208
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE13898
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb14052
_ZNK4PLMD15ActionAtomistic11getTotAtomsEv14315
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE18279
_ZN4PLMD15ActionAtomisticD2Ev18279
_ZN4PLMD15ActionAtomistic29getAtomValuesFromPlumedObjectERKNS_10PlumedMainERSt6vectorIPNS_5ValueESaIS6_EES9_S9_S9_S9_18287
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE30803
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS1_IPNS_5ValueESaISC_EEPNS_6ActionERS1_INS_10AtomNumberESaISJ_EE47930
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE51431
_ZN4PLMD15ActionAtomistic15actionHasForcesEv104010
_ZN4PLMD15ActionAtomistic15setForcesOnCellERKSt6vectorIdSaIdEERj142235
_ZN4PLMD15ActionAtomistic9makeWholeEv148438
_ZN4PLMD15ActionAtomistic15setForcesOnCellEPKdmRj165136
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEERj245975
_ZN4PLMD15ActionAtomistic17updateUniqueLocalERKbRKSt6vectorIiSaIiEE253978
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj405876
_ZN4PLMD15ActionAtomistic13retrieveAtomsERKb540990
_ZNK4PLMD15ActionAtomistic15getValueIndicesERKNS_10AtomNumberE1761170
+
+
+ + + +
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 000000000..867df647a --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func.html @@ -0,0 +1,184 @@ + + + + + + + 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:28730394.7 %
Date:2024-10-17 16:45:00Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb14052
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE13898
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE51431
_ZN4PLMD15ActionAtomistic13retrieveAtomsERKb540990
_ZN4PLMD15ActionAtomistic15actionHasForcesEv104010
_ZN4PLMD15ActionAtomistic15setForcesOnCellEPKdmRj165136
_ZN4PLMD15ActionAtomistic15setForcesOnCellERKSt6vectorIdSaIdEERj142235
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE30803
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEERj245975
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS1_IPNS_5ValueESaISC_EEPNS_6ActionERS1_INS_10AtomNumberESaISJ_EE47930
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE28
_ZN4PLMD15ActionAtomistic17updateUniqueLocalERKbRKSt6vectorIiSaIiEE253978
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE156
_ZN4PLMD15ActionAtomistic29getAtomValuesFromPlumedObjectERKNS_10PlumedMainERSt6vectorIPNS_5ValueESaIS6_EES9_S9_S9_S9_18287
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj240
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomistic9makeWholeEv148438
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE18279
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZN4PLMD15ActionAtomisticD2Ev18279
_ZNK4PLMD15ActionAtomistic11getGradientERKjRNS_13VectorGenericILj3EEERSt3mapINS_10AtomNumberES4_St4lessIS7_ESaISt4pairIKS7_S4_EEE8208
_ZNK4PLMD15ActionAtomistic11getTotAtomsEv14315
_ZNK4PLMD15ActionAtomistic15getValueIndicesERKNS_10AtomNumberE1761170
_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 000000000..6a96dfb99 --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.gcov.html @@ -0,0 +1,561 @@ + + + + + + + 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:28730394.7 %
Date:2024-10-17 16:45:00Functions:232882.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 "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 "ActionShortcut.h"
+      31             : #include "Group.h"
+      32             : #include "ActionWithVirtualAtom.h"
+      33             : #include "tools/Exception.h"
+      34             : #include "tools/Pbc.h"
+      35             : #include "tools/PDB.h"
+      36             : 
+      37             : namespace PLMD {
+      38             : 
+      39       18279 : ActionAtomistic::~ActionAtomistic() {
+      40             : // empty destructor to delete unique_ptr
+      41       18279 : }
+      42             : 
+      43       18279 : ActionAtomistic::ActionAtomistic(const ActionOptions&ao):
+      44             :   Action(ao),
+      45       18279 :   unique_local_needs_update(true),
+      46       18279 :   boxValue(NULL),
+      47       18279 :   lockRequestAtoms(false),
+      48       18279 :   donotretrieve(false),
+      49       18279 :   donotforce(false),
+      50       18279 :   massesWereSet(false),
+      51       18279 :   chargesWereSet(false)
+      52             : {
+      53       18279 :   ActionWithValue* bv = plumed.getActionSet().selectWithLabel<ActionWithValue*>("Box");
+      54       18279 :   if( bv ) boxValue=bv->copyOutput(0);
+      55             :   // We now get all the information about atoms that are lying about
+      56       18279 :   getAtomValuesFromPlumedObject( plumed, xpos, ypos, zpos, masv, chargev );
+      57       18279 :   if( xpos.size()!=ypos.size() || xpos.size()!=zpos.size() || xpos.size()!=masv.size() || xpos.size()!=chargev.size() )
+      58           0 :     error("mismatch between value arrays");
+      59       18279 : }
+      60             : 
+      61       18287 : void ActionAtomistic::getAtomValuesFromPlumedObject( const PlumedMain& plumed, std::vector<Value*>& xpos, std::vector<Value*>& ypos, std::vector<Value*>& zpos, std::vector<Value*>& masv, std::vector<Value*>& chargev ) {
+      62       18287 :   std::vector<ActionShortcut*> shortcuts = plumed.getActionSet().select<ActionShortcut*>(); bool foundpdb=false;
+      63     6737198 :   for(const auto & ss : shortcuts ) {
+      64     6718911 :     if( ss->getName()=="READMASSCHARGE" ) {
+      65             :       foundpdb=true;
+      66           2 :       ActionWithValue* mv = plumed.getActionSet().selectWithLabel<ActionWithValue*>( ss->getShortcutLabel() + "_mass");
+      67           2 :       plumed_assert( mv ); masv.push_back( mv->copyOutput(0) );
+      68           2 :       ActionWithValue* qv = plumed.getActionSet().selectWithLabel<ActionWithValue*>( ss->getShortcutLabel() + "_charges");
+      69           2 :       plumed_assert( qv ); chargev.push_back( qv->copyOutput(0) );
+      70             :     }
+      71             :   }
+      72       18287 :   std::vector<ActionWithValue*> vatoms = plumed.getActionSet().select<ActionWithValue*>();
+      73     7539134 :   for(const auto & vv : vatoms ) {
+      74     7520847 :     plumed_assert(vv); // needed for following calls, see #1046
+      75     7520847 :     ActionToPutData* ap = vv->castToActionToPutData();
+      76     7520847 :     if( ap ) {
+      77      253206 :       if( ap->getRole()=="x" ) xpos.push_back( ap->copyOutput(0) );
+      78      253206 :       if( ap->getRole()=="y" ) ypos.push_back( ap->copyOutput(0) );
+      79      253206 :       if( ap->getRole()=="z" ) zpos.push_back( ap->copyOutput(0) );
+      80      379781 :       if( !foundpdb && ap->getRole()=="m" ) masv.push_back( ap->copyOutput(0) );
+      81      379781 :       if( !foundpdb && ap->getRole()=="q" ) chargev.push_back( ap->copyOutput(0) );
+      82             :     }
+      83     7520847 :     ActionWithVirtualAtom* av = vv->castToActionWithVirtualAtom();
+      84     7520847 :     if( av || vv->getName()=="ARGS2VATOM" ) {
+      85     6711834 :       xpos.push_back( vv->copyOutput( vv->getLabel() + ".x") );
+      86     6711834 :       ypos.push_back( vv->copyOutput( vv->getLabel() + ".y") );
+      87     6711834 :       zpos.push_back( vv->copyOutput( vv->getLabel() + ".z") );
+      88     6711834 :       masv.push_back( vv->copyOutput( vv->getLabel() + ".mass") );
+      89     6711834 :       chargev.push_back( vv->copyOutput( vv->getLabel() + ".charge") );
+      90             :     }
+      91             :   }
+      92       18287 : }
+      93             : 
+      94       30803 : void ActionAtomistic::registerKeywords( Keywords& keys ) {
+      95             :   (void) keys; // avoid warning
+      96       30803 : }
+      97             : 
+      98             : 
+      99       14052 : void ActionAtomistic::requestAtoms(const std::vector<AtomNumber> & a, const bool clearDep) {
+     100       14052 :   plumed_massert(!lockRequestAtoms,"requested atom list can only be changed in the prepare() method");
+     101       14052 :   int nat=a.size();
+     102       14052 :   indexes=a;
+     103       14052 :   positions.resize(nat);
+     104       14052 :   forces.resize(nat);
+     105       14052 :   masses.resize(nat);
+     106       14052 :   charges.resize(nat);
+     107       14052 :   atom_value_ind.resize( a.size() );
+     108       14052 :   int n=getTotAtoms();
+     109       14052 :   if(clearDep) clearDependencies();
+     110       14581 :   unique.clear(); std::vector<bool> requirements( xpos.size(), false );
+     111       14052 :   if( boxValue ) addDependency( boxValue->getPntrToAction() );
+     112     1337327 :   for(unsigned i=0; i<indexes.size(); i++) {
+     113     1323278 :     if(indexes[i].index()>=n) { std::string num; Tools::convert( indexes[i].serial(),num ); error("atom " + num + " out of range"); }
+     114     1323275 :     atom_value_ind[i] = getValueIndices( indexes[i] ); requirements[atom_value_ind[i].first] = true;
+     115     1323275 :     if( atom_value_ind[i].first==0 ) unique.push_back(indexes[i]);
+     116       18024 :     else if( atom_value_ind[i].second>0 ) error("action atomistic is not set up to deal with multiple vectors in position input");
+     117             :   }
+     118             : 
+     119       14051 :   atom_value_ind_grouped.clear();
+     120             : 
+     121       14051 :   if(atom_value_ind.size()>0) {
+     122       14010 :     auto nn = atom_value_ind[0].first;
+     123       14010 :     auto kk = atom_value_ind[0].second;
+     124       14010 :     atom_value_ind_grouped.push_back(std::pair<std::size_t,std::vector<std::size_t>>(nn, {}));
+     125       14010 :     atom_value_ind_grouped.back().second.push_back(kk);
+     126             :     auto prev_nn=nn;
+     127     1323268 :     for(unsigned i=1; i<atom_value_ind.size(); i++) {
+     128     1309258 :       auto nn = atom_value_ind[i].first;
+     129     1309258 :       auto kk = atom_value_ind[i].second;
+     130     1328941 :       if(nn!=prev_nn) atom_value_ind_grouped.push_back(std::pair<std::size_t,std::vector<std::size_t>>(nn, {}));
+     131     1309258 :       atom_value_ind_grouped.back().second.push_back(kk);
+     132             :       prev_nn=nn;
+     133             :     }
+     134             :   }
+     135             : 
+     136             :   // Add the dependencies to the actions that we require
+     137       14051 :   Tools::removeDuplicates(unique); value_depends.resize(0);
+     138     6661321 :   for(unsigned i=0; i<requirements.size(); ++i ) {
+     139     6647270 :     if( !requirements[i] ) continue;
+     140       30758 :     value_depends.push_back( i );
+     141       30757 :     addDependency( xpos[i]->getPntrToAction() );
+     142       30757 :     addDependency( ypos[i]->getPntrToAction() );
+     143       30757 :     addDependency( zpos[i]->getPntrToAction() );
+     144       30757 :     addDependency( masv[i]->getPntrToAction() );
+     145       30757 :     addDependency( chargev[i]->getPntrToAction() );
+     146             :   }
+     147       14051 :   unique_local_needs_update=true;
+     148       14051 : }
+     149             : 
+     150      405876 : void ActionAtomistic::pbcApply(std::vector<Vector>& dlist, unsigned max_index)const {
+     151      405876 :   pbc.apply(dlist, max_index);
+     152      405876 : }
+     153             : 
+     154         156 : void ActionAtomistic::calculateNumericalDerivatives( ActionWithValue* a ) {
+     155         156 :   calculateAtomicNumericalDerivatives( a, 0 );
+     156         156 : }
+     157             : 
+     158           0 : void ActionAtomistic::changeBox( const Tensor& newbox ) {
+     159           0 :   pbc.setBox( newbox );
+     160           0 : }
+     161             : 
+     162         240 : void ActionAtomistic::calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum ) {
+     163         240 :   if(!a) {
+     164         240 :     a=castToActionWithValue();
+     165         240 :     plumed_massert(a,"only Actions with a value can be differentiated");
+     166             :   }
+     167             : 
+     168         240 :   const size_t nval=a->getNumberOfComponents();
+     169         240 :   const size_t natoms=getNumberOfAtoms();
+     170         240 :   std::vector<Vector> value(nval*natoms);
+     171         240 :   std::vector<Tensor> valuebox(nval);
+     172         240 :   std::vector<Vector> savedPositions(natoms);
+     173             :   const double delta=std::sqrt(epsilon);
+     174             : 
+     175       82068 :   for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     176       61371 :       savedPositions[i][k]=positions[i][k];
+     177       61371 :       positions[i][k]=positions[i][k]+delta;
+     178       61371 :       a->calculate();
+     179       61371 :       positions[i][k]=savedPositions[i][k];
+     180      188208 :       for(int j=0; j<nval; j++) {
+     181      126837 :         value[j*natoms+i][k]=a->getOutputQuantity(j);
+     182             :       }
+     183             :     }
+     184         240 :   Tensor box(pbc.getBox());
+     185        3120 :   for(int i=0; i<3; i++) for(int k=0; k<3; k++) {
+     186        2160 :       double arg0=box(i,k);
+     187      186273 :       for(int j=0; j<natoms; j++) positions[j]=pbc.realToScaled(positions[j]);
+     188        2160 :       box(i,k)=box(i,k)+delta;
+     189        2160 :       pbc.setBox(box);
+     190      186273 :       for(int j=0; j<natoms; j++) positions[j]=pbc.scaledToReal(positions[j]);
+     191        2160 :       a->calculate();
+     192        2160 :       box(i,k)=arg0;
+     193        2160 :       pbc.setBox(box);
+     194      186273 :       for(int j=0; j<natoms; j++) positions[j]=savedPositions[j];
+     195       14886 :       for(int j=0; j<nval; j++) valuebox[j](i,k)=a->getOutputQuantity(j);
+     196             :     }
+     197             : 
+     198         240 :   a->calculate();
+     199         240 :   a->clearDerivatives();
+     200        1654 :   for(int j=0; j<nval; j++) {
+     201        1414 :     Value* v=a->copyOutput(j);
+     202        1414 :     double ref=v->get();
+     203        1414 :     if(v->hasDerivatives()) {
+     204       89779 :       for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     205       66975 :           double d=(value[j*natoms+i][k]-ref)/delta;
+     206       66975 :           v->addDerivative(startnum+3*i+k,d);
+     207             :         }
+     208         479 :       Tensor virial;
+     209        6227 :       for(int i=0; i<3; i++) for(int k=0; k<3; k++)virial(i,k)= (valuebox[j](i,k)-ref)/delta;
+     210             : // BE CAREFUL WITH NON ORTHOROMBIC CELL
+     211         479 :       virial=-matmul(box.transpose(),virial);
+     212        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));
+     213             :     }
+     214             :   }
+     215         240 : }
+     216             : 
+     217      104010 : bool ActionAtomistic::actionHasForces() {
+     218      104010 :   ActionWithValue* av = castToActionWithValue();
+     219      104010 :   if( av ) return !av->doNotCalculateDerivatives();
+     220           0 :   if( indexes.size()>0 ) plumed_merror("you have to overwrite the function actionHasForce to tell plumed if you method applies forces");
+     221             :   return true;
+     222             : }
+     223             : 
+     224       13898 : void ActionAtomistic::parseAtomList(const std::string&key, std::vector<AtomNumber> &t) {
+     225       13898 :   parseAtomList(key,-1,t);
+     226       13897 : }
+     227             : 
+     228       51431 : void ActionAtomistic::parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t) {
+     229       51431 :   plumed_massert( keywords.style(key,"atoms") || keywords.style(key,"hidden"), "keyword " + key + " should be registered as atoms");
+     230             :   std::vector<std::string> strings;
+     231       51431 :   if( num<0 ) {
+     232       17374 :     parseVector(key,strings);
+     233       17373 :     if(strings.empty()) return;
+     234             :   } else {
+     235       34057 :     if ( !parseNumberedVector(key,num,strings) ) return;
+     236             :   }
+     237       47338 :   t.resize(0); interpretAtomList( strings, xpos, this, t );
+     238       51431 : }
+     239             : 
+     240          28 : void ActionAtomistic::interpretAtomList(std::vector<std::string>& strings, std::vector<AtomNumber> &t) {
+     241          28 :   interpretAtomList( strings, xpos, this, t );
+     242          28 : }
+     243             : 
+     244       47930 : void ActionAtomistic::interpretAtomList(std::vector<std::string>& strings, const std::vector<Value*>& xpos, Action* action, std::vector<AtomNumber> &t) {
+     245       47930 :   Tools::interpretRanges(strings);
+     246     1159762 :   for(unsigned i=0; i<strings.size(); ++i) {
+     247             :     AtomNumber atom;
+     248     1111832 :     bool ok=Tools::convertNoexcept(strings[i],atom); // this is converting strings to AtomNumbers
+     249     1111832 :     if(ok) t.push_back(atom);
+     250             : // here we check if this is a special symbol for MOLINFO
+     251     1111832 :     if( !ok && strings[i].compare(0,1,"@")==0 ) {
+     252         699 :       std::string symbol=strings[i].substr(1);
+     253         699 :       if(symbol=="allatoms") {
+     254          24 :         auto n=0; for(unsigned i=0; i<xpos.size(); ++i) n += xpos[i]->getNumberOfValues();
+     255         365 :         t.reserve(n); for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     256             :         ok=true;
+     257         689 :       } else if(symbol=="mdatoms") {
+     258          14 :         const auto n=xpos[0]->getNumberOfValues();
+     259          14 :         t.reserve(t.size()+n);
+     260        1166 :         for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     261             :         ok=true;
+     262        1350 :       } else if(Tools::startWith(symbol,"ndx:")) {
+     263          40 :         auto words=Tools::getWords(symbol.substr(4));
+     264             :         std::string ndxfile,ndxgroup;
+     265          20 :         if(words.size()==1) {
+     266             :           ndxfile=words[0];
+     267          18 :         } else if(words.size()==2) {
+     268             :           ndxfile=words[0];
+     269             :           ndxgroup=words[1];
+     270           0 :         } else plumed_error()<<"Cannot intepret selection "<<symbol;
+     271             : 
+     272          38 :         if(ndxgroup.size()>0) action->log<<"  importing group '"+ndxgroup+"'";
+     273           2 :         else                  action->log<<"  importing first group";
+     274          20 :         action->log<<" from index file "<<ndxfile<<"\n";
+     275             : 
+     276          20 :         IFile ifile;
+     277          20 :         ifile.open(ndxfile);
+     278             :         std::string line;
+     279             :         std::string groupname;
+     280             :         bool firstgroup=true;
+     281             :         bool groupfound=false;
+     282        3849 :         while(ifile.getline(line)) {
+     283        3829 :           std::vector<std::string> words=Tools::getWords(line);
+     284        7765 :           if(words.size()>=3 && words[0]=="[" && words[2]=="]") {
+     285         168 :             if(groupname.length()>0) firstgroup=false;
+     286             :             groupname=words[1];
+     287         168 :             if(groupname==ndxgroup || ndxgroup.length()==0) groupfound=true;
+     288        3661 :           } else if(groupname==ndxgroup || (firstgroup && ndxgroup.length()==0)) {
+     289        6186 :             for(unsigned i=0; i<words.size(); i++) {
+     290        5782 :               AtomNumber at; Tools::convert(words[i],at);
+     291        5782 :               t.push_back(at);
+     292             :             }
+     293             :           }
+     294        3829 :         }
+     295          20 :         if(!groupfound) plumed_error()<<"group has not been found in index file";
+     296             :         ok=true;
+     297          40 :       } else {
+     298         655 :         auto* moldat=action->plumed.getActionSet().selectLatest<GenericMolInfo*>(action);
+     299         655 :         if( moldat ) {
+     300         655 :           std::vector<AtomNumber> atom_list; moldat->interpretSymbol( symbol, atom_list );
+     301         655 :           if( atom_list.size()>0 ) { ok=true; t.insert(t.end(),atom_list.begin(),atom_list.end()); }
+     302           0 :           else { action->error(strings[i] + " is not a label plumed knows"); }
+     303             :         } else {
+     304           0 :           action->error("atoms specified using @ symbol but no MOLINFO was available");
+     305             :         }
+     306             :       }
+     307             :     }
+     308             : // here we check if the atom name is the name of a group
+     309     1111133 :     if(!ok) {
+     310       24226 :       Group* mygrp=action->plumed.getActionSet().selectWithLabel<Group*>(strings[i]);
+     311       24226 :       if(mygrp) {
+     312         445 :         std::vector<std::string> grp_str( mygrp->getGroupAtoms() );
+     313         445 :         interpretAtomList( grp_str, xpos, action, t ); ok=true;
+     314         445 :       } else {
+     315       23781 :         Group* mygrp2=action->plumed.getActionSet().selectWithLabel<Group*>(strings[i]+"_grp");
+     316       23781 :         if(mygrp2) {
+     317         111 :           std::vector<std::string> grp_str( mygrp2->getGroupAtoms() );
+     318         111 :           interpretAtomList( grp_str, xpos, action, t ); ok=true;
+     319         111 :         }
+     320             :       }
+     321             :     }
+     322             : // here we check if the atom name is the name of an added virtual atom
+     323     1111276 :     if(!ok) {
+     324             :       unsigned ind = 0;
+     325    13269158 :       for(unsigned j=0; j<xpos.size(); ++j) {
+     326    13269158 :         if( xpos[j]->getPntrToAction()->getLabel()==strings[i] ) {
+     327       23670 :           t.push_back( AtomNumber::index(ind) ); ok=true; break;
+     328             :         }
+     329    13245488 :         ind = ind + xpos[j]->getNumberOfValues();
+     330             :       }
+     331             :     }
+     332     1088162 :     if(!ok) action->error("it was not possible to interpret atom name " + strings[i]);
+     333             :     // plumed_massert(ok,"it was not possible to interpret atom name " + strings[i]);
+     334             :   }
+     335       47930 : }
+     336             : 
+     337     1761170 : std::pair<std::size_t, std::size_t> ActionAtomistic::getValueIndices( const AtomNumber& i ) const {
+     338     1761170 :   std::size_t valno=0, k = i.index();
+     339    15486384 :   for(unsigned j=0; j<xpos.size(); ++j) {
+     340    15486384 :     if( k<xpos[j]->getNumberOfValues() ) { valno=j; break; }
+     341    13725214 :     k = k - xpos[j]->getNumberOfValues();
+     342             :   }
+     343     1761170 :   return std::pair<std::size_t, std::size_t>( valno, k );
+     344             : }
+     345             : 
+     346      540990 : void ActionAtomistic::retrieveAtoms( const bool& force ) {
+     347      540990 :   if( boxValue ) {
+     348      524475 :     auto* ptr=boxValue->getPntrToAction();
+     349      524475 :     plumed_assert(ptr); // needed for following calls, see #1046
+     350      524475 :     PbcAction* pbca = ptr->castToPbcAction();
+     351      524475 :     plumed_assert( pbca ); pbc=pbca->pbc;
+     352             :   }
+     353      540990 :   if( donotretrieve || indexes.size()==0 ) return;
+     354      223575 :   auto * mtr=masv[0]->getPntrToAction();
+     355      223575 :   plumed_assert(mtr); // needed for following calls, see #1046
+     356      223575 :   ActionToPutData* mv = mtr->castToActionToPutData();
+     357      223575 :   if(mv) massesWereSet=mv->hasBeenSet();
+     358           2 :   else if( (masv[0]->getPntrToAction())->getName()=="CONSTANT" ) massesWereSet=true; // Read masses from PDB file
+     359      223575 :   auto * ptr=chargev[0]->getPntrToAction();
+     360      223575 :   plumed_assert(ptr); // needed for following calls, see #1046
+     361      223575 :   ActionToPutData* cv = ptr->castToActionToPutData();
+     362      223575 :   if(cv) chargesWereSet=cv->hasBeenSet();
+     363           2 :   else if( (chargev[0]->getPntrToAction())->getName()=="CONSTANT" ) chargesWereSet=true; // Read masses from PDB file
+     364             :   unsigned j = 0;
+     365             : 
+     366             : // for(const auto & a : atom_value_ind) {
+     367             : //   std::size_t nn = a.first, kk = a.second;
+     368             : //   positions[j][0] = xpos[nn]->data[kk];
+     369             : //   positions[j][1] = ypos[nn]->data[kk];
+     370             : //   positions[j][2] = zpos[nn]->data[kk];
+     371             : //   charges[j] = chargev[nn]->data[kk];
+     372             : //   masses[j] = masv[nn]->data[kk];
+     373             : //   j++;
+     374             : // }
+     375             : 
+     376      837791 :   for(const auto & a : atom_value_ind_grouped) {
+     377      614216 :     const auto nn=a.first;
+     378      614216 :     auto & xp=xpos[nn]->data;
+     379      614216 :     auto & yp=ypos[nn]->data;
+     380      614216 :     auto & zp=zpos[nn]->data;
+     381      614216 :     auto & ch=chargev[nn]->data;
+     382      614216 :     auto & ma=masv[nn]->data;
+     383     6598348 :     for(const auto & kk : a.second) {
+     384     5984132 :       positions[j][0] = xp[kk];
+     385     5984132 :       positions[j][1] = yp[kk];
+     386     5984132 :       positions[j][2] = zp[kk];
+     387     5984132 :       charges[j] = ch[kk];
+     388     5984132 :       masses[j] = ma[kk];
+     389     5984132 :       j++;
+     390             :     }
+     391             :   }
+     392             : 
+     393             : }
+     394             : 
+     395      245975 : void ActionAtomistic::setForcesOnAtoms(const std::vector<double>& forcesToApply, unsigned& ind) {
+     396      245975 :   if( donotforce || (indexes.size()==0 && getName()!="FIXEDATOM") ) return;
+     397      483839 :   for(unsigned i=0; i<value_depends.size(); ++i) {
+     398      341692 :     xpos[value_depends[i]]->hasForce = true;
+     399      341692 :     ypos[value_depends[i]]->hasForce = true;
+     400      341692 :     zpos[value_depends[i]]->hasForce = true;
+     401             :   }
+     402             : 
+     403             : // for(const auto & a : atom_value_ind) {
+     404             : //   plumed_dbg_massert( ind<forcesToApply.size(), "problem setting forces in " + getLabel() );
+     405             : //   std::size_t nn = a.first, kk = a.second;
+     406             : //   xpos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     407             : //   ypos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     408             : //   zpos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     409             : // }
+     410             : 
+     411      794227 :   for(const auto & a : atom_value_ind_grouped) {
+     412      652080 :     const auto nn=a.first;
+     413             :     plumed_dbg_assert(ind<forcesToApply.size()) << "problem setting forces in " << getLabel();
+     414      652080 :     auto & xp=xpos[nn]->inputForce;
+     415      652080 :     auto & yp=ypos[nn]->inputForce;
+     416      652080 :     auto & zp=zpos[nn]->inputForce;
+     417     3970652 :     for(const auto & kk : a.second) {
+     418     3318572 :       xp[kk] += forcesToApply[ind]; ind++;
+     419     3318572 :       yp[kk] += forcesToApply[ind]; ind++;
+     420     3318572 :       zp[kk] += forcesToApply[ind]; ind++;
+     421             :     }
+     422             :   }
+     423             : 
+     424      142147 :   setForcesOnCell( forcesToApply, ind );
+     425             : }
+     426             : 
+     427      142235 : void ActionAtomistic::setForcesOnCell(const std::vector<double>& forcesToApply, unsigned& ind) {
+     428      142235 :   setForcesOnCell(forcesToApply.data(),forcesToApply.size(),ind);
+     429      142235 : }
+     430             : 
+     431      165136 : void ActionAtomistic::setForcesOnCell(const double* forcesToApply, std::size_t size, unsigned& ind) {
+     432     1651360 :   for(unsigned i=0; i<9; ++i) {
+     433             :     plumed_dbg_massert( ind<size, "problem setting forces in " + getLabel() );
+     434     1486224 :     boxValue->addForce( i, forcesToApply[ind] ); ind++;
+     435             :   }
+     436      165136 : }
+     437             : 
+     438           6 : Tensor ActionAtomistic::getVirial() const {
+     439          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);
+     440           6 :   return vir;
+     441             : }
+     442             : 
+     443           0 : void ActionAtomistic::readAtomsFromPDB(const PDB& pdb) {
+     444             : 
+     445           0 :   for(unsigned j=0; j<indexes.size(); j++) {
+     446           0 :     if( indexes[j].index()>pdb.size() ) error("there are not enough atoms in the input pdb file");
+     447           0 :     if( pdb.getAtomNumbers()[j].index()!=indexes[j].index() ) error("there are atoms missing in the pdb file");
+     448           0 :     positions[j]=pdb.getPositions()[indexes[j].index()];
+     449             :   }
+     450           0 :   for(unsigned j=0; j<indexes.size(); j++) charges[j]=pdb.getBeta()[indexes[j].index()];
+     451           0 :   for(unsigned j=0; j<indexes.size(); j++) masses[j]=pdb.getOccupancy()[indexes[j].index()];
+     452           0 : }
+     453             : 
+     454       14315 : unsigned ActionAtomistic::getTotAtoms()const {
+     455             :   unsigned natoms = 0;
+     456     6661921 :   for(unsigned i=0; i<xpos.size(); ++i ) natoms += xpos[i]->getNumberOfValues();
+     457       14315 :   return natoms;
+     458             : }
+     459             : 
+     460      148438 : void ActionAtomistic::makeWhole() {
+     461     1367016 :   for(unsigned j=0; j<positions.size()-1; ++j) {
+     462             :     const Vector & first (positions[j]);
+     463     1218578 :     Vector & second (positions[j+1]);
+     464     1218578 :     second=first+pbcDistance(first,second);
+     465             :   }
+     466      148438 : }
+     467             : 
+     468        8208 : void ActionAtomistic::getGradient( const unsigned& ind, Vector& deriv, std::map<AtomNumber,Vector>& gradients ) const {
+     469        8208 :   std::size_t nn = atom_value_ind[ind].first;
+     470        8208 :   if( nn==0 ) { gradients[indexes[ind]] += deriv; return; }
+     471          39 :   xpos[nn]->passGradients( deriv[0], gradients );
+     472          39 :   ypos[nn]->passGradients( deriv[1], gradients );
+     473          39 :   zpos[nn]->passGradients( deriv[2], gradients );
+     474             : }
+     475             : 
+     476      253978 : void ActionAtomistic::updateUniqueLocal( const bool& useunique, const std::vector<int>& g2l ) {
+     477      253978 :   if( useunique ) { unique_local=unique; return; }
+     478             :   // Update unique local if it needs an update
+     479        9154 :   unique_local_needs_update=false; unique_local.clear();
+     480       75612 :   for(auto pp=unique.begin(); pp!=unique.end(); ++pp) {
+     481       66458 :     if(g2l[pp->index()]>=0) unique_local.push_back(*pp); // already sorted
+     482             :   }
+     483             : }
+     484             : 
+     485             : }
+
+
+
+ + + + +
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 000000000..131153cfa --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:4848100.0 %
Date:2024-10-17 16:45:00Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv216
_ZN4PLMD15ActionAtomistic8addForceERKSt4pairImmERKNS_13VectorGenericILj3EEE9946
_ZNK4PLMD15ActionAtomistic8getForceERKSt4pairImmE15886
_ZN4PLMD15ActionAtomistic12lockRequestsEv194178
_ZN4PLMD15ActionAtomistic14unlockRequestsEv194178
_ZN4PLMD15ActionAtomistic17setGlobalPositionERKSt4pairImmERKNS_13VectorGenericILj3EEE412916
_ZNK4PLMD15ActionAtomistic17getGlobalPositionERKSt4pairImmE424577
_ZN4PLMD15ActionAtomistic21castToActionAtomisticEv503636
_ZNK4PLMD15ActionAtomistic9getChargeEi1037364
_ZNK4PLMD15ActionAtomistic7getMassEi1751559
+
+
+ + + +
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 000000000..cfaf9ce46 --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:4848100.0 %
Date:2024-10-17 16:45:00Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic12lockRequestsEv194178
_ZN4PLMD15ActionAtomistic14unlockRequestsEv194178
_ZN4PLMD15ActionAtomistic17setGlobalPositionERKSt4pairImmERKNS_13VectorGenericILj3EEE412916
_ZN4PLMD15ActionAtomistic21castToActionAtomisticEv503636
_ZN4PLMD15ActionAtomistic8addForceERKSt4pairImmERKNS_13VectorGenericILj3EEE9946
_ZNK4PLMD15ActionAtomistic17getGlobalPositionERKSt4pairImmE424577
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv216
_ZNK4PLMD15ActionAtomistic7getMassEi1751559
_ZNK4PLMD15ActionAtomistic8getForceERKSt4pairImmE15886
_ZNK4PLMD15ActionAtomistic9getChargeEi1037364
+
+
+ + + +
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 000000000..d9b682c9d --- /dev/null +++ b/coverage/core/ActionAtomistic.h.gcov.html @@ -0,0 +1,385 @@ + + + + + + + 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:4848100.0 %
Date:2024-10-17 16:45:00Functions:1010100.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                  massesWereSet;
+      84             :   bool                  chargesWereSet;
+      85             :   void setExtraCV(const std::string &name);
+      86             : /// Used to interpret whether this index is a virtual atom or a real atom
+      87             :   std::pair<std::size_t, std::size_t> getValueIndices( const AtomNumber& i ) const ;
+      88             : public:
+      89             : /// Request an array of atoms.
+      90             : /// This method is used to ask for a list of atoms. Atoms
+      91             : /// should be asked for by number. If this routine is called
+      92             : /// during the simulation, atoms will be available at the next step
+      93             : /// MAYBE WE HAVE TO FIND SOMETHING MORE CLEAR FOR DYNAMIC
+      94             : /// LISTS OF ATOMS
+      95             :   void requestAtoms(const std::vector<AtomNumber> & a, const bool clearDep=true);
+      96             : /// Get position of i-th atom (access by relative index)
+      97             :   const Vector & getPosition(int)const;
+      98             : /// Get position of i-th atom (access by absolute AtomNumber).
+      99             : /// With direct access to the global atom array.
+     100             : /// \warning Should be only used by actions that need to read the shared position array.
+     101             : ///          This array is insensitive to local changes such as makeWhole(), numerical derivatives, etc.
+     102             :   Vector getGlobalPosition(const std::pair<std::size_t,std::size_t>& ) const ;
+     103             : /// Modify position of i-th atom (access by absolute AtomNumber).
+     104             : /// \warning Should be only used by actions that need to modify the shared position array.
+     105             : ///          This array is insensitive to local changes such as makeWhole(), numerical derivatives, etc.
+     106             :   void setGlobalPosition(const std::pair<std::size_t,std::size_t>&, const Vector& pos);
+     107             : /// Get total number of atoms, including virtual ones.
+     108             : /// Can be used to make a loop on modifyGlobalPosition or getGlobalPosition.
+     109             :   unsigned getTotAtoms()const;
+     110             : /// Get box shape
+     111             :   const Tensor & getBox()const;
+     112             : /// Get the array of all positions
+     113             :   const std::vector<Vector> & getPositions()const;
+     114             : /// Get the virial that is acting
+     115             :   Tensor getVirial() const ;
+     116             : /// Get energy
+     117             :   const double & getEnergy()const;
+     118             : /// Get mass of i-th atom
+     119             :   double getMass(int i)const;
+     120             : /// Get charge of i-th atom
+     121             :   double getCharge(int i)const;
+     122             : /// Get the force acting on a particular atom
+     123             :   Vector getForce( const std::pair<std::size_t, std::size_t>& a ) const ;
+     124             : /// Add force to an atom
+     125             :   void addForce( const std::pair<std::size_t, std::size_t>& a, const Vector& f );
+     126             : /// Get a reference to force on energy
+     127             :   double & modifyForceOnEnergy();
+     128             : /// Get number of available atoms
+     129    47132421 :   unsigned getNumberOfAtoms()const {return indexes.size();}
+     130             : /// Compute the pbc distance between two positions
+     131             :   Vector pbcDistance(const Vector&,const Vector&)const;
+     132             : /// Applies  PBCs to a seriens of positions or distances
+     133             :   void pbcApply(std::vector<Vector>& dlist, unsigned max_index=0) const;
+     134             : /// Get the vector of absolute indexes
+     135             :   virtual const std::vector<AtomNumber> & getAbsoluteIndexes()const;
+     136             : /// Get the absolute index of an atom
+     137             :   AtomNumber getAbsoluteIndex(int i)const;
+     138             : /// Parse a list of atoms without a numbered keyword
+     139             :   void parseAtomList(const std::string&key,std::vector<AtomNumber> &t);
+     140             : /// Parse an list of atom with a numbred keyword
+     141             :   void parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t);
+     142             : /// Interpret the atom selection.  Just a wrapper to the static function with four arguments called interpretAtomList that passes xpos and this.
+     143             :   void interpretAtomList( std::vector<std::string>& strings, std::vector<AtomNumber> &t);
+     144             : /// Convert a set of read in strings into an atom list (this is used in parseAtomList)
+     145             :   static void interpretAtomList( std::vector<std::string>& strings, const std::vector<Value*>& xpos, Action* action, std::vector<AtomNumber> &t);
+     146             : /// This gets std::vector that contain the PLMD::Value objects that contain xpositions, ypositions, zpositions, masses and charges
+     147             :   static void getAtomValuesFromPlumedObject( const PlumedMain& plumed, std::vector<Value*>& xpos, std::vector<Value*>& ypos, std::vector<Value*>& zpos, std::vector<Value*>& masv, std::vector<Value*>& chargev );
+     148             : /// Change the box shape
+     149             :   void changeBox( const Tensor& newbox );
+     150             : /// Get reference to Pbc
+     151             :   const Pbc & getPbc() const;
+     152             : /// Add the forces to the atoms
+     153             :   void setForcesOnAtoms( const std::vector<double>& forcesToApply, unsigned& ind );
+     154             : /// Add the virial forces
+     155             :   void setForcesOnCell(const std::vector<double>& forcesToApply, unsigned& ind);
+     156             : /// Add the virial forces (span-like syntax)
+     157             :   void setForcesOnCell(const double* forcesToApply, std::size_t size, unsigned& ind);
+     158             : /// Skip atom retrieval - use with care.
+     159             : /// If this function is called during initialization, then atoms are
+     160             : /// not going to be retrieved. Can be used for optimization. Notice that
+     161             : /// calling getPosition(int) in an Action where DoNotRetrieve() was called might
+     162             : /// lead to undefined behavior.
+     163          64 :   void doNotRetrieve() {donotretrieve=true;}
+     164             : /// Skip atom forces - use with care.
+     165             : /// If this function is called during initialization, then forces are
+     166             : /// not going to be propagated. Can be used for optimization.
+     167          64 :   void doNotForce() {donotforce=true;}
+     168             : /// Make atoms whole, assuming they are in the proper order
+     169             :   void makeWhole();
+     170             : public:
+     171             : 
+     172             : // virtual functions:
+     173             : 
+     174             :   explicit ActionAtomistic(const ActionOptions&ao);
+     175             :   ~ActionAtomistic();
+     176             :   static void registerKeywords( Keywords& keys );
+     177             : 
+     178             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+     179             : /// are doing.  The default will be correct for the vast majority of cases
+     180             :   void   calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+     181             : /// Numerical derivative routine to use when using Actions that inherit from BOTH
+     182             : /// ActionWithArguments and ActionAtomistic
+     183             :   void calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum );
+     184             : 
+     185             :   virtual void retrieveAtoms( const bool& force=false );
+     186             :   void lockRequests() override;
+     187             :   void unlockRequests() override;
+     188             :   const std::vector<AtomNumber> & getUnique()const;
+     189             :   const std::vector<AtomNumber> & getUniqueLocal()const;
+     190             : /// Read in an input file containing atom positions and calculate the action for the atomic
+     191             : /// configuration therin
+     192             :   void readAtomsFromPDB( const PDB& pdb ) override;
+     193             : /// Transfer the gradients
+     194             :   void getGradient( const unsigned& ind, Vector& deriv, std::map<AtomNumber,Vector>& gradients ) const ;
+     195      503636 :   ActionAtomistic* castToActionAtomistic() noexcept final { return this; }
+     196             :   virtual bool actionHasForces();
+     197             : };
+     198             : 
+     199             : inline
+     200             : const Vector & ActionAtomistic::getPosition(int i)const {
+     201   151945697 :   return positions[i];
+     202             : }
+     203             : 
+     204             : inline
+     205     1751559 : double ActionAtomistic::getMass(int i)const {
+     206     1751559 :   if( !massesWereSet ) log.printf("WARNING: masses were not passed to plumed\n");
+     207     1751559 :   return masses[i];
+     208             : }
+     209             : 
+     210             : inline
+     211     1037364 : double ActionAtomistic::getCharge(int i) const {
+     212     1037364 :   if( !chargesWereSet ) error("charges were not passed to plumed");
+     213     1037364 :   return charges[i];
+     214             : }
+     215             : 
+     216             : inline
+     217         216 : const std::vector<AtomNumber> & ActionAtomistic::getAbsoluteIndexes()const {
+     218         216 :   return indexes;
+     219             : }
+     220             : 
+     221             : inline
+     222             : AtomNumber ActionAtomistic::getAbsoluteIndex(int i)const {
+     223     9793398 :   return indexes[i];
+     224             : }
+     225             : 
+     226             : inline
+     227             : const std::vector<Vector> & ActionAtomistic::getPositions()const {
+     228      491226 :   return positions;
+     229             : }
+     230             : 
+     231             : inline
+     232             : const double & ActionAtomistic::getEnergy()const {
+     233             :   return energy;
+     234             : }
+     235             : 
+     236             : inline
+     237             : const Tensor & ActionAtomistic::getBox()const {
+     238        6466 :   return pbc.getBox();
+     239             : }
+     240             : 
+     241             : inline
+     242             : double & ActionAtomistic::modifyForceOnEnergy() {
+     243             :   return forceOnEnergy;
+     244             : }
+     245             : 
+     246             : inline
+     247             : const Pbc & ActionAtomistic::getPbc() const {
+     248       98535 :   return pbc;
+     249             : }
+     250             : 
+     251             : inline
+     252      194178 : void ActionAtomistic::lockRequests() {
+     253      477700 :   lockRequestAtoms=true;
+     254      194178 : }
+     255             : 
+     256             : inline
+     257      194178 : void ActionAtomistic::unlockRequests() {
+     258      477700 :   lockRequestAtoms=false;
+     259      194178 : }
+     260             : 
+     261             : inline
+     262             : const std::vector<AtomNumber> & ActionAtomistic::getUnique()const {
+     263       11456 :   return unique;
+     264             : }
+     265             : 
+     266             : inline
+     267             : const std::vector<AtomNumber> & ActionAtomistic::getUniqueLocal() const {
+     268      105192 :   return unique_local;
+     269             : }
+     270             : 
+     271             : inline
+     272      424577 : Vector ActionAtomistic::getGlobalPosition(const std::pair<std::size_t,std::size_t>& a) const {
+     273      424577 :   Vector pos;
+     274      424577 :   pos[0]=xpos[a.first]->data[a.second];
+     275      424577 :   pos[1]=ypos[a.first]->data[a.second];
+     276      424577 :   pos[2]=zpos[a.first]->data[a.second];
+     277      424577 :   return pos;
+     278             : }
+     279             : 
+     280             : inline
+     281      412916 : void ActionAtomistic::setGlobalPosition(const std::pair<std::size_t, std::size_t>& a, const Vector& pos ) {
+     282      412916 :   xpos[a.first]->data[a.second]=pos[0];
+     283      412916 :   ypos[a.first]->data[a.second]=pos[1];
+     284      412916 :   zpos[a.first]->data[a.second]=pos[2];
+     285      412916 : }
+     286             : 
+     287             : inline
+     288       15886 : Vector ActionAtomistic::getForce( const std::pair<std::size_t, std::size_t>& a ) const {
+     289       15886 :   Vector f;
+     290       15886 :   f[0]=xpos[a.first]->getForce(a.second);
+     291       15886 :   f[1]=ypos[a.first]->getForce(a.second);
+     292       15886 :   f[2]=zpos[a.first]->getForce(a.second);
+     293       15886 :   return f;
+     294             : }
+     295             : 
+     296             : inline
+     297        9946 : void ActionAtomistic::addForce( const std::pair<std::size_t, std::size_t>& a, const Vector& f ) {
+     298        9946 :   xpos[a.first]->addForce( a.second, f[0] );
+     299        9946 :   ypos[a.first]->addForce( a.second, f[1] );
+     300        9946 :   zpos[a.first]->addForce( a.second, f[2] );
+     301        9946 : }
+     302             : 
+     303             : inline
+     304             : Vector ActionAtomistic::pbcDistance(const Vector &v1,const Vector &v2)const {
+     305   269916602 :   return pbc.distance(v1,v2);
+     306             : }
+     307             : 
+     308             : }
+     309             : #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 000000000..c65a8c218 --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterfaceC1ERKNS_13ActionOptionsE0
_ZN4PLMD18ActionForInterface16registerKeywordsERNS_8KeywordsE8294
_ZN4PLMD18ActionForInterfaceC2ERKNS_13ActionOptionsE9489
_ZNK4PLMD18ActionForInterface7getRoleB5cxx11Ev633194
+
+
+ + + +
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 000000000..092aae35f --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterface16registerKeywordsERNS_8KeywordsE8294
_ZN4PLMD18ActionForInterfaceC1ERKNS_13ActionOptionsE0
_ZN4PLMD18ActionForInterfaceC2ERKNS_13ActionOptionsE9489
_ZNK4PLMD18ActionForInterface7getRoleB5cxx11Ev633194
+
+
+ + + +
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 000000000..3bd1f46e4 --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.gcov.html @@ -0,0 +1,125 @@ + + + + + + + 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-10-17 16:45:00Functions: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        8294 : void ActionForInterface::registerKeywords(Keywords& keys) {
+      30        8294 :   Action::registerKeywords(keys); ActionWithValue::registerKeywords( keys );
+      31       16588 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      32       16588 :   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        8294 : }
+      34             : 
+      35        9489 : ActionForInterface::ActionForInterface(const ActionOptions&ao):
+      36             :   Action(ao),
+      37             :   ActionWithValue(ao),
+      38        9489 :   firststep(true),
+      39        9489 :   wasscaled(false),
+      40        9489 :   wasset(false)
+      41             : {
+      42       26043 :   if( keywords.exists("ROLE") && getName()!="DOMAIN_DECOMPOSITION") parse("ROLE",role);
+      43        9489 : }
+      44             : 
+      45      633194 : std::string ActionForInterface::getRole() const {
+      46      633194 :   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 000000000..732d8508c --- /dev/null +++ b/coverage/core/ActionForInterface.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD18ActionForInterface26getNumberOfForcesToRescaleEv0
_ZN4PLMD18ActionForInterface24castToActionForInterfaceEv835
_ZN4PLMD18ActionForInterface5resetEv93649
_ZN4PLMD18ActionForInterface16clearDerivativesERKb519061
_ZN4PLMD18ActionForInterface20setGradientsIfNeededEv519061
_ZN4PLMD18ActionForInterface9calculateEv519061
_ZN4PLMD18ActionForInterface22getNumberOfDerivativesEv808767
+
+
+ + + +
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 000000000..e63e678f7 --- /dev/null +++ b/coverage/core/ActionForInterface.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterface16clearDerivativesERKb519061
_ZN4PLMD18ActionForInterface20setGradientsIfNeededEv519061
_ZN4PLMD18ActionForInterface22getNumberOfDerivativesEv808767
_ZN4PLMD18ActionForInterface24castToActionForInterfaceEv835
_ZN4PLMD18ActionForInterface5resetEv93649
_ZN4PLMD18ActionForInterface9calculateEv519061
_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 000000000..2c4062f10 --- /dev/null +++ b/coverage/core/ActionForInterface.h.gcov.html @@ -0,0 +1,166 @@ + + + + + + + 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-10-17 16:45:00Functions: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      519061 :   void clearDerivatives(const bool& force=false) override {}
+      47             : /// Override the need to deal with gradients
+      48      519061 :   void setGradientsIfNeeded() override {}
+      49             : /// Check if the value has been set
+      50             :   bool hasBeenSet() const ;
+      51             : /// The number of derivatives
+      52      808767 :   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      519061 :   void calculate() override { firststep=false; wasscaled=false; }
+      74       93649 :   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      782960 :   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 000000000..365980027 --- /dev/null +++ b/coverage/core/ActionPilot.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:141593.3 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilot9setStrideERKi8
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE3402
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE3911
_ZNK4PLMD11ActionPilot9getStrideEv120731
_ZNK4PLMD11ActionPilot6onStepEv1574380
+
+
+ + + +
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 000000000..47c962b2e --- /dev/null +++ b/coverage/core/ActionPilot.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:141593.3 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE3911
_ZN4PLMD11ActionPilot9setStrideERKi8
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE3402
_ZNK4PLMD11ActionPilot6onStepEv1574380
_ZNK4PLMD11ActionPilot9getStrideEv120731
+
+
+ + + +
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 000000000..c37350c6e --- /dev/null +++ b/coverage/core/ActionPilot.cpp.gcov.html @@ -0,0 +1,131 @@ + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:141593.3 %
Date:2024-10-17 16:45:00Functions: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        3911 : void ActionPilot::registerKeywords(Keywords& keys) {}
+      27             : 
+      28        3402 : ActionPilot::ActionPilot(const ActionOptions&ao):
+      29             :   Action(ao),
+      30        3402 :   stride(1)
+      31             : {
+      32        6804 :   if( keywords.exists("STRIDE") ) {
+      33        3402 :     parse("STRIDE",stride);
+      34        6804 :     if( !keywords.style("STRIDE","hidden") ) log.printf("  with stride %d\n",stride);
+      35             :   } else {
+      36           0 :     stride=0;
+      37             :   }
+      38        3402 : }
+      39             : 
+      40     1574380 : bool ActionPilot::onStep()const {
+      41     1574380 :   if( stride>0 ) return getStep()%stride==0;
+      42             :   return false;
+      43             : }
+      44             : 
+      45      120731 : int ActionPilot::getStride()const {
+      46      120731 :   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 000000000..c0e41d0f0 --- /dev/null +++ b/coverage/core/ActionPilot.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - core/ActionPilot.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4d5e1fb04 --- /dev/null +++ b/coverage/core/ActionPilot.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - core/ActionPilot.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..983b810e5 --- /dev/null +++ b/coverage/core/ActionPilot.h.gcov.html @@ -0,0 +1,134 @@ + + + + + + + LCOV - plumed test coverage - core/ActionPilot.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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        1936 : 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 000000000..f3556df88 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:344673.9 %
Date:2024-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE0
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev2
_ZN4PLMD14ActionRegister11getKeywordsERKSt6vectorIPvSaIS2_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE97
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_439
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE22942
_ZN4PLMD14ActionRegister6createERKSt6vectorIPvSaIS2_EERKNS_13ActionOptionsE51098
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE2321851
_ZN4PLMD14actionRegisterEv4729504
+
+
+ + + +
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 000000000..a4857e953 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:344673.9 %
Date:2024-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE22942
_ZN4PLMD14ActionRegister11getKeywordsERKSt6vectorIPvSaIS2_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE97
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_439
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE2321851
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE0
_ZN4PLMD14ActionRegister6createERKSt6vectorIPvSaIS2_EERKNS_13ActionOptionsE51098
_ZN4PLMD14actionRegisterEv4729504
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev2
+
+
+ + + +
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 000000000..1e24324b5 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + 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:344673.9 %
Date:2024-10-17 16:45:00Functions: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 "ActionRegister.h"
+      23             : #include "ModuleMap.h"
+      24             : #include "Action.h"
+      25             : #include <algorithm>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29     4729504 : ActionRegister& actionRegister() {
+      30     4734805 :   static ActionRegister ans;
+      31     4729504 :   return ans;
+      32             : }
+      33             : 
+      34           0 : std::unique_ptr<Action> ActionRegister::create(const ActionOptions&ao) {
+      35             :   std::vector<void*> images; // empty vector
+      36           0 :   return create(images,ao);
+      37             : }
+      38             : 
+      39       51098 : std::unique_ptr<Action> ActionRegister::create(const std::vector<void*> & images,const ActionOptions&ao) try {
+      40       51098 :   if(ao.line.size()<1)return nullptr;
+      41             : 
+      42       51098 :   auto content=get(images,ao.line[0]);
+      43       51096 :   Keywords keys; keys.thisactname = ao.line[0];
+      44       51096 :   content.keys(keys);
+      45       51096 :   ActionOptions nao( ao,keys );
+      46       51096 :   auto fullPath=getFullPath(images,ao.line[0]);
+      47             :   nao.setFullPath(fullPath);
+      48       51096 :   return content.create(nao);
+      49       51151 : } catch (PLMD::ExceptionRegisterError &e ) {
+      50             :   auto& actionName = e.getMissingKey();
+      51             :   e <<"Action \"" << actionName << "\" is not known.";
+      52           2 :   if (getModuleMap().count(actionName)>0) {
+      53             :     e << "\nAn Action named \""
+      54             :       <<actionName
+      55             :       <<"\" is available in module \""
+      56           0 :       << getModuleMap().at(actionName)
+      57             :       << "\".\nPlease consider installing PLUMED with that module enabled.";
+      58             :   }
+      59           2 :   throw e;
+      60           2 : }
+      61             : 
+      62         439 : bool ActionRegister::printManual(const std::string& action, const bool& vimout, const bool& spellout) {
+      63         439 :   if ( check(action) ) {
+      64         438 :     Keywords keys; getKeywords( action, keys );
+      65         438 :     if( vimout ) {
+      66         438 :       printf("%s",action.c_str()); keys.print_vim(); printf("\n");
+      67           0 :     } else if( spellout ) {
+      68           0 :       keys.print_spelling();
+      69             :     } else {
+      70           0 :       keys.print_html();
+      71             :     }
+      72             :     return true;
+      73         438 :   } else {
+      74             :     return false;
+      75             :   }
+      76             : }
+      77             : 
+      78           0 : bool ActionRegister::printTemplate(const std::string& action, bool include_optional) {
+      79             :   //no need to insert the try/catch block: check will ensure that action is known
+      80           0 :   if( check(action) ) {
+      81           0 :     Keywords keys; keys.thisactname = action;
+      82           0 :     get(action).keys(keys);
+      83           0 :     keys.print_template(action, include_optional);
+      84             :     return true;
+      85           0 :   } else {
+      86             :     return false;
+      87             :   }
+      88             : }
+      89             : 
+      90           2 : std::vector<std::string> ActionRegister::getActionNames() const {
+      91           2 :   return getKeys();
+      92             : }
+      93             : 
+      94     2321851 : ActionRegister::ID ActionRegister::add(std::string key,creator_pointer cp,keywords_pointer kp) {
+      95             :   // this force each action to be registered as an uppercase string
+      96    12112832 :   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";
+      97     4643702 :   return RegisterBase::add(key,Pointers{cp,kp});
+      98             : }
+      99             : 
+     100       22942 : bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
+     101             :   //no need to insert the try/catch block: check will ensure that action is known
+     102       22942 :   if(check(action)) {
+     103       22942 :     keys.thisactname = action;
+     104       22942 :     get(action).keys(keys);
+     105       22942 :     return true;
+     106             :   }
+     107             :   return false;
+     108             : }
+     109             : 
+     110          97 : void ActionRegister::getKeywords(const std::vector<void*> & images, const std::string& action, Keywords& keys) {
+     111          97 :   auto content=get(images,action); keys.thisactname = action; content.keys(keys);
+     112          97 : }
+     113             : 
+     114             : }
+
+
+
+ + + + +
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 000000000..ea8401875 --- /dev/null +++ b/coverage/core/ActionRegister.h.func-sort-c.html @@ -0,0 +1,4728 @@ + + + + + + + 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-10-17 16:45:00Functions:1144116498.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionRegistrationINS_10metatensor22MetatensorPlumedActionEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11matrixtools11DeterminantEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEE6createERKNS_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_4maze10Steered_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEE6createERKNS_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_6sprint6SprintEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEE6createERKNS_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_8function15FuncPathGeneralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7BetweenEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8LessThanEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9landmarks21FarthestPointSamplingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9sizeshape18position_maha_distEE6createERKNS_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_6colvar5DimerEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7generic15MassChargeInputEE6createERKNS_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_8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEE6createERKNS_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_11matrixtools16CovarianceMatrixEE6createERKNS_13ActionOptionsE4
_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_6colvar5ERMSDEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7generic7AverageEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_9sizeshape20position_linear_projEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_11matrixtools7VoronoiEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4wham11WhamWeightsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_4wham13WhamHistogramEE6createERKNS_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_9gridtools18MultiColvarDensityEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_9landmarks17LandmarkSelectionEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_11matrixtools12InvertMatrixEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic9CommittorEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_9landmarks9LogSumExpEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_4wham4WhamEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_7generic14GatherReplicasEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_7generic10CreateMaskEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEE6createERKNS_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_8function16FunctionShortcutINS1_4SortEEEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_9landmarks13CollectFramesEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEE6createERKNS_13ActionOptionsE21
_ZN4PLMD18ActionRegistrationINS_11matrixtools17DiagonalizeMatrixEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_9gridtools9HistogramEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7CombineEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_8function5StatsEE6createERKNS_13ActionOptionsE31
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEE6createERKNS_13ActionOptionsE32
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEE6createERKNS_13ActionOptionsE34
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEE6createERKNS_13ActionOptionsE35
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEE6createERKNS_13ActionOptionsE36
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEE6createERKNS_13ActionOptionsE40
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_3SumEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEE6createERKNS_13ActionOptionsE44
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEE6createERKNS_13ActionOptionsE45
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEE6createERKNS_13ActionOptionsE47
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEE6createERKNS_13ActionOptionsE48
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEE6createERKNS_13ActionOptionsE49
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEE6createERKNS_13ActionOptionsE53
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEE6createERKNS_13ActionOptionsE55
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesMatrixEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE62
_ZN4PLMD18ActionRegistrationINS_7generic10AccumulateEE6createERKNS_13ActionOptionsE63
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEE6createERKNS_13ActionOptionsE65
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEE6createERKNS_13ActionOptionsE67
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE68
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEE6createERKNS_13ActionOptionsE71
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEE6createERKNS_13ActionOptionsE73
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEE6createERKNS_13ActionOptionsE75
_ZN4PLMD18ActionRegistrationINS_11matrixtools12OuterProductEE6createERKNS_13ActionOptionsE77
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEE6createERKNS_13ActionOptionsE81
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEE6createERKNS_13ActionOptionsE82
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEE6createERKNS_13ActionOptionsE84
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEE6createERKNS_13ActionOptionsE91
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEE6createERKNS_13ActionOptionsE92
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEE6createERKNS_13ActionOptionsE93
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEE6createERKNS_13ActionOptionsE94
_ZN4PLMD18ActionRegistrationINS_7generic7CollectEE6createERKNS_13ActionOptionsE94
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEE6createERKNS_13ActionOptionsE95
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEE6createERKNS_13ActionOptionsE96
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEE6createERKNS_13ActionOptionsE104
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEE6createERKNS_13ActionOptionsE108
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEE6createERKNS_13ActionOptionsE112
_ZN4PLMD18ActionRegistrationINS_8function7ProductEE6createERKNS_13ActionOptionsE114
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEE6createERKNS_13ActionOptionsE116
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEE6createERKNS_13ActionOptionsE120
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEE6createERKNS_13ActionOptionsE135
_ZN4PLMD18ActionRegistrationINS_8valtools6VStackEE6createERKNS_13ActionOptionsE139
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE143
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEE6createERKNS_13ActionOptionsE149
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEE6createERKNS_13ActionOptionsE157
_ZN4PLMD18ActionRegistrationINS_11matrixtools15TransposeMatrixEE6createERKNS_13ActionOptionsE162
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEE6createERKNS_13ActionOptionsE176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE184
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEE6createERKNS_13ActionOptionsE191
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEE6createERKNS_13ActionOptionsE195
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEE6createERKNS_13ActionOptionsE204
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEE6createERKNS_13ActionOptionsE208
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEE6createERKNS_13ActionOptionsE210
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEE6createERKNS_13ActionOptionsE219
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEE6createERKNS_13ActionOptionsE220
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEE6createERKNS_13ActionOptionsE253
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEE6createERKNS_13ActionOptionsE255
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEE6createERKNS_13ActionOptionsE281
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEE6createERKNS_13ActionOptionsE286
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEE6createERKNS_13ActionOptionsE290
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEE6createERKNS_13ActionOptionsE305
_ZN4PLMD18ActionRegistrationINS_5GroupEE6createERKNS_13ActionOptionsE330
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesVectorEE6createERKNS_13ActionOptionsE352
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_6CustomEEEE6createERKNS_13ActionOptionsE370
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEE6createERKNS_13ActionOptionsE433
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEE6createERKNS_13ActionOptionsE620
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEE6createERKNS_13ActionOptionsE671
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEE6createERKNS_13ActionOptionsE685
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEE6createERKNS_13ActionOptionsE709
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEE6createERKNS_13ActionOptionsE728
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEE6createERKNS_13ActionOptionsE777
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEE6createERKNS_13ActionOptionsE818
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEE6createERKNS_13ActionOptionsE851
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEE6createERKNS_13ActionOptionsE1016
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEE6createERKNS_13ActionOptionsE1121
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEE6createERKNS_13ActionOptionsE1172
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEE6createERKNS_13ActionOptionsE1192
_ZN4PLMD18ActionRegistrationINS_9PbcActionEE6createERKNS_13ActionOptionsE1192
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEE6createERKNS_13ActionOptionsE2991
_ZN4PLMD18ActionRegistrationINS_10metatensor22MetatensorPlumedActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_10metatensor22MetatensorPlumedActionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools11DeterminantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools11DeterminantEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12InvertMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12InvertMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12OuterProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12OuterProductEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools15TransposeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools15TransposeMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools16CovarianceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools16CovarianceMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17DiagonalizeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17DiagonalizeMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesVectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools7VoronoiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools7VoronoiEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze4LossEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze4LossEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4wham11WhamWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4wham11WhamWeightsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4wham13WhamHistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4wham13WhamHistogramEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4wham4WhamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4wham4WhamEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5GroupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5GroupEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6sprint6SprintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6sprint6SprintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10AccumulateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10AccumulateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10CreateMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10CreateMaskEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic14GatherReplicasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic14GatherReplicasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15MassChargeInputEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15MassChargeInputEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7AverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7AverageEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7CollectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7CollectEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9CommittorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9CommittorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_3SumEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7BetweenEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8LessThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8MoreThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc7FccubicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function5StatsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function5StatsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function7ProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function7ProductEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools6VStackEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools6VStackEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9PbcActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9PbcActionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9HistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9HistogramEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9landmarks13CollectFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9landmarks13CollectFramesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9landmarks21FarthestPointSamplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9landmarks21FarthestPointSamplingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9landmarks9LogSumExpEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9landmarks9LogSumExpEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape18position_maha_distEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape18position_maha_distEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape20position_linear_projEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape20position_linear_projEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEE6createERKNS_13ActionOptionsE7065
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEE6createERKNS_13ActionOptionsE7748
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEE6createERKNS_13ActionOptionsE9576
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesMatrixEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15903
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEED2Ev15903
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15903
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEED2Ev15903
_ZN4PLMD18ActionRegistrationINS_9landmarks17LandmarkSelectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15903
_ZN4PLMD18ActionRegistrationINS_9landmarks17LandmarkSelectionEED2Ev15903
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE21204
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEED2Ev21204
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE21204
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEED2Ev21204
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE21204
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEED2Ev21204
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE26505
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEED2Ev26505
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE31806
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEED2Ev31806
+
+
+ + + +
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 000000000..360455273 --- /dev/null +++ b/coverage/core/ActionRegister.h.func.html @@ -0,0 +1,4728 @@ + + + + + + + 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-10-17 16:45:00Functions:1144116498.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionRegistrationINS_10metatensor22MetatensorPlumedActionEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_10metatensor22MetatensorPlumedActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_10metatensor22MetatensorPlumedActionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools11DeterminantEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11matrixtools11DeterminantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools11DeterminantEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12InvertMatrixEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_11matrixtools12InvertMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12InvertMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12OuterProductEE6createERKNS_13ActionOptionsE77
_ZN4PLMD18ActionRegistrationINS_11matrixtools12OuterProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools12OuterProductEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools15TransposeMatrixEE6createERKNS_13ActionOptionsE162
_ZN4PLMD18ActionRegistrationINS_11matrixtools15TransposeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools15TransposeMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools16CovarianceMatrixEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_11matrixtools16CovarianceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools16CovarianceMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17DiagonalizeMatrixEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_11matrixtools17DiagonalizeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17DiagonalizeMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesMatrixEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesMatrixEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesVectorEE6createERKNS_13ActionOptionsE352
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools17MatrixTimesVectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools7VoronoiEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_11matrixtools7VoronoiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11matrixtools7VoronoiEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE31806
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEED2Ev31806
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15903
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEED2Ev15903
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE21204
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEED2Ev21204
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEE6createERKNS_13ActionOptionsE96
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEE6createERKNS_13ActionOptionsE7065
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEE6createERKNS_13ActionOptionsE32
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEE6createERKNS_13ActionOptionsE1192
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEE6createERKNS_13ActionOptionsE95
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEE6createERKNS_13ActionOptionsE73
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEE6createERKNS_13ActionOptionsE47
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEE6createERKNS_13ActionOptionsE191
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEE6createERKNS_13ActionOptionsE75
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEE6createERKNS_13ActionOptionsE71
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEE6createERKNS_13ActionOptionsE120
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEE6createERKNS_13ActionOptionsE290
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEE6createERKNS_13ActionOptionsE157
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEE6createERKNS_13ActionOptionsE21
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEE6createERKNS_13ActionOptionsE204
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEE6createERKNS_13ActionOptionsE286
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEE6createERKNS_13ActionOptionsE44
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze4LossEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4maze4LossEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze4LossEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15903
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEED2Ev15903
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4wham11WhamWeightsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4wham11WhamWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4wham11WhamWeightsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4wham13WhamHistogramEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_4wham13WhamHistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4wham13WhamHistogramEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_4wham4WhamEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_4wham4WhamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_4wham4WhamEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5GroupEE6createERKNS_13ActionOptionsE330
_ZN4PLMD18ActionRegistrationINS_5GroupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5GroupEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEE6createERKNS_13ActionOptionsE34
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEE6createERKNS_13ActionOptionsE7748
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEE6createERKNS_13ActionOptionsE709
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEE6createERKNS_13ActionOptionsE9576
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEE6createERKNS_13ActionOptionsE35
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEE6createERKNS_13ActionOptionsE210
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEE6createERKNS_13ActionOptionsE92
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEE6createERKNS_13ActionOptionsE208
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEE6createERKNS_13ActionOptionsE49
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEE6createERKNS_13ActionOptionsE219
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEE6createERKNS_13ActionOptionsE104
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEE6createERKNS_13ActionOptionsE685
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEE6createERKNS_13ActionOptionsE728
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEE6createERKNS_13ActionOptionsE135
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEE6createERKNS_13ActionOptionsE116
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEE6createERKNS_13ActionOptionsE108
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEE6createERKNS_13ActionOptionsE81
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEE6createERKNS_13ActionOptionsE40
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEE6createERKNS_13ActionOptionsE671
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEE6createERKNS_13ActionOptionsE620
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEE6createERKNS_13ActionOptionsE112
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEE6createERKNS_13ActionOptionsE94
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_6sprint6SprintEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6sprint6SprintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_6sprint6SprintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10AccumulateEE6createERKNS_13ActionOptionsE63
_ZN4PLMD18ActionRegistrationINS_7generic10AccumulateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10AccumulateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10CreateMaskEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_7generic10CreateMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10CreateMaskEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEE6createERKNS_13ActionOptionsE36
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic14GatherReplicasEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_7generic14GatherReplicasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic14GatherReplicasEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEE6createERKNS_13ActionOptionsE253
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15MassChargeInputEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7generic15MassChargeInputEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15MassChargeInputEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEE6createERKNS_13ActionOptionsE255
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEE6createERKNS_13ActionOptionsE91
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEE6createERKNS_13ActionOptionsE1121
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7AverageEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7generic7AverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7AverageEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7CollectEE6createERKNS_13ActionOptionsE94
_ZN4PLMD18ActionRegistrationINS_7generic7CollectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7CollectEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEE6createERKNS_13ActionOptionsE851
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9CommittorEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic9CommittorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9CommittorEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEE6createERKNS_13ActionOptionsE220
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEE6createERKNS_13ActionOptionsE281
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEE6createERKNS_13ActionOptionsE55
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE21204
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEED2Ev21204
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE21204
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEED2Ev21204
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEE6createERKNS_13ActionOptionsE45
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE26505
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEED2Ev26505
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_3SumEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_3SumEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_6CustomEEEE6createERKNS_13ActionOptionsE370
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7BetweenEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7BetweenEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7CombineEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8LessThanEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8LessThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS1_8MoreThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfMatrixINS_7symfunc7FccubicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEE6createERKNS_13ActionOptionsE1172
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEE6createERKNS_13ActionOptionsE195
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEE6createERKNS_13ActionOptionsE777
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEE6createERKNS_13ActionOptionsE1016
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEE6createERKNS_13ActionOptionsE84
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEE6createERKNS_13ActionOptionsE48
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE62
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE143
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEE6createERKNS_13ActionOptionsE818
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEE6createERKNS_13ActionOptionsE2991
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEE6createERKNS_13ActionOptionsE53
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEE6createERKNS_13ActionOptionsE305
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEE6createERKNS_13ActionOptionsE67
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE68
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE184
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function5StatsEE6createERKNS_13ActionOptionsE31
_ZN4PLMD18ActionRegistrationINS_8function5StatsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function5StatsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function7ProductEE6createERKNS_13ActionOptionsE114
_ZN4PLMD18ActionRegistrationINS_8function7ProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function7ProductEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEE6createERKNS_13ActionOptionsE176
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEE6createERKNS_13ActionOptionsE93
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools6VStackEE6createERKNS_13ActionOptionsE139
_ZN4PLMD18ActionRegistrationINS_8valtools6VStackEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools6VStackEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9PbcActionEE6createERKNS_13ActionOptionsE1192
_ZN4PLMD18ActionRegistrationINS_9PbcActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9PbcActionEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEE6createERKNS_13ActionOptionsE65
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEE6createERKNS_13ActionOptionsE433
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEE6createERKNS_13ActionOptionsE82
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEE6createERKNS_13ActionOptionsE149
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10602
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEED2Ev10602
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9HistogramEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_9gridtools9HistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9HistogramEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9landmarks13CollectFramesEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_9landmarks13CollectFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9landmarks13CollectFramesEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9landmarks17LandmarkSelectionEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_9landmarks17LandmarkSelectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15903
_ZN4PLMD18ActionRegistrationINS_9landmarks17LandmarkSelectionEED2Ev15903
_ZN4PLMD18ActionRegistrationINS_9landmarks21FarthestPointSamplingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9landmarks21FarthestPointSamplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9landmarks21FarthestPointSamplingEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9landmarks9LogSumExpEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_9landmarks9LogSumExpEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9landmarks9LogSumExpEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape18position_maha_distEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9sizeshape18position_maha_distEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape18position_maha_distEED2Ev5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape20position_linear_projEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_9sizeshape20position_linear_projEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5301
_ZN4PLMD18ActionRegistrationINS_9sizeshape20position_linear_projEED2Ev5301
+
+
+ + + +
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 000000000..159f2a850 --- /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-10-17 16:45:00Functions:1144116498.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_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        5301 : 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             :   void getKeywords(const std::vector<void*> & images, const std::string& action, Keywords& keys);
+      68             : /// Print out a template command for an action
+      69             :   bool printTemplate(const std::string& action, bool include_optional);
+      70             :   std::vector<std::string> getActionNames() const;
+      71             : };
+      72             : 
+      73             : /// Function returning a reference to the ActionRegister.
+      74             : /// \relates ActionRegister
+      75             : /// To avoid problems with order of initialization, this function contains
+      76             : /// a static ActionRegister which is built the first time the function is called.
+      77             : /// In this manner, it is always initialized before it's used
+      78             : ActionRegister& actionRegister();
+      79             : 
+      80             : template<typename T>
+      81             : inline constexpr bool isActionType = std::is_base_of<Action, T>::value;
+      82             : //in C++20 you we'll make this a concept
+      83             : //template<typename T>
+      84             : //concept ActionType = std::is_base_of<::PLMD::Action, T>::value;
+      85             : //so the template will be template<ActionType ActionType>class ActionRegistration{...}
+      86             : //without the explicit need of the static assert
+      87             : 
+      88             : ///Each instance of this specialized class represents an action that can be called
+      89             : ///with  the specified directive.
+      90             : ///As soon it goes out of scope it will deregister the directive from the singleton ActionRegister
+      91             : template<typename ActionClass>
+      92             : class ActionRegistration {
+      93             :   ActionRegister::ID id;
+      94       51055 :   static std::unique_ptr<Action> create(const ActionOptions&ao) {
+      95      100924 :     return std::make_unique<ActionClass>(ao);
+      96             :   }
+      97             : public:
+      98             :   ///On construction register the ActionClass with the wanted directive
+      99     2321838 :   ActionRegistration(std::string_view directive):
+     100     2321838 :     id(actionRegister().add(directive.data(),create,ActionClass::registerKeywords))
+     101             :   {
+     102             :     static_assert(isActionType<ActionClass>,
+     103             :                   "ActionRegistration accepts only class that inherit from Action");
+     104     2321838 :   }
+     105             :   ///On destruction deregister the ActionClass (useful when you unload a shared object)
+     106     2321838 :   ~ActionRegistration() {actionRegister().remove(id);}
+     107             : };
+     108             : } //PLMD
+     109             : 
+     110             : #define PLUMED_CONCATENATE_DIRECT(s1, s2) s1##s2
+     111             : #define PLUMED_CONCATENATE(s1, s2) PLUMED_CONCATENATE_DIRECT(s1, s2)
+     112             : 
+     113             : /// Shortcut for Action registration
+     114             : /// \relates PLMD::ActionRegister
+     115             : /// For easier registration, this file also provides a macro PLUMED_REGISTER_ACTION.
+     116             : /// \param classname the name of the class to be registered
+     117             : /// \param directive a string containing the corresponding directive
+     118             : /// This macro should be used in the .cpp file of the corresponding class
+     119             : #define PLUMED_REGISTER_ACTION(classname,directive) \
+     120             :   namespace {::PLMD::ActionRegistration<classname> \
+     121             :              PLUMED_CONCATENATE(classname##Registerer,__LINE__)(directive);}
+     122             : #endif
+     123             : 
+
+
+
+ + + + +
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 000000000..2fdf5a5e1 --- /dev/null +++ b/coverage/core/ActionSet.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv3
_ZNK4PLMD9ActionSet26getShortcutActionWithLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6372
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE806680
_ZN4PLMD9ActionSetD2Ev806680
+
+
+ + + +
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 000000000..70fd793df --- /dev/null +++ b/coverage/core/ActionSet.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv3
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE806680
_ZN4PLMD9ActionSetD2Ev806680
_ZNK4PLMD9ActionSet26getShortcutActionWithLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6372
+
+
+ + + +
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 000000000..180bcb15f --- /dev/null +++ b/coverage/core/ActionSet.cpp.gcov.html @@ -0,0 +1,128 @@ + + + + + + + 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-10-17 16:45:00Functions: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      806680 : ActionSet::ActionSet(PlumedMain&p):
+      27      806680 :   plumed(p) {
+      28             :   (void) plumed; // to suppress warning about "unused plumed"
+      29      806680 : }
+      30             : 
+      31      806680 : ActionSet::~ActionSet()
+      32             : {
+      33             : // required in order to deallocate in reverse order:
+      34      857678 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      35      806680 : }
+      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        6372 : ActionShortcut* ActionSet::getShortcutActionWithLabel( const std::string& s ) const {
+      43             :   ActionShortcut* scf = NULL;
+      44      273396 :   for(const auto & p : (*this)) {
+      45      267024 :     ActionShortcut* sc=dynamic_cast<ActionShortcut*>(p.get());
+      46      267024 :     if( sc && sc->shortcutlabel==s ) scf = sc;
+      47             :   }
+      48        6372 :   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 000000000..6dc3b3aee --- /dev/null +++ b/coverage/core/ActionSet.h.func-sort-c.html @@ -0,0 +1,196 @@ + + + + + + + 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-10-17 16:45:00Functions: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_4opes12ExpansionCVsEEESt6vectorIT_SaIS6_EEv30
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_9PbcActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE75
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves7VesBiasEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE88
_ZNK4PLMD9ActionSet6selectIPNS_7generic4ReadEEESt6vectorIT_SaIS6_EEv91
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves14BasisFunctionsEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE241
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToGetDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE281
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE407
_ZNK4PLMD9ActionSet6selectIPNS_19DomainDecompositionEEESt6vectorIT_SaIS5_EEv1038
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE1080
_ZNK4PLMD9ActionSet6selectIPNS_15ActionAtomisticEEESt6vectorIT_SaIS5_EEv1108
_ZNK4PLMD9ActionSet6selectIPNS_15ActionToPutDataEEESt6vectorIT_SaIS5_EEv1335
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_18ActionForInterfaceEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1521
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToPutDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10999
_ZNK4PLMD9ActionSet6selectIPNS_14ActionShortcutEEESt6vectorIT_SaIS5_EEv18310
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv18634
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_5GroupEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE50504
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51130
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv52074
_ZNK4PLMD9ActionSet6selectIPNS_18ActionForInterfaceEEESt6vectorIT_SaIS5_EEv55197
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_16ActionWithVectorEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE176730
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1241658
+
+
+ + + +
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 000000000..d87e39e1d --- /dev/null +++ b/coverage/core/ActionSet.h.func.html @@ -0,0 +1,196 @@ + + + + + + + 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-10-17 16:45:00Functions:273187.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE1080
_ZNK4PLMD9ActionSet12selectLatestIPNS_3piv3PIVEEET_PKNS_6ActionE12
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionAtomisticEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToGetDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE281
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToPutDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10999
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1241658
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_16ActionWithVectorEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE176730
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_18ActionForInterfaceEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1521
_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_traitsIcESaIcEEE50504
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51130
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_9PbcActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE75
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv52074
_ZNK4PLMD9ActionSet6selectIPNS_14ActionShortcutEEESt6vectorIT_SaIS5_EEv18310
_ZNK4PLMD9ActionSet6selectIPNS_15ActionAtomisticEEESt6vectorIT_SaIS5_EEv1108
_ZNK4PLMD9ActionSet6selectIPNS_15ActionToPutDataEEESt6vectorIT_SaIS5_EEv1335
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv18634
_ZNK4PLMD9ActionSet6selectIPNS_18ActionForInterfaceEEESt6vectorIT_SaIS5_EEv55197
_ZNK4PLMD9ActionSet6selectIPNS_19DomainDecompositionEEESt6vectorIT_SaIS5_EEv1038
_ZNK4PLMD9ActionSet6selectIPNS_3ves14BasisFunctionsEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves18TargetDistributionEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves7VesBiasEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_4opes12ExpansionCVsEEESt6vectorIT_SaIS6_EEv30
_ZNK4PLMD9ActionSet6selectIPNS_6colvar10RMSDVectorEEESt6vectorIT_SaIS6_EEv10
_ZNK4PLMD9ActionSet6selectIPNS_7generic4ReadEEESt6vectorIT_SaIS6_EEv91
+
+
+ + + +
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 000000000..b1af20ed9 --- /dev/null +++ b/coverage/core/ActionSet.h.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-10-17 16:45:00Functions: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      147827 : std::vector<T> ActionSet::select()const {
+      88             :   std::vector<T> ret;
+      89    87746891 :   for(const auto & p : (*this)) {
+      90    87599064 :     T t=dynamic_cast<T>(p.get());
+      91    87599064 :     if(t) ret.push_back(t);
+      92             :   };
+      93      147827 :   return ret;
+      94             : }
+      95             : 
+      96             : template <class T>
+      97     1533648 : T ActionSet::selectWithLabel(const std::string&s)const {
+      98   162766624 :   for(const auto & p : (*this)) {
+      99   133443820 :     T t=dynamic_cast<T>(p.get());
+     100   162648839 :     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        1092 : T ActionSet::selectLatest(const Action*action) const {
+     136             :   T t=nullptr;
+     137       37673 :   for(const auto & p : (*this)) {
+     138       36609 :     if(p.get()==action) return t;
+     139       36581 :     T r=dynamic_cast<T>(p.get());
+     140       36581 :     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 000000000..d8cb0e42a --- /dev/null +++ b/coverage/core/ActionSetup.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - core/ActionSetup.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE90
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE192
+
+
+ + + +
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 000000000..6a5a0c7e4 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - core/ActionSetup.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE192
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE90
+
+
+ + + +
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 000000000..779b7d9b1 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.gcov.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions: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          90 : ActionSetup::ActionSetup(const ActionOptions&ao):
+      32          90 :   Action(ao)
+      33             : {
+      34          90 :   const ActionSet& actionset(plumed.getActionSet());
+      35         808 :   for(const auto & p : actionset) {
+      36             :     // check that all the preceding actions are ActionSetup
+      37         718 :     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          90 : }
+      42             : 
+      43         192 : void ActionSetup::registerKeywords( Keywords& keys ) {
+      44         192 :   Action::registerKeywords(keys);
+      45         192 :   keys.remove("LABEL");
+      46         192 : }
+      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 000000000..cdd1dcbc6 --- /dev/null +++ b/coverage/core/ActionSetup.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - core/ActionSetup.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..eaa4da9cc --- /dev/null +++ b/coverage/core/ActionSetup.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - core/ActionSetup.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..6d7a11f6d --- /dev/null +++ b/coverage/core/ActionSetup.h.gcov.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - core/ActionSetup.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..98500bb22 --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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:13914993.3 %
Date:2024-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionShortcut26addCommentToShortcutOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev18
_ZNK4PLMD14ActionShortcut15getUpdateLimitsB5cxx11Ev37
_ZNK4PLMD14ActionShortcut15getSavedOutputsB5cxx11Ev41
_ZN4PLMD14ActionShortcut20readShortcutKeywordsERKNS_8KeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE233
_ZNK4PLMD14ActionShortcut18interpretDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_6ActionERSt6vectorIPNS_5ValueESaISD_EE613
_ZN4PLMD14ActionShortcut20addToSavedInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6561
_ZN4PLMD14ActionShortcut24convertInputLineToStringB5cxx11Ev14795
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE16075
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE18463
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb21666
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev71708
+
+
+ + + +
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 000000000..dd04dd40d --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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:13914993.3 %
Date:2024-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb21666
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE18463
_ZN4PLMD14ActionShortcut20addToSavedInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6561
_ZN4PLMD14ActionShortcut20readShortcutKeywordsERKNS_8KeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE233
_ZN4PLMD14ActionShortcut24convertInputLineToStringB5cxx11Ev14795
_ZN4PLMD14ActionShortcut26addCommentToShortcutOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE16075
_ZNK4PLMD14ActionShortcut15getSavedOutputsB5cxx11Ev41
_ZNK4PLMD14ActionShortcut15getUpdateLimitsB5cxx11Ev37
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev71708
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev18
_ZNK4PLMD14ActionShortcut18interpretDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_6ActionERSt6vectorIPNS_5ValueESaISD_EE613
+
+
+ + + +
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 000000000..7aa767e5f --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.gcov.html @@ -0,0 +1,322 @@ + + + + + + + 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:13914993.3 %
Date:2024-10-17 16:45:00Functions:121392.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 "ActionShortcut.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionWithValue.h"
+      25             : #include "ActionRegister.h"
+      26             : #include "ActionSet.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30       18463 : void ActionShortcut::registerKeywords( Keywords& keys ) {
+      31       18463 :   Action::registerKeywords( keys );
+      32       36926 :   keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts");
+      33       36926 :   keys.add("hidden","HAS_VALUES","this is used in json output to determine those actions that have values");
+      34       18463 : }
+      35             : 
+      36         233 : void ActionShortcut::readShortcutKeywords( const Keywords& keys, std::map<std::string,std::string>& keymap ) {
+      37        2786 :   for(unsigned i=0; i<keys.size(); ++i) {
+      38        2553 :     std::string t, keyname = keys.get(i);
+      39        3481 :     if( keys.style( keyname, "optional") || keys.style( keyname, "compulsory") ) {
+      40        1625 :       parse(keyname,t);
+      41        1625 :       if( t.length()>0 ) {
+      42         102 :         keymap.insert(std::pair<std::string,std::string>(keyname,t));
+      43        1574 :       } else if( keys.numbered( keyname ) ) {
+      44         659 :         for(unsigned i=1;; ++i) {
+      45         674 :           std::string istr; Tools::convert( i, istr );
+      46         674 :           if( !parseNumbered(keyname,i,t) ) break ;
+      47          30 :           keymap.insert(std::pair<std::string,std::string>(keyname + istr,t));
+      48          15 :         }
+      49             :       }
+      50        1856 :     } else if( keys.style( keyname, "flag") ) {
+      51         928 :       bool found=false; parseFlag(keyname,found);
+      52        1032 :       if( found ) keymap.insert(std::pair<std::string,std::string>(keyname,""));
+      53           0 :     } else plumed_merror("shortcut keywords should be optional, compulsory or flags");
+      54             :   }
+      55         233 : }
+      56             : 
+      57       16075 : ActionShortcut::ActionShortcut(const ActionOptions&ao):
+      58             :   Action(ao),
+      59       16075 :   shortcutlabel(label)
+      60             : {
+      61       16075 :   std::string s; Tools::convert(plumed.getActionSet().size(),s);
+      62       16075 :   if( shortcutlabel==("@" + s) ) {
+      63           0 :     std::string t; Tools::convert(plumed.getActionSet().size(),t);
+      64           0 :     shortcutlabel="@" + t;
+      65       32150 :   } else label = ("@s" + s);
+      66       16075 : }
+      67             : 
+      68       21666 : void ActionShortcut::readInputLine( const std::string& input, bool saveline ) {
+      69       21666 :   std::vector<std::string> words=Tools::getWords(input); Tools::interpretLabel(words);
+      70             :   // Check if this action name has been registered
+      71       21666 :   bool founds=false, found = std::find(keywords.neededActions.begin(), keywords.neededActions.end(), words[0] )!=keywords.neededActions.end();
+      72             :   // Check if we are just calling something like SUM_VECTOR using just SUM.
+      73       36486 :   if( !found && words[0].find(getName())!=std::string::npos ) {
+      74       19594 :     for(unsigned j=0 ; j<keywords.actionNameSuffixes.size(); ++j) {
+      75       19594 :       if( (getName() + keywords.actionNameSuffixes[j])==words[0] ) { found=true; break; }
+      76             :     }
+      77             :     founds=true;
+      78             :   }
+      79       21666 :   if( found ) {
+      80       21666 :     std::string f_input = input; if( !founds && saveline ) addToSavedInputLines( input );
+      81       43332 :     if( keywords.exists("RESTART") ) {
+      82           0 :       if( restart ) f_input += " RESTART=YES";
+      83           0 :       if( !restart ) f_input += " RESTART=NO";
+      84             :     }
+      85       21666 :     plumed.readInputLine( f_input );
+      86       21651 :     if( !founds ) {
+      87             :       ActionWithValue* av=NULL;
+      88       11758 :       for(auto pp=plumed.getActionSet().rbegin(); pp!=plumed.getActionSet().rend(); ++pp) {
+      89       11758 :         av = pp->get()->castToActionWithValue();
+      90       11758 :         if( !av ) continue ;
+      91        6846 :         if( std::find(savedOutputs.begin(), savedOutputs.end(), av->getLabel() )!=savedOutputs.end() ) av=NULL;
+      92             :         break;
+      93             :       }
+      94        6840 :       if( av ) {
+      95        6840 :         std::string av_label = av->getLabel();
+      96        6840 :         if( av_label == getShortcutLabel() ) savedOutputs.push_back( av_label );
+      97             :         else {
+      98       36025 :           for(unsigned i=0; i<keywords.cnames.size(); ++i) {
+      99       30392 :             if( av_label == getShortcutLabel() + "_" + keywords.cnames[i] ) savedOutputs.push_back( av_label );
+     100       60190 :             else if( keywords.getOutputComponentFlag(keywords.cnames[i])!="default" ) {
+     101       26388 :               std::string thisflag = keywords.getOutputComponentFlag(keywords.cnames[i]);
+     102       53378 :               if( keywords.numbered(thisflag) && av_label.find(getShortcutLabel() + "_" + keywords.cnames[i])!=std::string::npos ) savedOutputs.push_back( av_label );
+     103             :             }
+     104             :           }
+     105             :         }
+     106             :       }
+     107             :     } else {
+     108       14805 :       ActionWithValue* av = plumed.getActionSet()[plumed.getActionSet().size()-1]->castToActionWithValue();
+     109       14820 :       if( !av ) error("shortcut is using suffix but action created is not ActionWithValue");
+     110       14805 :       Keywords thiskeys; actionRegister().getKeywords( av->getName(), thiskeys );
+     111       29610 :       if( thiskeys.getDisplayName()!=getName() ) error("mismatch between display name of hidden action " + thiskeys.getDisplayName() + " and shortcut that creates it " + getName() );
+     112       14805 :     }
+     113           0 :   } else error("requirement for action " + words[0] + " should be registered in registerKeywords function for shortcut action using keys.useAction");
+     114       21666 : }
+     115             : 
+     116           1 : void ActionShortcut::addCommentToShortcutOutput( const std::string& input ) {
+     117           1 :   savedInputLines.push_back( input );
+     118           1 : }
+     119             : 
+     120          37 : std::string ActionShortcut::getUpdateLimits() const {
+     121          37 :   std::string f_input="";
+     122          37 :   if( update_from!=std::numeric_limits<double>::max() ) {
+     123           4 :     std::string ufrom; Tools::convert( update_from, ufrom ); f_input += " UPDATE_FROM=" + ufrom;
+     124             :   }
+     125          37 :   if( update_until!=std::numeric_limits<double>::max() ) {
+     126           4 :     std::string util; Tools::convert( update_until, util ); f_input += " UPDATE_UNTIL=" + util;
+     127             :   }
+     128          37 :   return f_input;
+     129             : }
+     130             : 
+     131        6561 : void ActionShortcut::addToSavedInputLines( const std::string& line ) {
+     132        6561 :   std::vector<std::string> words = Tools::getWords(line); std::string actname;
+     133        6561 :   if( words[0].find_first_of(":")!=std::string::npos) actname = words[1]; else actname = words[0];
+     134        6561 :   if( !actionRegister().check(actname) ) error("found no action with name " + actname + " to create shortcut");
+     135        6561 :   Keywords thiskeys; actionRegister().getKeywords( actname, thiskeys ); std::vector<std::string> numberedkeys;
+     136       55560 :   for(unsigned i=0; i<thiskeys.size(); ++i ) {
+     137      105752 :     if( thiskeys.numbered( thiskeys.getKeyword(i) ) ) numberedkeys.push_back( thiskeys.getKeyword(i) );
+     138             :   }
+     139       12046 :   if( numberedkeys.size()>0 && actname!="CONCATENATE" ) {
+     140             :     std::string reducedline;
+     141      190250 :     for(unsigned i=0; i<words.size(); ++i) {
+     142             :       bool notnumbered=true;
+     143      481887 :       for(unsigned j=0; j<numberedkeys.size(); ++j) {
+     144      800495 :         if( words[i].find(numberedkeys[j])!=std::string::npos && words[i].substr(0,numberedkeys[j].length()+1)!=numberedkeys[j]+"=" ) { notnumbered=false; break; }
+     145             :       }
+     146      184939 :       if( notnumbered || words[i]==actname ) {
+     147       22711 :         if( words[i].find(" ")!=std::string::npos) {
+     148         244 :           std::size_t eq=words[i].find_first_of("=");
+     149         488 :           reducedline += words[i].substr(0,eq) + "={" + words[i].substr(eq+1) + "} ";
+     150       44934 :         } else reducedline += words[i] + " ";
+     151             :       }
+     152             :     }
+     153        5311 :     std::vector<unsigned> ninstances( numberedkeys.size(), 0 );
+     154       12717 :     for(unsigned j=0; j<numberedkeys.size(); ++j) {
+     155        7406 :       for(unsigned i=1;; ++i) {
+     156      169025 :         std::string num, val; Tools::convert(i, num);
+     157      169025 :         bool found = Tools::parse(words, numberedkeys[j] + num, val );
+     158      169025 :         if( !found) break ;
+     159      162198 :         if( i<6 ) reducedline += numberedkeys[j] + num + "=" + val + " ";
+     160      161040 :         else ninstances[j]++;
+     161      161619 :       }
+     162             :     }
+     163             :     bool outputcomment=false;
+     164       12595 :     for(unsigned j=0; j<numberedkeys.size(); ++j) {
+     165        7358 :       if( ninstances[j]>0 ) { outputcomment=true; break; }
+     166             :     }
+     167        5311 :     if( outputcomment ) {
+     168             :       reducedline += "    # Action input conctinues with ";
+     169         258 :       for(unsigned  j=0; j<numberedkeys.size(); ++j) {
+     170         184 :         std::string num; Tools::convert( ninstances[j], num );
+     171         262 :         if( ninstances[j]>0 ) reducedline += num + " further " + numberedkeys[j] + "n keywords, ";
+     172             :       }
+     173             :     }
+     174        5311 :     savedInputLines.push_back( reducedline );
+     175        1250 :   } else savedInputLines.push_back( line );
+     176       13122 : }
+     177             : 
+     178       71708 : const std::string & ActionShortcut::getShortcutLabel() const {
+     179       71708 :   return shortcutlabel;
+     180             : }
+     181             : 
+     182          18 : std::vector<std::string> ActionShortcut::getSavedInputLines() const {
+     183          18 :   return savedInputLines;
+     184             : }
+     185             : 
+     186          41 : std::vector<std::string> ActionShortcut::getSavedOutputs() const {
+     187          41 :   return savedOutputs;
+     188             : }
+     189             : 
+     190       14795 : std::string ActionShortcut::convertInputLineToString() {
+     191             :   std::string output;
+     192       66096 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     193       51301 :     if( (*p).find(" " )!=std::string::npos ) {
+     194         405 :       std::size_t eq = (*p).find_first_of("=");
+     195         810 :       output += " " + (*p).substr(0,eq) + "={" + (*p).substr(eq+1) + "}";
+     196      101792 :     } else output += " " + (*p);
+     197             :   }
+     198       14795 :   line.resize(0); return output;
+     199             : }
+     200             : 
+     201         613 : void ActionShortcut::interpretDataLabel( const std::string& mystr, Action* myuser, std::vector<Value*>& arg ) const {
+     202         613 :   std::size_t dot=mystr.find_first_of('.'); std::string a=mystr.substr(0,dot); std::string name=mystr.substr(dot+1);
+     203             :   // Retrieve the keywords for the shortcut
+     204         613 :   Keywords skeys; actionRegister().getKeywords( getName(), skeys );
+     205         613 :   std::vector<std::string> out_comps( skeys.getOutputComponents() );
+     206             :   // Now get the output components
+     207         613 :   if( name=="*" ) {
+     208        2613 :     for(unsigned k=0; k<out_comps.size(); ++k) {
+     209        2228 :       if( out_comps[k]=="" ) {
+     210           0 :         ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a );
+     211           0 :         if( action ) {
+     212           0 :           if( action->getNumberOfComponents()!=1 ) myuser->error("action named " + a + " has more than one component");
+     213           0 :           arg.push_back(action->copyOutput(0));
+     214             :         }
+     215             :       } else {
+     216        4456 :         ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a + "_" + out_comps[k] );
+     217        2228 :         if( action ) {
+     218         234 :           if( action->getNumberOfComponents()!=1 ) myuser->error("action named " + a + "_" + out_comps[k] + " has more than one component");
+     219         234 :           arg.push_back(action->copyOutput(0));
+     220             :         } else {
+     221        1994 :           for(unsigned j=1;; ++j) {
+     222        4031 :             std::string numstr; Tools::convert( j, numstr );
+     223        8062 :             ActionWithValue* act=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a + "_" + out_comps[k] + "-" + numstr );
+     224        4031 :             if( act ) {
+     225         140 :               for(unsigned n=0; n<act->getNumberOfComponents(); ++n ) arg.push_back(act->copyOutput(n));
+     226        3961 :             } else if( j>1 ) break;    // This ensures that * syntax works with moments, which normally start from 2
+     227        2037 :           }
+     228             :         }
+     229             :       }
+     230             :     }
+     231             :   } else {
+     232             :     // Check for an action that has action.component
+     233         228 :     ActionWithValue* act=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a );
+     234         228 :     if( act && act->exists(mystr) ) return;
+     235             :     // Get components that are actually actions
+     236         231 :     for(unsigned k=0; k<out_comps.size(); ++k) {
+     237         231 :       if(name.find_first_of(out_comps[k])!=std::string::npos ) {
+     238         392 :         ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a + "_" + name );
+     239         196 :         if( action ) arg.push_back(action->copyOutput(a+"_"+name));
+     240             :         break;
+     241             :       }
+     242             :     }
+     243             :   }
+     244         613 : }
+     245             : 
+     246             : }
+
+
+
+ + + + +
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 000000000..fefc10763 --- /dev/null +++ b/coverage/core/ActionShortcut.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1333.3 %
Date:2024-10-17 16:45:00Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut5applyEv0
_ZN4PLMD14ActionShortcut9calculateEv0
_ZN4PLMD14ActionShortcut20castToActionShortcutEv59
+
+
+ + + +
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 000000000..ddcc02847 --- /dev/null +++ b/coverage/core/ActionShortcut.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1333.3 %
Date:2024-10-17 16:45:00Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut20castToActionShortcutEv59
_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 000000000..d2a26622b --- /dev/null +++ b/coverage/core/ActionShortcut.h.gcov.html @@ -0,0 +1,147 @@ + + + + + + + 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:1333.3 %
Date:2024-10-17 16:45:00Functions:1333.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #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             :   std::vector<std::string> savedOutputs;
+      40             :   void addToSavedInputLines( const std::string& line );
+      41             : protected:
+      42             :   std::string getUpdateLimits() const ;
+      43             : public:
+      44             :   const std::string & getShortcutLabel() const ;
+      45             :   static void registerKeywords( Keywords& keys );
+      46             : /// Constructor
+      47             :   explicit ActionShortcut(const ActionOptions&ao);
+      48             : /// Read keywords
+      49             :   void readShortcutKeywords( const Keywords& keys, std::map<std::string,std::string>& keymap );
+      50             : /// Read a line of input and create appropriate actions
+      51             :   void readInputLine( const std::string& input, bool saveline=true );
+      52             : /// Add a comment to your shortcut output
+      53             :   void addCommentToShortcutOutput( const std::string& input );
+      54             : /// Do nothing.
+      55           0 :   void calculate() override {}
+      56             : /// Do nothing.
+      57           0 :   void apply() override {}
+      58             : /// Get the lines of the shortcut that were read in
+      59             :   std::vector<std::string> getSavedInputLines() const ;
+      60             : /// Get the labels of the actions that this creates
+      61             :   std::vector<std::string> getSavedOutputs() const ;
+      62             : /// Take everything that was input to this action and convert it to a string
+      63             :   std::string convertInputLineToString();
+      64             : /// This sorts out the reading of arguments from shortcuts
+      65             :   void interpretDataLabel( const std::string& mystr, Action* myuser, std::vector<Value*>& args ) const ;
+      66          59 :   ActionShortcut* castToActionShortcut() noexcept final { return this; }
+      67             : };
+      68             : 
+      69             : }
+      70             : 
+      71             : #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 000000000..f03392433 --- /dev/null +++ b/coverage/core/ActionToGetData.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:293290.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..9d7395d83 --- /dev/null +++ b/coverage/core/ActionToGetData.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:293290.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..4a78ba26b --- /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:293290.6 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("a copy of the data in the value specified by the ARG keyword");
+      45         117 : }
+      46             : 
+      47         115 : ActionToGetData::ActionToGetData(const ActionOptions&ao):
+      48             :   Action(ao),
+      49             :   ActionPilot(ao),
+      50             :   ActionWithArguments(ao),
+      51         115 :   mydata(DataPassingObject::create(plumed.getRealPrecision()))
+      52             : {
+      53         230 :   std::string type; parse("TYPE",type);
+      54         115 :   if( type=="value" ) gtype=val;
+      55           0 :   else if( type=="derivatives" ) gtype=deriv;
+      56           0 :   else if( type=="forces" ) gtype=force;
+      57           0 :   else plumed_merror("cannot get " + type + " for value TYPE should be value/derivative/force");
+      58             : 
+      59         115 :   if( gtype!=val ) error("not implemented functionality to pass derviatives or forces to python.  Email gareth.tribello@gmail.com if you want this.");
+      60             : 
+      61         115 :   if( getNumberOfArguments()!=1 ) error("python interface works best when you ask for one argument at a time");
+      62         115 :   if( getPntrToArgument(0)->getNumberOfValues()==0 ) error("cannot get data as shape of value " + getPntrToArgument(0)->getName() + " has not been set");
+      63         115 :   getPntrToArgument(0)->buildDataStore(); data.resize( getPntrToArgument(0)->getNumberOfValues() );
+      64         115 : }
+      65             : 
+      66         115 : void ActionToGetData::get_rank( const TypesafePtr & dims ) {
+      67         115 :   if( getPntrToArgument(0)->getRank()==0 ) { dims.set(long(1)); return; }
+      68          17 :   dims.set(long(getPntrToArgument(0)->getRank()));
+      69             : }
+      70             : 
+      71          51 : void ActionToGetData::get_shape( const TypesafePtr & dims ) {
+      72          51 :   if( getPntrToArgument(0)->getRank()==0 ) { dims.set(long(1)); return; }
+      73          17 :   auto dims_=dims.get<long*>( { getPntrToArgument(0)->getRank() } );
+      74          37 :   for(unsigned j=0; j<getPntrToArgument(0)->getRank(); ++j) dims_[j] = getPntrToArgument(0)->getShape()[j];
+      75             : }
+      76             : 
+      77         115 : void ActionToGetData::set_memory( const TypesafePtr & val ) {
+      78         115 :   mydata->setValuePointer(val,getPntrToArgument(0)->getShape(),false);
+      79         115 : }
+      80             : 
+      81       12447 : void ActionToGetData::calculate() {
+      82       12447 :   plumed_assert( gtype==val ); mydata->setData( getPntrToArgument(0) );
+      83       12447 : }
+      84             : 
+      85             : }
+
+
+
+ + + + +
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 000000000..405e211c8 --- /dev/null +++ b/coverage/core/ActionToGetData.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5f9db152c --- /dev/null +++ b/coverage/core/ActionToGetData.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7504131c3 --- /dev/null +++ b/coverage/core/ActionToGetData.h.gcov.html @@ -0,0 +1,134 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1e5bace68 --- /dev/null +++ b/coverage/core/ActionToPutData.cpp.func-sort-c.html @@ -0,0 +1,140 @@ + + + + + + + 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:9710592.4 %
Date:2024-10-17 16:45:00Functions:1717100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionToPutData26getNumberOfForcesToRescaleEv150
_ZN4PLMD15ActionToPutData13rescaleForcesERKd200
_ZN4PLMD15ActionToPutData10readBinaryERSi798
_ZN4PLMD15ActionToPutData11writeBinaryERSo798
_ZN4PLMD15ActionToPutDataC2ERKNS_13ActionOptionsE1232
_ZNK4PLMD15ActionToPutData14getLocalValuesERSt6vectorIdSaIdEE1350
_ZN4PLMD15ActionToPutDataC1ERKNS_13ActionOptionsE7065
_ZN4PLMD15ActionToPutData16registerKeywordsERNS_8KeywordsE7100
_ZN4PLMD15ActionToPutData7setUnitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8297
_ZNK4PLMD15ActionToPutData11getUnitNameB5cxx11Ev9588
_ZN4PLMD15ActionToPutData11updateUnitsEPNS_16DataPassingToolsE9608
_ZN4PLMD15ActionToPutData4waitEv93799
_ZN4PLMD15ActionToPutData5applyEv444088
_ZN4PLMD15ActionToPutData8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj449854
_ZN4PLMD15ActionToPutData9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj449854
_ZN4PLMD15ActionToPutData15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE974159
_ZN4PLMD15ActionToPutData15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1927195
+
+
+ + + +
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 000000000..9d11ad05a --- /dev/null +++ b/coverage/core/ActionToPutData.cpp.func.html @@ -0,0 +1,140 @@ + + + + + + + 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:9710592.4 %
Date:2024-10-17 16:45:00Functions:1717100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData10readBinaryERSi798
_ZN4PLMD15ActionToPutData11updateUnitsEPNS_16DataPassingToolsE9608
_ZN4PLMD15ActionToPutData11writeBinaryERSo798
_ZN4PLMD15ActionToPutData13rescaleForcesERKd200
_ZN4PLMD15ActionToPutData15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE974159
_ZN4PLMD15ActionToPutData15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1927195
_ZN4PLMD15ActionToPutData16registerKeywordsERNS_8KeywordsE7100
_ZN4PLMD15ActionToPutData4waitEv93799
_ZN4PLMD15ActionToPutData5applyEv444088
_ZN4PLMD15ActionToPutData7setUnitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8297
_ZN4PLMD15ActionToPutData8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj449854
_ZN4PLMD15ActionToPutData9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj449854
_ZN4PLMD15ActionToPutDataC1ERKNS_13ActionOptionsE7065
_ZN4PLMD15ActionToPutDataC2ERKNS_13ActionOptionsE1232
_ZNK4PLMD15ActionToPutData11getUnitNameB5cxx11Ev9588
_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 000000000..d6e0ba4b7 --- /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:9710592.4 %
Date:2024-10-17 16:45:00Functions: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        7100 : void ActionToPutData::registerKeywords(Keywords& keys) {
+      41        7100 :   ActionForInterface::registerKeywords( keys );
+      42       14200 :   keys.add("compulsory","SHAPE","0","the shape of the value that is being passed to PLUMED");
+      43       14200 :   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       14200 :   keys.add("compulsory","FORCE_UNIT","default","the units to use for the force");
+      45       14200 :   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       14200 :   keys.addFlag("CONSTANT",false,"does this quantity not depend on time");
+      49       14200 :   keys.addFlag("FROM_DOMAINS",false,"is this quantity passed through the domain decomposition object");
+      50       14200 :   keys.addFlag("MUTABLE",false,"can plumed change the value of the pointer that is passed from the MD code");
+      51        7100 :   keys.setValueDescription("the data that was passed from the MD code");
+      52        7100 : }
+      53             : 
+      54        8297 : ActionToPutData::ActionToPutData(const ActionOptions&ao):
+      55             :   Action(ao),
+      56             :   ActionForInterface(ao),
+      57        8297 :   noforce(false),
+      58        8297 :   fixed(false),
+      59        8297 :   from_domains(false),
+      60        8297 :   resetable(false),
+      61        8297 :   dataCanBeSet(true),
+      62        8297 :   unit(n),
+      63        8297 :   mydata(DataPassingObject::create(plumed.getRealPrecision()))
+      64             : {
+      65       15362 :   if( getName()!="ENERGY" && getName()!="PBC" ) {
+      66       14130 :     std::vector<unsigned> shape; parseVector("SHAPE",shape);
+      67        7065 :     if( shape.size()==1 && shape[0]==0 ) { shape.resize(0); addValue( shape ); }
+      68        5980 :     else { addValue( shape ); }
+      69             : 
+      70        7065 :     std::string unitstr, funitstr; parse("UNIT",unitstr);
+      71       14130 :     parse("FORCE_UNIT",funitstr); setUnit( unitstr, funitstr );
+      72             : 
+      73             :     // Now sort out period
+      74       14130 :     std::vector<std::string> period; parseVector("PERIODIC",period);
+      75        7065 :     if( period.size()==1 ) {
+      76        7063 :       if( period[0]!="NO") error("input to PERIODIC keyword does not make sense");
+      77        7063 :       setNotPeriodic();
+      78           2 :     } else if( period.size()==2 ) setPeriodic( period[0], period[1] );
+      79           0 :     else  error("input to PERIODIC keyword does not make sense");
+      80             : 
+      81       14130 :     parseFlag("CONSTANT",fixed); if( fixed ) { noforce=true; copyOutput(0)->setConstant(); }
+      82       14130 :     parseFlag("FROM_DOMAINS",from_domains); parseFlag("MUTABLE",resetable);
+      83        7065 :   }
+      84        8297 : }
+      85             : 
+      86        8297 : void ActionToPutData::setUnit( const std::string& unitstr, const std::string& funitstr ) {
+      87        8297 :   if( unitstr=="number" ) unit=n;
+      88        8274 :   else if( unitstr=="energy" ) unit=e;
+      89        8173 :   else if( unitstr=="length" ) unit=l;
+      90        3405 :   else if( unitstr=="mass" ) unit=m;
+      91        2213 :   else if( unitstr=="charge" ) unit=q;
+      92        1021 :   else if( unitstr=="time" ) unit=t;
+      93           0 :   else error( unitstr + " is not a valid input unit");
+      94             :   // Set the force units
+      95        8297 :   if( funitstr=="default" ) funit=d;
+      96        1192 :   else if( funitstr=="energy" ) funit=eng;
+      97           0 :   else error( funitstr + " is not a valid input force unit");
+      98        8297 : }
+      99             : 
+     100        9588 : std::string ActionToPutData::getUnitName() const {
+     101        9588 :   if( unit==e ) return "energy";
+     102        9423 :   if( unit==l ) return "length";
+     103        4523 :   if( unit==m ) return "mass";
+     104        3298 :   if( unit==q ) return "charge";
+     105        2073 :   if( unit==t ) return "time";
+     106           0 :   plumed_error();
+     107             : }
+     108             : 
+     109      449854 : void ActionToPutData::setStart( const std::string& name, const unsigned& sss) {
+     110      449854 :   plumed_assert( name==getLabel() ); mydata->setStart(sss);
+     111      449854 : }
+     112             : 
+     113      449854 : void ActionToPutData::setStride( const std::string& name, const unsigned& sss ) {
+     114      449854 :   plumed_assert( name==getLabel() ); mydata->setStride(sss);
+     115      449854 : }
+     116             : 
+     117        9608 : void ActionToPutData::updateUnits( DataPassingTools* passtools ) {
+     118             :   // Don't need to do anythign if this is just a number
+     119        9608 :   if( unit==n ) return ;
+     120             : 
+     121       19176 :   double vunits=passtools->getUnitConversion( getUnitName() );
+     122        9588 :   mydata->setUnit(vunits); if( fixed && wasset ) mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
+     123        9588 :   if( funit==eng ) mydata->setForceUnit( 1/passtools->getUnitConversion("energy"));
+     124        8363 :   else if( funit==d ) mydata->setForceUnit(1/passtools->getUnitConversion("energy")*vunits);
+     125             : }
+     126             : 
+     127     1927195 : bool ActionToPutData::setValuePointer( const std::string& name, const TypesafePtr & val ) {
+     128     1927195 :   if( name!=getLabel() ) return false;
+     129      450948 :   wasset=true; plumed_massert( dataCanBeSet, "set " + getLabel() + " cannot be set at this time");
+     130      450939 :   if( !from_domains ) {
+     131       96833 :     if( !resetable && getPntrToComponent(0)->getRank()==0 ) {
+     132        5073 :       mydata->saveValueAsDouble( val );
+     133        5073 :       if( fixed ) mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
+     134       91760 :     } else mydata->setValuePointer(val,getPntrToComponent(0)->getShape(), !resetable);
+     135      708212 :   } else mydata->setValuePointer(val,std::vector<unsigned>(), !resetable);
+     136             :   return true;
+     137             : }
+     138             : 
+     139      974159 : bool ActionToPutData::setForcePointer( const std::string& name, const TypesafePtr & val ) {
+     140      974159 :   if( name!=getLabel() ) return false;
+     141      281875 :   plumed_massert( dataCanBeSet, "force on " + getLabel() + " cannot be set at this time");
+     142      281875 :   if( !from_domains ) mydata->setForcePointer(val,getPntrToComponent(0)->getShape());
+     143      434514 :   else mydata->setForcePointer(val,std::vector<unsigned>());
+     144             :   return true;
+     145             : }
+     146             : 
+     147        1350 : void ActionToPutData::getLocalValues( std::vector<double>& vals ) const {
+     148        1350 :   mydata->share_data( vals );
+     149        1350 : }
+     150             : 
+     151       93799 : void ActionToPutData::wait() {
+     152       93799 :   dataCanBeSet=false; if( fixed || !wasset ) { return; } plumed_assert( wasset );
+     153       93799 :   mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
+     154             : }
+     155             : 
+     156      444088 : void ActionToPutData::apply() {
+     157      444088 :   if( getPntrToValue()->forcesWereAdded() && !noforce ) {
+     158      181172 :     if( getName()=="ENERGY" || getDependencies().size()==0 ) mydata->add_force( getPntrToValue() );
+     159             :   }
+     160      444088 : }
+     161             : 
+     162         150 : unsigned ActionToPutData::getNumberOfForcesToRescale() const {
+     163         150 :   if( getName()!="ENERGY" || getDependencies().size()>0 ) return copyOutput(0)->getNumberOfValues();
+     164           0 :   plumed_assert( getDependencies().size()==1 );
+     165           0 :   plumed_assert(getDependencies()[0]); // needed for following calls, see #1046
+     166           0 :   ActionForInterface* ai = getDependencies()[0]->castToActionForInterface();
+     167           0 :   return ai->getNumberOfForcesToRescale();
+     168             : }
+     169             : 
+     170         200 : void ActionToPutData::rescaleForces( const double& alpha ) {
+     171         200 :   if( noforce ) return; wasscaled=true;
+     172         150 :   mydata->rescale_force( getNumberOfForcesToRescale(), alpha, getPntrToValue() );
+     173             : 
+     174             : }
+     175             : 
+     176         798 : void ActionToPutData::writeBinary(std::ostream&o) {
+     177         798 :   if(!fixed) getPntrToValue()->writeBinary(o);
+     178         798 : }
+     179             : 
+     180         798 : void ActionToPutData::readBinary(std::istream&i) {
+     181         798 :   if(!fixed) getPntrToValue()->readBinary(i);
+     182         798 : }
+     183             : 
+     184             : }
+
+
+
+ + + + +
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 000000000..0c666d24c --- /dev/null +++ b/coverage/core/ActionToPutData.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData8Set_commERNS_12CommunicatorE1
_ZN4PLMD15ActionToPutData8shareAllEv228
_ZNK4PLMD15ActionToPutData6onStepEv3415
_ZN4PLMD15ActionToPutData21castToActionToPutDataEv573749
_ZN4PLMD15ActionToPutData5shareEv743113
_ZN4PLMD15ActionToPutData17resetForStepStartEv754414
+
+
+ + + +
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 000000000..4cdfd7a56 --- /dev/null +++ b/coverage/core/ActionToPutData.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData17resetForStepStartEv754414
_ZN4PLMD15ActionToPutData21castToActionToPutDataEv573749
_ZN4PLMD15ActionToPutData5shareEv743113
_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 000000000..ffdfdd952 --- /dev/null +++ b/coverage/core/ActionToPutData.h.gcov.html @@ -0,0 +1,172 @@ + + + + + + + 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-10-17 16:45:00Functions: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      754414 :   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      743113 :   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      573749 :   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 000000000..29c97d1d6 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-10-17 16:45:00Functions: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_EE9849
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE10180
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKNS_9ActionSetEPNS_6ActionERS1_IPNS_5ValueESaISI_EE15177
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE17812
_ZN4PLMD19ActionWithArguments23calculateConstantValuesERKb18065
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE185918
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKjRKSt6vectorIdSaIdEERjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE200205
+
+
+ + + +
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 000000000..ea4ee599a --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-10-17 16:45:00Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE17812
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE185918
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE9849
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE101
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKjRKSt6vectorIdSaIdEERjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE200205
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE0
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKNS_9ActionSetEPNS_6ActionERS1_IPNS_5ValueESaISI_EE15177
_ZN4PLMD19ActionWithArguments23calculateConstantValuesERKb18065
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE10180
_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 000000000..7bd0a61ea --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.gcov.html @@ -0,0 +1,436 @@ + + + + + + + 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-10-17 16:45:00Functions: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       17812 : void ActionWithArguments::registerKeywords(Keywords& keys) {
+      38       35624 :   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       17812 : }
+      49             : 
+      50        9849 : void ActionWithArguments::parseArgumentList(const std::string&key,std::vector<Value*>&arg) {
+      51        9849 :   std::string def; std::vector<std::string> c; arg.clear(); parseVector(key,c);
+      52       10700 :   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        9842 :   interpretArgumentList(c,plumed.getActionSet(),this,arg);
+      57        9849 : }
+      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       15177 : void ActionWithArguments::interpretArgumentList(const std::vector<std::string>& c, const ActionSet& as, Action* readact, std::vector<Value*>&arg) {
+      69       40776 :   for(unsigned i=0; i<c.size(); i++) {
+      70             :     // is a regex? then just interpret it. The signal is ()
+      71       25602 :     if(!c[i].compare(0,1,"(")) {
+      72         219 :       unsigned l=c[i].length();
+      73         219 :       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         218 :         std::string myregex=c[i];
+      78         218 :         std::vector<ActionWithValue*> all=as.select<ActionWithValue*>();
+      79         219 :         if( all.empty() ) readact->error("your input file is not telling plumed to calculate anything");
+      80             : 
+      81             :         try {
+      82         218 :           std::regex txt_regex(myregex,std::regex::extended);
+      83         217 :           plumed_massert(txt_regex.mark_count()==1,"I can parse with only one subexpression");
+      84       24239 :           for(unsigned j=0; j<all.size(); j++) {
+      85       24022 :             std::vector<std::string> ss=all[j]->getComponentsVector();
+      86      349707 :             for(unsigned  k=0; k<ss.size(); ++k) {
+      87      325685 :               if(std::regex_match(ss[k],txt_regex)) {
+      88       21601 :                 arg.push_back(all[j]->copyOutput(ss[k]));
+      89             :                 found_something=true;
+      90             :               }
+      91             :             }
+      92       24022 :           }
+      93         218 :         } catch(std::regex_error & e) {
+      94           3 :           plumed_error()<<"Error parsing regular expression: "<<e.what();
+      95           1 :         }
+      96         217 :         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       25383 :       std::string a=c[i].substr(0,dot);
+     103       25383 :       std::string name=c[i].substr(dot+1);
+     104       25383 :       if(c[i].find(".")!=std::string::npos) {   // if it contains a dot:
+     105        6380 :         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        6365 :         } else if ( name=="*") {
+     115             :           unsigned carg=arg.size();
+     116             :           // Take all the values from an action with a specific name
+     117         606 :           ActionShortcut* shortcut=as.getShortcutActionWithLabel(a);
+     118         991 :           if( shortcut ) shortcut->interpretDataLabel( a + "." + name, readact, arg );
+     119         606 :           if( arg.size()==carg ) {
+     120             :             // Take all the values from an action with a specific name
+     121         375 :             ActionWithValue* action=as.selectWithLabel<ActionWithValue*>(a);
+     122         375 :             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         375 :             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        6171 :             for(int k=0; k<action->getNumberOfComponents(); ++k) arg.push_back(action->copyOutput(k));
+     129             :           }
+     130        5759 :         } else if ( a=="*" ) {
+     131          13 :           std::vector<ActionShortcut*> shortcuts=as.select<ActionShortcut*>();
+     132             :           // Take components from all actions with a specific name
+     133          13 :           std::vector<ActionWithValue*> all=as.select<ActionWithValue*>();
+     134          13 :           if( all.empty() ) readact->error("your input file is not telling plumed to calculate anything");
+     135             :           unsigned carg=arg.size();
+     136         157 :           for(unsigned j=0; j<shortcuts.size(); ++j) {
+     137         288 :             shortcuts[j]->interpretDataLabel( shortcuts[j]->getShortcutLabel() + "." + name, readact, arg );
+     138             :           }
+     139             :           unsigned nval=0;
+     140         276 :           for(unsigned j=0; j<all.size(); j++) {
+     141         526 :             std::string flab; flab=all[j]->getLabel() + "." + name;
+     142         263 :             if( all[j]->exists(flab) ) { arg.push_back(all[j]->copyOutput(flab)); nval++; }
+     143             :           }
+     144          13 :           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        5746 :           ActionWithValue* action=as.selectWithLabel<ActionWithValue*>(a);
+     148        5746 :           ActionShortcut* shortcut=as.getShortcutActionWithLabel(a);
+     149        5746 :           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        5746 :           } else if( action && action->exists(c[i]) ) {
+     154        5662 :             arg.push_back(action->copyOutput(c[i]));
+     155          84 :           } else if( shortcut ) {
+     156         168 :             unsigned narg=arg.size(); shortcut->interpretDataLabel( a + "." + name, readact, arg );
+     157          84 :             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       19017 :         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       18911 :           ActionWithValue* action=as.selectWithLabel<ActionWithValue*>(c[i]);
+     177       18911 :           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       18910 :           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       18911 :           arg.push_back(action->copyOutput(c[i]));
+     188             :         }
+     189             :       }
+     190             :     }
+     191             :   }
+     192       15174 : }
+     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      185918 : void ActionWithArguments::requestArguments(const std::vector<Value*> &arg) {
+     203      185918 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     204      185918 :   arguments=arg;
+     205      185918 :   clearDependencies();
+     206             :   std::string fullname;
+     207             :   std::string name;
+     208     1275652 :   for(unsigned i=0; i<arguments.size(); i++) {
+     209     1089734 :     fullname=arguments[i]->getName();
+     210     1089734 :     if(fullname.find(".")!=std::string::npos) {
+     211             :       std::size_t dot=fullname.find_first_of('.');
+     212      745752 :       name=fullname.substr(0,dot);
+     213             :     } else {
+     214             :       name=fullname;
+     215             :     }
+     216     1089734 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     217     1089734 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     218     1089734 :     addDependency(action);
+     219             :   }
+     220      185918 :   ActionWithValue* av=dynamic_cast<ActionWithValue*>(this);
+     221      185918 :   if(av) av->firststep=true;
+     222      185918 : }
+     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       10180 : ActionWithArguments::ActionWithArguments(const ActionOptions&ao):
+     243             :   Action(ao),
+     244       10180 :   lockRequestArguments(false)
+     245             : {
+     246       20360 :   if( keywords.exists("ARG") ) {
+     247             :     std::vector<Value*> arg;
+     248       19014 :     parseArgumentList("ARG",arg);
+     249             : 
+     250        9507 :     if(!arg.empty()) {
+     251        9205 :       log.printf("  with arguments : \n");
+     252       45215 :       for(unsigned i=0; i<arg.size(); i++) {
+     253       36010 :         if( arg[i]->hasDerivatives() && arg[i]->getRank()>0 ) log.printf(" function on grid with label %s \n",arg[i]->getName().c_str());
+     254       35001 :         else if( arg[i]->getRank()==2 ) log.printf("   matrix with label %s \n",arg[i]->getName().c_str());
+     255       32395 :         else if( arg[i]->getRank()==1 ) log.printf("   vector with label %s \n",arg[i]->getName().c_str());
+     256       26282 :         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        9507 :     requestArguments(arg);
+     261             :   }
+     262       10180 : }
+     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      200205 : void ActionWithArguments::addForcesOnArguments( const unsigned& argstart, const std::vector<double>& forces, unsigned& ind, const std::string& c  ) {
+     299      526545 :   for(unsigned i=0; i<arguments.size(); ++i) {
+     300      326340 :     if( i==0 && getName().find("EVALUATE_FUNCTION_FROM_GRID")!=std::string::npos ) continue ;
+     301      322990 :     if( !arguments[i]->ignoreStoredValue(c) || arguments[i]->getRank()==0 || (arguments[i]->getRank()>0 && arguments[i]->hasDerivatives()) ) {
+     302      300635 :       unsigned nvals = arguments[i]->getNumberOfStoredValues();
+     303    33592519 :       for(unsigned j=0; j<nvals; ++j) { arguments[i]->addForce( j, forces[ind], false ); ind++; }
+     304             :     }
+     305             :   }
+     306      200205 : }
+     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       18065 : bool ActionWithArguments::calculateConstantValues( const bool& haveatoms ) {
+     328       18065 :   ActionWithValue* av = castToActionWithValue();
+     329       18065 :   if( !av || arguments.size()==0 ) return false;
+     330             :   bool constant = true, atoms=false;
+     331       14749 :   for(unsigned i=0; i<arguments.size(); ++i) {
+     332       13637 :     auto * ptr=arguments[i]->getPntrToAction();
+     333       13637 :     plumed_assert(ptr); // needed for following calls, see #1046
+     334       13637 :     ActionAtomistic* aa=ptr->castToActionAtomistic();
+     335       13637 :     if( aa ) {
+     336       10739 :       ActionWithVector* av=dynamic_cast<ActionWithVector*>( arguments[i]->getPntrToAction() );
+     337       10739 :       if( !av || aa->getNumberOfAtoms()>0 ) atoms=true;
+     338             :     }
+     339       13637 :     if( !arguments[i]->isConstant() ) { constant=false; break; }
+     340             :   }
+     341       13389 :   if( constant ) {
+     342             :     // Set everything constant first as we need to set the shape
+     343        2248 :     for(unsigned i=0; i<av->getNumberOfComponents(); ++i) (av->copyOutput(i))->setConstant();
+     344        1112 :     if( !haveatoms ) log.printf("  values stored by this action are computed during startup and stay fixed during the simulation\n");
+     345        1112 :     if( atoms ) return haveatoms;
+     346             :   }
+     347             :   // Now do the calculation and store the values if we don't need anything from the atoms
+     348       13353 :   if( constant && !haveatoms ) {
+     349        1076 :     plumed_assert( !atoms ); activate(); calculate(); deactivate();
+     350        2176 :     for(unsigned i=0; i<av->getNumberOfComponents(); ++i) {
+     351        1100 :       unsigned nv = av->copyOutput(i)->getNumberOfValues();
+     352        1100 :       log.printf("  %d values stored in component labelled %s are : ", nv, (av->copyOutput(i))->getName().c_str() );
+     353        3939 :       for(unsigned j=0; j<nv; ++j) log.printf(" %f", (av->copyOutput(i))->get(j) );
+     354        1100 :       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 000000000..7fd90a668 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsD2Ev10180
_ZN4PLMD19ActionWithArguments25castToActionWithArgumentsEv21059
_ZNK4PLMD19ActionWithArguments12getArgumentsEv186364
_ZNK4PLMD19ActionWithArguments11getArgumentEj205382
_ZN4PLMD19ActionWithArguments12lockRequestsEv676118
_ZN4PLMD19ActionWithArguments14unlockRequestsEv676118
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv618202546
+
+
+ + + +
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 000000000..27aa26990 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments12lockRequestsEv676118
_ZN4PLMD19ActionWithArguments14unlockRequestsEv676118
_ZN4PLMD19ActionWithArguments25castToActionWithArgumentsEv21059
_ZN4PLMD19ActionWithArgumentsD2Ev10180
_ZNK4PLMD19ActionWithArguments11getArgumentEj205382
_ZNK4PLMD19ActionWithArguments12getArgumentsEv186364
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv618202546
+
+
+ + + +
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 000000000..88c32d011 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.gcov.html @@ -0,0 +1,215 @@ + + + + + + + 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-10-17 16:45:00Functions: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       10180 :   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       21059 :   ActionWithArguments* castToActionWithArguments() noexcept final { return this; }
+      94             : };
+      95             : 
+      96             : 
+      97             : inline
+      98             : Value* ActionWithArguments::getPntrToArgument( const unsigned n ) const {
+      99   971912305 :   return arguments[n];
+     100             : }
+     101             : 
+     102             : inline
+     103      205382 : double ActionWithArguments::getArgument(const unsigned n) const {
+     104      205382 :   return arguments[n]->get();
+     105             : }
+     106             : 
+     107             : inline
+     108   618202546 : unsigned ActionWithArguments::getNumberOfArguments()const {
+     109   618238577 :   return arguments.size();
+     110             : }
+     111             : 
+     112             : inline
+     113             : double ActionWithArguments::difference(int i,double d1,double d2)const {
+     114    11460734 :   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      676118 : void ActionWithArguments::lockRequests() {
+     124      959640 :   lockRequestArguments=true;
+     125      676118 : }
+     126             : 
+     127             : inline
+     128      676118 : void ActionWithArguments::unlockRequests() {
+     129      959640 :   lockRequestArguments=false;
+     130      676118 : }
+     131             : 
+     132             : inline
+     133      186364 : const std::vector<Value*> & ActionWithArguments::getArguments() const {
+     134      186795 :   return arguments;
+     135             : }
+     136             : 
+     137             : }
+     138             : 
+     139             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithMatrix.cpp.func-sort-c.html b/coverage/core/ActionWithMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000..b0e5debe2 --- /dev/null +++ b/coverage/core/ActionWithMatrix.cpp.func-sort-c.html @@ -0,0 +1,160 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:138138100.0 %
Date:2024-10-17 16:45:00Functions:192286.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD16ActionWithMatrixD0Ev0
_ZN4PLMD16ActionWithMatrixD1Ev0
_ZNK4PLMD16ActionWithMatrix31getAllActionLabelsInMatrixChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE16
_ZNK4PLMD16ActionWithMatrix21getFirstMatrixInChainEv1263
_ZN4PLMD16ActionWithMatrixC2ERKNS_13ActionOptionsE1472
_ZN4PLMD16ActionWithMatrixD2Ev1472
_ZN4PLMD16ActionWithMatrix16registerKeywordsERNS_8KeywordsE3176
_ZN4PLMD16ActionWithMatrix16finishChainBuildEPNS_16ActionWithVectorE3317
_ZN4PLMD16ActionWithMatrix15gatherProcessesERSt6vectorIdSaIdEE17481
_ZN4PLMD16ActionWithMatrix13gatherThreadsERKjS2_RKSt6vectorIdSaIdEERS5_RNS_10MultiValueE19981
_ZN4PLMD16ActionWithMatrix23updateAllNeighbourListsEv30968
_ZN4PLMD16ActionWithMatrix24getTotalMatrixBookeepingERj30968
_ZN4PLMD16ActionWithMatrix37transferNonZeroMatrixElementsToValuesERjRKSt6vectorIjSaIjEE30968
_ZN4PLMD16ActionWithMatrix9calculateEv31010
_ZN4PLMD16ActionWithMatrix23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_55934
_ZNK4PLMD16ActionWithMatrix25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE210505
_ZNK4PLMD16ActionWithMatrix17gatherStoredValueERKjS2_RKNS_10MultiValueES2_RSt6vectorIdSaIdEE389280
_ZNK4PLMD16ActionWithMatrix17checkForTaskForceERKjPKNS_5ValueE721141
_ZNK4PLMD16ActionWithMatrix11performTaskERKjRNS_10MultiValueE1379763
_ZNK4PLMD16ActionWithMatrix19clearMatrixElementsERNS_10MultiValueE88130811
_ZNK4PLMD16ActionWithMatrix7runTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjjRNS_10MultiValueE88130811
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithMatrix.cpp.func.html b/coverage/core/ActionWithMatrix.cpp.func.html new file mode 100644 index 000000000..3e7f4b694 --- /dev/null +++ b/coverage/core/ActionWithMatrix.cpp.func.html @@ -0,0 +1,160 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:138138100.0 %
Date:2024-10-17 16:45:00Functions:192286.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithMatrix13gatherThreadsERKjS2_RKSt6vectorIdSaIdEERS5_RNS_10MultiValueE19981
_ZN4PLMD16ActionWithMatrix15gatherProcessesERSt6vectorIdSaIdEE17481
_ZN4PLMD16ActionWithMatrix16finishChainBuildEPNS_16ActionWithVectorE3317
_ZN4PLMD16ActionWithMatrix16registerKeywordsERNS_8KeywordsE3176
_ZN4PLMD16ActionWithMatrix23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_55934
_ZN4PLMD16ActionWithMatrix23updateAllNeighbourListsEv30968
_ZN4PLMD16ActionWithMatrix24getTotalMatrixBookeepingERj30968
_ZN4PLMD16ActionWithMatrix37transferNonZeroMatrixElementsToValuesERjRKSt6vectorIjSaIjEE30968
_ZN4PLMD16ActionWithMatrix9calculateEv31010
_ZN4PLMD16ActionWithMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD16ActionWithMatrixC2ERKNS_13ActionOptionsE1472
_ZN4PLMD16ActionWithMatrixD0Ev0
_ZN4PLMD16ActionWithMatrixD1Ev0
_ZN4PLMD16ActionWithMatrixD2Ev1472
_ZNK4PLMD16ActionWithMatrix11performTaskERKjRNS_10MultiValueE1379763
_ZNK4PLMD16ActionWithMatrix17checkForTaskForceERKjPKNS_5ValueE721141
_ZNK4PLMD16ActionWithMatrix17gatherStoredValueERKjS2_RKNS_10MultiValueES2_RSt6vectorIdSaIdEE389280
_ZNK4PLMD16ActionWithMatrix19clearMatrixElementsERNS_10MultiValueE88130811
_ZNK4PLMD16ActionWithMatrix21getFirstMatrixInChainEv1263
_ZNK4PLMD16ActionWithMatrix25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE210505
_ZNK4PLMD16ActionWithMatrix31getAllActionLabelsInMatrixChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE16
_ZNK4PLMD16ActionWithMatrix7runTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjjRNS_10MultiValueE88130811
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithMatrix.cpp.gcov.html b/coverage/core/ActionWithMatrix.cpp.gcov.html new file mode 100644 index 000000000..be70c43a8 --- /dev/null +++ b/coverage/core/ActionWithMatrix.cpp.gcov.html @@ -0,0 +1,319 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:138138100.0 %
Date:2024-10-17 16:45:00Functions: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             : #include "tools/Communicator.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27        3176 : void ActionWithMatrix::registerKeywords( Keywords& keys ) {
+      28        3176 :   ActionWithVector::registerKeywords( keys ); keys.use("ARG");
+      29        3176 : }
+      30             : 
+      31        1472 : ActionWithMatrix::ActionWithMatrix(const ActionOptions&ao):
+      32             :   Action(ao),
+      33             :   ActionWithVector(ao),
+      34        1472 :   next_action_in_chain(NULL),
+      35        1472 :   matrix_to_do_before(NULL),
+      36        1472 :   matrix_to_do_after(NULL),
+      37        1472 :   clearOnEachCycle(true)
+      38             : {
+      39        1472 : }
+      40             : 
+      41        1472 : ActionWithMatrix::~ActionWithMatrix() {
+      42        1472 :   if( matrix_to_do_before ) { matrix_to_do_before->matrix_to_do_after=NULL; matrix_to_do_before->next_action_in_chain=NULL; }
+      43        1472 : }
+      44             : 
+      45          16 : void ActionWithMatrix::getAllActionLabelsInMatrixChain( std::vector<std::string>& mylabels ) const {
+      46             :   bool found=false;
+      47          24 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+      48           8 :     if( getLabel()==mylabels[i] ) { found=true; }
+      49             :   }
+      50          16 :   if( !found ) mylabels.push_back( getLabel() );
+      51          16 :   if( matrix_to_do_after ) matrix_to_do_after->getAllActionLabelsInMatrixChain( mylabels );
+      52          16 : }
+      53             : 
+      54       55934 : void ActionWithMatrix::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+      55       55934 :   ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+      56             : 
+      57      121740 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      58       65806 :     Value* myval=getPntrToComponent(i);
+      59       65806 :     if( myval->getRank()!=2 || myval->hasDerivatives() ) continue;
+      60       35389 :     myval->setPositionInMatrixStash(nmat); nmat++;
+      61       35389 :     if( !myval->valueIsStored() ) continue;
+      62        7794 :     if( myval->getShape()[1]>maxcol ) maxcol=myval->getShape()[1];
+      63             :     myval->setMatrixBookeepingStart(nbookeeping);
+      64        7794 :     nbookeeping += myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
+      65             :   }
+      66             :   // Turn off clearning of derivatives after each matrix run if there are no matrices in the output of this action
+      67       55934 :   clearOnEachCycle = false;
+      68       86351 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      69       60992 :     const Value* myval=getConstPntrToComponent(i);
+      70       60992 :     if( myval->getRank()==2 && !myval->hasDerivatives() ) { clearOnEachCycle = true; break; }
+      71             :   }
+      72             :   // Turn off clearing of derivatives if we have only the values of adjacency matrices
+      73       55934 :   if( doNotCalculateDerivatives() && isAdjacencyMatrix() ) clearOnEachCycle = false;
+      74       55934 : }
+      75             : 
+      76        3317 : void ActionWithMatrix::finishChainBuild( ActionWithVector* act ) {
+      77        3317 :   ActionWithMatrix* am=dynamic_cast<ActionWithMatrix*>(act); if( !am || act==this ) return;
+      78             :   // Build the list that contains everything we are going to loop over in getTotalMatrixBookeepgin and updateAllNeighbourLists
+      79        2269 :   if( next_action_in_chain ) next_action_in_chain->finishChainBuild( act );
+      80             :   else {
+      81         887 :     next_action_in_chain=am;
+      82             :     // Build the list of things we are going to loop over in runTask
+      83         887 :     if( am->isAdjacencyMatrix() || act->getName()=="VSTACK" ) return ;
+      84         828 :     plumed_massert( !matrix_to_do_after, "cannot add " + act->getLabel() + " in " + getLabel() + " as have already added " + matrix_to_do_after->getLabel() );
+      85         828 :     matrix_to_do_after=am; am->matrix_to_do_before=this;
+      86             :   }
+      87             : }
+      88             : 
+      89        1263 : const ActionWithMatrix* ActionWithMatrix::getFirstMatrixInChain() const {
+      90        1263 :   if( !actionInChain() ) return this;
+      91         410 :   return matrix_to_do_before->getFirstMatrixInChain();
+      92             : }
+      93             : 
+      94       30968 : void ActionWithMatrix::getTotalMatrixBookeeping( unsigned& nbookeeping ) {
+      95       67917 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      96       36949 :     Value* myval=getPntrToComponent(i);
+      97       36949 :     if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() ) continue;
+      98        4781 :     myval->reshapeMatrixStore( getNumberOfColumns() );
+      99        4781 :     nbookeeping += myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
+     100             :   }
+     101       30968 :   if( next_action_in_chain ) next_action_in_chain->getTotalMatrixBookeeping( nbookeeping );
+     102       30968 : }
+     103             : 
+     104       31010 : void ActionWithMatrix::calculate() {
+     105       31010 :   if( actionInChain() ) return ;
+     106             :   // Update all the neighbour lists
+     107       17481 :   updateAllNeighbourLists();
+     108             :   // Setup the matrix indices
+     109       17481 :   unsigned nbookeeping=0; getTotalMatrixBookeeping( nbookeeping );
+     110       17481 :   if( matrix_bookeeping.size()!=nbookeeping ) matrix_bookeeping.resize( nbookeeping );
+     111             :   std::fill( matrix_bookeeping.begin(), matrix_bookeeping.end(), 0 );
+     112             :   // And run all the tasks
+     113       17481 :   runAllTasks();
+     114             : }
+     115             : 
+     116       30968 : void ActionWithMatrix::updateAllNeighbourLists() {
+     117       30968 :   updateNeighbourList();
+     118       30968 :   if( next_action_in_chain ) next_action_in_chain->updateAllNeighbourLists();
+     119       30968 : }
+     120             : 
+     121     1379763 : void ActionWithMatrix::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+     122             :   std::vector<unsigned> & indices( myvals.getIndices() );
+     123     1379763 :   if( matrix_to_do_before ) {
+     124             :     plumed_dbg_assert( myvals.inVectorCall() );
+     125      714734 :     runEndOfRowJobs( task_index, indices, myvals );
+     126      714734 :     return;
+     127             :   }
+     128      665029 :   setupForTask( task_index, indices, myvals );
+     129             : 
+     130             :   // Now loop over the row of the matrix
+     131             :   unsigned ntwo_atoms = myvals.getSplitIndex();
+     132    29790804 :   for(unsigned i=1; i<ntwo_atoms; ++i) {
+     133             :     // This does everything in the stream that is done with single matrix elements
+     134    29125775 :     runTask( getLabel(), task_index, indices[i], myvals );
+     135             :     // Now clear only elements that are not accumulated over whole row
+     136    29125775 :     clearMatrixElements( myvals );
+     137             :   }
+     138             :   // This updates the jobs that need to be completed when we get to the end of a row of the matrix
+     139      665029 :   runEndOfRowJobs( task_index, indices, myvals );
+     140             : }
+     141             : 
+     142    88130811 : void ActionWithMatrix::runTask( const std::string& controller, const unsigned& current, const unsigned colno, MultiValue& myvals ) const {
+     143    88130811 :   double outval=0; myvals.setTaskIndex(current); myvals.setSecondTaskIndex( colno );
+     144    88130811 :   if( isActive() ) performTask( controller, current, colno, myvals );
+     145    88130811 :   bool hasval = !isAdjacencyMatrix();
+     146   172328138 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     147   145388947 :     if( fabs(myvals.get( getConstPntrToComponent(i)->getPositionInStream()) )>0 ) { hasval=true; break; }
+     148             :   }
+     149             : 
+     150    88130811 :   if( hasval ) {
+     151   284622928 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     152   201333077 :       const Value* myval=getConstPntrToComponent(i);
+     153   201333077 :       if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() ) continue;
+     154    14169812 :       unsigned matindex = myval->getPositionInMatrixStash(), matbook_start = myval->getMatrixBookeepingStart(), col_stash_index = colno;
+     155    14169812 :       if( colno>=myval->getShape()[0] ) col_stash_index = colno - myval->getShape()[0];
+     156    14169812 :       unsigned rowstart = matbook_start+current*(1+myval->getNumberOfColumns());
+     157    14169812 :       if( myval->forcesWereAdded() ) {
+     158     1551066 :         unsigned sind = myval->getPositionInStream(), find = myvals.getMatrixBookeeping()[rowstart];
+     159     1551066 :         double fforce = myval->getForce( myvals.getTaskIndex()*myval->getNumberOfColumns() + find );
+     160     1551066 :         if( getNumberOfColumns()>=myval->getShape()[1] ) fforce = myval->getForce( myvals.getTaskIndex()*myval->getShape()[1] + col_stash_index );
+     161    20795223 :         for(unsigned j=0; j<myvals.getNumberActive(sind); ++j) {
+     162    19244157 :           unsigned kindex = myvals.getActiveIndex(sind,j); myvals.addMatrixForce( matindex, kindex, fforce*myvals.getDerivative(sind,kindex ) );
+     163             :         }
+     164             :       }
+     165    14169812 :       double finalval = myvals.get( myval->getPositionInStream() );
+     166    14169812 :       if( fabs(finalval)>0 ) myvals.stashMatrixElement( matindex, rowstart, col_stash_index, finalval );
+     167             :     }
+     168             :   }
+     169    88130811 :   if( matrix_to_do_after ) matrix_to_do_after->runTask( controller, current, colno, myvals );
+     170    88130811 : }
+     171             : 
+     172       19981 : void ActionWithMatrix::gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) {
+     173       19981 :   ActionWithVector::gatherThreads( nt, bufsize, omp_buffer, buffer, myvals );
+     174    64708661 :   for(unsigned i=0; i<matrix_bookeeping.size(); ++i) matrix_bookeeping[i] += myvals.getMatrixBookeeping()[i];
+     175       19981 : }
+     176             : 
+     177       17481 : void ActionWithMatrix::gatherProcesses( std::vector<double>& buffer ) {
+     178       17481 :   ActionWithVector::gatherProcesses( buffer );
+     179       17481 :   if( matrix_bookeeping.size()>0 && !runInSerial() ) comm.Sum( matrix_bookeeping );
+     180       17481 :   unsigned nval=0; transferNonZeroMatrixElementsToValues( nval, matrix_bookeeping );
+     181       17481 : }
+     182             : 
+     183       30968 : void ActionWithMatrix::transferNonZeroMatrixElementsToValues( unsigned& nval, const std::vector<unsigned>& matbook ) {
+     184       67917 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     185       36949 :     Value* myval=getPntrToComponent(i);
+     186       36949 :     if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() || getNumberOfColumns()>=myval->getShape()[1] ) continue;
+     187          99 :     unsigned nelements = myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
+     188     5060331 :     for(unsigned j=0; j<nelements; ++j) myval->setMatrixBookeepingElement( j, matbook[nval+j] );
+     189          99 :     nval += nelements;
+     190             :   }
+     191       30968 :   if( next_action_in_chain ) next_action_in_chain->transferNonZeroMatrixElementsToValues( nval, matbook );
+     192       30968 : }
+     193             : 
+     194      389280 : void ActionWithMatrix::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     195             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     196      389280 :   if( getConstPntrToComponent(valindex)->getRank()==1 ) { ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer ); return; }
+     197      229528 :   const Value* myval=getConstPntrToComponent(valindex);
+     198             :   unsigned ncols = myval->getNumberOfColumns(), matind = myval->getPositionInMatrixStash();
+     199      229528 :   unsigned matbook_start = myval->getMatrixBookeepingStart(), vindex = bufstart + code*myval->getNumberOfColumns();
+     200      229528 :   const std::vector<unsigned> & matbook( myvals.getMatrixBookeeping() ); unsigned nelements = matbook[matbook_start+code*(1+ncols)];
+     201      229528 :   if( ncols>=myval->getShape()[1] ) {
+     202             :     // In this case we store the full matrix
+     203     6470140 :     for(unsigned j=0; j<nelements; ++j) {
+     204     6275153 :       unsigned jind = matbook[matbook_start+code*(1+ncols)+1+j];
+     205             :       plumed_dbg_massert( vindex+j<buffer.size(), "failing in " + getLabel() + " on value " + myval->getName() );
+     206     6275153 :       buffer[vindex + jind] += myvals.getStashedMatrixElement( matind, jind );
+     207             :     }
+     208             :   } else {
+     209             :     // This is for storing sparse matrices when we can
+     210      965403 :     for(unsigned j=0; j<nelements; ++j) {
+     211      930862 :       unsigned jind = matbook[matbook_start+code*(1+ncols)+1+j];
+     212             :       plumed_dbg_massert( vindex+j<buffer.size(), "failing in " + getLabel() + " on value " + myval->getName() );
+     213      930862 :       buffer[vindex + j] += myvals.getStashedMatrixElement( matind, jind );
+     214             :     }
+     215             :   }
+     216             : }
+     217             : 
+     218      721141 : bool ActionWithMatrix::checkForTaskForce( const unsigned& itask, const Value* myval ) const {
+     219      721141 :   if( myval->getRank()<2 ) return ActionWithVector::checkForTaskForce( itask, myval );
+     220      479889 :   unsigned nelements = myval->getRowLength(itask), startr = itask*myval->getNumberOfColumns();
+     221    10439083 :   for(unsigned j=0; j<nelements; ++j ) {
+     222    10051254 :     if( fabs( myval->getForce( startr + j ) )>epsilon ) return true;
+     223             :   }
+     224             :   return false;
+     225             : }
+     226             : 
+     227      210505 : void ActionWithMatrix::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     228      210505 :   if( myval->getRank()==1 ) { ActionWithVector::gatherForcesOnStoredValue( myval, itask, myvals, forces ); return; }
+     229             :   unsigned matind = myval->getPositionInMatrixStash();
+     230   842701414 :   for(unsigned j=0; j<forces.size(); ++j) forces[j] += myvals.getStashedMatrixForce( matind, j );
+     231             : }
+     232             : 
+     233    88130811 : void ActionWithMatrix::clearMatrixElements( MultiValue& myvals ) const {
+     234    88130811 :   if( isActive() && clearOnEachCycle ) {
+     235   153880620 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     236   103870566 :       const Value* myval=getConstPntrToComponent(i);
+     237   103870566 :       if( myval->getRank()==2 && !myval->hasDerivatives() ) myvals.clearDerivatives( myval->getPositionInStream() );
+     238             :     }
+     239             :   }
+     240    88130811 :   if( matrix_to_do_after ) matrix_to_do_after->clearMatrixElements( myvals );
+     241    88130811 : }
+     242             : 
+     243             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithMatrix.h.func-sort-c.html b/coverage/core/ActionWithMatrix.h.func-sort-c.html new file mode 100644 index 000000000..5dd79c544 --- /dev/null +++ b/coverage/core/ActionWithMatrix.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithMatrix19updateNeighbourListEv19272
_ZNK4PLMD16ActionWithMatrix29addDerivativeOnVectorArgumentERKbRKjS4_S4_RKdRNS_10MultiValueE32289795
_ZNK4PLMD16ActionWithMatrix26getElementOfMatrixArgumentERKjS2_S2_RKNS_10MultiValueE32301796
_ZNK4PLMD16ActionWithMatrix29addDerivativeOnMatrixArgumentERKbRKjS4_S4_S4_RKdRNS_10MultiValueE56805054
_ZNK4PLMD16ActionWithMatrix17isAdjacencyMatrixEv66890656
_ZNK4PLMD16ActionWithMatrix18getArgumentElementERKjS2_RKNS_10MultiValueE70002481
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithMatrix.h.func.html b/coverage/core/ActionWithMatrix.h.func.html new file mode 100644 index 000000000..3c5f46a27 --- /dev/null +++ b/coverage/core/ActionWithMatrix.h.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithMatrix19updateNeighbourListEv19272
_ZNK4PLMD16ActionWithMatrix17isAdjacencyMatrixEv66890656
_ZNK4PLMD16ActionWithMatrix18getArgumentElementERKjS2_RKNS_10MultiValueE70002481
_ZNK4PLMD16ActionWithMatrix26getElementOfMatrixArgumentERKjS2_S2_RKNS_10MultiValueE32301796
_ZNK4PLMD16ActionWithMatrix29addDerivativeOnMatrixArgumentERKbRKjS4_S4_S4_RKdRNS_10MultiValueE56805054
_ZNK4PLMD16ActionWithMatrix29addDerivativeOnVectorArgumentERKbRKjS4_S4_RKdRNS_10MultiValueE32289795
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithMatrix.h.gcov.html b/coverage/core/ActionWithMatrix.h.gcov.html new file mode 100644 index 000000000..e889b7533 --- /dev/null +++ b/coverage/core/ActionWithMatrix.h.gcov.html @@ -0,0 +1,226 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-10-17 16:45:00Functions: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_ActionWithMatrix_h
+      23             : #define __PLUMED_core_ActionWithMatrix_h
+      24             : 
+      25             : #include "ActionWithVector.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class ActionWithMatrix : public ActionWithVector {
+      30             : private:
+      31             :   ActionWithMatrix* next_action_in_chain;
+      32             :   ActionWithMatrix* matrix_to_do_before;
+      33             :   ActionWithMatrix* matrix_to_do_after;
+      34             : /// This holds the bookeeping arrays for sparse matrices
+      35             :   std::vector<unsigned> matrix_bookeeping;
+      36             : /// Update all the neighbour lists in the chain
+      37             :   void updateAllNeighbourLists();
+      38             : /// This is used to clear up the matrix elements
+      39             :   void clearMatrixElements( MultiValue& myvals ) const ;
+      40             : /// This is used to find the total amount of space we need for storing matrix elements
+      41             :   void getTotalMatrixBookeeping( unsigned& stashsize );
+      42             : /// This transfers the non-zero elements to the Value
+      43             :   void transferNonZeroMatrixElementsToValues( unsigned& nval, const std::vector<unsigned>& matbook );
+      44             : /// This does the calculation of a particular matrix element
+      45             :   void runTask( const std::string& controller, const unsigned& current, const unsigned colno, MultiValue& myvals ) const ;
+      46             : protected:
+      47             : /// This turns off derivative clearing for contact matrix if we are not storing derivatives
+      48             :   bool clearOnEachCycle;
+      49             : /// Does the matrix chain continue on from this action
+      50             :   bool matrixChainContinues() const ;
+      51             : /// This returns the jelem th element of argument ic
+      52             :   double getArgumentElement( const unsigned& ic, const unsigned& jelem, const MultiValue& myvals ) const ;
+      53             : /// This returns an element of a matrix that is passed an argument
+      54             :   double getElementOfMatrixArgument( const unsigned& imat, const unsigned& irow, const unsigned& jcol, const MultiValue& myvals ) const ;
+      55             : /// Add derivatives given the derivative wrt to the input vector element as input
+      56             :   void addDerivativeOnVectorArgument( const bool& inchain, const unsigned& ival, const unsigned& jarg, const unsigned& jelem, const double& der, MultiValue& myvals ) const ;
+      57             : /// Add derivatives given the derative wrt to the input matrix element as input
+      58             :   void addDerivativeOnMatrixArgument( const bool& inchain, const unsigned& ival, const unsigned& jarg, const unsigned& irow, const unsigned& jcol, const double& der, MultiValue& myvals ) const ;
+      59             : public:
+      60             :   static void registerKeywords( Keywords& keys );
+      61             :   explicit ActionWithMatrix(const ActionOptions&);
+      62             :   virtual ~ActionWithMatrix();
+      63             : ///
+      64    66890656 :   virtual bool isAdjacencyMatrix() const { return false; }
+      65             : ///
+      66             :   void getAllActionLabelsInMatrixChain( std::vector<std::string>& mylabels ) const override ;
+      67             : /// Get the first matrix in this chain
+      68             :   const ActionWithMatrix* getFirstMatrixInChain() const ;
+      69             : ///
+      70             :   void finishChainBuild( ActionWithVector* act );
+      71             : /// This should return the number of columns to help with sparse storage of matrices
+      72             :   virtual unsigned getNumberOfColumns() const = 0;
+      73             : /// This requires some thought
+      74             :   void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override;
+      75             : //// This does some setup before we run over the row of the matrix
+      76             :   virtual void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const = 0;
+      77             : /// Run over one row of the matrix
+      78             :   void performTask( const unsigned& task_index, MultiValue& myvals ) const override ;
+      79             : /// Gather a row of the matrix
+      80             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals, const unsigned& bufstart, std::vector<double>& buffer ) const override;
+      81             : /// Gather all the data from the threads
+      82             :   void gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) override ;
+      83             : /// Gather all the data from the MPI processes
+      84             :   void gatherProcesses( std::vector<double>& buffer ) override;
+      85             : /// This is the virtual that will do the calculation of the task for a particular matrix element
+      86             :   virtual void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const = 0;
+      87             : /// This is the jobs that need to be done when we have run all the jobs in a row of the matrix
+      88             :   virtual void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const = 0;
+      89             : /// This is overwritten in Adjacency matrix where we have a neighbour list
+      90       19272 :   virtual void updateNeighbourList() {}
+      91             : /// Run the calculation
+      92             :   virtual void calculate() override;
+      93             : /// Check if there are forces we need to account for on this task
+      94             :   bool checkForTaskForce( const unsigned& itask, const Value* myval ) const override ;
+      95             : /// This gathers the force on a particular value
+      96             :   void gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const override;
+      97             : };
+      98             : 
+      99             : inline
+     100             : bool ActionWithMatrix::matrixChainContinues() const {
+     101      552731 :   return matrix_to_do_after!=NULL;
+     102             : }
+     103             : 
+     104             : inline
+     105    70002481 : double ActionWithMatrix::getArgumentElement( const unsigned& ic, const unsigned& jelem, const MultiValue& myvals ) const {
+     106    70002481 :   if( !getPntrToArgument(ic)->valueHasBeenSet() ) return myvals.get( getPntrToArgument(ic)->getPositionInStream() );
+     107    68729606 :   return getPntrToArgument(ic)->get( jelem );
+     108             : }
+     109             : 
+     110             : inline
+     111    32301796 : double ActionWithMatrix::getElementOfMatrixArgument( const unsigned& imat, const unsigned& irow, const unsigned& jcol, const MultiValue& myvals ) const {
+     112             :   plumed_dbg_assert( imat<getNumberOfArguments() && getPntrToArgument(imat)->getRank()==2 && !getPntrToArgument(imat)->hasDerivatives() );
+     113    32301796 :   if( !getPntrToArgument(imat)->valueHasBeenSet() ) return myvals.get( getPntrToArgument(imat)->getPositionInStream() );
+     114    30768796 :   return getArgumentElement( imat, irow*getPntrToArgument(imat)->getShape()[1] + jcol, myvals );
+     115             : }
+     116             : 
+     117             : inline
+     118    32289795 : void ActionWithMatrix::addDerivativeOnVectorArgument( const bool& inchain, const unsigned& ival, const unsigned& jarg, const unsigned& jelem, const double& der, MultiValue& myvals ) const {
+     119             :   plumed_dbg_massert( jarg<getNumberOfArguments() && getPntrToArgument(jarg)->getRank()<2, "failing in action " + getName() + " with label " + getLabel() );
+     120    32289795 :   unsigned ostrn = getConstPntrToComponent(ival)->getPositionInStream(), vstart=arg_deriv_starts[jarg];
+     121    32289795 :   if( !inchain ) {
+     122    31433348 :     myvals.addDerivative( ostrn, vstart + jelem, der ); myvals.updateIndex( ostrn, vstart + jelem );
+     123             :   } else {
+     124             :     unsigned istrn = getPntrToArgument(jarg)->getPositionInStream();
+     125    43315006 :     for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     126    42458559 :       unsigned kind=myvals.getActiveIndex(istrn,k);
+     127    42458559 :       myvals.addDerivative( ostrn, arg_deriv_starts[jarg] + kind, der*myvals.getDerivative( istrn, kind ) );
+     128    42458559 :       myvals.updateIndex( ostrn, arg_deriv_starts[jarg] + kind );
+     129             :     }
+     130             :   }
+     131    32289795 : }
+     132             : 
+     133             : inline
+     134    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 {
+     135             :   plumed_dbg_assert( jarg<getNumberOfArguments() && getPntrToArgument(jarg)->getRank()==2 && !getPntrToArgument(jarg)->hasDerivatives() );
+     136    56805054 :   unsigned ostrn = getConstPntrToComponent(ival)->getPositionInStream(), vstart=arg_deriv_starts[jarg];
+     137    56805054 :   if( !inchain ) {
+     138     2243240 :     unsigned dloc = vstart + irow*getPntrToArgument(jarg)->getNumberOfColumns() + jcol;
+     139     2243240 :     myvals.addDerivative( ostrn, dloc, der ); myvals.updateIndex( ostrn, dloc );
+     140             :   } else {
+     141             :     unsigned istrn = getPntrToArgument(jarg)->getPositionInStream();
+     142   353992585 :     for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     143   299430771 :       unsigned kind=myvals.getActiveIndex(istrn,k);
+     144   299430771 :       myvals.addDerivative( ostrn, kind, der*myvals.getDerivative( istrn, kind ) );
+     145             :     }
+     146             :   }
+     147    56805054 : }
+     148             : 
+     149             : }
+     150             : #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 000000000..4cec1a85d --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func-sort-c.html @@ -0,0 +1,204 @@ + + + + + + + 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:15817192.4 %
Date:2024-10-17 16:45:00Functions: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
_ZNK4PLMD15ActionWithValue29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE23
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_137
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_805
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE854
_ZN4PLMD15ActionWithValue23addValueWithDerivativesERKSt6vectorIjSaIjEE5105
_ZN4PLMD15ActionWithValue8addValueERKSt6vectorIjSaIjEE12693
_ZN4PLMD15ActionWithValue14setNotPeriodicEv16992
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev24075
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE31312
_ZN4PLMD15ActionWithValueD2Ev31312
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE32217
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE42162
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE46010
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE84954
_ZN4PLMD15ActionWithValue14checkForForcesEv498054
_ZNK4PLMD15ActionWithValue10copyOutputERKj1136655
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv1639697
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1851003
_ZN4PLMD15ActionWithValue16clearDerivativesERKb1885665
_ZN4PLMD15ActionWithValue16clearInputForcesERKb2405001
_ZN4PLMD15ActionWithValue17calculateOnUpdateEv4607697
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602966
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10688057
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10713281
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33605471
_ZN4PLMD15ActionWithValue18getPntrToComponentEi87329175
_ZNK4PLMD15ActionWithValue23getConstPntrToComponentEi1190410193
+
+
+ + + +
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 000000000..9c474ecbf --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func.html @@ -0,0 +1,204 @@ + + + + + + + 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:15817192.4 %
Date:2024-10-17 16:45:00Functions:283384.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_805
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE46010
_ZN4PLMD15ActionWithValue14checkForForcesEv498054
_ZN4PLMD15ActionWithValue14setNotPeriodicEv16992
_ZN4PLMD15ActionWithValue16clearDerivativesERKb1885665
_ZN4PLMD15ActionWithValue16clearInputForcesERKb2405001
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE32217
_ZN4PLMD15ActionWithValue17calculateOnUpdateEv4607697
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv1639697
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602966
_ZN4PLMD15ActionWithValue18getPntrToComponentEi87329175
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_137
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1851003
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE84954
_ZN4PLMD15ActionWithValue23addValueWithDerivativesERKSt6vectorIjSaIjEE5105
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE854
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE42162
_ZN4PLMD15ActionWithValue8addValueERKSt6vectorIjSaIjEE12693
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE31312
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZN4PLMD15ActionWithValueD2Ev31312
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33605471
_ZNK4PLMD15ActionWithValue10copyOutputERKj1136655
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10688057
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev24075
_ZNK4PLMD15ActionWithValue21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE19
_ZNK4PLMD15ActionWithValue23getConstPntrToComponentEi1190410193
_ZNK4PLMD15ActionWithValue29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE23
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10713281
+
+
+ + + +
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 000000000..6d25293c8 --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.gcov.html @@ -0,0 +1,415 @@ + + + + + + + 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:15817192.4 %
Date:2024-10-17 16:45:00Functions: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       32217 : void ActionWithValue::registerKeywords(Keywords& keys) {
+      33       32217 :   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       64434 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
+      39       64434 :   keys.add("hidden","HAS_VALUES","this is used in json output to determine those actions that have values");
+      40       32217 : }
+      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         854 : void ActionWithValue::useCustomisableComponents(Keywords& keys) {
+      48        2562 :   if( !keys.outputComponentExists(".#!custom") ) keys.addOutputComponent(".#!custom","default","the names of the output components for this action depend on the actions input file see the example inputs below for details");
+      49         854 :   keys.setComponentsIntroduction("The names of the components in this action can be customized by the user in the "
+      50             :                                  "actions input file.  However, in addition to the components that can be customized the "
+      51             :                                  "following quantities will always be output");
+      52         854 : }
+      53             : 
+      54       31312 : ActionWithValue::ActionWithValue(const ActionOptions&ao):
+      55             :   Action(ao),
+      56       31312 :   firststep(true),
+      57       31312 :   noderiv(true),
+      58       31312 :   numericalDerivatives(false)
+      59             : {
+      60       78626 :   if( keywords.exists("NUMERICAL_DERIVATIVES") ) parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
+      61       62624 :   if(!keywords.exists("NO_ACTION_LOG") && numericalDerivatives) log.printf("  using numerical derivatives\n");
+      62       31312 : }
+      63             : 
+      64       31312 : ActionWithValue::~ActionWithValue() {
+      65             : // empty destructor to delete unique_ptr
+      66       31312 : }
+      67             : 
+      68     2405001 : void ActionWithValue::clearInputForces( const bool& force ) {
+      69     5652138 :   for(unsigned i=0; i<values.size(); i++) values[i]->clearInputForce();
+      70     2405001 : }
+      71             : 
+      72     1885665 : void ActionWithValue::clearDerivatives( const bool& force ) {
+      73     1885665 :   unsigned nt = OpenMP::getNumThreads();
+      74     1885665 :   #pragma omp parallel num_threads(nt)
+      75             :   {
+      76             :     #pragma omp for
+      77             :     for(unsigned i=0; i<values.size(); i++) values[i]->clearDerivatives();
+      78             :   }
+      79     1885665 : }
+      80             : 
+      81             : // -- These are the routine for copying the value pointers to other classes -- //
+      82             : 
+      83    10713281 : bool ActionWithValue::exists( const std::string& name ) const {
+      84   101771283 :   for(unsigned i=0; i<values.size(); ++i) {
+      85    91082653 :     if (values[i]->name==name) return true;
+      86             :   }
+      87             :   return false;
+      88             : }
+      89             : 
+      90          19 : void ActionWithValue::getMatrixColumnTitles( std::vector<std::string>& argnames ) const {
+      91          19 :   plumed_assert( getNumberOfComponents()==1 && getConstPntrToComponent(0)->getRank()==2 );
+      92          19 :   unsigned nargs = getConstPntrToComponent(0)->getShape()[1]; std::string aname = getConstPntrToComponent(0)->getName();
+      93         393 :   for(unsigned j=0; j<nargs; ++j) { std::string nn; Tools::convert( j+1, nn ); argnames.push_back( aname + "." + nn ); }
+      94          19 : }
+      95             : 
+      96    33605471 : Value* ActionWithValue::copyOutput( const std::string& name ) const {
+      97   112036446 :   for(unsigned i=0; i<values.size(); ++i) {
+      98   112036446 :     if (values[i]->name==name) return values[i].get();
+      99             :   }
+     100           0 :   plumed_merror("there is no pointer with name " + name);
+     101             : }
+     102             : 
+     103     1136655 : Value* ActionWithValue::copyOutput( const unsigned& n ) const {
+     104     1136655 :   plumed_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     105     1136655 :   return values[n].get();
+     106             : }
+     107             : 
+     108             : // -- HERE WE HAVE THE STUFF FOR THE DEFAULT VALUE -- //
+     109             : 
+     110       12693 : void ActionWithValue::addValue( const std::vector<unsigned>& shape ) {
+     111       25452 :   if( !keywords.outputComponentExists(".#!value") ) warning("documentation for the value calculated by this action has not been included");
+     112       12693 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     113       12693 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), false, shape ) );
+     114       12693 : }
+     115             : 
+     116        5105 : void ActionWithValue::addValueWithDerivatives( const std::vector<unsigned>& shape ) {
+     117       10258 :   if( !keywords.outputComponentExists(".#!value") ) warning("documentation for the value calculated by this action has not been included");
+     118        5105 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     119        5105 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), true, shape ) );
+     120        5105 : }
+     121             : 
+     122       16992 : void ActionWithValue::setNotPeriodic() {
+     123       16992 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     124       16992 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     125       16992 :   values[0]->min=0; values[0]->max=0;
+     126       16992 :   values[0]->setupPeriodicity();
+     127       16992 : }
+     128             : 
+     129         805 : void ActionWithValue::setPeriodic( const std::string& min, const std::string& max ) {
+     130         805 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     131         805 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     132         805 :   values[0]->setDomain( min, max );
+     133         805 : }
+     134             : 
+     135             : // -- HERE WE HAVE THE STUFF FOR NAMED VALUES / COMPONENTS -- //
+     136             : 
+     137       46010 : void ActionWithValue::addComponent( const std::string& name, const std::vector<unsigned>& shape ) {
+     138       46010 :   if( !keywords.outputComponentExists(name) ) {
+     139           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     140             :                   "registerKeywords as described in the developer docs.");
+     141             :   }
+     142       92020 :   std::string thename; thename=getLabel() + "." + name;
+     143    18798388 :   for(unsigned i=0; i<values.size(); ++i) {
+     144    18752378 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     145    18752378 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     146    18752378 :     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"
+     147             :                    "Remove the line addComponent(\"bias\") from your bias.");
+     148             :   }
+     149       46010 :   values.emplace_back(Tools::make_unique<Value>(this,thename, false, shape ) );
+     150       46010 :   std::string msg="  added component to this action:  "+thename+" \n";
+     151       46010 :   log.printf(msg.c_str());
+     152       46010 : }
+     153             : 
+     154       42162 : void ActionWithValue::addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape ) {
+     155       42162 :   if( !keywords.outputComponentExists(name) ) {
+     156           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     157             :                   "registerKeywords as described in the developer doc.");
+     158             :   }
+     159       84324 :   std::string thename; thename=getLabel() + "." + name;
+     160     2505298 :   for(unsigned i=0; i<values.size(); ++i) {
+     161     2463136 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     162     2463136 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     163     2463136 :     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"
+     164             :                    "Remove the line addComponentWithDerivatives(\"bias\") from your bias.");
+     165             :   }
+     166       42162 :   values.emplace_back(Tools::make_unique<Value>(this,thename, true, shape ) );
+     167       42162 :   std::string msg="  added component to this action:  "+thename+" \n";
+     168       42162 :   log.printf(msg.c_str());
+     169       42162 : }
+     170             : 
+     171          23 : std::string ActionWithValue::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     172          46 :   if( keys.outputComponentExists(".#!custom") ) return "a quantity calculated by the action " + getName() + " with label " + getLabel();
+     173          23 :   std::size_t und=cname.find_last_of("_"); std::size_t hyph=cname.find_first_of("-");
+     174          23 :   if( und!=std::string::npos ) return keys.getOutputComponentDescription(cname.substr(und)) + " This particular component measures this quantity for the input CV named " + cname.substr(0,und);
+     175          30 :   if( hyph!=std::string::npos ) return keys.getOutputComponentDescription(cname.substr(0,hyph)) + "  This is the " + cname.substr(hyph+1) + "th of these quantities";
+     176          16 :   plumed_massert( keys.outputComponentExists(cname), "component " + cname + " does not exist in " + keys.getDisplayName() + " if the component names are customizable then you should override this function" );
+     177          16 :   return keys.getOutputComponentDescription( cname );
+     178             : }
+     179             : 
+     180    10688057 : int ActionWithValue::getComponent( const std::string& name ) const {
+     181    10688057 :   plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
+     182    21376114 :   std::string thename; thename=getLabel() + "." + name;
+     183    64348621 :   for(unsigned i=0; i<values.size(); ++i) {
+     184    64348621 :     if (values[i]->name==thename) return i;
+     185             :   }
+     186           0 :   plumed_merror("there is no component with name " + name);
+     187             : }
+     188             : 
+     189           0 : std::string ActionWithValue::getComponentsList( ) const {
+     190             :   std::string complist;
+     191           0 :   for(unsigned i=0; i<values.size(); ++i) {
+     192           0 :     complist+=values[i]->name+" ";
+     193             :   }
+     194           0 :   return complist;
+     195             : }
+     196             : 
+     197       24075 : std::vector<std::string> ActionWithValue::getComponentsVector( ) const {
+     198             :   std::vector<std::string> complist;
+     199      349845 :   for(unsigned i=0; i<values.size(); ++i) {
+     200      325770 :     complist.push_back(values[i]->name);
+     201             :   }
+     202       24075 :   return complist;
+     203           0 : }
+     204             : 
+     205       84954 : void ActionWithValue::componentIsNotPeriodic( const std::string& name ) {
+     206       84954 :   int kk=getComponent(name);
+     207       84954 :   values[kk]->min=0; values[kk]->max=0;
+     208       84954 :   values[kk]->setupPeriodicity();
+     209       84954 : }
+     210             : 
+     211         137 : void ActionWithValue::componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ) {
+     212         137 :   int kk=getComponent(name);
+     213         137 :   values[kk]->setDomain(min,max);
+     214         137 : }
+     215             : 
+     216     1851003 : void ActionWithValue::setGradientsIfNeeded() {
+     217     3702006 :   if(isOptionOn("GRADIENTS")) {
+     218         201 :     ActionAtomistic* aa=castToActionAtomistic();
+     219         201 :     if(aa) {
+     220         308 :       for(unsigned i=0; i<values.size(); i++) { unsigned start=0; values[i]->gradients.clear(); values[i]->setGradients( aa, start ); }
+     221             :     } else {
+     222          83 :       ActionWithArguments* aarg = castToActionWithArguments();
+     223          83 :       if( !aarg ) plumed_merror( "failing in " + getLabel() );
+     224         166 :       for(unsigned i=0; i<values.size(); i++) { unsigned start=0; values[i]->gradients.clear(); aarg->setGradients( values[i].get(), start ); }
+     225             :     }
+     226             :   }
+     227     1851003 : }
+     228             : 
+     229     1639697 : void ActionWithValue::turnOnDerivatives() {
+     230             :   // Turn on the derivatives
+     231     1639697 :   noderiv=false;
+     232             :   // Resize the derivatives
+     233     5993037 :   for(unsigned i=0; i<values.size(); ++i) values[i]->resizeDerivatives( getNumberOfDerivatives() );
+     234             :   // And turn on the derivatives in all actions on which we are dependent
+     235     3273461 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
+     236     1633764 :     ActionWithValue* vv=getDependencies()[i]->castToActionWithValue();
+     237     1633764 :     if(vv) vv->turnOnDerivatives();
+     238             :   }
+     239     1639697 : }
+     240             : 
+     241    10602966 : Value* ActionWithValue::getPntrToComponent( const std::string& name ) {
+     242    10602966 :   int kk=getComponent(name);
+     243    10602966 :   return values[kk].get();
+     244             : }
+     245             : 
+     246  1190410193 : const Value* ActionWithValue::getConstPntrToComponent(int n) const {
+     247             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     248  1190410193 :   return values[n].get();
+     249             : }
+     250             : 
+     251    87329175 : Value* ActionWithValue::getPntrToComponent( int n ) {
+     252             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     253    87329175 :   return values[n].get();
+     254             : }
+     255             : 
+     256     4607697 : bool ActionWithValue::calculateOnUpdate() {
+     257     4607697 :   if( firststep ) {
+     258      205887 :     ActionWithArguments* aa=dynamic_cast<ActionWithArguments*>(this);
+     259      205887 :     if(aa) {
+     260      183942 :       const std::vector<Value*> & args(aa->getArguments());
+     261     1261509 :       for(const auto & p : args ) {
+     262     1077981 :         if( p->calculateOnUpdate() ) {
+     263         869 :           for(unsigned i=0; i<values.size(); ++i) values[i]->setValType("calcFromAverage");
+     264             :           break;
+     265             :         }
+     266             :       }
+     267             :     }
+     268      205887 :     firststep=false;
+     269             :   }
+     270    11028918 :   for(unsigned i=0; i<values.size(); ++i) {
+     271     6430079 :     if( values[i]->calculateOnUpdate() ) return true;
+     272             :   }
+     273             :   return false;
+     274             : }
+     275             : 
+     276      498054 : bool ActionWithValue::checkForForces() {
+     277      498054 :   const unsigned    ncp=getNumberOfComponents();
+     278      498054 :   unsigned    nder=getNumberOfDerivatives();
+     279      498054 :   if( ncp==0 || nder==0 ) return false;
+     280             : 
+     281             :   unsigned nvalsWithForce=0;
+     282      496908 :   valsToForce.resize(ncp);
+     283     1392748 :   for(unsigned i=0; i<ncp; ++i) {
+     284      895840 :     if( values[i]->hasForce && !values[i]->isConstant() ) {
+     285      287844 :       valsToForce[nvalsWithForce]=i; nvalsWithForce++;
+     286             :     }
+     287             :   }
+     288      496908 :   if( nvalsWithForce==0 ) return false;
+     289             : 
+     290             :   // Make sure forces to apply is empty of forces
+     291      237105 :   if( forcesForApply.size()!=nder ) forcesForApply.resize( nder );
+     292             :   std::fill(forcesForApply.begin(),forcesForApply.end(),0);
+     293             : 
+     294             :   unsigned stride=1;
+     295             :   unsigned rank=0;
+     296      237105 :   if(ncp>4*comm.Get_size()) {
+     297       22970 :     stride=comm.Get_size();
+     298       22970 :     rank=comm.Get_rank();
+     299             :   }
+     300             : 
+     301      237105 :   unsigned nt=OpenMP::getNumThreads();
+     302      237105 :   if(nt>ncp/(4*stride)) nt=1;
+     303             : 
+     304      237105 :   #pragma omp parallel num_threads(nt)
+     305             :   {
+     306             :     std::vector<double> omp_f;
+     307             :     if( nt>1 ) omp_f.resize(nder,0);
+     308             :     #pragma omp for
+     309             :     for(unsigned i=rank; i<nvalsWithForce; i+=stride) {
+     310             :       double ff=values[valsToForce[i]]->inputForce[0];
+     311             :       std::vector<double> & thisderiv( values[valsToForce[i]]->data );
+     312             :       int nn=nder;
+     313             :       int one1=1;
+     314             :       int one2=1;
+     315             :       if( nt>1 ) plumed_blas_daxpy(&nn,&ff,thisderiv.data()+1,&one1,omp_f.data(),&one2);
+     316             :       else       plumed_blas_daxpy(&nn,&ff,thisderiv.data()+1,&one1,forcesForApply.data(),&one2);
+     317             :       // if( nt>1 ) for(unsigned j=0; j<nder; ++j) omp_f[j] += ff*thisderiv[1+j];
+     318             :       //else for(unsigned j=0; j<nder; ++j) forcesForApply[j] += ff*thisderiv[1+j];
+     319             :     }
+     320             :     #pragma omp critical
+     321             :     {
+     322             :       if( nt>1 ) {
+     323             :         int nn=forcesForApply.size();
+     324             :         double one0=1.0;
+     325             :         int one1=1;
+     326             :         int one2=1;
+     327             :         plumed_blas_daxpy(&nn,&one0,omp_f.data(),&one1,forcesForApply.data(),&one2);
+     328             :       }
+     329             :       // for(unsigned j=0; j<forcesForApply.size(); ++j) {
+     330             :       // forcesForApply[j]+=omp_f[j];
+     331             :       // }
+     332             :     }
+     333             :   }
+     334             : 
+     335      237105 :   if(ncp>4*comm.Get_size()) comm.Sum(&forcesForApply[0],nder);
+     336             :   return true;
+     337             : }
+     338             : 
+     339             : }
+
+
+
+ + + + +
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 000000000..5028ef285 --- /dev/null +++ b/coverage/core/ActionWithValue.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj142134
_ZN4PLMD15ActionWithValue8setValueERKd167491
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv2334926
_ZN4PLMD15ActionWithValue21castToActionWithValueEv4137956
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4670390
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv229368002
+
+
+ + + +
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 000000000..5d0ed18bb --- /dev/null +++ b/coverage/core/ActionWithValue.h.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue21castToActionWithValueEv4137956
_ZN4PLMD15ActionWithValue8setValueERKd167491
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4670390
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj142134
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv2334926
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv229368002
+
+
+ + + +
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 000000000..d3c42731a --- /dev/null +++ b/coverage/core/ActionWithValue.h.gcov.html @@ -0,0 +1,329 @@ + + + + + + + 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-10-17 16:45:00Functions: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             : /// Get the description of this component
+     116             :   virtual std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const ;
+     117             : protected:
+     118             : /// Return a pointer to the component by index
+     119             :   Value* getPntrToComponent(int i);
+     120             : /// Get a const pointer to the ith component
+     121             :   const Value* getConstPntrToComponent(int i) const;
+     122             : /// Return a pointer to the value by name
+     123             :   Value* getPntrToComponent(const std::string& name);
+     124             : /// Accumulate the forces from the Values
+     125             :   bool checkForForces();
+     126             : /// Get the forces to apply
+     127             :   const std::vector<double>& getForcesToApply() const;
+     128             : public:
+     129             :   explicit ActionWithValue(const ActionOptions&ao);
+     130             :   ~ActionWithValue();
+     131             : 
+     132             : /// Register all the relevant keywords for the action
+     133             :   static void registerKeywords( Keywords& keys );
+     134             : /// Insist that numerical derivatives should always be used for an action and make this fact appear in the manual
+     135             :   static void noAnalyticalDerivatives(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     4137956 :   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     4670390 : double ActionWithValue::getOutputQuantity( const std::string& name ) const {
+     200     4670390 :   auto offset=getLabel().size();
+     201    10500137 :   for(unsigned i=0; i<values.size(); ++i) {
+     202             :     const std::string & valname=values[i]->name;
+     203     5937784 :     if(valname.size()>offset+1 && valname[offset]=='.' ) {
+     204             :       plumed_dbg_assert(Tools::startWith(valname,getLabel()));
+     205     2561670 :       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      167491 : void ActionWithValue::setValue(const double& d) {
+     213      167491 :   plumed_massert(values.size()==1, "cannot use setValue in multi-component actions");
+     214      167491 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     215      167491 :   values[0]->set(d);
+     216      167491 : }
+     217             : 
+     218             : inline
+     219             : int ActionWithValue::getNumberOfComponents() const {
+     220  1145229620 :   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     2334926 : bool ActionWithValue::checkNumericalDerivatives() const {
+     231     2334926 :   return numericalDerivatives;
+     232             : }
+     233             : 
+     234             : inline
+     235   229368002 : bool ActionWithValue::doNotCalculateDerivatives() const {
+     236   229368002 :   return noderiv;
+     237             : }
+     238             : 
+     239             : inline
+     240             : const std::vector<double>& ActionWithValue::getForcesToApply() const {
+     241      289041 :   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 000000000..e6e75b599 --- /dev/null +++ b/coverage/core/ActionWithVector.cpp.func-sort-c.html @@ -0,0 +1,288 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZN4PLMD16ActionWithVector24reallyBuildArgumentStoreERKj989
_ZN4PLMD16ActionWithVector26getAdditionalTasksRequiredEPS0_RSt6vectorIjSaIjEE1309
_ZN4PLMD16ActionWithVector29updateTaskListReductionStatusEv2674
_ZN4PLMD16ActionWithVector18buildArgumentStoreERKj3401
_ZN4PLMD16ActionWithVector16finishChainBuildEPS0_3544
_ZN4PLMD16ActionWithVectorC2ERKNS_13ActionOptionsE4916
_ZN4PLMD16ActionWithVectorD2Ev4916
_ZN4PLMD16ActionWithVector16registerKeywordsERNS_8KeywordsE5380
_ZN4PLMD16ActionWithVector16addActionToChainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPS0_11762
_ZN4PLMD16ActionWithVector24getActionWithDerivativesEPS0_17691
_ZN4PLMD16ActionWithVector14canReduceTasksERSt6vectorIPS0_SaIS2_EE20916
_ZNK4PLMD16ActionWithVector25getAllActionLabelsInChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE36905
_ZNK4PLMD16ActionWithVector25updateForceTasksFromValueEPKNS_5ValueERSt6vectorIjSaIjEE90719
_ZNK4PLMD16ActionWithVector13getForceTasksERSt6vectorIjSaIjEE103595
_ZN4PLMD16ActionWithVector15gatherProcessesERSt6vectorIdSaIdEE132962
_ZN4PLMD16ActionWithVector11runAllTasksEv133004
_ZN4PLMD16ActionWithVector20getListOfActiveTasksEPS0_144849
_ZN4PLMD16ActionWithVector16addForcesToInputERKSt6vectorIdSaIdEERj186367
_ZN4PLMD16ActionWithVector13gatherThreadsERKjS2_RKSt6vectorIdSaIdEERS5_RNS_10MultiValueE209939
_ZN4PLMD16ActionWithVector23updateTaskReductionFlagERb229464
_ZN4PLMD16ActionWithVector14checkForForcesEv254422
_ZN4PLMD16ActionWithVector5applyEv254422
_ZN4PLMD16ActionWithVector12lockRequestsEv273524
_ZN4PLMD16ActionWithVector14unlockRequestsEv273524
_ZN4PLMD16ActionWithVector7prepareEv274530
_ZNK4PLMD16ActionWithVector28checkChainForNonScalarForcesEv292884
_ZN4PLMD16ActionWithVector16getNumberOfTasksERj314964
_ZN4PLMD16ActionWithVector15getSizeOfBufferERKjRj317683
_ZN4PLMD16ActionWithVector18finishComputationsERKSt6vectorIdSaIdEE317683
_ZNK4PLMD16ActionWithVector13checkForGridsERj317683
_ZN4PLMD16ActionWithVector23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421278
_ZN4PLMD16ActionWithVector29getNumberOfStreamedQuantitiesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421278
_ZN4PLMD16ActionWithVector30getNumberOfStreamedDerivativesERjPNS_5ValueE424411
_ZN4PLMD16ActionWithVector13retrieveAtomsERKb456395
_ZN4PLMD16ActionWithVector16clearDerivativesERKb457632
_ZN4PLMD16ActionWithVector16clearInputForcesERKb457632
_ZNK4PLMD16ActionWithVector25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE1565796
_ZNK4PLMD16ActionWithVector23checkComponentsForForceEv2039456
_ZNK4PLMD16ActionWithVector12gatherForcesERKjRKNS_10MultiValueERSt6vectorIdSaIdEE2101182
_ZNK4PLMD16ActionWithVector17gatherStoredValueERKjS2_RKNS_10MultiValueES2_RSt6vectorIdSaIdEE3571815
_ZN4PLMD16ActionWithVector28broadcastThatTasksAreReducedEPS0_3843518
_ZNK4PLMD16ActionWithVector17checkForTaskForceERKjPKNS_5ValueE5561312
_ZNK4PLMD16ActionWithVector12taskIsActiveERKjRi6793058
_ZNK4PLMD16ActionWithVector18gatherAccumulatorsERKjRKNS_10MultiValueERSt6vectorIdSaIdEE9239280
_ZNK4PLMD16ActionWithVector7runTaskERKjRNS_10MultiValueE11340462
_ZN4PLMD16ActionWithVector21getFirstActionInChainEv209535206
+
+
+ + + +
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 000000000..42e92f6f9 --- /dev/null +++ b/coverage/core/ActionWithVector.cpp.func.html @@ -0,0 +1,288 @@ + + + + + + + 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-10-17 16:45:00Functions:505492.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithVector11runAllTasksEv133004
_ZN4PLMD16ActionWithVector12lockRequestsEv273524
_ZN4PLMD16ActionWithVector13gatherThreadsERKjS2_RKSt6vectorIdSaIdEERS5_RNS_10MultiValueE209939
_ZN4PLMD16ActionWithVector13retrieveAtomsERKb456395
_ZN4PLMD16ActionWithVector14canReduceTasksERSt6vectorIPS0_SaIS2_EE20916
_ZN4PLMD16ActionWithVector14checkForForcesEv254422
_ZN4PLMD16ActionWithVector14unlockRequestsEv273524
_ZN4PLMD16ActionWithVector15gatherProcessesERSt6vectorIdSaIdEE132962
_ZN4PLMD16ActionWithVector15getSizeOfBufferERKjRj317683
_ZN4PLMD16ActionWithVector16addActionToChainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPS0_11762
_ZN4PLMD16ActionWithVector16addForcesToInputERKSt6vectorIdSaIdEERj186367
_ZN4PLMD16ActionWithVector16clearDerivativesERKb457632
_ZN4PLMD16ActionWithVector16clearInputForcesERKb457632
_ZN4PLMD16ActionWithVector16finishChainBuildEPS0_3544
_ZN4PLMD16ActionWithVector16getNumberOfTasksERj314964
_ZN4PLMD16ActionWithVector16registerKeywordsERNS_8KeywordsE5380
_ZN4PLMD16ActionWithVector17argumentDependsOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS0_PNS_5ValueE344
_ZN4PLMD16ActionWithVector18buildArgumentStoreERKj3401
_ZN4PLMD16ActionWithVector18finishComputationsERKSt6vectorIdSaIdEE317683
_ZN4PLMD16ActionWithVector20getListOfActiveTasksEPS0_144849
_ZN4PLMD16ActionWithVector21getFirstActionInChainEv209535206
_ZN4PLMD16ActionWithVector23getNumberOfStoredValuesEPNS_5ValueERjRKjRKSt6vectorIS2_SaIS2_EE136
_ZN4PLMD16ActionWithVector23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421278
_ZN4PLMD16ActionWithVector23updateTaskReductionFlagERb229464
_ZN4PLMD16ActionWithVector24getActionWithDerivativesEPS0_17691
_ZN4PLMD16ActionWithVector24reallyBuildArgumentStoreERKj989
_ZN4PLMD16ActionWithVector26getAdditionalTasksRequiredEPS0_RSt6vectorIjSaIjEE1309
_ZN4PLMD16ActionWithVector28broadcastThatTasksAreReducedEPS0_3843518
_ZN4PLMD16ActionWithVector29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD16ActionWithVector29getNumberOfStreamedQuantitiesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421278
_ZN4PLMD16ActionWithVector29updateTaskListReductionStatusEv2674
_ZN4PLMD16ActionWithVector30getNumberOfStreamedDerivativesERjPNS_5ValueE424411
_ZN4PLMD16ActionWithVector5applyEv254422
_ZN4PLMD16ActionWithVector7prepareEv274530
_ZN4PLMD16ActionWithVectorC1ERKNS_13ActionOptionsE0
_ZN4PLMD16ActionWithVectorC2ERKNS_13ActionOptionsE4916
_ZN4PLMD16ActionWithVectorD0Ev0
_ZN4PLMD16ActionWithVectorD1Ev0
_ZN4PLMD16ActionWithVectorD2Ev4916
_ZNK4PLMD16ActionWithVector12gatherForcesERKjRKNS_10MultiValueERSt6vectorIdSaIdEE2101182
_ZNK4PLMD16ActionWithVector12taskIsActiveERKjRi6793058
_ZNK4PLMD16ActionWithVector13checkForGridsERj317683
_ZNK4PLMD16ActionWithVector13getForceTasksERSt6vectorIjSaIjEE103595
_ZNK4PLMD16ActionWithVector17checkForTaskForceERKjPKNS_5ValueE5561312
_ZNK4PLMD16ActionWithVector17gatherStoredValueERKjS2_RKNS_10MultiValueES2_RSt6vectorIdSaIdEE3571815
_ZNK4PLMD16ActionWithVector18gatherAccumulatorsERKjRKNS_10MultiValueERSt6vectorIdSaIdEE9239280
_ZNK4PLMD16ActionWithVector18hasStoredArgumentsEv46
_ZNK4PLMD16ActionWithVector21getFirstActionInChainEv46
_ZNK4PLMD16ActionWithVector23checkComponentsForForceEv2039456
_ZNK4PLMD16ActionWithVector25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE1565796
_ZNK4PLMD16ActionWithVector25getAllActionLabelsInChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE36905
_ZNK4PLMD16ActionWithVector25updateForceTasksFromValueEPKNS_5ValueERSt6vectorIjSaIjEE90719
_ZNK4PLMD16ActionWithVector28checkChainForNonScalarForcesEv292884
_ZNK4PLMD16ActionWithVector7runTaskERKjRNS_10MultiValueE11340462
+
+
+ + + +
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 000000000..49be40a57 --- /dev/null +++ b/coverage/core/ActionWithVector.cpp.gcov.html @@ -0,0 +1,847 @@ + + + + + + + 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-10-17 16:45:00Functions: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        5380 : void ActionWithVector::registerKeywords( Keywords& keys ) {
+      31        5380 :   Action::registerKeywords( keys );
+      32        5380 :   ActionAtomistic::registerKeywords( keys );
+      33        5380 :   ActionWithValue::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+      34        5380 :   ActionWithArguments::registerKeywords( keys );
+      35       10760 :   keys.addFlag("SERIAL",false,"do the calculation in serial.  Do not parallelize");
+      36        5380 : }
+      37             : 
+      38        4916 : ActionWithVector::ActionWithVector(const ActionOptions&ao):
+      39             :   Action(ao),
+      40             :   ActionAtomistic(ao),
+      41             :   ActionWithValue(ao),
+      42             :   ActionWithArguments(ao),
+      43        4916 :   serial(false),
+      44        4916 :   action_to_do_before(NULL),
+      45        4916 :   action_to_do_after(NULL),
+      46        4916 :   never_reduce_tasks(false),
+      47        4916 :   reduce_tasks(false),
+      48        4916 :   atomsWereRetrieved(false),
+      49        4916 :   done_in_chain(false)
+      50             : {
+      51       12272 :   if( keywords.exists("SERIAL") ) parseFlag("SERIAL",serial);
+      52        4916 : }
+      53             : 
+      54        4916 : ActionWithVector::~ActionWithVector() {
+      55        4916 :   if( action_to_do_before ) action_to_do_before->action_to_do_after=NULL;
+      56        4916 : }
+      57             : 
+      58      273524 : void ActionWithVector::lockRequests() {
+      59             :   ActionAtomistic::lockRequests();
+      60             :   ActionWithArguments::lockRequests();
+      61      273524 : }
+      62             : 
+      63      273524 : void ActionWithVector::unlockRequests() {
+      64             :   ActionAtomistic::unlockRequests();
+      65             :   ActionWithArguments::unlockRequests();
+      66      273524 : }
+      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      457632 : void ActionWithVector::clearDerivatives( const bool& force ) {
+      73      457632 :   if( !force && actionInChain() ) return;
+      74      338953 :   ActionWithValue::clearDerivatives();
+      75      338953 :   if( action_to_do_after ) action_to_do_after->clearDerivatives( true );
+      76             : }
+      77             : 
+      78      457632 : void ActionWithVector::clearInputForces( const bool& force ) {
+      79      457632 :   if( !force && actionInChain() ) return;
+      80      338953 :   ActionWithValue::clearInputForces();
+      81      338953 :   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   209535206 : ActionWithVector* ActionWithVector::getFirstActionInChain() {
+      90   209535206 :   if( !actionInChain() ) return this;
+      91   198646985 :   return action_to_do_before->getFirstActionInChain();
+      92             : }
+      93             : 
+      94      456395 : void ActionWithVector::retrieveAtoms( const bool& force ) {
+      95      456395 :   if( !force && actionInChain() || atomsWereRetrieved ) return;
+      96      337377 :   ActionAtomistic::retrieveAtoms(); atomsWereRetrieved = !actionInChain();
+      97      337377 :   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        3401 : unsigned ActionWithVector::buildArgumentStore( const unsigned& argstart ) {
+     120             :   // Don't use chains for grids
+     121       10627 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     122        7608 :     if( getPntrToArgument(i)->isConstant() ) continue;
+     123        6707 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>(getPntrToArgument(i)->getPntrToAction());
+     124        6707 :     if( !av || getPntrToArgument(i)->getRank()>0 && getPntrToArgument(i)->hasDerivatives() ) { done_in_chain=false; break; }
+     125             :   }
+     126        3401 :   if( done_in_chain ) {
+     127             :     std::vector<std::string> alabels; std::vector<ActionWithVector*> f_actions;
+     128        8623 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     129        6200 :       bool found=false; std::string mylab = (getPntrToArgument(i)->getPntrToAction())->getLabel();
+     130       12803 :       for(unsigned j=0; j<alabels.size(); ++j) {
+     131        8749 :         if( alabels[j]==mylab ) { found=true; break; }
+     132             :       }
+     133        6200 :       if( !found ) alabels.push_back( mylab );
+     134             : 
+     135             :       // If this is calculated in setup we never need to add to chain
+     136        6200 :       if( getPntrToArgument(i)->isConstant() ) continue;
+     137             :       // Find the chain we need to add this to from the arguments
+     138        5783 :       ActionWithVector* av=dynamic_cast<ActionWithVector*>(getPntrToArgument(i)->getPntrToAction()); plumed_assert( av );
+     139        5783 :       found=false; ActionWithVector* myact = av->getFirstActionInChain();
+     140        5783 :       if( getPntrToArgument(i)->getRank()==1 && getPntrToArgument(i)->storedata ) {
+     141        5540 :         for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     142        5252 :           ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( getPntrToArgument(j)->getPntrToAction() );
+     143        5252 :           if( !aarg || i==j ) continue;
+     144       14182 :           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        6129 :       for(unsigned j=0; j<f_actions.size(); ++j) {
+     150        3320 :         if( f_actions[j]==myact ) { found=true; break; }
+     151             :       }
+     152        5763 :       if( !found ) {
+     153        2809 :         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        2809 :         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        2423 :     if( f_actions.size()>0 ) {
+     162             :       // Check everything for later f_actions is done before f_actions[0]
+     163        2448 :       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        2326 :       std::vector<std::string> empty(1); empty[0] = f_actions[0]->getLabel();
+     182        2437 :       for(unsigned i=1; i<f_actions.size(); ++i) f_actions[0]->addActionToChain( empty, f_actions[i] );
+     183        2326 :     }
+     184             :     // Now add this argument to the chain
+     185             :     bool added=false;
+     186        2461 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     187             :       // Add this function to jobs to do in recursive loop in previous action
+     188        2461 :       if( getPntrToArgument(i)->getRank()>0 && !getPntrToArgument(i)->isConstant() ) {
+     189        2461 :         ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     190        2461 :         if( av && av->addActionToChain( alabels, this ) ) { added=true; break; }
+     191             :       }
+     192             :     }
+     193        2412 :     plumed_massert(added, "could not add action " + getLabel() + " to chain of any of its arguments");
+     194             :     // And get the number of derivatives
+     195        2412 :     ActionWithVector* head=getFirstActionInChain();
+     196        2412 :     unsigned nder=0; arg_deriv_starts.resize( getNumberOfArguments() );
+     197        8565 :     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        6153 :       if( i==0 && getName().find("EVALUATE_FUNCTION_FROM_GRID")!=std::string::npos ) continue ;
+     200        6152 :       ActionWithVector* iaction=dynamic_cast<ActionWithVector*>(getPntrToArgument(i)->getPntrToAction());
+     201        6152 :       if( actionInChain() && !getPntrToArgument(i)->ignoreStoredValue(head->getLabel()) ) {
+     202         675 :         arg_deriv_starts[i] = 0; head->getNumberOfStreamedDerivatives( arg_deriv_starts[i], getPntrToArgument(i) );
+     203        5477 :       } else if( iaction && iaction->isInSubChain(nder) ) {
+     204        2255 :         arg_deriv_starts[i] = nder;
+     205             :         // Add the total number of derivatives that we have by this point in the chain to nder
+     206        2255 :         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        3222 :         if( iaction ) {
+     211        3222 :           ActionWithVector* ider_action=iaction->getActionWithDerivatives( iaction );
+     212        3443 :           for(unsigned j=0; j<i; ++j) {
+     213        1628 :             if( j==0 && getName().find("EVALUATE_FUNCTION_FROM_GRID")!=std::string::npos ) continue ;
+     214        1627 :             ActionWithVector* jaction=dynamic_cast<ActionWithVector*>(getPntrToArgument(j)->getPntrToAction());
+     215        1627 :             if( jaction->getActionWithDerivatives(jaction)==ider_action || jaction->checkForDependency(ider_action) ) { k=j; break; }
+     216             :           }
+     217        3222 :           if( k>=0 ) { arg_deriv_starts[i] = arg_deriv_starts[k]; continue; }
+     218             :         }
+     219             : 
+     220        1815 :         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         136 :           unsigned mder=0;
+     231         136 :           ActionWithVector* jaction=dynamic_cast<ActionWithVector*>(getPntrToArgument(i-1)->getPntrToAction());
+     232         136 :           if( jaction->action_to_do_after && !(jaction->action_to_do_after)->getNumberOfStoredValues( getPntrToArgument(i-1), mder, i, getArguments() ) ) mder=0;
+     233         136 :           if( mder>0 ) nder = nder + mder;
+     234             :         }
+     235             : 
+     236        1815 :         arg_deriv_starts[i] = nder;
+     237             :         // Add the total number of derivatives that we have by this point in the chain to nder
+     238        1815 :         if( iaction ) {
+     239        1815 :           nder=0;
+     240        1815 :           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        1815 :           } else head->getNumberOfStreamedDerivatives( nder, getPntrToArgument(i) );
+     246             :         }
+     247             :       }
+     248             :     }
+     249        2412 :     nder=0; head->getNumberOfStreamedDerivatives( nder, NULL );
+     250        2412 :     return nder;
+     251        2443 :   }
+     252         958 :   return reallyBuildArgumentStore( argstart );
+     253             : }
+     254             : 
+     255         989 : unsigned ActionWithVector::reallyBuildArgumentStore( const unsigned& argstart ) {
+     256        2703 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) { if( getPntrToArgument(i)->getRank()>0 ) getPntrToArgument(i)->buildDataStore(); }
+     257         989 :   unsigned nder=0; arg_deriv_starts.resize( getNumberOfArguments() );
+     258        2703 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) { arg_deriv_starts[i] = nder; nder += getPntrToArgument(i)->getNumberOfValues(); }
+     259         989 :   return nder;
+     260             : }
+     261             : 
+     262       17691 : ActionWithVector* ActionWithVector::getActionWithDerivatives( ActionWithVector* depaction ) {
+     263       17691 :   if( depaction==this || depaction->checkForDependency(this) ) {
+     264       11635 :     if( getNumberOfAtoms()>0 ) return this;
+     265        6786 :     std::string c=getFirstActionInChain()->getLabel();
+     266       42648 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     267       36322 :       if( !getPntrToArgument(i)->ignoreStoredValue(c) && !getPntrToArgument(i)->isConstant() ) return this;
+     268             :     }
+     269             :   }
+     270       12842 :   plumed_assert( action_to_do_before );
+     271       12842 :   return action_to_do_before->getActionWithDerivatives(depaction);
+     272             : }
+     273             : 
+     274       11762 : bool ActionWithVector::addActionToChain( const std::vector<std::string>& alabels, ActionWithVector* act ) {
+     275       11762 :   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        2572 :   std::vector<std::string> mylabels; getFirstActionInChain()->getAllActionLabelsInChain( mylabels );
+     278       21211 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+     279       18639 :     if( act->getLabel()==mylabels[i] ) return true;
+     280             :   }
+     281             : 
+     282             :   // Check that everything that is required has been calculated
+     283        6756 :   for(unsigned i=0; i<alabels.size(); ++i) {
+     284             :     bool found=false;
+     285       20767 :     for(unsigned j=0; j<mylabels.size(); ++j) {
+     286       20037 :       if( alabels[i]==mylabels[j] ) { found=true; break; }
+     287             :     }
+     288        4233 :     if( !found ) {
+     289         730 :       ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( alabels[i] );
+     290         730 :       plumed_massert( av, "could not cast " + alabels[i] ); bool storingall=true;
+     291        1522 :       for(int j=0; j<av->getNumberOfComponents(); ++j) {
+     292         792 :         if( !(av->getPntrToComponent(j))->storedata ) storingall=false;
+     293             :       }
+     294         730 :       if( !storingall ) return false;
+     295             :     }
+     296             :   }
+     297             :   // This checks that there is nothing that will cause problems in the chain
+     298        2523 :   mylabels.resize(0); getFirstActionInChain()->getAllActionLabelsInChain( mylabels );
+     299       20709 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+     300       18186 :     ActionWithVector* av1=plumed.getActionSet().selectWithLabel<ActionWithVector*>( mylabels[i] );
+     301      176648 :     for(unsigned j=0; j<i; ++j) {
+     302      158462 :       ActionWithVector* av2=plumed.getActionSet().selectWithLabel<ActionWithVector*>( mylabels[j] );
+     303      158462 :       if( !av1->canBeAfterInChain( av2 ) ) error("must calculate " + mylabels[j] + " before " + mylabels[i] );
+     304             :     }
+     305             :   }
+     306        2523 :   action_to_do_after=act; act->action_to_do_before=this; updateTaskListReductionStatus();
+     307        2523 :   ActionWithVector* head = getFirstActionInChain();
+     308        2523 :   head->broadcastThatTasksAreReduced( head ); head->finishChainBuild( act );
+     309             :   return true;
+     310        2572 : }
+     311             : 
+     312        2674 : void ActionWithVector::updateTaskListReductionStatus() {
+     313        2674 :   ActionWithVector* head = getFirstActionInChain();
+     314        2674 :   std::vector<ActionWithVector*> task_reducing_actions; head->canReduceTasks( task_reducing_actions );
+     315        2674 :   if( task_reducing_actions.size()>0 ) head->reduce_tasks=true;
+     316        2674 : }
+     317             : 
+     318     3843518 : void ActionWithVector::broadcastThatTasksAreReduced( ActionWithVector* aselect ) {
+     319     3843518 :   std::string c=getFirstActionInChain()->getLabel();
+     320    18085391 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     321    14241873 :     if( !getPntrToArgument(i)->ignoreStoredValue(c) ) {
+     322       71210 :       ActionWithVector* av = dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     323       71210 :       if( av ) {
+     324             :         bool found=false;
+     325       12111 :         ActionWithVector* av_head = av->getFirstActionInChain();
+     326       17731 :         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       12111 :         if( !found ) av_head->task_control_list.insert( av_head->task_control_list.begin(), aselect );
+     330             : 
+     331       12111 :         av_head->reduce_tasks=true; av_head->updateTaskReductionFlag( av_head->reduce_tasks );
+     332             :       }
+     333             :     }
+     334             :   }
+     335     3843518 :   if( action_to_do_after ) action_to_do_after->broadcastThatTasksAreReduced( aselect );
+     336     3843518 : }
+     337             : 
+     338      229464 : void ActionWithVector::updateTaskReductionFlag( bool& head_reduce_tasks ) {
+     339      229464 :   if( actionInChain() ) {
+     340      217353 :     plumed_assert( task_control_list.size()==0 );
+     341             :   } else {
+     342       30767 :     for(unsigned i=0; i<task_control_list.size(); ++i) {
+     343       18656 :       if( !(task_control_list[i]->getFirstActionInChain())->reduce_tasks ) head_reduce_tasks=false;
+     344             :     }
+     345             :   }
+     346      229464 :   broadcastThatTasksAreReduced( getFirstActionInChain() );
+     347      229464 :   if( action_to_do_after ) action_to_do_after->updateTaskReductionFlag( head_reduce_tasks );
+     348      229464 : }
+     349             : 
+     350       20916 : void ActionWithVector::canReduceTasks( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     351       20916 :   areAllTasksRequired( task_reducing_actions );
+     352       20916 :   if( action_to_do_after ) action_to_do_after->canReduceTasks( task_reducing_actions );
+     353       20916 : }
+     354             : 
+     355        3544 : void ActionWithVector::finishChainBuild( ActionWithVector* act ) {
+     356        3544 :   if( action_to_do_after ) action_to_do_after->finishChainBuild( act );
+     357        3544 : }
+     358             : 
+     359       36905 : void ActionWithVector::getAllActionLabelsInChain( std::vector<std::string>& mylabels ) const {
+     360             :   bool found = false ;
+     361      359315 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+     362      322410 :     if( getLabel()==mylabels[i] ) { found=true; }
+     363             :   }
+     364       36905 :   if( !found ) mylabels.push_back( getLabel() );
+     365       36905 :   if( action_to_do_after ) action_to_do_after->getAllActionLabelsInChain( mylabels );
+     366       36905 : }
+     367             : 
+     368     6793058 : void ActionWithVector::taskIsActive( const unsigned& current, int& flag ) const {
+     369     6793058 :   if( isActive() ) flag = checkTaskStatus( current, flag );
+     370     6793058 :   if( flag<=0 && action_to_do_after ) action_to_do_after->taskIsActive( current, flag );
+     371     6793058 : }
+     372             : 
+     373        1309 : void ActionWithVector::getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) {
+     374        1341 :   for(unsigned i=0; i<task_control_list.size(); ++i ) task_control_list[i]->getAdditionalTasksRequired( action, atasks );
+     375        1309 : }
+     376             : 
+     377      274530 : void ActionWithVector::prepare() {
+     378      274530 :   active_tasks.resize(0); atomsWereRetrieved=false;
+     379      274530 : }
+     380             : 
+     381      144849 : std::vector<unsigned>& ActionWithVector::getListOfActiveTasks( ActionWithVector* action ) {
+     382      144849 :   if( active_tasks.size()>0 ) return active_tasks;
+     383      132859 :   unsigned ntasks=0; getNumberOfTasks( ntasks );
+     384             : 
+     385      132859 :   unsigned stride=comm.Get_size();
+     386      132859 :   unsigned rank=comm.Get_rank();
+     387      132859 :   if(serial) { stride=1; rank=0; }
+     388             : 
+     389             :   // Get number of threads for OpenMP
+     390      132859 :   unsigned nt=OpenMP::getNumThreads();
+     391      132859 :   if( nt*stride*10>ntasks ) nt=ntasks/stride/10;
+     392             :   if( nt==0 ) nt=1;
+     393             : 
+     394      132859 :   if( !never_reduce_tasks && reduce_tasks ) {
+     395        1493 :     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        1385 :       std::vector<int> taskFlags( ntasks, -1 );
+     405             : 
+     406        1385 :       #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     2492457 :       for(unsigned i=0; i<ntasks; ++i) taskFlags[i] = std::abs( taskFlags[i] );
+     414        1385 :       if( !serial ) comm.Sum( taskFlags );
+     415             : 
+     416             :       unsigned nt=0;
+     417     2492457 :       for(unsigned i=0; i<ntasks; ++i) {
+     418     2491072 :         if( taskFlags[i]>=stride ) nt++;
+     419             :       }
+     420        1385 :       active_tasks.resize(nt); nt=0;
+     421     2492457 :       for(unsigned i=0; i<ntasks; ++i) {
+     422     2491072 :         if( taskFlags[i]>=stride ) { active_tasks[nt]=i; nt++; }
+     423             :       }
+     424        1385 :       getAdditionalTasksRequired( this, active_tasks );
+     425             :     }
+     426             :   } else {
+     427      131366 :     active_tasks.resize( ntasks );
+     428     5116683 :     for(unsigned i=0; i<ntasks; ++i) active_tasks[i]=i;
+     429             :   }
+     430      132859 :   return active_tasks;
+     431             : }
+     432             : 
+     433      133004 : void ActionWithVector::runAllTasks() {
+     434             : // Skip this if this is done elsewhere
+     435      133004 :   if( action_to_do_before ) return;
+     436             : 
+     437      132969 :   unsigned stride=comm.Get_size();
+     438      132969 :   unsigned rank=comm.Get_rank();
+     439      132969 :   if(serial) { stride=1; rank=0; }
+     440             : 
+     441             :   // Get the list of active tasks
+     442      132969 :   std::vector<unsigned> & partialTaskList( getListOfActiveTasks( this ) );
+     443      132969 :   unsigned nactive_tasks=partialTaskList.size();
+     444             : 
+     445             :   // Get number of threads for OpenMP
+     446      132969 :   unsigned nt=OpenMP::getNumThreads();
+     447      132969 :   if( nt*stride*10>nactive_tasks ) nt=nactive_tasks/stride/10;
+     448      132969 :   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      132969 :   unsigned nquants=0, nmatrices=0, maxcol=0, nbooks=0;
+     455      132969 :   getNumberOfStreamedQuantities( getLabel(), nquants, nmatrices, maxcol, nbooks );
+     456             :   // Get size for buffer
+     457      132969 :   unsigned bufsize=0; getSizeOfBuffer( nactive_tasks, bufsize );
+     458      132969 :   if( buffer.size()!=bufsize ) buffer.resize( bufsize );
+     459             :   // Clear buffer
+     460      132969 :   buffer.assign( buffer.size(), 0.0 );
+     461             : 
+     462             :   // Recover the number of derivatives we require
+     463      132969 :   unsigned nderivatives = 0; bool gridsInStream=checkForGrids(nderivatives);
+     464      132969 :   if( !doNotCalculateDerivatives() && !gridsInStream ) getNumberOfStreamedDerivatives( nderivatives, NULL );
+     465             : 
+     466      132969 :   #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();
+     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();
+     484             :     }
+     485             :     #pragma omp critical
+     486             :     gatherThreads( nt, bufsize, omp_buffer, buffer, myvals );
+     487             :   }
+     488             : 
+     489             :   // MPI Gather everything
+     490      132969 :   if( !serial && buffer.size()>0 ) gatherProcesses( buffer );
+     491      132969 :   finishComputations( buffer );
+     492             : }
+     493             : 
+     494      209939 : void ActionWithVector::gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) {
+     495   100317013 :   if( nt>1 ) for(unsigned i=0; i<bufsize; ++i) buffer[i]+=omp_buffer[i];
+     496      209939 : }
+     497             : 
+     498      132962 : void ActionWithVector::gatherProcesses( std::vector<double>& buffer ) {
+     499      132962 :   comm.Sum( buffer );
+     500      132962 : }
+     501             : 
+     502      317683 : bool ActionWithVector::checkForGrids( unsigned& nder ) const {
+     503      650581 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     504      341631 :     if( getConstPntrToComponent(i)->getRank()>0 && getConstPntrToComponent(i)->hasDerivatives() ) {
+     505        8733 :       nder=getConstPntrToComponent(i)->getNumberOfGridDerivatives(); return true;
+     506             :     }
+     507             :   }
+     508      308950 :   if( action_to_do_after ) return action_to_do_after->checkForGrids(nder);
+     509             :   return false;
+     510             : }
+     511             : 
+     512      314964 : void ActionWithVector::getNumberOfTasks( unsigned& ntasks ) {
+     513      314964 :   if( ntasks==0 ) {
+     514      130206 :     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      127921 :       plumed_assert( getNumberOfComponents()>0 && getPntrToComponent(0)->getRank()>0 );
+     519      127921 :       if( getPntrToComponent(0)->hasDerivatives() ) ntasks = getPntrToComponent(0)->getNumberOfValues();
+     520      121860 :       else ntasks = getPntrToComponent(0)->getShape()[0];
+     521             :     }
+     522             :   }
+     523      653872 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     524      338908 :     if( getPntrToComponent(i)->getRank()==0 ) {
+     525       65937 :       if( getNumberOfArguments()!=1 ) error("mismatched numbers of tasks in streamed quantities");
+     526       65937 :       if( getPntrToArgument(0)->hasDerivatives() && ntasks!=getPntrToArgument(0)->getNumberOfValues() ) error("mismatched numbers of tasks in streamed quantities");
+     527       65937 :       else if ( !getPntrToArgument(0)->hasDerivatives() && ntasks!=getPntrToArgument(0)->getShape()[0] ) error("mismatched numbers of tasks in streamed quantities");
+     528      272971 :     } else if( getPntrToComponent(i)->hasDerivatives() && ntasks!=getPntrToComponent(i)->getNumberOfValues() ) error("mismatched numbers of tasks in streamed quantities");
+     529      272971 :     else if( !getPntrToComponent(i)->hasDerivatives() && ntasks!=getPntrToComponent(i)->getShape()[0] ) error("mismatched numbers of tasks in streamed quantities");
+     530             :   }
+     531      314964 :   if( action_to_do_after ) action_to_do_after->getNumberOfTasks( ntasks );
+     532      314964 : }
+     533             : 
+     534      421278 : void ActionWithVector::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     535     1075219 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     536      653941 :     if( !getPntrToArgument(i)->ignoreStoredValue(headstr) ) { getPntrToArgument(i)->streampos=nquants; nquants++; }
+     537             :   }
+     538      881595 :   for(int i=0; i<getNumberOfComponents(); ++i) { getPntrToComponent(i)->streampos=nquants; nquants++; }
+     539      421278 : }
+     540             : 
+     541      421278 : void ActionWithVector::getNumberOfStreamedQuantities( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     542      421278 :   setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     543      421278 :   if( action_to_do_after ) action_to_do_after->getNumberOfStreamedQuantities( headstr, nquants, nmat, maxcol, nbookeeping );
+     544      421278 : }
+     545             : 
+     546      317683 : void ActionWithVector::getSizeOfBuffer( const unsigned& nactive_tasks, unsigned& bufsize ) {
+     547      659314 :   for(int i=0; i<getNumberOfComponents(); ++i) { getPntrToComponent(i)->bufstart=bufsize; bufsize += getPntrToComponent(i)->data.size(); }
+     548      317683 :   if( action_to_do_after ) action_to_do_after->getSizeOfBuffer( nactive_tasks, bufsize );
+     549      317683 : }
+     550             : 
+     551      424411 : void ActionWithVector::getNumberOfStreamedDerivatives( unsigned& nderivatives, Value* stopat ) {
+     552      424411 :   std::string c=getFirstActionInChain()->getLabel();
+     553     1144906 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     554      721170 :     if( !getPntrToArgument(i)->ignoreStoredValue(c) ) {
+     555      385865 :       if( getPntrToArgument(i)==stopat ) return;
+     556      385190 :       nderivatives += getPntrToArgument(i)->getNumberOfValues();
+     557             :     }
+     558             :   }
+     559      423736 :   if( getNumberOfAtoms()>0 ) nderivatives += 3*getNumberOfAtoms() + 9;
+     560             :   // Don't do the whole chain if we have been told to stop early
+     561      423736 :   if( stopat && stopat->getPntrToAction()==this ) return;
+     562             : 
+     563      419562 :   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    11340462 : void ActionWithVector::runTask( const unsigned& current, MultiValue& myvals ) const {
+     587    11340462 :   if( isActive() ) {
+     588    10224413 :     myvals.setTaskIndex(current); myvals.vector_call=true; performTask( current, myvals );
+     589             :   }
+     590    11340462 :   if( action_to_do_after ) action_to_do_after->runTask( current, myvals );
+     591    11340462 : }
+     592             : 
+     593     9239280 : void ActionWithVector::gatherAccumulators( const unsigned& taskCode, const MultiValue& myvals, std::vector<double>& buffer ) const {
+     594     9239280 :   if( isActive() ) {
+     595    18562303 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     596    10284069 :       unsigned bufstart = getConstPntrToComponent(i)->bufstart;
+     597             :       // This looks after storing of scalars that are summed from vectors/matrices
+     598    10284069 :       if( getConstPntrToComponent(i)->getRank()==0 ) {
+     599             :         plumed_dbg_massert( bufstart<buffer.size(), "problem in " + getLabel() );
+     600     1146054 :         unsigned sind = getConstPntrToComponent(i)->streampos; buffer[bufstart] += myvals.get(sind);
+     601     1146054 :         if( getConstPntrToComponent(i)->hasDerivatives() ) {
+     602    26904718 :           for(unsigned k=0; k<myvals.getNumberActive(sind); ++k) {
+     603    25758664 :             unsigned kindex = myvals.getActiveIndex(sind,k);
+     604             :             plumed_dbg_massert( bufstart+1+kindex<buffer.size(), "problem in " + getLabel()  );
+     605    25758664 :             buffer[bufstart + 1 + kindex] += myvals.getDerivative(sind,kindex);
+     606             :           }
+     607             :         }
+     608             :         // This looks after storing of vectors
+     609     9138015 :       } else if( getConstPntrToComponent(i)->storedata ) gatherStoredValue( i, taskCode, myvals, bufstart, buffer );
+     610             :     }
+     611             :   }
+     612     9239280 :   if( action_to_do_after ) action_to_do_after->gatherAccumulators( taskCode, myvals, buffer );
+     613     9239280 : }
+     614             : 
+     615     3571815 : 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     3571815 :   unsigned vindex = getConstPntrToComponent(valindex)->bufstart + taskCode; plumed_dbg_massert( vindex<buffer.size(), "failing in " + getLabel() );
+     619     3571815 :   buffer[vindex] += myvals.get(getConstPntrToComponent(valindex)->streampos);
+     620     3571815 : }
+     621             : 
+     622      317683 : void ActionWithVector::finishComputations( const std::vector<double>& buf ) {
+     623      317683 :   if( isActive() ) {
+     624      527282 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     625             :       // This gathers vectors and grids at the end of the calculation
+     626      275615 :       unsigned bufstart = getPntrToComponent(i)->bufstart;
+     627      275615 :       getPntrToComponent(i)->data.assign( getPntrToComponent(i)->data.size(), 0 );
+     628      275615 :       if( (getPntrToComponent(i)->getRank()>0 && getPntrToComponent(i)->hasDerivatives()) || getPntrToComponent(i)->storedata ) {
+     629      130918 :         unsigned sz_v = getPntrToComponent(i)->data.size();
+     630    46583551 :         for(unsigned j=0; j<sz_v; ++j) {
+     631             :           plumed_dbg_assert( bufstart+j<buf.size() );
+     632    46452633 :           getPntrToComponent(i)->add( j, buf[bufstart+j] );
+     633             :         }
+     634             :         // Make sure single values are set
+     635      144697 :       } else if( getPntrToComponent(i)->getRank()==0 ) getPntrToComponent(i)->set( buf[bufstart] );
+     636             :       // This gathers derivatives of scalars
+     637      275615 :       if( !doNotCalculateDerivatives() && getPntrToComponent(i)->hasDeriv && getPntrToComponent(i)->getRank()==0 ) {
+     638    16229167 :         for(unsigned j=0; j<getPntrToComponent(i)->getNumberOfDerivatives(); ++j) getPntrToComponent(i)->setDerivative( j, buf[bufstart+1+j] );
+     639             :       }
+     640             :     }
+     641             :   }
+     642      317683 :   if( action_to_do_after ) action_to_do_after->finishComputations( buf );
+     643      317683 : }
+     644             : 
+     645      292884 : bool ActionWithVector::checkChainForNonScalarForces() const {
+     646      523180 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     647      305133 :     if( getConstPntrToComponent(i)->getRank()>0 && getConstPntrToComponent(i)->forcesWereAdded() ) return true;
+     648             :   }
+     649      218047 :   if( action_to_do_after ) return action_to_do_after->checkChainForNonScalarForces();
+     650             :   return false;
+     651             : }
+     652             : 
+     653      254422 : bool ActionWithVector::checkForForces() {
+     654      254422 :   if( getPntrToComponent(0)->getRank()==0 ) return ActionWithValue::checkForForces();
+     655      202650 :   else if( actionInChain() ) return false;
+     656             : 
+     657             :   // Check if there are any forces
+     658      125264 :   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();
+     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();
+     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    20912845 :   for(unsigned j=0; j<myvals.getNumberActive(sspos); ++j) {
+     744    19347049 :     unsigned jder=myvals.getActiveIndex(sspos, j); plumed_dbg_assert( jder<forces.size() );
+     745    19347049 :     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      254422 : void ActionWithVector::apply() {
+     760      254422 :   if( !checkForForces() ) return;
+     761             :   // Find the top of the chain and add forces
+     762      117831 :   unsigned ind=0; getFirstActionInChain()->addForcesToInput( getForcesToApply(), ind );
+     763             : }
+     764             : 
+     765      186367 : void ActionWithVector::addForcesToInput( const std::vector<double>& forcesToApply, unsigned& ind ) {
+     766      186367 :   if( ind>=forcesToApply.size() ) return;
+     767      136821 :   addForcesOnArguments( 0, forcesToApply, ind, getFirstActionInChain()->getLabel() ); setForcesOnAtoms( forcesToApply, ind );
+     768      136821 :   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 000000000..3c55551ef --- /dev/null +++ b/coverage/core/ActionWithVector.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithVector19switchTaskReductionERKbPS0_0
_ZNK4PLMD16ActionWithVector31getAllActionLabelsInMatrixChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE22
_ZN4PLMD16ActionWithVector12isInSubChainERj3222
_ZN4PLMD16ActionWithVector19areAllTasksRequiredERSt6vectorIPS0_SaIS2_EE7699
_ZNK4PLMD16ActionWithVector23updateAdditionalIndicesERKjRNS_10MultiValueE13807
_ZN4PLMD16ActionWithVector17canBeAfterInChainEPS0_158462
_ZNK4PLMD16ActionWithVector15checkTaskStatusERKjRi4220851
+
+
+ + + +
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 000000000..5dff8c943 --- /dev/null +++ b/coverage/core/ActionWithVector.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithVector12isInSubChainERj3222
_ZN4PLMD16ActionWithVector17canBeAfterInChainEPS0_158462
_ZN4PLMD16ActionWithVector19areAllTasksRequiredERSt6vectorIPS0_SaIS2_EE7699
_ZN4PLMD16ActionWithVector19switchTaskReductionERKbPS0_0
_ZNK4PLMD16ActionWithVector15checkTaskStatusERKjRi4220851
_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 000000000..fa1c08d11 --- /dev/null +++ b/coverage/core/ActionWithVector.h.gcov.html @@ -0,0 +1,267 @@ + + + + + + + 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-10-17 16:45:00Functions: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      158462 :   virtual bool canBeAfterInChain( ActionWithVector* av ) { return true; }
+     143             : /// Do we always need to do all the tasks for this action
+     144        7699 :   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     4220851 :   virtual int checkTaskStatus( const unsigned& taskno, int& flag ) const { return flag; }
+     149             : /// Check if we are in a subchain
+     150        3222 :   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   257479546 :   return (action_to_do_before!=NULL);
+     182             : }
+     183             : 
+     184             : inline
+     185             : bool ActionWithVector::runInSerial() const {
+     186       27747 :   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 000000000..3e89c079c --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE2143
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv2143
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE10284
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE10320
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE18068
_ZN4PLMD21ActionWithVirtualAtom5applyEv35011
+
+
+ + + +
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 000000000..2898bf6e4 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE10284
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE18068
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE2143
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv2143
_ZN4PLMD21ActionWithVirtualAtom5applyEv35011
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE10320
+
+
+ + + +
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 000000000..f23fdec1a --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html @@ -0,0 +1,207 @@ + + + + + + + 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-10-17 16:45:00Functions: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       18068 : void ActionWithVirtualAtom::registerKeywords(Keywords& keys) {
+      29       18068 :   Action::registerKeywords(keys);
+      30       18068 :   ActionAtomistic::registerKeywords(keys);
+      31       36136 :   keys.add("atoms","ATOMS","the list of atoms which are involved the virtual atom's definition");
+      32       36136 :   keys.addOutputComponent("x","default","the x coordinate of the virtual atom");
+      33       36136 :   keys.addOutputComponent("y","default","the y coordinate of the virtual atom");
+      34       36136 :   keys.addOutputComponent("z","default","the z coordinate of the virtual atom");
+      35       36136 :   keys.addOutputComponent("mass","default","the mass of the virtual atom");
+      36       36136 :   keys.addOutputComponent("charge","default","the charge of the virtual atom");
+      37       18068 : }
+      38             : 
+      39       10320 : ActionWithVirtualAtom::ActionWithVirtualAtom(const ActionOptions&ao):
+      40             :   Action(ao),
+      41             :   ActionAtomistic(ao),
+      42       10320 :   ActionWithValue(ao)
+      43             : {
+      44       30960 :   addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+      45       30960 :   addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+      46       20640 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+      47             :   // Store the derivatives with respect to the virial only even if there are no atoms
+      48       41280 :   for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->resizeDerivatives(9);
+      49       41280 :   addComponent("mass"); componentIsNotPeriodic("mass"); getPntrToComponent("mass")->isConstant();
+      50       30960 :   addComponent("charge"); componentIsNotPeriodic("charge"); getPntrToComponent("charge")->isConstant();
+      51       10320 : }
+      52             : 
+      53       10284 : void ActionWithVirtualAtom::requestAtoms(const std::vector<AtomNumber> & a) {
+      54       41136 :   ActionAtomistic::requestAtoms(a); for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
+      55       10284 : }
+      56             : 
+      57       35011 : void ActionWithVirtualAtom::apply() {
+      58       35011 :   if( !checkForForces() ) return ;
+      59             : 
+      60       22901 :   Value* xval=getPntrToComponent(0);
+      61       22901 :   Value* yval=getPntrToComponent(1);
+      62       22901 :   Value* zval=getPntrToComponent(2);
+      63       22901 :   if( !xval->forcesWereAdded() && !yval->forcesWereAdded() && !zval->forcesWereAdded() ) return ;
+      64       22901 :   if( xval->isConstant() && yval->isConstant() && zval->isConstant() ) return;
+      65             : 
+      66       45643 :   for(unsigned i=0; i<value_depends.size(); ++i) {
+      67       22742 :     xpos[value_depends[i]]->hasForce = true;
+      68       22742 :     ypos[value_depends[i]]->hasForce = true;
+      69       22742 :     zpos[value_depends[i]]->hasForce = true;
+      70             :   }
+      71             :   unsigned k=0;
+      72       22901 :   double xf = xval->inputForce[0];
+      73       22901 :   double yf = yval->inputForce[0];
+      74       22901 :   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       45643 :   for(const auto & a : atom_value_ind_grouped) {
+      82       22742 :     const auto nn=a.first;
+      83       22742 :     auto & xp=xpos[nn]->inputForce;
+      84       22742 :     auto & yp=ypos[nn]->inputForce;
+      85       22742 :     auto & zp=zpos[nn]->inputForce;
+      86      333478 :     for(const auto & kk : a.second) {
+      87      310736 :       xp[kk] += xf*xval->data[1+k] + yf*yval->data[1+k] + zf*zval->data[1+k]; k++;
+      88      310736 :       yp[kk] += xf*xval->data[1+k] + yf*yval->data[1+k] + zf*zval->data[1+k]; k++;
+      89      310736 :       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      229010 :   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       22901 :   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        2143 : void ActionWithVirtualAtom::setBoxDerivatives(const std::vector<Tensor> &d) {
+     103        2143 :   plumed_assert(d.size()==3); unsigned nbase = 3*getNumberOfAtoms();
+     104        8572 :   for(unsigned i=0; i<3; ++i) {
+     105        6429 :     Value* myval = getPntrToComponent(i);
+     106       25716 :     for(unsigned j=0; j<3; ++j) {
+     107       77148 :       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        8572 :   Vector pos; for(unsigned i=0; i<3; ++i) pos[i] = getPntrToComponent(i)->get();
+     114       27859 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) getPntrToComponent(j)->addDerivative( nbase + 3*i + j, pos[i] );
+     115        2143 : }
+     116             : 
+     117        2143 : void ActionWithVirtualAtom::setBoxDerivativesNoPbc() {
+     118        2143 :   std::vector<Tensor> bd(3);
+     119       85720 :   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      172314 :         for(unsigned l=0; l<getNumberOfAtoms(); l++) {
+     125      114453 :           bd[k][i][j]-=getPosition(l)[i]*getPntrToComponent(k)->getDerivative(3*l+j);
+     126             :         }
+     127             :       }
+     128        2143 :   setBoxDerivatives(bd);
+     129        2143 : }
+     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 000000000..6da99369c --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom7setMassEd27098
_ZN4PLMD21ActionWithVirtualAtom9setChargeEd27098
_ZN4PLMD21ActionWithVirtualAtom11setPositionERKNS_13VectorGenericILj3EEE35094
_ZN4PLMD21ActionWithVirtualAtom19setAtomsDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE35094
_ZN4PLMD21ActionWithVirtualAtom22getNumberOfDerivativesEv645611
_ZN4PLMD21ActionWithVirtualAtom27castToActionWithVirtualAtomEv6746861
+
+
+ + + +
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 000000000..54019777e --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom11setPositionERKNS_13VectorGenericILj3EEE35094
_ZN4PLMD21ActionWithVirtualAtom19setAtomsDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE35094
_ZN4PLMD21ActionWithVirtualAtom22getNumberOfDerivativesEv645611
_ZN4PLMD21ActionWithVirtualAtom27castToActionWithVirtualAtomEv6746861
_ZN4PLMD21ActionWithVirtualAtom7setMassEd27098
_ZN4PLMD21ActionWithVirtualAtom9setChargeEd27098
+
+
+ + + +
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 000000000..81ee2cabe --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.gcov.html @@ -0,0 +1,196 @@ + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-10-17 16:45:00Functions: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     6746861 :   ActionWithVirtualAtom* castToActionWithVirtualAtom() noexcept final { return this; }
+      80             : };
+      81             : 
+      82             : inline
+      83      645611 : unsigned ActionWithVirtualAtom::getNumberOfDerivatives() {
+      84      645611 :   return 3*getNumberOfAtoms()+9;
+      85             : }
+      86             : 
+      87             : inline
+      88       35094 : void ActionWithVirtualAtom::setPosition(const Vector & pos) {
+      89      140376 :   for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->set(pos[i]);
+      90       35094 : }
+      91             : 
+      92             : inline
+      93       27098 : void ActionWithVirtualAtom::setMass(double m) {
+      94       27098 :   getPntrToComponent(3)->set(m);
+      95       27098 : }
+      96             : 
+      97             : inline
+      98       27098 : void ActionWithVirtualAtom::setCharge(double c) {
+      99       27098 :   getPntrToComponent(4)->set(c);
+     100       27098 : }
+     101             : 
+     102             : inline
+     103       35094 : void ActionWithVirtualAtom::setAtomsDerivatives(const std::vector<Tensor> &d) {
+     104             :   unsigned jj=0;
+     105       35094 :   Value* xval=getPntrToComponent(0);
+     106       35094 :   Value* yval=getPntrToComponent(1);
+     107       35094 :   Value* zval=getPntrToComponent(2);
+     108      419563 :   for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     109     1537876 :     for(unsigned k=0; k<3; ++k) {
+     110     1153407 :       xval->setDerivative( jj, d[j][k][0] );
+     111     1153407 :       yval->setDerivative( jj, d[j][k][1] );
+     112     1153407 :       zval->setDerivative( jj, d[j][k][2] );
+     113             :       jj++;
+     114             :     }
+     115             :   }
+     116       35094 : }
+     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 000000000..844509583 --- /dev/null +++ b/coverage/core/CLTool.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE3719
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3771
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3771
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3847
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3847
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3847
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb25874
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE90127
+
+
+ + + +
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 000000000..783d95296 --- /dev/null +++ b/coverage/core/CLTool.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3847
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3847
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE90127
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE3719
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3771
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb25874
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3771
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3847
+
+
+ + + +
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 000000000..f22c6a5d3 --- /dev/null +++ b/coverage/core/CLTool.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-10-17 16:45:00Functions: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        3847 : CLToolOptions::CLToolOptions(const std::string &name):
+      29        3847 :   line(1,name),
+      30        3847 :   keys(emptyKeys)
+      31             : {
+      32        3847 : }
+      33             : 
+      34        3847 : CLToolOptions::CLToolOptions(const CLToolOptions& co, const Keywords& k):
+      35        3847 :   line(co.line),
+      36        3847 :   keys(k)
+      37             : {
+      38        3847 : }
+      39             : 
+      40       90127 : void CLTool::registerKeywords( Keywords& keys ) {
+      41      180254 :   keys.addFlag("--help/-h",false,"print this help");
+      42       90127 : }
+      43             : 
+      44        3847 : CLTool::CLTool(const CLToolOptions& co ):
+      45        3847 :   name(co.line[0]),
+      46        3847 :   keywords(co.keys),
+      47        3847 :   inputdata(unset)
+      48             : {
+      49        3847 : }
+      50             : 
+      51       25874 : void CLTool::parseFlag( const std::string&key, bool&t ) {
+      52       25874 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+      53       51748 :   plumed_massert(keywords.style(key,"flag"),"keyword " + key + " has not been registered as a flag");
+      54           0 :   plumed_assert(inputData.count(key)>0);
+      55       51748 :   if( inputData[key]=="true") t=true;
+      56       46104 :   else if( inputData[key]=="false") t=false;
+      57           0 :   else plumed_error();
+      58       25874 : }
+      59             : 
+      60        3771 : bool CLTool::readInput( int argc, char**argv, FILE* in, FILE*out ) {
+      61        3771 :   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        3771 :   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        3719 : bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
+      71        3719 :   plumed_assert(inputdata==commandline);
+      72        3719 :   std::string prefix(""), a(""), thiskey;
+      73             : 
+      74             :   // Set all flags to default false
+      75       69153 :   for(unsigned k=0; k<keywords.size(); ++k) {
+      76       65434 :     thiskey=keywords.get(k);
+      77      160864 :     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       15109 :   for(int i=1; i<argc; i++) {
+      83       22780 :     a=prefix+argv[i];
+      84       11390 :     if(a.length()==0) continue;
+      85       22780 :     if(a=="-h" || a=="--help") {
+      86             :       printhelp=true;
+      87             :     } else {
+      88             :       bool found=false;
+      89      366956 :       for(unsigned k=0; k<keywords.size(); ++k) {
+      90      355566 :         thiskey=keywords.get(k);
+      91      711132 :         if( keywords.style(thiskey,"flag") ) {
+      92       72830 :           if( a==thiskey ) { found=true; inputData[thiskey]="true"; }
+      93             :         } else {
+      94      282736 :           if( a==thiskey ) {
+      95        3963 :             prefix=thiskey+"="; found=true;
+      96        7926 :             inputData.insert(std::pair<std::string,std::string>(thiskey,""));
+      97      557546 :           } else if(Tools::startWith(a,thiskey+"=")) {
+      98        4607 :             a.erase(0,a.find("=")+1); prefix=""; found=true;
+      99             :             if(inputData.count(thiskey)==0) {
+     100        1290 :               inputData.insert(std::pair<std::string,std::string>(thiskey,a));
+     101             :             } else {
+     102        3962 :               inputData[thiskey]=a;
+     103             :             }
+     104             :           }
+     105             :         }
+     106             :       }
+     107       11390 :       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       11390 :     if(printhelp) break;
+     116             :   }
+     117             : 
+     118        3719 :   if(!printhelp) setRemainingToDefault(out);
+     119             : 
+     120        3719 :   if(printhelp) {
+     121             :     std::fprintf(out,"Usage: %s [options] \n\n", name.c_str() );
+     122           0 :     keywords.print( out );
+     123             :   }
+     124             : 
+     125        3719 :   return !printhelp;
+     126             : }
+     127             : 
+     128        3771 : void CLTool::setRemainingToDefault(FILE* out) {
+     129             :   std::string def, thiskey;
+     130       70213 :   for(unsigned k=0; k<keywords.size(); ++k) {
+     131       66442 :     thiskey=keywords.get(k);
+     132      132884 :     if( keywords.style(thiskey,"compulsory") ) {
+     133             :       if( inputData.count(thiskey)==0 ) {
+     134        1986 :         if( keywords.getDefaultValue(thiskey,def) ) {
+     135        1986 :           plumed_assert( def.length()>0 );
+     136        3972 :           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        3771 : }
+     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 000000000..e93872d3f --- /dev/null +++ b/coverage/core/CLTool.h.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253473.5 %
Date:2024-10-17 16:45:00Functions: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_939
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_987
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1858
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1972
_ZN4PLMD6CLToolD2Ev3837
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_27449
+
+
+ + + +
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 000000000..80ff1910d --- /dev/null +++ b/coverage/core/CLTool.h.func.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253473.5 %
Date:2024-10-17 16:45:00Functions: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_27449
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1972
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1858
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_987
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool5parseIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_939
_ZN4PLMD6CLTool5parseIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_40
_ZN4PLMD6CLToolD0Ev0
_ZN4PLMD6CLToolD2Ev3837
_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 000000000..37ac9f89e --- /dev/null +++ b/coverage/core/CLTool.h.gcov.html @@ -0,0 +1,241 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253473.5 %
Date:2024-10-17 16:45:00Functions: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        7694 : 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        3837 :   virtual ~CLTool() {}
+     100             : };
+     101             : 
+     102             : template<class T>
+     103       33325 : bool CLTool::parse(const std::string&key,T&t) {
+     104       33325 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     105       66650 :   if(keywords.style(key,"compulsory") ) {
+     106           0 :     if(inputData.count(key)==0) error("missing data for keyword " + key);
+     107        4806 :     bool check=Tools::convertNoexcept(inputData[key],t);
+     108        4806 :     if(!check) error("data input for keyword " + key + " has wrong type");
+     109             :     return true;
+     110             :   }
+     111       26284 :   if( inputData.count(key)==0 ) return false;
+     112        2235 :   Tools::convert(inputData[key],t);
+     113        2235 :   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 000000000..89e2bd662 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - core/CLToolMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11313484.3 %
Date:2024-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE5348
_ZN4PLMD10CLToolMainC2Ev5348
_ZN4PLMD10CLToolMainD0Ev5348
_ZN4PLMD10CLToolMainD2Ev5348
_ZN4PLMD10CLToolMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE16329
+
+
+ + + +
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 000000000..398f9fcca --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - core/CLToolMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11313484.3 %
Date:2024-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE16329
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE5348
_ZN4PLMD10CLToolMainC2Ev5348
_ZN4PLMD10CLToolMainD0Ev5348
_ZN4PLMD10CLToolMainD2Ev5348
+
+
+ + + +
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 000000000..95d82d4a3 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.gcov.html @@ -0,0 +1,363 @@ + + + + + + + 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:11313484.3 %
Date:2024-10-17 16:45:00Functions: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        5348 : CLToolMain::CLToolMain():
+      41        5348 :   argc(0),
+      42        5348 :   in(stdin),
+      43        5348 :   out(stdout)
+      44             : {
+      45        5348 : }
+      46             : 
+      47       10696 : CLToolMain::~CLToolMain() {
+      48             : // empty destructor to delete unique_ptr
+      49       10696 : }
+      50             : 
+      51             : #define CHECK_NULL(val,word) plumed_assert(val) << "NULL pointer received in cmd(\"CLTool " << word <<  "\"";
+      52             : 
+      53       16329 : 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       16329 :   };
+      64             : 
+      65             :   gch::small_vector<std::string_view> words;
+      66       16329 :   Tools::getWordsSimple(words,word);
+      67       16329 :   unsigned nw=words.size();
+      68       16329 :   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       16329 :     if(it!=word_map.end()) iword=it->second;
+      76       16329 :     switch(iword) {
+      77             :     case cmd_setArgc:
+      78        5264 :       CHECK_NULL(val,word);
+      79        5264 :       argc=val.get<int>();
+      80        5264 :       break;
+      81             :     case cmd_setArgv:
+      82        5264 :       CHECK_NULL(val,word);
+      83        5264 :       v=val.get<const char*const*>({argc});
+      84       34035 :       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          84 :       vv=val.getCString();
+      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         352 :     case cmd_setMPIComm:
+     100         352 :       comm.Set_comm(val);
+     101             :       break;
+     102           0 :     case cmd_setMPIFComm:
+     103           0 :       comm.Set_fcomm(val);
+     104             :       break;
+     105             :     case cmd_run:
+     106        5348 :       CHECK_NULL(val,word);
+     107        5348 :       argc=argv.size();
+     108             :       {
+     109       34607 :         int n=0; for(int i=0; i<argc; ++i) n+=argv[i].length()+1;
+     110        5348 :         std::vector<char> args(n);
+     111        5348 :         std::vector<char*> vvv(argc);
+     112             :         char* ptr=&args[0];
+     113       34607 :         for(int i=0; i<argc; ++i) {
+     114       29259 :           vvv[i]=ptr;
+     115      252829 :           for(unsigned c=0; c<argv[i].length(); ++c) {
+     116      223570 :             *ptr=argv[i][c]; ptr++;
+     117             :           }
+     118       29259 :           *ptr=0; ptr++;
+     119             :         }
+     120        5348 :         val.set(int(run(argc,&vvv[0],in,out,comm)));
+     121             :       }
+     122        5348 :       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       16329 : }
+     129             : 
+     130             : /**
+     131             : This is the entry point to the command line tools
+     132             : included in the plumed library.
+     133             : */
+     134             : 
+     135        5348 : int CLToolMain::run(int argc, char **argv,FILE*in,FILE*out,Communicator& pc) {
+     136             :   int i;
+     137             :   bool printhelp=false;
+     138             : 
+     139        5348 :   DLLoader dlloader;
+     140             : 
+     141        5348 :   std::string root=config::getPlumedRoot();
+     142             : 
+     143             :   bool standalone_executable=false;
+     144             : 
+     145             : // Start parsing options
+     146        5348 :   std::string prefix("");
+     147        5348 :   std::string a("");
+     148       10264 :   for(i=1; i<argc; i++) {
+     149       20528 :     a=prefix+argv[i];
+     150       10264 :     if(a.length()==0) continue;
+     151       30792 :     if(a=="help" || a=="-h" || a=="--help") {
+     152             :       printhelp=true;
+     153             :       break;
+     154       10260 :     } else if(a=="--has-mpi") {
+     155           0 :       if(Communicator::initialized()) return 0;
+     156           0 :       else return 1;
+     157       10260 :     } else if(a=="--has-cregex") {
+     158           0 :       return (config::hasCregex()?0:1);
+     159       10260 :     } else if(a=="--has-dlopen") {
+     160           0 :       return (config::hasDlopen()?0:1);
+     161       10260 :     } else if(a=="--has-molfile") {
+     162           0 :       return (config::hasMolfile()?0:1);
+     163       10260 :     } else if(a=="--has-external-molfile") {
+     164           0 :       return (config::hasExternalMolfile()?0:1);
+     165       10260 :     } else if(a=="--has-zlib") {
+     166           0 :       return (config::hasZlib()?0:1);
+     167       10260 :     } else if(a=="--has-xdrfile") {
+     168             :       return 0; // always ok
+     169       10260 :     } else if(a=="--is-installed") {
+     170         791 :       return (config::isInstalled()?0:1);
+     171        9469 :     } else if(a=="--no-mpi") {
+     172             : // this is ignored, as it is parsed in main
+     173        4896 :       continue;
+     174        4573 :     } else if(a=="--mpi") {
+     175             : // this is ignored, as it is parsed in main
+     176           0 :       continue;
+     177        4573 :     } else if(a=="--standalone-executable") {
+     178             :       standalone_executable=true;
+     179        9146 :     } else if(Tools::startWith(a,"--load=")) {
+     180          10 :       a.erase(0,a.find("=")+1);
+     181             :       prefix="";
+     182          10 :       dlloader.load(a);
+     183        4563 :     } else if(a=="--load") {
+     184             :       prefix="--load=";
+     185        4553 :     } 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        4557 :   if(!standalone_executable) {
+     194        4557 :     std::vector<std::string> files=Tools::ls(root);
+     195        4557 :     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        4557 :   }
+     201             : 
+     202             : // Build list of available C++ tools:
+     203        4557 :   std::vector<std::string> availableCxx=cltoolRegister().list();
+     204             : // Build list of available shell tools:
+     205             :   std::vector<std::string> availableShell;
+     206        4557 :   if(!standalone_executable) {
+     207             :     std::vector<std::string> tmp;
+     208        9114 :     tmp=Tools::ls(std::string(root+"/scripts"));
+     209       36456 :     for(unsigned j=0; j<tmp.size(); ++j) {
+     210       31899 :       size_t ff=tmp[j].find(".sh");
+     211       31899 :       if(ff==std::string::npos) tmp[j].erase();
+     212       31899 :       else                 tmp[j].erase(ff);
+     213             :     }
+     214       36456 :     for(unsigned j=0; j<tmp.size(); ++j) if(tmp[j].length()>0) availableShell.push_back(tmp[j]);
+     215        4557 :   }
+     216             : 
+     217        4557 :   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        4553 :   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        4553 :   std::string command(argv[i]);
+     259             : 
+     260        4553 :   if(find(availableCxx.begin(),availableCxx.end(),command)!=availableCxx.end()) {
+     261        7542 :     auto cl=cltoolRegister().create(dlloader.getHandles(),CLToolOptions(command));
+     262        3771 :     plumed_assert(cl);
+     263             :     // Read the command line options (returns false if we are just printing help)
+     264        3771 :     if( !cl->readInput( argc-i,&argv[i],in,out ) ) { return 0; }
+     265        3771 :     int ret=cl->main(in,out,pc);
+     266             :     return ret;
+     267        3771 :   }
+     268             : 
+     269         782 :   if(find(availableShell.begin(),availableShell.end(),command)!=availableShell.end()) {
+     270         782 :     plumed_massert(in==stdin,"shell tools can only work on stdin");
+     271         782 :     plumed_massert(out==stdout,"shell tools can only work on stdin");
+     272        1564 :     std::string cmd=config::getEnvCommand()+" \""+root+"/scripts/"+command+".sh\"";
+     273        2996 :     for(int j=i+1; j<argc; j++) cmd+=std::string(" ")+argv[j];
+     274         782 :     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         782 :     if(r!=0) return 1;
+     279         666 :     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        9905 : }
+     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 000000000..ae3bb3ed0 --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:183452.9 %
Date:2024-10-17 16:45:00Functions: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_13CLToolOptionsE3847
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev4557
_ZN4PLMD14CLToolRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS8_EERKNS_13CLToolOptionsEEPFvRNS_8KeywordsEE100729
_ZN4PLMD14cltoolRegisterEv210302
+
+
+ + + +
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 000000000..0b2ac679a --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:183452.9 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsEE100729
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE0
_ZN4PLMD14CLToolRegister6createERKSt6vectorIPvSaIS2_EERKNS_13CLToolOptionsE3847
_ZN4PLMD14cltoolRegisterEv210302
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev4557
_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 000000000..ba71a022d --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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:183452.9 %
Date:2024-10-17 16:45:00Functions: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      210302 : CLToolRegister& cltoolRegister() {
+      32      215603 :   static CLToolRegister ans;
+      33      210302 :   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        3847 : std::unique_ptr<CLTool> CLToolRegister::create(const std::vector<void*> & images,const CLToolOptions&ao) try {
+      42        3847 :   if(ao.line.size()<1)return nullptr;
+      43        3847 :   auto & content=get(images,ao.line[0]);
+      44        3847 :   CLToolOptions nao( ao,content.keys );
+      45        3847 :   return content.create(nao);
+      46           0 : } catch (PLMD::ExceptionRegisterError &e ) {
+      47             :   auto& toolName = e.getMissingKey();
+      48           0 :   throw e <<"CL tool \"" << toolName << "\" is not known.";
+      49           0 : }
+      50             : 
+      51      100729 : CLToolRegister::ID CLToolRegister::add(std::string key,creator_pointer cp,keywords_pointer kp) {
+      52             :   // this force each action to be registered as an uppercase string
+      53      434712 :   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";
+      54             : 
+      55      100729 :   Keywords keys; kp(keys);
+      56      302187 :   return RegisterBase::add(key,Pointers{cp,keys});
+      57      100729 : }
+      58             : 
+      59           1 : bool CLToolRegister::printManual( const std::string& cltool, const bool& spelling ) {
+      60           1 :   if( spelling && check(cltool) ) {
+      61           0 :     auto cl=get(cltool);
+      62           0 :     cl.keys.print_spelling();
+      63             :     return true;
+      64           1 :   } else if ( check(cltool) ) {
+      65           0 :     auto cl=get(cltool);
+      66           0 :     cl.keys.print_html();
+      67             :     return true;
+      68             :   } else {
+      69             :     return false;
+      70             :   }
+      71             : }
+      72             : 
+      73           0 : std::vector<std::string> CLToolRegister::getKeys(const std::string& cltool)const {
+      74           0 :   if ( check(cltool) ) {
+      75           0 :     auto cl=get(cltool);
+      76             :     auto k=cl.keys.getKeys();
+      77           0 :     std::cerr<<k.size()<<"\n";
+      78           0 :     for(unsigned i=0; i<k.size(); i++) std::cerr<<k[i]<<"\n";
+      79             :     return k;
+      80           0 :   } else {
+      81             :     std::vector<std::string> empty;
+      82             :     return empty;
+      83           0 :   }
+      84             : }
+      85             : 
+      86             : 
+      87        4557 : std::vector<std::string> CLToolRegister::list()const {
+      88        4557 :   return RegisterBase::getKeys();
+      89             : }
+      90             : 
+      91             : }
+
+
+
+ + + + +
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 000000000..d6c5c785b --- /dev/null +++ b/coverage/core/CLToolRegister.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2976807c9 --- /dev/null +++ b/coverage/core/CLToolRegister.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d6cfbc299 --- /dev/null +++ b/coverage/core/CLToolRegister.h.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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-10-17 16:45:00Functions: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      402906 : 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        5301 : 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 000000000..cfd194392 --- /dev/null +++ b/coverage/core/Colvar.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE2158
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2591
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE6302
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE112014
_ZN4PLMD6Colvar5applyEv142194
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS1_IS5_SaIS5_EERS1_INS_13TensorGenericILj3ELj3EEESaISC_EE452846
+
+
+ + + +
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 000000000..045584164 --- /dev/null +++ b/coverage/core/Colvar.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2591
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE6302
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE112014
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS1_IS5_SaIS5_EERS1_INS_13TensorGenericILj3ELj3EEESaISC_EE452846
_ZN4PLMD6Colvar5applyEv142194
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE2158
+
+
+ + + +
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 000000000..8f4866906 --- /dev/null +++ b/coverage/core/Colvar.cpp.gcov.html @@ -0,0 +1,149 @@ + + + + + + + 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-10-17 16:45:00Functions: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        2158 : Colvar::Colvar(const ActionOptions&ao):
+      30             :   Action(ao),
+      31             :   ActionAtomistic(ao),
+      32        2158 :   ActionWithValue(ao)
+      33             : {
+      34        2158 : }
+      35             : 
+      36        6302 : void Colvar::registerKeywords( Keywords& keys ) {
+      37        6302 :   Action::registerKeywords( keys );
+      38        6302 :   ActionWithValue::registerKeywords( keys );
+      39        6302 :   ActionAtomistic::registerKeywords( keys );
+      40       12604 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      41        6302 : }
+      42             : 
+      43        2591 : void Colvar::requestAtoms(const std::vector<AtomNumber> & a) {
+      44             : // Tell actionAtomistic what atoms we are getting
+      45        2591 :   ActionAtomistic::requestAtoms(a);
+      46             : // Resize the derivatives of all atoms
+      47        6677 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
+      48        2590 : }
+      49             : 
+      50      142194 : void Colvar::apply() {
+      51      142194 :   if( !checkForForces() ) return ;
+      52      108651 :   unsigned ind=0;
+      53      108651 :   if( getNumberOfAtoms()>0 ) setForcesOnAtoms( getForcesToApply(), ind );
+      54          88 :   else setForcesOnCell( getForcesToApply(), ind );
+      55             : }
+      56             : 
+      57      452846 : void Colvar::setBoxDerivativesNoPbc( const std::vector<Vector>& pos, std::vector<std::vector<Vector> >& derivs, std::vector<Tensor>& virial ) {
+      58      452846 :   unsigned nat=pos.size();
+      59     1118062 :   for(unsigned i=0; i<virial.size(); ++i) {
+      60     2180803 :     virial[i].zero(); for(unsigned j=0; j<nat; j++) virial[i]-=Tensor(pos[j],derivs[i][j]);
+      61             :   }
+      62      452846 : }
+      63             : 
+      64      112014 : void Colvar::setBoxDerivativesNoPbc(Value* v) {
+      65      112014 :   Tensor virial;
+      66             :   unsigned nat=getNumberOfAtoms();
+      67    32947498 :   for(unsigned i=0; i<nat; i++) virial-=Tensor(getPosition(i),
+      68    16417742 :                                           Vector(v->getDerivative(3*i+0),
+      69             :                                               v->getDerivative(3*i+1),
+      70    32835484 :                                               v->getDerivative(3*i+2)));
+      71      112014 :   setBoxDerivatives(v,virial);
+      72      112014 : }
+      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 000000000..b58575def --- /dev/null +++ b/coverage/core/Colvar.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarD2Ev2118
_ZN4PLMD6Colvar22getNumberOfDerivativesEv149155
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE262504
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18276419
+
+
+ + + +
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 000000000..370ddf7c9 --- /dev/null +++ b/coverage/core/Colvar.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE262504
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18276419
_ZN4PLMD6Colvar22getNumberOfDerivativesEv149155
_ZN4PLMD6ColvarD2Ev2118
+
+
+ + + +
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 000000000..825cee682 --- /dev/null +++ b/coverage/core/Colvar.h.gcov.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - core/Colvar.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-10-17 16:45:00Functions: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        2118 :   ~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    18276419 : void Colvar::setAtomsDerivatives(Value*v,int i,const Vector&d) {
+      74    18276419 :   v->addDerivative(3*i+0,d[0]);
+      75    18276419 :   v->addDerivative(3*i+1,d[1]);
+      76    18276419 :   v->addDerivative(3*i+2,d[2]);
+      77    18276419 : }
+      78             : 
+      79             : 
+      80             : inline
+      81      262504 : void Colvar::setBoxDerivatives(Value* v,const Tensor&d) {
+      82             :   unsigned nat=getNumberOfAtoms();
+      83      262504 :   v->addDerivative(3*nat+0,d(0,0));
+      84      262504 :   v->addDerivative(3*nat+1,d(0,1));
+      85      262504 :   v->addDerivative(3*nat+2,d(0,2));
+      86      262504 :   v->addDerivative(3*nat+3,d(1,0));
+      87      262504 :   v->addDerivative(3*nat+4,d(1,1));
+      88      262504 :   v->addDerivative(3*nat+5,d(1,2));
+      89      262504 :   v->addDerivative(3*nat+6,d(2,0));
+      90      262504 :   v->addDerivative(3*nat+7,d(2,1));
+      91      262504 :   v->addDerivative(3*nat+8,d(2,2));
+      92      262504 : }
+      93             : 
+      94             : inline
+      95             : void Colvar::setAtomsDerivatives(int i,const Vector&d) {
+      96    16464001 :   setAtomsDerivatives(getPntrToValue(),i,d);
+      97             : }
+      98             : 
+      99             : inline
+     100             : void Colvar::setBoxDerivatives(const Tensor&d) {
+     101      123118 :   setBoxDerivatives(getPntrToValue(),d);
+     102        2010 : }
+     103             : 
+     104             : inline
+     105             : void Colvar::setBoxDerivativesNoPbc() {
+     106       42244 :   setBoxDerivativesNoPbc(getPntrToValue());
+     107         222 : }
+     108             : 
+     109             : inline
+     110      149155 : unsigned Colvar::getNumberOfDerivatives() {
+     111      149155 :   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 000000000..b4cf52e83 --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.func-sort-c.html @@ -0,0 +1,188 @@ + + + + + + + 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:687491.9 %
Date:2024-10-17 16:45:00Functions: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_11TypesafePtrE5073
_ZN4PLMD17DataPassingObject6createEj8412
_ZN4PLMD22DataPassingObjectTypedIdE7setDataEPNS_5ValueE12447
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceEPNS_5ValueE39698
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE61896
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE69945
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE79580
_ZN4PLMDL10getPointerIdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_193028
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKjS3_PNS_5ValueE239748
_ZN4PLMD22DataPassingObjectTypedIdE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE281875
_ZN4PLMDL10getPointerIKdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_303700
_ZN4PLMD22DataPassingObjectTypedIdE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb445981
+
+
+ + + +
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 000000000..29ce1508a --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.func.html @@ -0,0 +1,188 @@ + + + + + + + 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:687491.9 %
Date:2024-10-17 16:45:00Functions:142948.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17DataPassingObject6createEj8412
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE69945
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKjS3_PNS_5ValueE239748
_ZN4PLMD22DataPassingObjectTypedIdE13rescale_forceERKjRKdPNS_5ValueE150
_ZN4PLMD22DataPassingObjectTypedIdE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE281875
_ZN4PLMD22DataPassingObjectTypedIdE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb445981
_ZN4PLMD22DataPassingObjectTypedIdE17saveValueAsDoubleERKNS_11TypesafePtrE5073
_ZN4PLMD22DataPassingObjectTypedIdE7setDataEPNS_5ValueE12447
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceEPNS_5ValueE39698
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE61896
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE79580
_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_303700
_ZN4PLMDL10getPointerIKfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_0
_ZN4PLMDL10getPointerIdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_193028
_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 000000000..31e60bd83 --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + 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:687491.9 %
Date:2024-10-17 16:45:00Functions: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      496728 : static void getPointer(const TypesafePtr & p, const std::vector<unsigned>& shape, const unsigned& start, const unsigned& stride, T*&pp ) {
+      30      496728 :   if( shape.size()==1 && stride==1 ) { pp=p.get<T*>( {shape[0]} );  }
+      31      459562 :   else if( shape.size()==1 ) { auto p_=p.get<T*>( {shape[0],stride} ); pp = p_+start; }
+      32      105952 :   else if( shape.size()==2 ) { pp=p.get<T*>( {shape[0],shape[1]} ); }
+      33      496710 : }
+      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        8412 : std::unique_ptr<DataPassingObject> DataPassingObject::create(unsigned n) {
+      69        8412 :   if(n==sizeof(double)) {
+      70        8412 :     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        5073 : void DataPassingObjectTyped<T>::saveValueAsDouble( const TypesafePtr & val ) {
+      86        5073 :   hasbackup=true; bvalue=double(val.template get<T>());
+      87        5073 : }
+      88             : 
+      89             : template <class T>
+      90      445981 : void DataPassingObjectTyped<T>::setValuePointer( const TypesafePtr & val, const std::vector<unsigned>& shape, const bool& isconst ) {
+      91      445981 :   if( shape.size()==0 ) {
+      92      354234 :     if( isconst ) val.get<const T*>(); else val.get<T*>();  // just check type and discard pointer
+      93       91747 :   } else if( shape.size()==1 ) {
+      94       23470 :     if( isconst ) val.get<const T*>({shape[0]}); else val.get<T*>({shape[0]});  // just check type and discard pointer
+      95       68277 :   } else if( shape.size()==2 ) {
+      96       68277 :     if( isconst ) val.get<const T*>({shape[0],shape[1]}); else val.get<T*>({shape[0],shape[1]});  // just check type and discard pointer
+      97             :   }
+      98      445980 :   v=val.copy();
+      99      445980 : }
+     100             : 
+     101             : template <class T>
+     102      281875 : void DataPassingObjectTyped<T>::setForcePointer( const TypesafePtr & val, const std::vector<unsigned>& shape ) {
+     103      281875 :   if( shape.size()==0 ) val.get<T*>();  // just check type and discard pointer
+     104       64588 :   else if( shape.size()==1 ) val.get<T*>({shape[0]});   // just check type and discard pointer
+     105       64588 :   else if( shape.size()==2 ) val.get<T*>({shape[0],shape[1]});   // just check type and discard pointer
+     106      281859 :   f=val.copy();
+     107      281857 : }
+     108             : 
+     109             : template <class T>
+     110       12447 : void DataPassingObjectTyped<T>::setData( Value* value ) {
+     111       12447 :   if( value->getRank()==0 ) { *v.template get<T*>() = static_cast<T>(value->get()) / unit; return; }
+     112       11744 :   T* pp; getPointer( v, value->getShape(), start, stride, pp ); unsigned nvals=value->getNumberOfValues();
+     113      429326 :   for(unsigned i=0; i<nvals; ++i) pp[i] = T( value->get(i) );
+     114             : }
+     115             : 
+     116             : template <class T>
+     117      239748 : void DataPassingObjectTyped<T>::share_data( const unsigned& j, const unsigned& k, Value* value ) {
+     118      239748 :   if( value->getRank()==0 ) {
+     119        7343 :     if( hasbackup ) value->set( unit*bvalue );
+     120          72 :     else value->set( unit*double(v.template get<T>()) );
+     121        7343 :     return;
+     122             :   }
+     123      232405 :   std::vector<unsigned> s(value->getShape()); if( s.size()==1 ) s[0]=k-j;
+     124      232405 :   const T* pp; getPointer( v, s, start, stride, pp );
+     125      232389 :   std::vector<double> & d=value->data;
+     126      232389 :   #pragma omp parallel for num_threads(value->getGoodNumThreads(j,k))
+     127             :   for(unsigned i=j; i<k; ++i) d[i]=unit*pp[i*stride];
+     128             : }
+     129             : 
+     130             : template <class T>
+     131        1350 : void DataPassingObjectTyped<T>::share_data( std::vector<double>& values ) const {
+     132        1350 :   std::vector<unsigned> maxel(1,values.size()); const T* pp; getPointer( v, maxel, start, stride, pp );
+     133        1350 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(values))
+     134             :   for(unsigned i=0; i<values.size(); ++i) values[i]=unit*pp[i*stride];
+     135        1350 : }
+     136             : 
+     137             : template <class T>
+     138       69945 : void DataPassingObjectTyped<T>::share_data( const std::vector<AtomNumber>&index, const std::vector<unsigned>& i, Value* value ) {
+     139       69945 :   plumed_dbg_assert( value->getRank()==1 ); std::vector<unsigned> maxel(1,index.size());
+     140             : #ifndef NDEBUG
+     141             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     142             :   maxel[0]=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     143             : #else
+     144       69945 :   maxel[0]=0;
+     145             : #endif
+     146       69945 :   const T* pp; getPointer( v, maxel, start, stride, pp );
+     147             :   // cannot be parallelized with omp because access to data is not ordered
+     148     2461207 :   unsigned k=0; for(const auto & p : index) { value->data[p.index()]=unit*pp[i[k]*stride]; k++; }
+     149       69945 : }
+     150             : 
+     151             : template <class T>
+     152       39698 : void DataPassingObjectTyped<T>::add_force( Value* value ) {
+     153       39698 :   if( value->getRank()==0 ) { *f.template get<T*>() += funit*static_cast<T>(value->getForce(0)); return; }
+     154       39658 :   T* pp; getPointer( f, value->getShape(), start, stride, pp ); unsigned nvals=value->getNumberOfValues();
+     155       39658 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(pp,nvals))
+     156             :   for(unsigned i=0; i<nvals; ++i) pp[i*stride] += funit*T(value->getForce(i));
+     157             : }
+     158             : 
+     159             : template <class T>
+     160       79580 : void DataPassingObjectTyped<T>::add_force( const std::vector<int>& index, Value* value ) {
+     161       79580 :   plumed_assert( value->getRank()==1 ); std::vector<unsigned> s(1,index.size()); T* pp; getPointer( f, s, start, stride, pp );
+     162       79578 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(pp,index.size()))
+     163             :   for(unsigned i=0; i<index.size(); ++i) pp[i*stride] += funit*T(value->getForce(index[i]));
+     164       79578 : }
+     165             : 
+     166             : template <class T>
+     167       61896 : void DataPassingObjectTyped<T>::add_force( const std::vector<AtomNumber>& index, const std::vector<unsigned>& i, Value* value ) {
+     168       61896 :   plumed_dbg_assert( value->getRank()==1 ); std::vector<unsigned> maxel(1,index.size());
+     169             : #ifndef NDEBUG
+     170             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     171             :   maxel[0]=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     172             : #else
+     173       61896 :   maxel[0]=0;
+     174             : #endif
+     175       61896 :   T* pp; getPointer( f, maxel, start, stride, pp );
+     176     1835196 :   unsigned k=0; for(const auto & p : index) { pp[stride*i[k]] += funit*T(value->getForce(p.index())); k++; }
+     177       61896 : }
+     178             : 
+     179             : template <class T>
+     180         150 : void DataPassingObjectTyped<T>::rescale_force( const unsigned& n, const double& factor, Value* value ) {
+     181         150 :   plumed_assert( value->getRank()>0 ); std::vector<unsigned> s( value->getShape() ); if( s.size()==1 ) s[0] = n;
+     182         150 :   T* pp; getPointer( f, s, start, stride, pp );
+     183         150 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(pp,n))
+     184             :   for(unsigned i=0; i<n; ++i) pp[i*stride] *= T(factor);
+     185         150 : }
+     186             : 
+     187             : }
+
+
+
+ + + + +
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 000000000..a30d98521 --- /dev/null +++ b/coverage/core/DataPassingObject.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ae4e60c9f --- /dev/null +++ b/coverage/core/DataPassingObject.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..bc11b68cf --- /dev/null +++ b/coverage/core/DataPassingObject.h.gcov.html @@ -0,0 +1,162 @@ + + + + + + + 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-10-17 16:45:00Functions: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      449854 :   void setStart( const unsigned& s ) { start=s; }
+      56             : /// Set the stride to use when getting data from the input array
+      57      449854 :   void setStride( const unsigned& s ) { stride=s; }
+      58             : /// Set the unit for the value
+      59        9588 :   void setUnit( const double& u ) { unit=u; }
+      60             : /// Set the unit for the force
+      61        9588 :   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 000000000..4b84c43a4 --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD21DataPassingToolsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD21DataPassingToolsTypedIfE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD21DataPassingToolsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
_ZNK4PLMD21DataPassingToolsTypedIdE9MD2doubleERKNS_11TypesafePtrE2910
_ZNK4PLMD21DataPassingToolsTypedIdE9double2MDERKdRKNS_11TypesafePtrE7268
_ZNK4PLMD21DataPassingToolsTypedIdE16getRealPrecisionEv10719
_ZNK4PLMD16DataPassingTools17getUnitConversionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26398
_ZN4PLMD16DataPassingTools6createEj807720
+
+
+ + + +
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 000000000..1a1cf2f45 --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16DataPassingTools6createEj807720
_ZNK4PLMD16DataPassingTools17getUnitConversionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26398
_ZNK4PLMD21DataPassingToolsTypedIdE16getRealPrecisionEv10719
_ZNK4PLMD21DataPassingToolsTypedIdE9MD2doubleERKNS_11TypesafePtrE2910
_ZNK4PLMD21DataPassingToolsTypedIdE9double2MDERKdRKNS_11TypesafePtrE7268
_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 000000000..17f2dcd2e --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + 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-10-17 16:45:00Functions: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       26398 : double DataPassingTools::getUnitConversion( const std::string& unit ) const {
+      29       26398 :   if( unit=="energy" ) return MDUnits.getEnergy()/units.getEnergy();
+      30        9423 :   if( unit=="length" ) return MDUnits.getLength()/units.getLength();
+      31        4523 :   if( unit=="mass" ) return  MDUnits.getMass()/units.getMass();
+      32        3298 :   if( unit=="charge" ) return MDUnits.getCharge()/units.getCharge();
+      33        2073 :   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      807720 : 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      807720 : std::unique_ptr<DataPassingTools> DataPassingTools::create(unsigned n) {
+      47      807720 :   if(n==sizeof(double)) {
+      48      807719 :     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       10719 : int DataPassingToolsTyped<T>::getRealPrecision() const {
+      59       10719 :   return sizeof(T);
+      60             : }
+      61             : 
+      62             : template <class T>
+      63        2910 : double DataPassingToolsTyped<T>::MD2double(const TypesafePtr & m) const {
+      64        2910 :   return double(m.template get<T>());
+      65             : }
+      66             : 
+      67             : template <class T>
+      68        7269 : void DataPassingToolsTyped<T>::double2MD(const double&d,const TypesafePtr & m) const {
+      69        7269 :   m.set(T(d));
+      70        7269 : }
+      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 000000000..ad9e5ad60 --- /dev/null +++ b/coverage/core/DataPassingTools.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16DataPassingToolsD0Ev0
_ZN4PLMD16DataPassingToolsD2Ev807720
+
+
+ + + +
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 000000000..9e93053a5 --- /dev/null +++ b/coverage/core/DataPassingTools.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16DataPassingToolsD0Ev0
_ZN4PLMD16DataPassingToolsD2Ev807720
+
+
+ + + +
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 000000000..ad82ced2b --- /dev/null +++ b/coverage/core/DataPassingTools.h.gcov.html @@ -0,0 +1,130 @@ + + + + + + + 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-10-17 16:45:00Functions: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      807720 :   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 000000000..95496d6da --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.func-sort-c.html @@ -0,0 +1,204 @@ + + + + + + + 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:26428094.3 %
Date:2024-10-17 16:45:00Functions:313393.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecompositionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD19DomainDecomposition26getNumberOfForcesToRescaleEv0
_ZN4PLMD19DomainDecomposition10readBinaryERSi114
_ZN4PLMD19DomainDecomposition11writeBinaryERSo114
_ZN4PLMD19DomainDecomposition11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition13clearFullListEv116
_ZN4PLMD19DomainDecomposition14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition11DomainComms6enableERNS_12CommunicatorE393
_ZN4PLMD19DomainDecomposition8Set_commERNS_12CommunicatorE393
_ZNK4PLMD19DomainDecomposition11getGatindexEv459
_ZN4PLMD19DomainDecomposition18setAtomsContiguousEi545
_ZN4PLMD12_GLOBAL__N_118interpretEnvStringEPKcS2_731
_ZNK4PLMD19DomainDecomposition9getDdStepEv900
_ZN4PLMD19DomainDecomposition16setAtomsGatindexERKNS_11TypesafePtrEb988
_ZN4PLMD19DomainDecompositionC1ERKNS_13ActionOptionsE1192
_ZN4PLMD19DomainDecomposition16registerKeywordsERNS_8KeywordsE1194
_ZN4PLMD19DomainDecomposition8shareAllEv1218
_ZN4PLMD19DomainDecomposition14setAtomsNlocalEi1533
_ZN4PLMD19DomainDecomposition17getAllActiveAtomsERSt6vectorINS_10AtomNumberESaIS2_EE2183
_ZN4PLMD19DomainDecomposition14sumOverDomainsEPNS_5ValueE3989
_ZN4PLMD19DomainDecomposition18broadcastToDomainsEPNS_5ValueE66396
_ZN4PLMD12_GLOBAL__N_117getenvForceUniqueEv69715
_ZN4PLMD19DomainDecomposition5resetEv70078
_ZN4PLMD19DomainDecomposition5applyEv70080
_ZN4PLMD19DomainDecomposition4waitEv70204
_ZN4PLMD19DomainDecomposition5shareERKSt6vectorINS_10AtomNumberESaIS2_EE70228
_ZN4PLMD19DomainDecomposition5shareEv70819
_ZN4PLMD19DomainDecomposition17resetForStepStartEv72431
_ZN4PLMD19DomainDecomposition15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE217287
_ZN4PLMD19DomainDecomposition8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj354106
_ZN4PLMD19DomainDecomposition9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj354106
_ZN4PLMD19DomainDecomposition15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE358128
_ZNK4PLMD19DomainDecomposition16getNumberOfAtomsEv536231
+
+
+ + + +
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 000000000..0f63b294c --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.func.html @@ -0,0 +1,204 @@ + + + + + + + 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:26428094.3 %
Date:2024-10-17 16:45:00Functions:313393.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_117getenvForceUniqueEv69715
_ZN4PLMD12_GLOBAL__N_118interpretEnvStringEPKcS2_731
_ZN4PLMD19DomainDecomposition10readBinaryERSi114
_ZN4PLMD19DomainDecomposition11DomainComms6enableERNS_12CommunicatorE393
_ZN4PLMD19DomainDecomposition11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition11writeBinaryERSo114
_ZN4PLMD19DomainDecomposition13clearFullListEv116
_ZN4PLMD19DomainDecomposition14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition14setAtomsNlocalEi1533
_ZN4PLMD19DomainDecomposition14sumOverDomainsEPNS_5ValueE3989
_ZN4PLMD19DomainDecomposition15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE217287
_ZN4PLMD19DomainDecomposition15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE358128
_ZN4PLMD19DomainDecomposition16registerKeywordsERNS_8KeywordsE1194
_ZN4PLMD19DomainDecomposition16setAtomsGatindexERKNS_11TypesafePtrEb988
_ZN4PLMD19DomainDecomposition17getAllActiveAtomsERSt6vectorINS_10AtomNumberESaIS2_EE2183
_ZN4PLMD19DomainDecomposition17resetForStepStartEv72431
_ZN4PLMD19DomainDecomposition18broadcastToDomainsEPNS_5ValueE66396
_ZN4PLMD19DomainDecomposition18setAtomsContiguousEi545
_ZN4PLMD19DomainDecomposition4waitEv70204
_ZN4PLMD19DomainDecomposition5applyEv70080
_ZN4PLMD19DomainDecomposition5resetEv70078
_ZN4PLMD19DomainDecomposition5shareERKSt6vectorINS_10AtomNumberESaIS2_EE70228
_ZN4PLMD19DomainDecomposition5shareEv70819
_ZN4PLMD19DomainDecomposition8Set_commERNS_12CommunicatorE393
_ZN4PLMD19DomainDecomposition8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj354106
_ZN4PLMD19DomainDecomposition8shareAllEv1218
_ZN4PLMD19DomainDecomposition9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj354106
_ZN4PLMD19DomainDecompositionC1ERKNS_13ActionOptionsE1192
_ZN4PLMD19DomainDecompositionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD19DomainDecomposition11getGatindexEv459
_ZNK4PLMD19DomainDecomposition16getNumberOfAtomsEv536231
_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 000000000..d803e5c1d --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.gcov.html @@ -0,0 +1,578 @@ + + + + + + + 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:26428094.3 %
Date:2024-10-17 16:45:00Functions: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         731 : Option interpretEnvString(const char* env,const char* str) {
+      48         731 :   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       69715 : Option getenvForceUnique() {
+      65             :   static const char* name="PLUMED_FORCE_UNIQUE";
+      66       69715 :   static const auto opt = interpretEnvString(name,std::getenv(name));
+      67       69715 :   return opt;
+      68             : }
+      69             : 
+      70             : }
+      71             : 
+      72             : PLUMED_REGISTER_ACTION(DomainDecomposition,"DOMAIN_DECOMPOSITION")
+      73             : 
+      74         393 : void DomainDecomposition::DomainComms::enable(Communicator& c) {
+      75         393 :   on=true;
+      76         393 :   Set_comm(c.Get_comm());
+      77         393 :   async=Get_size()<10;
+      78         393 :   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         393 : }
+      85             : 
+      86        1194 : void DomainDecomposition::registerKeywords(Keywords& keys) {
+      87        1194 :   ActionForInterface::registerKeywords( keys ); keys.remove("ROLE");
+      88        2388 :   keys.add("compulsory","NATOMS","the number of atoms across all the domains");
+      89        2388 :   keys.add("numbered","VALUE","value to create for the domain decomposition");
+      90        2388 :   keys.add("numbered","UNIT","unit of the ith value that is being passed through the domain decomposition");
+      91        2388 :   keys.add("numbered","CONSTANT","is the ith value that is being passed through the domain decomposition constant");
+      92        2388 :   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        2388 :   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        2388 :   keys.add("compulsory","PBCLABEL","Box","the label to use for the PBC action that will be created");
+      97        1194 :   keys.setValueDescription("the domain that each atom is within");
+      98        1194 : }
+      99             : 
+     100        1192 : DomainDecomposition::DomainDecomposition(const ActionOptions&ao):
+     101             :   Action(ao),
+     102             :   ActionForInterface(ao),
+     103        1192 :   ddStep(0),
+     104        1192 :   shuffledAtoms(0),
+     105        1192 :   asyncSent(false),
+     106        1192 :   unique_serial(false)
+     107             : {
+     108             :   // Read in the number of atoms
+     109        2384 :   int natoms; parse("NATOMS",natoms);
+     110        1192 :   std::string str_natoms; Tools::convert( natoms, str_natoms );
+     111             :   // Setup the gat index
+     112     9190557 :   gatindex.resize(natoms); for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=i;
+     113             :   // Now read in the values we are creating here
+     114        5960 :   for(unsigned i=1;; ++i) {
+     115             :     std::string valname;
+     116       14304 :     if( !parseNumbered("VALUE",i,valname) ) break;
+     117       11920 :     std::string unit; parseNumbered("UNIT",i,unit);
+     118       11920 :     std::string constant; parseNumbered("CONSTANT",i,constant);
+     119       11920 :     std::string period; parseNumbered("PERIODIC",i,period);
+     120       11920 :     std::string role; parseNumbered("ROLE",i,role);
+     121        8344 :     if( constant=="True") plumed.readInputLine( valname + ": PUT FROM_DOMAINS CONSTANT SHAPE=" + str_natoms + " UNIT=" + unit + " PERIODIC=" + period + " ROLE=" + role, true );
+     122        7152 :     else if( constant=="False") plumed.readInputLine( valname + ": PUT FROM_DOMAINS SHAPE=" + str_natoms + " UNIT=" + unit + " PERIODIC=" + period + " ROLE=" + role, true );
+     123           0 :     else plumed_merror("missing information on whether value is constant");
+     124             :     // And save the list of values that are set from here
+     125        5960 :     ActionToPutData* ap=plumed.getActionSet().selectWithLabel<ActionToPutData*>(valname); ap->addDependency( this ); inputs.push_back( ap );
+     126        5960 :   }
+     127        2384 :   std::string pbclabel; parse("PBCLABEL",pbclabel); plumed.readInputLine(pbclabel + ": PBC",true);
+     128             :   // Turn on the domain decomposition
+     129        1192 :   if( Communicator::initialized() ) Set_comm(comm);
+     130        1192 : }
+     131             : 
+     132         393 : void DomainDecomposition::Set_comm(Communicator& comm) {
+     133         393 :   dd.enable(comm); setAtomsNlocal(getNumberOfAtoms()); setAtomsContiguous(0);
+     134         393 :   if( dd.Get_rank()!=0 ) {
+     135         284 :     ActionToPutData* ap=plumed.getActionSet().selectWithLabel<ActionToPutData*>("Box"); ap->noforce=true;
+     136             :   }
+     137         393 : }
+     138             : 
+     139      536231 : unsigned DomainDecomposition::getNumberOfAtoms() const {
+     140      536231 :   if( inputs.size()==0 ) return 0;
+     141      536231 :   return (inputs[0]->getPntrToValue())->getShape()[0];
+     142             : }
+     143             : 
+     144       72431 : void DomainDecomposition::resetForStepStart() {
+     145      434586 :   for(const auto & pp : inputs) pp->resetForStepStart();
+     146       72431 : }
+     147             : 
+     148      354106 : void DomainDecomposition::setStart( const std::string& name, const unsigned& sss) {
+     149     1046051 :   for(const auto & pp : inputs) {
+     150     1046051 :     if( pp->getLabel()==name ) { pp->setStart(name, sss); return; }
+     151             :   }
+     152           0 :   plumed_error();
+     153             : }
+     154             : 
+     155      354106 : void DomainDecomposition::setStride( const std::string& name, const unsigned& sss) {
+     156     1046051 :   for(const auto & pp : inputs) {
+     157     1046051 :     if( pp->getLabel()==name ) { pp->setStride(name, sss); return; }
+     158             :   }
+     159           0 :   plumed_error();
+     160             : }
+     161             : 
+     162      358128 : bool DomainDecomposition::setValuePointer( const std::string& name, const TypesafePtr & val ) {
+     163      358128 :   wasset=true;  // Once the domain decomposition stuff is transferred moved the setting of this to where the g2l vector is setup
+     164     1070177 :   for(const auto & pp : inputs) {
+     165     1066158 :     if( pp->setValuePointer( name, val ) ) return true;
+     166             :   }
+     167             :   return false;
+     168             : }
+     169             : 
+     170      217287 : bool DomainDecomposition::setForcePointer( const std::string& name, const TypesafePtr & val ) {
+     171      434694 :   for(const auto & pp : inputs) {
+     172      434664 :     if( pp->setForcePointer( name, val ) ) return true;
+     173             :   }
+     174             :   return false;
+     175             : }
+     176             : 
+     177        1533 : void DomainDecomposition::setAtomsNlocal(int n) {
+     178        1533 :   gatindex.resize(n);
+     179        1533 :   g2l.resize(getNumberOfAtoms(),-1);
+     180        1533 :   if(dd) {
+     181             : // Since these vectors are sent with MPI by using e.g.
+     182             : // &dd.positionsToBeSent[0]
+     183             : // we make sure they are non-zero-sized so as to
+     184             : // avoid errors when doing boundary check
+     185        1509 :     if(n==0) n++;
+     186        1509 :     std::size_t nvals = inputs.size(), natoms = getNumberOfAtoms();
+     187        1509 :     dd.positionsToBeSent.resize(n*nvals,0.0);
+     188        1509 :     dd.positionsToBeReceived.resize(natoms*nvals,0.0);
+     189        1509 :     dd.indexToBeSent.resize(n,0);
+     190        1509 :     dd.indexToBeReceived.resize(natoms,0);
+     191             :   }
+     192        1533 : }
+     193             : 
+     194         988 : void DomainDecomposition::setAtomsGatindex(const TypesafePtr & g,bool fortran) {
+     195         988 :   plumed_massert( g || gatindex.size()==0, "NULL gatindex pointer with non-zero local atoms");
+     196         988 :   auto gg=g.get<const int*>({gatindex.size()});
+     197         988 :   ddStep=getStep();
+     198         988 :   if(fortran) {
+     199           0 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i]-1;
+     200             :   } else {
+     201       22140 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i];
+     202             :   }
+     203       57530 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     204         988 :   if( gatindex.size()==getNumberOfAtoms() ) {
+     205           9 :     shuffledAtoms=0;
+     206        1005 :     for(unsigned i=0; i<gatindex.size(); i++) {
+     207         996 :       if( gatindex[i]!=i ) { shuffledAtoms=1; break; }
+     208             :     }
+     209             :   } else {
+     210         979 :     shuffledAtoms=1;
+     211             :   }
+     212         988 :   if(dd) dd.Sum(shuffledAtoms);
+     213       22140 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     214             :   // keep in unique only those atoms that are local
+     215        9906 :   for(unsigned i=0; i<actions.size(); i++) actions[i]->unique_local_needs_update=true;
+     216             :   unique.clear(); forced_unique.clear();
+     217         988 : }
+     218             : 
+     219         545 : void DomainDecomposition::setAtomsContiguous(int start) {
+     220         545 :   ddStep=plumed.getStep();
+     221      211635 :   for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=start+i;
+     222      223947 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     223      211635 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     224         545 :   if(gatindex.size()<getNumberOfAtoms()) shuffledAtoms=1;
+     225             :   // keep in unique only those atoms that are local
+     226         757 :   for(unsigned i=0; i<actions.size(); i++) actions[i]->unique_local_needs_update=true;
+     227             :   unique.clear(); forced_unique.clear();
+     228         545 : }
+     229             : 
+     230        1218 : void DomainDecomposition::shareAll() {
+     231        1446 :   unique.clear(); forced_unique.clear(); int natoms = getNumberOfAtoms();
+     232        1218 :   if( dd && shuffledAtoms>0 ) {
+     233       17616 :     for(int i=0; i<natoms; ++i) if( g2l[i]>=0 ) unique.push_back( AtomNumber::index(i) );
+     234             :   } else {
+     235        1032 :     unique.resize(natoms);
+     236     5132522 :     for(int i=0; i<natoms; i++) unique[i]=AtomNumber::index(i);
+     237             :   }
+     238        1218 :   forced_unique.resize( unique.size() );
+     239     5140711 :   for(unsigned i=0; i<unique.size(); ++i) forced_unique[i] = unique[i];
+     240        1218 :   share(unique);
+     241        1202 : }
+     242             : 
+     243       70819 : void DomainDecomposition::share() {
+     244             :   // We can no longer set the pointers after the share
+     245      424914 :   bool atomsNeeded=false; for(const auto & pp : inputs) pp->share();
+     246             :   // At first step I scatter all the atoms so as to store their mass and charge
+     247             :   // Notice that this works with the assumption that charges and masses are
+     248             :   // not changing during the simulation!
+     249       70819 :   if( firststep ) {
+     250        1104 :     actions = plumed.getActionSet().select<ActionAtomistic*>();
+     251        1104 :     shareAll(); return;
+     252             :   }
+     253             : 
+     254       69715 :   if(getenvForceUnique()==Option::automatic) {
+     255             :     unsigned largest=0;
+     256      718384 :     for(unsigned i=0; i<actions.size(); i++) {
+     257      648669 :       if(actions[i]->isActive()) {
+     258             :         auto l=actions[i]->getUnique().size();
+     259      443047 :         if(l>largest) largest=l;
+     260             :       }
+     261             :     }
+     262       69715 :     if(largest*2<getNumberOfAtoms()) unique_serial=true;
+     263       46317 :     else unique_serial=false;
+     264           0 :   } else if(getenvForceUnique()==Option::yes) {
+     265           0 :     unique_serial=true;
+     266           0 :   } else if(getenvForceUnique()==Option::no) {
+     267           0 :     unique_serial=false;
+     268             :   } else {
+     269           0 :     plumed_error();
+     270             :   }
+     271             : 
+     272       69715 :   if(unique_serial || !(int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0)) {
+     273      286188 :     for(unsigned i=0; i<actions.size(); i++) {
+     274      271556 :       if( actions[i]->unique_local_needs_update ) actions[i]->updateUniqueLocal( !(dd && shuffledAtoms>0), g2l );
+     275             :     }
+     276             :     // Now reset unique for the new step
+     277             :     gch::small_vector<const std::vector<AtomNumber>*,32> forced_vectors;
+     278             :     gch::small_vector<const std::vector<AtomNumber>*,32> nonforced_vectors;
+     279             :     forced_vectors.reserve(actions.size()); nonforced_vectors.reserve(actions.size());
+     280      286188 :     for(unsigned i=0; i<actions.size(); i++) {
+     281      262402 :       if(actions[i]->isActive()) {
+     282      190191 :         if(!actions[i]->getUnique().empty()) {
+     283             :           // unique are the local atoms
+     284      199203 :           if( actions[i]->actionHasForces() ) forced_vectors.push_back(&actions[i]->getUniqueLocal());
+     285       22362 :           else nonforced_vectors.push_back(&actions[i]->getUniqueLocal());
+     286             :         }
+     287             :       }
+     288             :     }
+     289       23786 :     if( !(forced_vectors.empty() && nonforced_vectors.empty()) ) atomsNeeded=true;
+     290             :     // Merge the atoms from the atoms that have a force on
+     291       45823 :     unique.clear(); forced_unique.clear();
+     292       23786 :     mergeVectorTools::mergeSortedVectors(forced_vectors,forced_unique);
+     293             :     // Merge all the atoms
+     294       23786 :     nonforced_vectors.push_back( &forced_unique );
+     295       23786 :     mergeVectorTools::mergeSortedVectors(nonforced_vectors,unique);
+     296             :   } else {
+     297      432196 :     for(unsigned i=0; i<actions.size(); i++) {
+     298      386267 :       if(actions[i]->isActive()) {
+     299      252856 :         if(!actions[i]->getUnique().empty()) { atomsNeeded=true; }
+     300             :       }
+     301             :     }
+     302             :   }
+     303             : 
+     304             :   // Now we retrieve the atom numbers we need
+     305       69715 :   if( atomsNeeded ) share( unique );
+     306             : }
+     307             : 
+     308       70228 : void DomainDecomposition::share(const std::vector<AtomNumber>& unique) {
+     309             :   // This retrieves what values we need to get
+     310             :   int ndata=0; std::vector<Value*> values_to_get;
+     311       70228 :   if(!(int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0)) {
+     312        2212 :     uniq_index.resize(unique.size());
+     313       32705 :     for(unsigned i=0; i<unique.size(); i++) uniq_index[i]=g2l[unique[i].index()];
+     314       13272 :     for(const auto & ip : inputs) {
+     315       11060 :       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++; }
+     316             :     }
+     317       68016 :   } else if( unique_serial) {
+     318       21055 :     uniq_index.resize(unique.size());
+     319      785998 :     for(unsigned i=0; i<unique.size(); i++) uniq_index[i]=unique[i].index();
+     320      126330 :     for(const auto & ip : inputs) {
+     321      105275 :       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++; }
+     322             :     }
+     323             :   } else {
+     324             : // faster version, which retrieves all atoms
+     325      281686 :     for(const auto & ip : inputs) {
+     326      234741 :       if( (!ip->fixed || firststep) && ip->wasset ) { (ip->mydata)->share_data( 0, getNumberOfAtoms(), ip->copyOutput(0) ); values_to_get.push_back(ip->copyOutput(0)); ndata++; }
+     327             :     }
+     328             :   }
+     329             : 
+     330       70212 :   if(dd && shuffledAtoms>0) {
+     331        2188 :     if(dd.async) {
+     332        9598 :       for(unsigned i=0; i<dd.mpi_request_positions.size(); i++) dd.mpi_request_positions[i].wait();
+     333        9598 :       for(unsigned i=0; i<dd.mpi_request_index.size(); i++)     dd.mpi_request_index[i].wait();
+     334             :     }
+     335             : 
+     336        2188 :     int count=0;
+     337       32623 :     for(const auto & p : unique) {
+     338       30435 :       dd.indexToBeSent[count]=p.index(); int dpoint=0;
+     339      126694 :       for(unsigned i=0; i<values_to_get.size(); ++i) {
+     340       96259 :         dd.positionsToBeSent[ndata*count+dpoint]=values_to_get[i]->get(p.index());
+     341       96259 :         dpoint++;
+     342             :       }
+     343       30435 :       count++;
+     344             :     }
+     345             : 
+     346        2188 :     if(dd.async) {
+     347        2168 :       asyncSent=true;
+     348        2168 :       dd.mpi_request_positions.resize(dd.Get_size());
+     349        2168 :       dd.mpi_request_index.resize(dd.Get_size());
+     350        9802 :       for(int i=0; i<dd.Get_size(); i++) {
+     351        7634 :         dd.mpi_request_index[i]=dd.Isend(&dd.indexToBeSent[0],count,i,666);
+     352        7634 :         dd.mpi_request_positions[i]=dd.Isend(&dd.positionsToBeSent[0],ndata*count,i,667);
+     353             :       }
+     354             :     } else {
+     355          20 :       const int n=(dd.Get_size());
+     356          36 :       std::vector<int> counts(n);
+     357          20 :       std::vector<int> displ(n);
+     358          20 :       std::vector<int> counts5(n);
+     359          20 :       std::vector<int> displ5(n);
+     360          20 :       dd.Allgather(count,counts);
+     361          20 :       displ[0]=0;
+     362          80 :       for(int i=1; i<n; ++i) displ[i]=displ[i-1]+counts[i-1];
+     363         100 :       for(int i=0; i<n; ++i) counts5[i]=counts[i]*ndata;
+     364         100 :       for(int i=0; i<n; ++i) displ5[i]=displ[i]*ndata;
+     365          20 :       dd.Allgatherv(&dd.indexToBeSent[0],count,&dd.indexToBeReceived[0],&counts[0],&displ[0]);
+     366          20 :       dd.Allgatherv(&dd.positionsToBeSent[0],ndata*count,&dd.positionsToBeReceived[0],&counts5[0],&displ5[0]);
+     367          20 :       int tot=displ[n-1]+counts[n-1];
+     368        1620 :       for(int i=0; i<tot; i++) {
+     369             :         int dpoint=0;
+     370        7264 :         for(unsigned j=0; j<values_to_get.size(); ++j) {
+     371        5664 :           values_to_get[j]->data[dd.indexToBeReceived[i]] = dd.positionsToBeReceived[ndata*i+dpoint]; dpoint++;
+     372             :         }
+     373             :       }
+     374             :     }
+     375             :   }
+     376       70212 : }
+     377             : 
+     378       70204 : void DomainDecomposition::wait() {
+     379      421224 :   for(const auto & ip : inputs) ip->dataCanBeSet=false;
+     380             : 
+     381       70204 :   if(dd && shuffledAtoms>0) {
+     382             :     int ndata=0; std::vector<Value*> values_to_set;
+     383       13128 :     for(const auto & ip : inputs) {
+     384       10940 :       if( (!ip->fixed || firststep) && ip->wasset ) { values_to_set.push_back(ip->copyOutput(0)); ndata++; }
+     385             :     }
+     386             : 
+     387             : // receive toBeReceived
+     388        2188 :     if(asyncSent) {
+     389             :       Communicator::Status status;
+     390             :       std::size_t count=0;
+     391        9802 :       for(int i=0; i<dd.Get_size(); i++) {
+     392        7634 :         dd.Recv(&dd.indexToBeReceived[count],dd.indexToBeReceived.size()-count,i,666,status);
+     393        7634 :         int c=status.Get_count<int>();
+     394        7634 :         dd.Recv(&dd.positionsToBeReceived[ndata*count],dd.positionsToBeReceived.size()-ndata*count,i,667);
+     395        7634 :         count+=c;
+     396             :       }
+     397       68220 :       for(int i=0; i<count; i++) {
+     398             :         int dpoint=0;
+     399      276100 :         for(unsigned j=0; j<values_to_set.size(); ++j) {
+     400      210048 :           values_to_set[j]->set(dd.indexToBeReceived[i], dd.positionsToBeReceived[ndata*i+dpoint] );
+     401      210048 :           dpoint++;
+     402             :         }
+     403             :       }
+     404        2168 :       asyncSent=false;
+     405             :     }
+     406             :   }
+     407       70204 : }
+     408             : 
+     409           0 : unsigned DomainDecomposition::getNumberOfForcesToRescale() const {
+     410           0 :   return gatindex.size();
+     411             : }
+     412             : 
+     413       70080 : void DomainDecomposition::apply() {
+     414       70080 :   std::vector<unsigned> forced_uniq_index(forced_unique.size());
+     415       70080 :   if(!(int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0)) {
+     416       24159 :     for(unsigned i=0; i<forced_unique.size(); i++) forced_uniq_index[i]=g2l[forced_unique[i].index()];
+     417             :   } else {
+     418     3898125 :     for(unsigned i=0; i<forced_unique.size(); i++) forced_uniq_index[i]=forced_unique[i].index();
+     419             :   }
+     420      420470 :   for(const auto & ip : inputs) {
+     421      350392 :     if( !(ip->getPntrToValue())->forcesWereAdded() || ip->noforce ) {
+     422      208916 :       continue;
+     423      141476 :     } else if( ip->wasscaled || (!unique_serial && int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0) ) {
+     424       79580 :       (ip->mydata)->add_force( gatindex, ip->getPntrToValue() );
+     425       61896 :     } else { (ip->mydata)->add_force( forced_unique, forced_uniq_index, ip->getPntrToValue() ); }
+     426             :   }
+     427       70078 : }
+     428             : 
+     429       70078 : void DomainDecomposition::reset() {
+     430       70078 :   if( !unique_serial && int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0 ) return;
+     431             :   // This is an optimisation to ensure that we don't call std::fill over the whole forces
+     432             :   // array if there are a small number of atoms passed between the MD code and PLUMED
+     433       23143 :   if( dd && shuffledAtoms>0 ) getAllActiveAtoms( unique );
+     434      138858 :   for(const auto & ip : inputs) (ip->copyOutput(0))->clearInputForce( unique );
+     435             : }
+     436             : 
+     437         114 : void DomainDecomposition::writeBinary(std::ostream&o) {
+     438         684 :   for(const auto & ip : inputs) ip->writeBinary(o);
+     439         114 : }
+     440             : 
+     441         114 : void DomainDecomposition::readBinary(std::istream&i) {
+     442         684 :   for(const auto & ip : inputs) ip->readBinary(i);
+     443         114 : }
+     444             : 
+     445       66396 : void DomainDecomposition::broadcastToDomains( Value* val ) {
+     446       66396 :   if( dd ) dd.Bcast( val->data, 0 );
+     447       66396 : }
+     448             : 
+     449        3989 : void DomainDecomposition::sumOverDomains( Value* val ) {
+     450        3989 :   if( dd && shuffledAtoms>0 ) dd.Sum( val->data );
+     451        3989 : }
+     452             : 
+     453         900 : const long int& DomainDecomposition::getDdStep() const {
+     454         900 :   return ddStep;
+     455             : }
+     456             : 
+     457         459 : const std::vector<int>& DomainDecomposition::getGatindex() const {
+     458         459 :   return gatindex;
+     459             : }
+     460             : 
+     461        2183 : void DomainDecomposition::getAllActiveAtoms( std::vector<AtomNumber>& u ) {
+     462             :   gch::small_vector<const std::vector<AtomNumber>*,32> vectors;
+     463             :   vectors.reserve(actions.size());
+     464       21016 :   for(unsigned i=0; i<actions.size(); i++) {
+     465       37666 :     if(actions[i]->isActive()) {
+     466       13033 :       if(!actions[i]->getUnique().empty()) {
+     467             :         // unique are the local atoms
+     468       22912 :         vectors.push_back(&actions[i]->getUnique());
+     469             :       }
+     470             :     }
+     471             :   }
+     472             :   u.clear();
+     473        2183 :   mergeVectorTools::mergeSortedVectors(vectors,u);
+     474        2183 : }
+     475             : 
+     476         116 : void DomainDecomposition::createFullList(const TypesafePtr & n) {
+     477         116 :   if( firststep ) {
+     478           7 :     int natoms = getNumberOfAtoms();
+     479           7 :     n.set(int(natoms)); fullList.resize(natoms);
+     480         803 :     for(unsigned i=0; i<natoms; i++) fullList[i]=i;
+     481             :   } else {
+     482             : // We update here the unique list defined at Atoms::unique.
+     483             : // This is not very clear, and probably should be coded differently.
+     484             : // Hopefully this fix the longstanding issue with NAMD.
+     485         109 :     getAllActiveAtoms( unique );
+     486         109 :     fullList.clear(); fullList.reserve(unique.size());
+     487        5012 :     for(const auto & p : unique) fullList.push_back(p.index());
+     488         109 :     n.set(int(fullList.size()));
+     489             :   }
+     490         116 : }
+     491             : 
+     492         116 : void DomainDecomposition::getFullList(const TypesafePtr & x) {
+     493             :   auto xx=x.template get<const int**>();
+     494         116 :   if(!fullList.empty()) *xx=&fullList[0];
+     495           6 :   else *xx=NULL;
+     496         116 : }
+     497             : 
+     498         116 : void DomainDecomposition::clearFullList() {
+     499         116 :   fullList.resize(0);
+     500         116 : }
+     501             : 
+     502             : }
+
+
+
+ + + + +
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 000000000..51a65a147 --- /dev/null +++ b/coverage/core/DomainDecomposition.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecomposition11DomainCommsC2Ev1192
_ZNK4PLMD19DomainDecomposition6onStepEv1707
_ZN4PLMD19DomainDecomposition25castToDomainDecompositionEv3819
+
+
+ + + +
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 000000000..5c67a558e --- /dev/null +++ b/coverage/core/DomainDecomposition.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecomposition11DomainCommsC2Ev1192
_ZN4PLMD19DomainDecomposition25castToDomainDecompositionEv3819
_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 000000000..3aa2741b9 --- /dev/null +++ b/coverage/core/DomainDecomposition.h.gcov.html @@ -0,0 +1,190 @@ + + + + + + + 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-10-17 16:45:00Functions: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      491661 :     operator bool() const {return on;}
+      48        1192 :     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        3819 :   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 000000000..92fa6032e --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-10-17 16:45:00Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev806680
_ZN4PLMD16ExchangePatternsD2Ev806680
+
+
+ + + +
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 000000000..91ac60a00 --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-10-17 16:45:00Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev806680
_ZN4PLMD16ExchangePatternsD2Ev806680
+
+
+ + + +
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 000000000..7d3e18e28 --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-10-17 16:45:00Functions: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      806680 : ExchangePatterns::ExchangePatterns():
+      28      806680 :   PatternFlag(NONE),
+      29      806680 :   NumberOfReplicas(1)
+      30      806680 : {}
+      31             : 
+      32      806680 : 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 000000000..1e2e591a3 --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - core/FlexibleBin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - FlexibleBin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11514678.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..12bce7327 --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - core/FlexibleBin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - FlexibleBin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11514678.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..a4b70351f --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.gcov.html @@ -0,0 +1,412 @@ + + + + + + + LCOV - plumed test coverage - core/FlexibleBin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - FlexibleBin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11514678.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..c45199077 --- /dev/null +++ b/coverage/core/GREX.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - core/GREX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GREX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10013375.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..d22e71628 --- /dev/null +++ b/coverage/core/GREX.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - core/GREX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GREX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10013375.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..13de96618 --- /dev/null +++ b/coverage/core/GREX.cpp.gcov.html @@ -0,0 +1,291 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..79faadc08 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19022285.6 %
Date:2024-10-17 16:45:00Functions: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_EE32
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE96
_ZN4PLMD14GenericMolInfoD0Ev96
_ZN4PLMD14GenericMolInfoD1Ev96
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE98
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE186
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE249
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE655
_ZN4PLMD14GenericMolInfo7prepareEv5155
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE14949
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv17337
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE61001
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE68097
+
+
+ + + +
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 000000000..6b87c2d04 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19022285.6 %
Date:2024-10-17 16:45:00Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo11getBackboneERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS1_IS1_INS_10AtomNumberESaISD_EESaISF_EE32
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE655
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE98
_ZN4PLMD14GenericMolInfo18getSpecialKeywordsB5cxx11Ev1
_ZN4PLMD14GenericMolInfo7prepareEv5155
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE96
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD0Ev96
_ZN4PLMD14GenericMolInfoD1Ev96
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv17337
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE68097
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE186
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE14949
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE61001
_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 000000000..4a5f78291 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.gcov.html @@ -0,0 +1,448 @@ + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19022285.6 %
Date:2024-10-17 16:45:00Functions: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          98 : void GenericMolInfo::registerKeywords( Keywords& keys ) {
+      42          98 :   ActionSetup::registerKeywords(keys);
+      43         196 :   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         196 :   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         196 :   keys.add("compulsory","PYTHON_BIN","default","python interpreter");
+      48         196 :   keys.add("atoms","CHAIN","(for masochists ( mostly Davide Branduardi ) ) The atoms involved in each of the chains of interest in the structure.");
+      49         196 :   keys.add("hidden","STRIDE","frequency for resetting the python interpreter. Should be 1.");
+      50         196 :   keys.addFlag("WHOLE", false, "The reference structure is whole, i.e. not broken by PBC");
+      51          98 : }
+      52             : 
+      53         192 : GenericMolInfo::~GenericMolInfo() {
+      54             : // empty destructor to delete unique_ptr
+      55         288 : }
+      56             : 
+      57          96 : GenericMolInfo::GenericMolInfo( const ActionOptions&ao ):
+      58             :   Action(ao),
+      59             :   ActionAnyorder(ao),
+      60             :   ActionPilot(ao),
+      61             :   ActionAtomistic(ao),
+      62          96 :   iswhole_(false)
+      63             : {
+      64          96 :   plumed_assert(getStride()==1);
+      65             :   // Read what is contained in the pdb file
+      66          96 :   parse("MOLTYPE",mytype);
+      67             : 
+      68             :   // check if whole
+      69          96 :   parseFlag("WHOLE", iswhole_);
+      70             : 
+      71          96 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      72          96 :   if( moldat ) log<<"  overriding last MOLINFO with label " << moldat->getLabel()<<"\n";
+      73             : 
+      74             :   std::vector<AtomNumber> backbone;
+      75         192 :   parseAtomList("CHAIN",backbone);
+      76          96 :   if( read_backbone.size()==0 ) {
+      77           0 :     for(unsigned i=1;; ++i) {
+      78         192 :       parseAtomList("CHAIN",i,backbone);
+      79          96 :       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          96 :   if( read_backbone.size()==0 ) {
+      87          96 :     parse("STRUCTURE",reference);
+      88             : 
+      89          96 :     if( ! pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()))plumed_merror("missing input file " + reference );
+      90             : 
+      91          96 :     std::vector<std::string> chains; pdb.getChainNames( chains );
+      92          96 :     log.printf("  pdb file named %s contains %u chains \n",reference.c_str(), static_cast<unsigned>(chains.size()));
+      93         285 :     for(unsigned i=0; i<chains.size(); ++i) {
+      94             :       unsigned start,end; std::string errmsg;
+      95         189 :       pdb.getResidueRange( chains[i], start, end, errmsg );
+      96         189 :       if( errmsg.length()!=0 ) error( errmsg );
+      97             :       AtomNumber astart,aend;
+      98         189 :       pdb.getAtomRange( chains[i], astart, aend, errmsg );
+      99         189 :       if( errmsg.length()!=0 ) error( errmsg );
+     100         189 :       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         192 :     parse("PYTHON_BIN",python_bin);
+     105          96 :     if(python_bin=="no") {
+     106           0 :       log<<"  python interpreter disabled\n";
+     107             :     } else {
+     108         192 :       pythonCmd=config::getEnvCommand();
+     109          96 :       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          96 :       const auto & at=pdb.getAtomNumbers();
+     115      102394 :       for(unsigned i=0; i<at.size(); i++) {
+     116      102298 :         if(at[i].index()!=i) sorted=false;
+     117             :       }
+     118          96 :       if(!sorted) {
+     119           2 :         log<<"  PDB is not sorted, python interpreter will be disabled\n";
+     120          94 :       } else if(!Subprocess::available()) {
+     121           0 :         log<<"  subprocess is not available, python interpreter will be disabled\n";
+     122             :       } else {
+     123          94 :         enablePythonInterpreter=true;
+     124             :       }
+     125             :     }
+     126          96 :   }
+     127          96 : }
+     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          32 : void GenericMolInfo::getBackbone( std::vector<std::string>& restrings, const std::string& fortype, std::vector< std::vector<AtomNumber> >& backbone ) {
+     170          32 :   if( fortype!=mytype ) error("cannot calculate a variable designed for " + fortype + " molecules for molecule type " + mytype );
+     171          32 :   if( MolDataClass::numberOfAtomsPerResidueInBackbone( mytype )==0 ) error("backbone is not defined for molecule type " + mytype );
+     172             : 
+     173          32 :   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          32 :     if( restrings.size()==1 ) {
+     184          31 :       useter=( restrings[0].find("ter")!=std::string::npos );
+     185          31 :       if( restrings[0].find("all")!=std::string::npos ) {
+     186          30 :         std::vector<std::string> chains; pdb.getChainNames( chains );
+     187         468 :         for(unsigned i=0; i<chains.size(); ++i) {
+     188             :           unsigned r_start, r_end; std::string errmsg, mm, nn;
+     189         438 :           pdb.getResidueRange( chains[i], r_start, r_end, errmsg );
+     190         438 :           if( !useter ) {
+     191         438 :             std::string resname = pdb.getResidueName( r_start );
+     192         438 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_start++;
+     193         438 :             resname = pdb.getResidueName( r_end );
+     194         438 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_end--;
+     195             :           }
+     196         438 :           Tools::convert(r_start,mm); Tools::convert(r_end,nn);
+     197         468 :           if(i==0) restrings[0] = mm + "-" + nn;
+     198         816 :           else restrings.push_back(  mm + "-" + nn );
+     199             :         }
+     200          30 :       }
+     201             :     }
+     202          32 :     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          32 :     Tools::convert(restrings[0],nk); thissegment.push_back(nk);
+     208        3540 :     for(unsigned i=1; i<restrings.size(); ++i) {
+     209        3508 :       Tools::convert(restrings[i-1],nk);
+     210        3508 :       Tools::convert(restrings[i],nj);
+     211        9706 :       if( (nk+1)!=nj || pdb.getChainID(nk)!=pdb.getChainID(nj) ) {
+     212         409 :         segments.push_back(thissegment);
+     213         409 :         thissegment.resize(0);
+     214             :       }
+     215        3508 :       thissegment.push_back(nj);
+     216             :     }
+     217          32 :     segments.push_back( thissegment );
+     218             : 
+     219             :     // And now get the backbone atoms from each segment
+     220          32 :     backbone.resize( segments.size() );
+     221             :     std::vector<AtomNumber> atomnumbers;
+     222         473 :     for(unsigned i=0; i<segments.size(); ++i) {
+     223        3981 :       for(unsigned j=0; j<segments[i].size(); ++j) {
+     224        3540 :         std::string resname=pdb.getResidueName( segments[i][j] );
+     225        3540 :         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        3540 :         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        3540 :         if( resname=="GLY" ) warning("GLY residues are achiral - assuming HA1 atom is in CB position");
+     234        3540 :         MolDataClass::getBackboneForResidue( mytype, segments[i][j], pdb, atomnumbers );
+     235        3540 :         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       21240 :           for(unsigned k=0; k<atomnumbers.size(); ++k) backbone[i].push_back( atomnumbers[k] );
+     240             :         }
+     241        3540 :         atomnumbers.resize(0);
+     242             :       }
+     243             :     }
+     244          32 :   }
+     245          32 : }
+     246             : 
+     247         655 : void GenericMolInfo::interpretSymbol( const std::string& symbol, std::vector<AtomNumber>& atoms ) {
+     248        2566 :   if(Tools::startWith(symbol,"mdt:") || Tools::startWith(symbol,"mda:") || Tools::startWith(symbol,"vmd:") || Tools::startWith(symbol,"vmdexec:")) {
+     249             : 
+     250          24 :     plumed_assert(enablePythonInterpreter);
+     251             : 
+     252          48 :     log<<"  symbol " + symbol + " will be sent to python interpreter\n";
+     253          24 :     if(!selector_running) {
+     254           3 :       log<<"  MOLINFO "<<getLabel()<<": starting python interpreter\n";
+     255           3 :       if(comm.Get_rank()==0) {
+     256           4 :         selector=Tools::make_unique<Subprocess>(pythonCmd+" \""+config::getPlumedRoot()+"\"/scripts/selector.sh --pdb " + reference);
+     257           2 :         selector->stop();
+     258             :       }
+     259           3 :       selector_running=true;
+     260             :     }
+     261             : 
+     262          24 :     atoms.resize(0);
+     263             : 
+     264          24 :     if(comm.Get_rank()==0) {
+     265          16 :       int ok=0;
+     266             :       std::string error_msg;
+     267             :       // this is a complicated way to have the exception propagated with MPI.
+     268             :       // It is necessary since only one process calls the selector.
+     269             :       // Probably I should recycle the exception propagation at library boundaries
+     270             :       // to allow transferring the exception to other processes.
+     271             :       try {
+     272          16 :         plumed_assert(selector) << "Python interpreter is disabled, selection " + symbol + " cannot be interpreted";
+     273             :         auto h=selector->contStop(); // stops again when it goes out of scope
+     274          16 :         (*selector) << symbol << "\n";
+     275          16 :         selector->flush();
+     276             :         std::string res;
+     277             :         std::vector<std::string> words;
+     278             :         while(true) {
+     279          16 :           selector->getline(res);
+     280          32 :           words=Tools::getWords(res);
+     281          32 :           if(!words.empty() && words[0]=="Error") plumed_error()<<res;
+     282          32 :           if(!words.empty() && words[0]=="Selection:") break;
+     283             :         }
+     284             :         words.erase(words.begin());
+     285         712 :         for(const auto & w : words) {
+     286             :           int n;
+     287         696 :           if(w.empty()) continue;
+     288         696 :           Tools::convert(w,n);
+     289        1392 :           atoms.push_back(AtomNumber::serial(n));
+     290             :         }
+     291          16 :         ok=1;
+     292          32 :       } catch (const Exception & e) {
+     293           0 :         error_msg=e.what();
+     294           0 :       }
+     295          16 :       comm.Bcast(ok,0);
+     296          16 :       if(!ok) {
+     297           0 :         size_t s=error_msg.length();
+     298           0 :         comm.Bcast(s,0);
+     299           0 :         comm.Bcast(error_msg,0);
+     300           0 :         throw Exception()<<error_msg;
+     301             :       }
+     302          16 :       size_t nat=atoms.size();
+     303          16 :       comm.Bcast(nat,0);
+     304          16 :       comm.Bcast(atoms,0);
+     305             :     } else {
+     306           8 :       int ok=0;
+     307             :       std::string error_msg;
+     308           8 :       comm.Bcast(ok,0);
+     309           8 :       if(!ok) {
+     310             :         size_t s;
+     311           0 :         comm.Bcast(s,0);
+     312           0 :         error_msg.resize(s);
+     313           0 :         comm.Bcast(error_msg,0);
+     314           0 :         throw Exception()<<error_msg;
+     315             :       }
+     316           8 :       size_t nat=0;
+     317           8 :       comm.Bcast(nat,0);
+     318           8 :       atoms.resize(nat);
+     319           8 :       comm.Bcast(atoms,0);
+     320             :     }
+     321          24 :     log<<"  selection interpreted using ";
+     322          54 :     if(Tools::startWith(symbol,"mdt:")) log<<"mdtraj "<<cite("McGibbon et al, Biophys. J., 109, 1528 (2015)")<<"\n";
+     323          66 :     if(Tools::startWith(symbol,"mda:")) log<<"MDAnalysis "<<cite("Gowers et al, Proceedings of the 15th Python in Science Conference, doi:10.25080/majora-629e541a-00e (2016)")<<"\n";
+     324          48 :     if(Tools::startWith(symbol,"vmdexec:")) log<<"VMD "<<cite("Humphrey, Dalke, and Schulten, K., J. Molec. Graphics, 14, 33 (1996)")<<"\n";
+     325          48 :     if(Tools::startWith(symbol,"vmd:")) log<<"VMD (github.com/Eigenstate/vmd-python) "<<cite("Humphrey, Dalke, and Schulten, K., J. Molec. Graphics, 14, 33 (1996)")<<"\n";
+     326          24 :     return;
+     327             :   }
+     328         631 :   MolDataClass::specialSymbol( mytype, symbol, pdb, atoms );
+     329         631 :   if(atoms.empty()) error(symbol + " not found in your MOLINFO structure");
+     330             : }
+     331             : 
+     332       68097 : std::string GenericMolInfo::getAtomName(AtomNumber a)const {
+     333       68097 :   return pdb.getAtomName(a);
+     334             : }
+     335             : 
+     336         249 : bool GenericMolInfo::checkForAtom(AtomNumber a)const {
+     337         249 :   return pdb.checkForAtom(a);
+     338             : }
+     339             : 
+     340       61001 : unsigned GenericMolInfo::getResidueNumber(AtomNumber a)const {
+     341       61001 :   return pdb.getResidueNumber(a);
+     342             : }
+     343             : 
+     344       17337 : unsigned GenericMolInfo::getPDBsize()const {
+     345       17337 :   return pdb.size();
+     346             : }
+     347             : 
+     348       14949 : std::string GenericMolInfo::getResidueName(AtomNumber a)const {
+     349       14949 :   return pdb.getResidueName(a);
+     350             : }
+     351             : 
+     352           0 : std::string GenericMolInfo::getChainID(AtomNumber a)const {
+     353           0 :   return pdb.getChainID(a);
+     354             : }
+     355             : 
+     356         186 : Vector GenericMolInfo::getPosition(AtomNumber a)const {
+     357         186 :   return pdb.getPosition(a);
+     358             : }
+     359             : 
+     360           2 : bool GenericMolInfo::isWhole() const {
+     361           2 :   return iswhole_;
+     362             : }
+     363             : 
+     364        5155 : void GenericMolInfo::prepare() {
+     365        5155 :   if(selector_running) {
+     366           3 :     log<<"  MOLINFO "<<getLabel()<<": killing python interpreter\n";
+     367             :     selector.reset();
+     368           3 :     selector_running=false;
+     369             :   }
+     370        5155 : }
+     371             : 
+     372             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.func-sort-c.html b/coverage/core/GenericMolInfo.h.func-sort-c.html new file mode 100644 index 000000000..455e8073d --- /dev/null +++ b/coverage/core/GenericMolInfo.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5155
_ZN4PLMD14GenericMolInfo9calculateEv5155
+
+
+ + + +
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 000000000..e444f5e49 --- /dev/null +++ b/coverage/core/GenericMolInfo.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5155
_ZN4PLMD14GenericMolInfo9calculateEv5155
+
+
+ + + +
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 000000000..7299cf55f --- /dev/null +++ b/coverage/core/GenericMolInfo.h.gcov.html @@ -0,0 +1,165 @@ + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5GroupC2ERKNS_13ActionOptionsE0
_ZN4PLMD5GroupC1ERKNS_13ActionOptionsE330
_ZN4PLMD5Group16registerKeywordsERNS_8KeywordsE500
_ZNK4PLMD5Group13getGroupAtomsB5cxx11Ev567
+
+
+ + + +
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 000000000..6135e6a63 --- /dev/null +++ b/coverage/core/Group.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Group16registerKeywordsERNS_8KeywordsE500
_ZN4PLMD5GroupC1ERKNS_13ActionOptionsE330
_ZN4PLMD5GroupC2ERKNS_13ActionOptionsE0
_ZNK4PLMD5Group13getGroupAtomsB5cxx11Ev567
+
+
+ + + +
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 000000000..161071c90 --- /dev/null +++ b/coverage/core/Group.cpp.gcov.html @@ -0,0 +1,305 @@ + + + + + + + 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-10-17 16:45:00Functions: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         330 : Group::Group(const ActionOptions&ao):
+     144             :   Action(ao),
+     145         330 :   ActionAtomistic(ao)
+     146             : {
+     147         660 :   parseAtomList("ATOMS",atoms);
+     148             :   std::string ndxfile,ndxgroup;
+     149         330 :   parse("NDX_FILE",ndxfile);
+     150         660 :   parse("NDX_GROUP",ndxgroup);
+     151         330 :   if(ndxfile.length()>0 && atoms.size()>0) error("either use explicit atom list or import from index file");
+     152         330 :   if(ndxfile.length()==0 && ndxgroup.size()>0) error("NDX_GROUP can be only used is NDX_FILE is also used");
+     153             : 
+     154         330 :   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         660 :   parseAtomList("REMOVE",remove);
+     165         330 :   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         330 :   bool sortme=false;
+     187         330 :   parseFlag("SORT",sortme);
+     188         330 :   if(sortme) {
+     189           1 :     log<<"  atoms are sorted\n";
+     190           1 :     sort(atoms.begin(),atoms.end());
+     191             :   }
+     192         330 :   bool unique=false;
+     193         330 :   parseFlag("UNIQUE",unique);
+     194         330 :   if(unique) {
+     195           1 :     log<<"  sorting atoms and removing duplicates\n";
+     196           1 :     Tools::removeDuplicates(atoms);
+     197             :   }
+     198             : 
+     199         330 :   log.printf("  list of atoms:");
+     200      309888 :   for(unsigned i=0; i<atoms.size(); i++) {
+     201      309558 :     if(i%25==0) log<<"\n";
+     202      309558 :     log<<" "<<atoms[i].serial();
+     203             :   }
+     204         330 :   log.printf("\n");
+     205         330 : }
+     206             : 
+     207         500 : void Group::registerKeywords( Keywords& keys ) {
+     208         500 :   Action::registerKeywords( keys );
+     209         500 :   ActionAtomistic::registerKeywords( keys );
+     210        1000 :   keys.add("atoms", "ATOMS", "the numerical indexes for the set of atoms in the group");
+     211        1000 :   keys.add("atoms", "REMOVE","remove these atoms from the list");
+     212        1000 :   keys.addFlag("SORT",false,"sort the resulting list");
+     213        1000 :   keys.addFlag("UNIQUE",false,"sort atoms and remove duplicated ones");
+     214        1000 :   keys.add("optional", "NDX_FILE", "the name of index file (gromacs syntax)");
+     215        1000 :   keys.add("optional", "NDX_GROUP", "the name of the group to be imported (gromacs syntax) - first group found is used by default");
+     216         500 : }
+     217             : 
+     218         567 : std::vector<std::string> Group::getGroupAtoms() const {
+     219         567 :   std::vector<std::string> atoms_str(atoms.size());
+     220      381283 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     221      380716 :     std::pair<std::size_t,std::size_t> a = getValueIndices( atoms[i] );
+     222      380716 :     if( xpos[a.first]->getNumberOfValues()==1 ) atoms_str[i] = (xpos[a.first]->getPntrToAction())->getLabel();
+     223      370663 :     else { Tools::convert( atoms[i].serial(), atoms_str[i] ); }
+     224             :   }
+     225         567 :   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 000000000..62d7bfd25 --- /dev/null +++ b/coverage/core/Group.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d8fcec63e --- /dev/null +++ b/coverage/core/Group.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ff700640a --- /dev/null +++ b/coverage/core/Group.h.gcov.html @@ -0,0 +1,117 @@ + + + + + + + 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-10-17 16:45:00Functions: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/ModuleMap.cpp.func-sort-c.html b/coverage/core/ModuleMap.cpp.func-sort-c.html new file mode 100644 index 000000000..82496d9e5 --- /dev/null +++ b/coverage/core/ModuleMap.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - core/ModuleMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ModuleMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12getModuleMapB5cxx11Ev878
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ModuleMap.cpp.func.html b/coverage/core/ModuleMap.cpp.func.html new file mode 100644 index 000000000..7b463c87d --- /dev/null +++ b/coverage/core/ModuleMap.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - core/ModuleMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ModuleMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12getModuleMapB5cxx11Ev878
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ModuleMap.cpp.gcov.html b/coverage/core/ModuleMap.cpp.gcov.html new file mode 100644 index 000000000..9f07047ce --- /dev/null +++ b/coverage/core/ModuleMap.cpp.gcov.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - plumed test coverage - core/ModuleMap.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ModuleMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcActionC2ERKNS_13ActionOptionsE0
_ZN4PLMD9PbcAction10readBinaryERSi114
_ZN4PLMD9PbcActionC1ERKNS_13ActionOptionsE1192
_ZN4PLMD9PbcAction16registerKeywordsERNS_8KeywordsE1199
_ZN4PLMD9PbcAction4waitEv66282
_ZN4PLMD9PbcAction6setPbcEv66396
+
+
+ + + +
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 000000000..ae7ee6541 --- /dev/null +++ b/coverage/core/PbcAction.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:2626100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcAction10readBinaryERSi114
_ZN4PLMD9PbcAction16registerKeywordsERNS_8KeywordsE1199
_ZN4PLMD9PbcAction4waitEv66282
_ZN4PLMD9PbcAction6setPbcEv66396
_ZN4PLMD9PbcActionC1ERKNS_13ActionOptionsE1192
_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 000000000..16861019c --- /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:2626100.0 %
Date:2024-10-17 16:45:00Functions: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        1199 : void PbcAction::registerKeywords( Keywords& keys ) {
+      43        1199 :   Action::registerKeywords( keys );
+      44        2398 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      45        1199 :   keys.setValueDescription("a matrix containing the cell vectors that were passed from the MD code");
+      46        1199 : }
+      47             : 
+      48        1192 : PbcAction::PbcAction(const ActionOptions&ao):
+      49             :   Action(ao),
+      50             :   ActionToPutData(ao),
+      51        1192 :   interface(NULL)
+      52             : {
+      53        1192 :   std::vector<unsigned> shape(2); shape[0]=shape[1]=3;
+      54        2384 :   addValue( shape ); setNotPeriodic(); setUnit( "length", "energy" );
+      55        1192 :   getPntrToValue()->buildDataStore(); getPntrToValue()->reshapeMatrixStore(3);
+      56        1192 : }
+      57             : 
+      58             : 
+      59       66396 : void PbcAction::setPbc() {
+      60       66396 :   if( !interface ) {
+      61         989 :     std::vector<DomainDecomposition*> allput=plumed.getActionSet().select<DomainDecomposition*>();
+      62         989 :     if( allput.size()>1 ) warning("found more than one interface so don't know how to broadcast cell");
+      63         989 :     interface = allput[0];
+      64             :   }
+      65       66396 :   Tensor box; if( interface ) interface->broadcastToDomains( getPntrToValue() );
+      66      863148 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) box(i,j) = getPntrToValue()->get(3*i+j);
+      67       66396 :   pbc.setBox(box);
+      68       66396 : }
+      69             : 
+      70       66282 : void PbcAction::wait() {
+      71       66282 :   ActionToPutData::wait(); setPbc();
+      72       66282 : }
+      73             : 
+      74         114 : void PbcAction::readBinary(std::istream&i) {
+      75         114 :   ActionToPutData::readBinary(i); setPbc();
+      76         114 : }
+      77             : 
+      78             : }
+      79             : 
+      80             : 
+      81             : 
+
+
+
+ + + + +
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 000000000..b5c45ec59 --- /dev/null +++ b/coverage/core/PbcAction.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcAction15castToPbcActionEv524475
+
+
+ + + +
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 000000000..78b4e56e5 --- /dev/null +++ b/coverage/core/PbcAction.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcAction15castToPbcActionEv524475
+
+
+ + + +
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 000000000..3912e50c1 --- /dev/null +++ b/coverage/core/PbcAction.h.gcov.html @@ -0,0 +1,135 @@ + + + + + + + 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-10-17 16:45:00Functions: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      524475 :   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 000000000..91898e125 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func-sort-c.html @@ -0,0 +1,352 @@ + + + + + + + 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:84894489.8 %
Date:2024-10-17 16:45:00Functions:657092.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain9justApplyEv0
_ZNK4PLMD10PlumedMain15DeprecatedAtoms16setCollectEnergyEb0
_ZNK4PLMD10PlumedMain15DeprecatedAtoms9getEnergyEv0
_ZNK4PLMD10PlumedMain18MDQuantityToPLUMEDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZNK4PLMD10PlumedMain15DeprecatedAtoms13getKBoltzmannEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms17usingNaturalUnitsEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms6getKbTEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms9getNatomsEv1
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD10PlumedMain8getAtomsEv4
_ZN4PLMD10PlumedMain21activateParseOnlyModeEv5
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMD10PlumedMain14setEnergyValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE42
_ZNK4PLMD10PlumedMain24useCountReferenceCounterEv42
_ZNK4PLMD10PlumedMain11valueExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZN4PLMDL9testThrowEPKc61
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_82
_ZNK4PLMD10PlumedMain20getKeywordsForActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE97
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE99
_ZN4PLMD10PlumedMain10readBinaryERSi114
_ZN4PLMD10PlumedMain8shareAllEv114
_ZNK4PLMD10PlumedMain11writeBinaryERSo114
_ZNK4PLMD10PlumedMain7getWorkEv450
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv943
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1026
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE1028
_ZN4PLMD10PlumedMain4initEv1286
_ZN4PLMD10PlumedMain8setUnitsERKbRKNS_5UnitsE1323
_ZN4PLMD10PlumedMain6fflushEv1762
_ZNK4PLMD10PlumedMain15inputsAreActiveEv1763
_ZNK4PLMD10PlumedMain13parseOnlyModeEv2160
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4684
_ZNK4PLMD10PlumedMain17usingNaturalUnitsEv5021
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE5076
_ZN4PLMD12_GLOBAL__N_114CountInstancesD2Ev5278
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE5338
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv7011
_ZNK4PLMD10PlumedMain18plumedQuantityToMDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdRKNS_11TypesafePtrE7222
_ZNK4PLMD10PlumedMain7getBiasEv7684
_ZNK4PLMD10PlumedMain16getRealPrecisionEv9433
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb32800
_ZN4PLMD10PlumedMain6getLogEv51096
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKb51273
_ZN4PLMD10PlumedMain21setupInterfaceActionsEv52074
_ZN4PLMD10PlumedMain11performCalcEv277795
_ZN4PLMD10PlumedMain4calcEv277801
_ZN4PLMD10PlumedMain6updateEv277872
_ZN4PLMD10PlumedMain13setInputForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE281875
_ZN4PLMD10PlumedMain9startStepEv284749
_ZN4PLMD10PlumedMain11prepareCalcEv284752
_ZN4PLMD10PlumedMain11resetInputsEv284804
_ZN4PLMD10PlumedMain17backwardPropagateEv284806
_ZN4PLMD10PlumedMain9shareDataEv284836
_ZN4PLMD10PlumedMain13justCalculateEv284930
_ZN4PLMD10PlumedMain8waitDataEv284930
_ZN4PLMD10PlumedMain19prepareDependenciesEv285079
_ZN4PLMD10PlumedMain13setInputValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSA_RKNS_11TypesafePtrE449858
_ZN4PLMD10PlumedMainD0Ev805706
_ZN4PLMD10PlumedMainC2Ev806680
_ZN4PLMD10PlumedMainD2Ev806680
_ZN4PLMD12_GLOBAL__N_114CountInstances8decreaseEv806680
_ZN4PLMD12_GLOBAL__N_114CountInstances8increaseEv806680
_ZN4PLMD10PlumedMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1329166
_ZN4PLMD12_GLOBAL__N_114CountInstances8instanceEv1613360
_ZN4PLMD10PlumedMain24decreaseReferenceCounterEv8806275
_ZN4PLMD10PlumedMain24increaseReferenceCounterEv8807351
_ZN4PLMD10PlumedMain8getUnitsEv15935469
+
+
+ + + +
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 000000000..75d5eea90 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func.html @@ -0,0 +1,352 @@ + + + + + + + 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:84894489.8 %
Date:2024-10-17 16:45:00Functions:657092.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE5076
_ZN4PLMD10PlumedMain10readBinaryERSi114
_ZN4PLMD10PlumedMain11performCalcEv277795
_ZN4PLMD10PlumedMain11prepareCalcEv284752
_ZN4PLMD10PlumedMain11resetInputsEv284804
_ZN4PLMD10PlumedMain13justCalculateEv284930
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1026
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE1028
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb32800
_ZN4PLMD10PlumedMain13setInputForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE281875
_ZN4PLMD10PlumedMain13setInputValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSA_RKNS_11TypesafePtrE449858
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKb51273
_ZN4PLMD10PlumedMain14setEnergyValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD10PlumedMain17backwardPropagateEv284806
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv7011
_ZN4PLMD10PlumedMain19prepareDependenciesEv285079
_ZN4PLMD10PlumedMain21activateParseOnlyModeEv5
_ZN4PLMD10PlumedMain21setupInterfaceActionsEv52074
_ZN4PLMD10PlumedMain24decreaseReferenceCounterEv8806275
_ZN4PLMD10PlumedMain24increaseReferenceCounterEv8807351
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv943
_ZN4PLMD10PlumedMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1329166
_ZN4PLMD10PlumedMain4calcEv277801
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4684
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain4initEv1286
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE42
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_82
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE99
_ZN4PLMD10PlumedMain6fflushEv1762
_ZN4PLMD10PlumedMain6getLogEv51096
_ZN4PLMD10PlumedMain6updateEv277872
_ZN4PLMD10PlumedMain8getAtomsEv4
_ZN4PLMD10PlumedMain8getUnitsEv15935469
_ZN4PLMD10PlumedMain8setUnitsERKbRKNS_5UnitsE1323
_ZN4PLMD10PlumedMain8shareAllEv114
_ZN4PLMD10PlumedMain8waitDataEv284930
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE5338
_ZN4PLMD10PlumedMain9justApplyEv0
_ZN4PLMD10PlumedMain9shareDataEv284836
_ZN4PLMD10PlumedMain9startStepEv284749
_ZN4PLMD10PlumedMainC2Ev806680
_ZN4PLMD10PlumedMainD0Ev805706
_ZN4PLMD10PlumedMainD2Ev806680
_ZN4PLMD12_GLOBAL__N_114CountInstances8decreaseEv806680
_ZN4PLMD12_GLOBAL__N_114CountInstances8increaseEv806680
_ZN4PLMD12_GLOBAL__N_114CountInstances8instanceEv1613360
_ZN4PLMD12_GLOBAL__N_114CountInstancesD2Ev5278
_ZN4PLMDL9testThrowEPKc61
_ZNK4PLMD10PlumedMain11valueExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZNK4PLMD10PlumedMain11writeBinaryERSo114
_ZNK4PLMD10PlumedMain13parseOnlyModeEv2160
_ZNK4PLMD10PlumedMain15DeprecatedAtoms13getKBoltzmannEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms16setCollectEnergyEb0
_ZNK4PLMD10PlumedMain15DeprecatedAtoms17usingNaturalUnitsEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms6getKbTEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms9getEnergyEv0
_ZNK4PLMD10PlumedMain15DeprecatedAtoms9getNatomsEv1
_ZNK4PLMD10PlumedMain15inputsAreActiveEv1763
_ZNK4PLMD10PlumedMain16getRealPrecisionEv9433
_ZNK4PLMD10PlumedMain17usingNaturalUnitsEv5021
_ZNK4PLMD10PlumedMain18MDQuantityToPLUMEDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZNK4PLMD10PlumedMain18plumedQuantityToMDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdRKNS_11TypesafePtrE7222
_ZNK4PLMD10PlumedMain20getKeywordsForActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE97
_ZNK4PLMD10PlumedMain24useCountReferenceCounterEv42
_ZNK4PLMD10PlumedMain7getBiasEv7684
_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 000000000..b5723037a --- /dev/null +++ b/coverage/core/PlumedMain.cpp.gcov.html @@ -0,0 +1,1592 @@ + + + + + + + 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:84894489.8 %
Date:2024-10-17 16:45:00Functions:657092.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             :   // private constructor to avoid direct usage
+     220        5278 :   CountInstances() noexcept {}
+     221        5278 :   ~CountInstances() {
+     222        5278 :     if(counter!=0) {
+     223           0 :       std::cerr<<"WARNING: internal inconsistency in allocated PlumedMain instances (" <<counter<< ")\n";
+     224           0 :       std::cerr<<"Might be a consequence of incorrectly paired plumed_create/plumed_finalize in the C interface\n";
+     225           0 :       std::cerr<<"Or it could be due to incorrect calls to std::exit, without properly destroying all PlumedMain objects\n";
+     226             : #ifndef NDEBUG
+     227             :       std::cerr<<"This is a debug build, so the warning will make PLUMED abort\n";
+     228             :       std::abort();
+     229             : #endif
+     230             :     }
+     231        5278 :   }
+     232     1613360 :   static CountInstances & instance() {
+     233     1613360 :     static CountInstances counter;
+     234     1613360 :     return counter;
+     235             :   }
+     236             : public:
+     237             :   /// Only access through these static functions
+     238             :   /// The first call to increase() ensures the instance is constructed
+     239             :   /// This should provide the correct construction and destruction order
+     240             :   /// also in cases where the PlumedMain object is constructed in the
+     241             :   /// constructor of a static object
+     242      806680 :   static void increase() noexcept {
+     243      806680 :     ++instance().counter;
+     244      806680 :   }
+     245             :   /// See increase()
+     246      806680 :   static void decrease() noexcept {
+     247      806680 :     --instance().counter;
+     248      806680 :   }
+     249             : };
+     250             : 
+     251             : }
+     252             : 
+     253             : 
+     254      806680 : PlumedMain::PlumedMain():
+     255      806680 :   datoms_fwd(*this),
+     256             : // automatically write on log in destructor
+     257      806680 :   stopwatch_fwd(log),
+     258      806680 :   actionSet_fwd(*this),
+     259      806680 :   passtools(DataPassingTools::create(sizeof(double)))
+     260             : {
+     261      806680 :   passtools->usingNaturalUnits=false;
+     262      806680 :   increaseReferenceCounter();
+     263      806680 :   log.link(comm);
+     264      806680 :   log.setLinePrefix("PLUMED: ");
+     265             :   // this is at last so as to avoid inconsistencies if an exception is thrown
+     266      806680 :   CountInstances::increase(); // noexcept
+     267      806680 : }
+     268             : 
+     269             : // destructor needed to delete forward declarated objects
+     270     1612386 : PlumedMain::~PlumedMain() {
+     271      806680 :   CountInstances::decrease();
+     272     4839106 : }
+     273             : 
+     274             : /////////////////////////////////////////////////////////////
+     275             : //  MAIN INTERPRETER
+     276             : 
+     277             : #define CHECK_INIT(ini,word) plumed_assert(ini)<<"cmd(\"" << word << "\") should be only used after plumed initialization"
+     278             : #define CHECK_NOTINIT(ini,word) plumed_assert(!(ini))<<"cmd(\"" << word << "\") should be only used before plumed initialization"
+     279             : #define CHECK_NOTNULL(val,word) plumed_assert(val)<<"NULL pointer received in cmd(\"" << word << "\")"
+     280             : 
+     281             : 
+     282     1329166 : void PlumedMain::cmd(std::string_view word,const TypesafePtr & val) {
+     283             : 
+     284             : // Enumerate all possible commands:
+     285             :   enum {
+     286             : #include "PlumedMainEnum.inc"
+     287             :   };
+     288             : 
+     289             : // Static object (initialized once) containing the map of commands:
+     290             :   const static Tools::FastStringUnorderedMap<int> word_map = {
+     291             : #include "PlumedMainMap.inc"
+     292     1329166 :   };
+     293             : 
+     294             :   try {
+     295             : 
+     296     1329166 :     auto ss=stopwatch.startPause();
+     297             : 
+     298             :     gch::small_vector<std::string_view> words;
+     299     1329166 :     Tools::getWordsSimple(words,word);
+     300             : 
+     301     1329166 :     unsigned nw=words.size();
+     302     1329166 :     if(nw==0) {
+     303             :       // do nothing
+     304             :     } else {
+     305             :       int iword=-1;
+     306             :       const auto it=word_map.find(words[0]);
+     307     1329165 :       if(it!=word_map.end()) iword=it->second;
+     308             : 
+     309     1329158 :       switch(iword) {
+     310       68274 :       case cmd_setBox:
+     311       68274 :         CHECK_INIT(initialized,word);
+     312       68274 :         CHECK_NOTNULL(val,word);
+     313       68274 :         setInputValue( "Box", 0, 1, val );
+     314       68273 :         break;
+     315       72451 :       case cmd_setPositions:
+     316       72451 :         CHECK_INIT(initialized,word);
+     317       72451 :         setInputValue("posx", 0, 3, val );
+     318       72451 :         setInputValue("posy", 1, 3, val );
+     319       72451 :         setInputValue("posz", 2, 3, val );
+     320       72451 :         break;
+     321       72414 :       case cmd_setMasses:
+     322       72414 :         CHECK_INIT(initialized,word);
+     323       72414 :         setInputValue("Masses", 0, 1, val );
+     324       72411 :         break;
+     325       64339 :       case cmd_setCharges:
+     326       64339 :         CHECK_INIT(initialized,word);
+     327       64339 :         setInputValue("Charges", 0, 1, val);
+     328       64339 :         break;
+     329           1 :       case cmd_setPositionsX:
+     330           1 :         CHECK_INIT(initialized,word);
+     331           1 :         setInputValue("posx", 0, 1, val);
+     332           1 :         break;
+     333           1 :       case cmd_setPositionsY:
+     334           1 :         CHECK_INIT(initialized,word);
+     335           1 :         setInputValue("posy", 0, 1, val);
+     336           1 :         break;
+     337           1 :       case cmd_setPositionsZ:
+     338           1 :         CHECK_INIT(initialized,word);
+     339           1 :         setInputValue("posz", 0, 1, val);
+     340           1 :         break;
+     341       64588 :       case cmd_setVirial:
+     342       64588 :         CHECK_INIT(initialized,word);
+     343       64588 :         CHECK_NOTNULL(val,word);
+     344       64588 :         setInputForce("Box",val);
+     345       64570 :         break;
+     346        7842 :       case cmd_setEnergy:
+     347        7842 :         CHECK_INIT(initialized,word);
+     348        7842 :         CHECK_NOTNULL(val,word);
+     349        7842 :         if( name_of_energy!="" ) setInputValue( name_of_energy, 0, 1,  val );
+     350             :         break;
+     351       72418 :       case cmd_setForces:
+     352       72418 :         CHECK_INIT(initialized,word);
+     353       72418 :         setInputForce("posx",val);
+     354       72418 :         setInputForce("posy",val);
+     355       72418 :         setInputForce("posz",val);
+     356       72418 :         break;
+     357           1 :       case cmd_setForcesX:
+     358           1 :         CHECK_INIT(initialized,word);
+     359           1 :         setInputForce("posx",val);
+     360           1 :         break;
+     361           1 :       case cmd_setForcesY:
+     362           1 :         CHECK_INIT(initialized,word);
+     363           1 :         setInputForce("posy",val);
+     364           1 :         break;
+     365           1 :       case cmd_setForcesZ:
+     366           1 :         CHECK_INIT(initialized,word);
+     367           1 :         setInputForce("posz",val);
+     368           1 :         break;
+     369      277801 :       case cmd_calc:
+     370      277801 :         CHECK_INIT(initialized,word);
+     371      277801 :         calc();
+     372             :         break;
+     373          99 :       case cmd_prepareDependencies:
+     374          99 :         CHECK_INIT(initialized,word);
+     375          99 :         prepareDependencies();
+     376             :         break;
+     377          84 :       case cmd_shareData:
+     378          84 :         CHECK_INIT(initialized,word);
+     379          84 :         shareData();
+     380             :         break;
+     381        6951 :       case cmd_prepareCalc:
+     382        6951 :         CHECK_INIT(initialized,word);
+     383        6951 :         prepareCalc();
+     384             :         break;
+     385          10 :       case cmd_performCalc:
+     386          10 :         CHECK_INIT(initialized,word);
+     387          10 :         performCalc();
+     388             :         break;
+     389        7011 :       case cmd_performCalcNoUpdate:
+     390        7011 :         CHECK_INIT(initialized,word);
+     391        7011 :         performCalcNoUpdate();
+     392             :         break;
+     393          10 :       case cmd_performCalcNoForces:
+     394          10 :         CHECK_INIT(initialized,word);
+     395          10 :         performCalcNoForces();
+     396             :         break;
+     397          79 :       case cmd_update:
+     398          79 :         CHECK_INIT(initialized,word);
+     399          79 :         update();
+     400             :         break;
+     401       16009 :       case cmd_setStep:
+     402       16009 :         CHECK_INIT(initialized,word);
+     403       16012 :         CHECK_NOTNULL(val,word);
+     404       16006 :         step=val.get<int>();
+     405       16005 :         startStep();
+     406             :         break;
+     407           0 :       case cmd_setStepLong:
+     408           0 :         CHECK_INIT(initialized,word);
+     409           0 :         CHECK_NOTNULL(val,word);
+     410           0 :         step=val.get<long int>();
+     411           0 :         startStep();
+     412             :         break;
+     413      268744 :       case cmd_setStepLongLong:
+     414      268744 :         CHECK_INIT(initialized,word);
+     415      268744 :         CHECK_NOTNULL(val,word);
+     416      268744 :         step=val.get<long long int>();
+     417      268744 :         startStep();
+     418             :         break;
+     419       23456 :       case cmd_setValue:
+     420             :       {
+     421       23456 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2); setInputValue( std::string(words[1]), 0, 1, val );
+     422             :       }
+     423       23456 :       break;
+     424             :       /* ADDED WITH API=7 */
+     425           0 :       case cmd_setValueForces:
+     426             :       {
+     427           0 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2); setInputForce( std::string(words[1]), val );
+     428             :       }
+     429           0 :       break;
+     430             :       // words used less frequently:
+     431        1140 :       case cmd_setAtomsNlocal:
+     432        1140 :         CHECK_INIT(initialized,word);
+     433        1140 :         CHECK_NOTNULL(val,word);
+     434        4582 :         for(const auto & pp : inputs ) {
+     435        3442 :           plumed_assert(pp);
+     436        3442 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     437        3442 :           if( dd ) dd->setAtomsNlocal(val.get<int>());
+     438             :         }
+     439             :         break;
+     440         988 :       case cmd_setAtomsGatindex:
+     441         988 :         CHECK_INIT(initialized,word);
+     442        3974 :         for(const auto & pp : inputs ) {
+     443        2986 :           plumed_assert(pp);
+     444        2986 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     445        2986 :           if( dd ) dd->setAtomsGatindex(val,false);
+     446             :         }
+     447             :         break;
+     448           0 :       case cmd_setAtomsFGatindex:
+     449           0 :         CHECK_INIT(initialized,word);
+     450           0 :         for(const auto & pp : inputs ) {
+     451           0 :           plumed_assert(pp);
+     452           0 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     453           0 :           if( dd ) dd->setAtomsGatindex(val,false);
+     454             :         }
+     455             :         break;
+     456         152 :       case cmd_setAtomsContiguous:
+     457         152 :         CHECK_INIT(initialized,word);
+     458         152 :         CHECK_NOTNULL(val,word);
+     459         608 :         for(const auto & pp : inputs ) {
+     460         456 :           plumed_assert(pp);
+     461         456 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     462         456 :           if( dd ) dd->setAtomsContiguous(val.get<int>());
+     463             :         }
+     464             :         break;
+     465         116 :       case cmd_createFullList:
+     466         116 :         CHECK_INIT(initialized,word);
+     467         116 :         CHECK_NOTNULL(val,word);
+     468         553 :         for(const auto & pp : inputs ) {
+     469         437 :           plumed_assert(pp);
+     470         437 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     471         437 :           if( dd ) dd->createFullList(val);
+     472             :         }
+     473             :         break;
+     474         116 :       case cmd_getFullList:
+     475             :       {
+     476         116 :         CHECK_INIT(initialized,word);
+     477         116 :         CHECK_NOTNULL(val,word);
+     478             :         unsigned nlists=0;
+     479         553 :         for(const auto & pp : inputs ) {
+     480         437 :           plumed_assert(pp);
+     481         437 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     482         437 :           if( dd ) { dd->getFullList(val); nlists++; }
+     483             :         }
+     484         116 :         plumed_assert( nlists==1 );
+     485             :       }
+     486             :       break;
+     487         116 :       case cmd_clearFullList:
+     488         116 :         CHECK_INIT(initialized,word);
+     489         553 :         for(const auto & pp : inputs ) {
+     490         437 :           plumed_assert(pp);
+     491         437 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     492         437 :           if( dd ) dd->clearFullList();
+     493             :         }
+     494             :         break;
+     495             :       /* ADDED WITH API==6 */
+     496         115 :       case cmd_getDataRank:
+     497             :       {
+     498         115 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     499         115 :         std::string vtype=""; if( nw==3 ) vtype=" TYPE="+std::string(words[2]);
+     500         345 :         readInputLine( "grab_" + std::string(words[1]) + ": GET ARG=" + std::string(words[1]) + vtype );
+     501         230 :         ActionToGetData* as=actionSet.selectWithLabel<ActionToGetData*>("grab_"+std::string(words[1]));
+     502         115 :         plumed_assert( as ); as->get_rank( val );
+     503             :       }
+     504         115 :       break;
+     505             :       /* ADDED WITH API==6 */
+     506          51 :       case cmd_getDataShape:
+     507             :       {
+     508          51 :         CHECK_INIT(initialized,std::string(words[0]));
+     509         102 :         ActionToGetData* as1=actionSet.selectWithLabel<ActionToGetData*>("grab_"+std::string(words[1]));
+     510          51 :         plumed_assert( as1 ); as1->get_shape( val );
+     511             :       }
+     512             :       break;
+     513             :       /* ADDED WITH API==6 */
+     514         115 :       case cmd_setMemoryForData:
+     515             :       {
+     516         115 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     517         230 :         ActionToGetData* as2=actionSet.selectWithLabel<ActionToGetData*>("grab_"+std::string(words[1]));
+     518         115 :         plumed_assert( as2 ); as2->set_memory( val );
+     519             :       }
+     520             :       break;
+     521             :       /* ADDED WITH API==6 */
+     522             :       case cmd_setErrorHandler:
+     523             :       {
+     524           0 :         if(val) error_handler=*static_cast<const plumed_error_handler*>(val.get<const void*>());
+     525           0 :         else error_handler.handler=NULL;
+     526             :       }
+     527             :       break;
+     528           0 :       case cmd_read:
+     529           0 :         CHECK_INIT(initialized,word);
+     530           0 :         if(val)readInputFile(val.getCString());
+     531           0 :         else   readInputFile("plumed.dat");
+     532             :         break;
+     533         819 :       case cmd_readInputLine:
+     534         819 :         CHECK_INIT(initialized,word);
+     535         819 :         CHECK_NOTNULL(val,word);
+     536         819 :         readInputLine(val.getCString());
+     537         777 :         break;
+     538           2 :       case cmd_readInputLines:
+     539           2 :         CHECK_INIT(initialized,word);
+     540           2 :         CHECK_NOTNULL(val,word);
+     541           2 :         readInputLines(val.getCString());
+     542           2 :         break;
+     543           3 :       case cmd_clear:
+     544             :       {
+     545           3 :         CHECK_INIT(initialized,word);
+     546             :         std::vector<int> natoms;
+     547           7 :         for(const auto & pp : inputs ) {
+     548           4 :           plumed_assert(pp);
+     549           4 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     550           4 :           if ( dd ) natoms.push_back( dd->getNumberOfAtoms() );
+     551             :         }
+     552           3 :         actionSet.clearDelete(); inputs.clear();
+     553           4 :         for(unsigned i=0; i<natoms.size(); ++i) {
+     554           1 :           std::string str_natoms; Tools::convert( natoms[i], str_natoms );
+     555           3 :           readInputLine( MDEngine + ": DOMAIN_DECOMPOSITION NATOMS=" + str_natoms +
+     556           2 :                          " VALUE1=posx UNIT1=length PERIODIC1=NO CONSTANT1=False ROLE1=x" +
+     557           2 :                          " VALUE2=posy UNIT2=length PERIODIC2=NO CONSTANT2=False ROLE2=y" +
+     558           2 :                          " VALUE3=posz UNIT3=length PERIODIC3=NO CONSTANT3=False ROLE3=z" +
+     559           2 :                          " VALUE4=Masses UNIT4=mass PERIODIC4=NO CONSTANT4=True ROLE4=m" +
+     560             :                          " VALUE5=Charges UNIT5=charge PERIODIC5=NO CONSTANT5=True ROLE5=q");
+     561             : 
+     562             :         }
+     563           3 :         setUnits( passtools->usingNaturalUnits, passtools->units );
+     564             :       }
+     565           3 :       break;
+     566             :       case cmd_getApiVersion:
+     567          44 :         CHECK_NOTNULL(val,word);
+     568          44 :         val.set(int(10));
+     569             :         break;
+     570             :       // commands which can be used only before initialization:
+     571        1286 :       case cmd_init:
+     572        1286 :         CHECK_NOTINIT(initialized,word);
+     573        1286 :         init();
+     574             :         break;
+     575        1041 :       case cmd_setRealPrecision:
+     576        1041 :         CHECK_NOTINIT(initialized,word);
+     577        1041 :         CHECK_NOTNULL(val,word);
+     578        2081 :         passtools=DataPassingTools::create(val.get<int>());
+     579        1040 :         passtools->usingNaturalUnits=false;
+     580        1040 :         break;
+     581         953 :       case cmd_setMDLengthUnits:
+     582         953 :         CHECK_NOTINIT(initialized,word);
+     583         953 :         CHECK_NOTNULL(val,word);
+     584         953 :         passtools->MDUnits.setLength(passtools->MD2double(val));
+     585             :         break;
+     586         953 :       case cmd_setMDChargeUnits:
+     587         953 :         CHECK_NOTINIT(initialized,word);
+     588         953 :         CHECK_NOTNULL(val,word);
+     589         953 :         passtools->MDUnits.setCharge(passtools->MD2double(val));
+     590             :         break;
+     591         953 :       case cmd_setMDMassUnits:
+     592         953 :         CHECK_NOTINIT(initialized,word);
+     593         953 :         CHECK_NOTNULL(val,word);
+     594         953 :         passtools->MDUnits.setMass(passtools->MD2double(val));
+     595             :         break;
+     596          45 :       case cmd_setMDEnergyUnits:
+     597          45 :         CHECK_NOTINIT(initialized,word);
+     598          45 :         CHECK_NOTNULL(val,word);
+     599          45 :         passtools->MDUnits.setEnergy(passtools->MD2double(val));
+     600             :         break;
+     601           6 :       case cmd_setMDTimeUnits:
+     602           6 :         CHECK_NOTINIT(initialized,word);
+     603           6 :         CHECK_NOTNULL(val,word);
+     604           6 :         passtools->MDUnits.setTime(passtools->MD2double(val));
+     605             :         break;
+     606           0 :       case cmd_setNaturalUnits:
+     607             :         // set the boltzman constant for MD in natural units (kb=1)
+     608             :         // only needed in LJ codes if the MD is passing temperatures to plumed (so, not yet...)
+     609             :         // use as cmd("setNaturalUnits")
+     610           0 :         CHECK_NOTINIT(initialized,word);
+     611           0 :         passtools->usingNaturalUnits=true;
+     612           0 :         break;
+     613          62 :       case cmd_setNoVirial:
+     614             :       {
+     615          62 :         CHECK_NOTINIT(initialized,word);
+     616          62 :         ActionToPutData* ap=actionSet.selectWithLabel<ActionToPutData*>("Box");
+     617          62 :         if( ap ) ap->noforce=true;
+     618             :         else {
+     619          10 :           ActionForInterface* af = actionSet.selectWithLabel<ActionForInterface*>(MDEngine);
+     620          10 :           if( af ) plumed_merror("setNoVirial should be called after number of atoms have been set");
+     621             :         }
+     622             :       }
+     623             :       break;
+     624        1003 :       case cmd_setPlumedDat:
+     625        1003 :         CHECK_NOTINIT(initialized,word);
+     626        1003 :         CHECK_NOTNULL(val,word);
+     627        1003 :         plumedDat=val.getCString();
+     628             :         break;
+     629         353 :       case cmd_setMPIComm:
+     630         353 :         CHECK_NOTINIT(initialized,word);
+     631         353 :         comm.Set_comm(val);
+     632         355 :         for(const auto & pp : inputs ) pp->Set_comm(comm);
+     633             :         break;
+     634           0 :       case cmd_setMPIFComm:
+     635           0 :         CHECK_NOTINIT(initialized,word);
+     636           0 :         comm.Set_fcomm(val);
+     637           0 :         for(const auto & pp : inputs ) pp->Set_comm(comm);
+     638             :         break;
+     639           0 :       case cmd_setMPImultiSimComm:
+     640           0 :         CHECK_NOTINIT(initialized,word);
+     641           0 :         multi_sim_comm.Set_comm(val);
+     642             :         break;
+     643        1270 :       case cmd_setNatoms:
+     644             :       {
+     645        1270 :         CHECK_NOTINIT(initialized,word);
+     646        1270 :         CHECK_NOTNULL(val,word);
+     647        1270 :         int natoms = val.get<int>(); std::string str_natoms; Tools::convert( natoms, str_natoms );
+     648        1260 :         ActionForInterface* dd=actionSet.selectWithLabel<ActionForInterface*>(MDEngine);
+     649        4833 :         if( !dd && natoms>0 ) readInputLine( MDEngine + ": DOMAIN_DECOMPOSITION NATOMS=" + str_natoms +  +
+     650        2382 :                                                " VALUE1=posx UNIT1=length PERIODIC1=NO CONSTANT1=False ROLE1=x" +
+     651        2382 :                                                " VALUE2=posy UNIT2=length PERIODIC2=NO CONSTANT2=False ROLE2=y" +
+     652        2382 :                                                " VALUE3=posz UNIT3=length PERIODIC3=NO CONSTANT3=False ROLE3=z" +
+     653        2382 :                                                " VALUE4=Masses UNIT4=mass PERIODIC4=NO CONSTANT4=True ROLE4=m" +
+     654        2382 :                                                " VALUE5=Charges UNIT5=charge PERIODIC5=NO CONSTANT5=True ROLE5=q", true );
+     655             :       }
+     656        1260 :       break;
+     657        1021 :       case cmd_setTimestep:
+     658             :       {
+     659        1021 :         CHECK_NOTINIT(initialized,word);
+     660        1021 :         CHECK_NOTNULL(val,word);
+     661        1021 :         ActionToPutData* ts = actionSet.selectWithLabel<ActionToPutData*>("timestep");
+     662        1021 :         if( !ts ) {
+     663        1019 :           readInputLine("timestep: PUT UNIT=time PERIODIC=NO CONSTANT", true);
+     664        2038 :           ts = actionSet.selectWithLabel<ActionToPutData*>("timestep");
+     665             :         }
+     666        2042 :         if( !ts->setValuePointer("timestep", val ) ) plumed_error();
+     667             :         // The following is to avoid extra digits in case the MD code uses floats
+     668             :         // e.g.: float f=0.002 when converted to double becomes 0.002000000094995
+     669             :         // To avoid this, we keep only up to 6 significant digits after first one
+     670        1021 :         if( getRealPrecision()<=4 ) {
+     671         166 :           Value* tstepv = ts->copyOutput(0);
+     672           0 :           double magnitude=std::pow(10,std::floor(std::log10(tstepv->get())));
+     673           0 :           tstepv->set( std::round(tstepv->get()/magnitude*1e6)/1e6*magnitude );
+     674             :         }
+     675        1021 :         ts->updateUnits( passtools.get() );
+     676             :       }
+     677             :       break;
+     678             :       /* ADDED WITH API==2 */
+     679          61 :       case cmd_setKbT:
+     680             :       {
+     681          61 :         CHECK_NOTINIT(initialized,word);
+     682          61 :         CHECK_NOTNULL(val,word);
+     683          61 :         readInputLine("kBT: PUT CONSTANT PERIODIC=NO UNIT=energy", true);
+     684          61 :         ActionToPutData* kb = actionSet.selectWithLabel<ActionToPutData*>("kBT");
+     685         122 :         if( !kb->setValuePointer("kBT", val ) ) plumed_error();
+     686          61 :         kb->updateUnits( passtools.get() );
+     687             :       }
+     688             :       break;
+     689             :       /* ADDED WITH API==3 */
+     690           8 :       case cmd_setRestart:
+     691           8 :         CHECK_NOTINIT(initialized,word);
+     692           8 :         CHECK_NOTNULL(val,word);
+     693           8 :         if(val.get<int>()!=0) restart=true;
+     694             :         break;
+     695             :       /* ADDED WITH API==4 */
+     696           0 :       case cmd_doCheckPoint:
+     697           0 :         CHECK_INIT(initialized,word);
+     698           0 :         CHECK_NOTNULL(val,word);
+     699           0 :         doCheckPoint = false;
+     700           0 :         if(val.get<int>()!=0) doCheckPoint = true;
+     701             :         break;
+     702             :       /* ADDED WITH API==6 */
+     703             :       case cmd_setNumOMPthreads:
+     704           0 :         CHECK_NOTNULL(val,word);
+     705             :         {
+     706           0 :           auto nt=val.get<unsigned>();
+     707             :           if(nt==0) nt=1;
+     708           0 :           OpenMP::setNumThreads(nt);
+     709             :         }
+     710             :         break;
+     711             :       /* ADDED WITH API==10 */
+     712             :       case cmd_setGpuDeviceId:
+     713           0 :         CHECK_NOTNULL(val,word);
+     714             :         {
+     715           0 :           auto id=val.get<int>();
+     716           0 :           if(id>=0) gpuDeviceId=id;
+     717             :         }
+     718             :         break;
+     719             :       /* ADDED WITH API==6 */
+     720             :       /* only used for testing */
+     721             :       case cmd_throw:
+     722          61 :         CHECK_NOTNULL(val,word);
+     723          61 :         testThrow(val.getCString());
+     724             :       /* ADDED WITH API==10 */
+     725             :       case cmd_setNestedExceptions:
+     726          27 :         CHECK_NOTNULL(val,word);
+     727          27 :         if(val.get<int>()!=0) nestedExceptions=true;
+     728           1 :         else nestedExceptions=false;
+     729             :         break;
+     730             :       /* STOP API */
+     731        1018 :       case cmd_setMDEngine:
+     732        1018 :         CHECK_NOTINIT(initialized,word);
+     733        1018 :         CHECK_NOTNULL(val,word);
+     734        1018 :         MDEngine=val.getCString();
+     735             :         break;
+     736         993 :       case cmd_setLog:
+     737         993 :         CHECK_NOTINIT(initialized,word);
+     738         993 :         log.link(val.get<FILE*>());
+     739             :         break;
+     740         169 :       case cmd_setLogFile:
+     741         169 :         CHECK_NOTINIT(initialized,word);
+     742         169 :         CHECK_NOTNULL(val,word);
+     743         169 :         log.open(val.getCString());
+     744         169 :         break;
+     745             :       // other commands that should be used after initialization:
+     746      265887 :       case cmd_setStopFlag:
+     747      265887 :         CHECK_INIT(initialized,word);
+     748      265887 :         CHECK_NOTNULL(val,word);
+     749      265887 :         val.get<int*>(); // just check type and discard pointer
+     750      265886 :         stopFlag=val.copy();
+     751      265886 :         break;
+     752           0 :       case cmd_getExchangesFlag:
+     753           0 :         CHECK_INIT(initialized,word);
+     754           0 :         CHECK_NOTNULL(val,word);
+     755           0 :         exchangePatterns.getFlag(*val.get<int*>()); // note: getFlag changes the value of the reference!
+     756             :         break;
+     757           0 :       case cmd_setExchangesSeed:
+     758           0 :         CHECK_INIT(initialized,word);
+     759           0 :         CHECK_NOTNULL(val,word);
+     760           0 :         exchangePatterns.setSeed(val.get<int>());
+     761             :         break;
+     762           0 :       case cmd_setNumberOfReplicas:
+     763           0 :         CHECK_INIT(initialized,word);
+     764           0 :         CHECK_NOTNULL(val,word);
+     765           0 :         exchangePatterns.setNofR(val.get<int>());
+     766             :         break;
+     767           0 :       case cmd_getExchangesList:
+     768           0 :         CHECK_INIT(initialized,word);
+     769           0 :         CHECK_NOTNULL(val,word);
+     770           0 :         exchangePatterns.getList(val);
+     771             :         break;
+     772         943 :       case cmd_runFinalJobs:
+     773         943 :         CHECK_INIT(initialized,word);
+     774         943 :         runJobsAtEndOfCalculation();
+     775             :         break;
+     776          96 :       case cmd_isEnergyNeeded:
+     777             :       {
+     778          96 :         CHECK_INIT(initialized,word);
+     779          96 :         CHECK_NOTNULL(val,word);
+     780          96 :         if( name_of_energy =="" ) {
+     781          96 :           val.set(int(0));
+     782             :         } else {
+     783           0 :           ActionToPutData* ap=actionSet.selectWithLabel<ActionToPutData*>(name_of_energy);
+     784           0 :           if(ap->isActive()) val.set(int(1));
+     785           0 :           else               val.set(int(0));
+     786             :         }
+     787             :       }
+     788             :       break;
+     789        7051 :       case cmd_getBias:
+     790        7051 :         CHECK_INIT(initialized,word);
+     791        7051 :         CHECK_NOTNULL(val,word);
+     792        7051 :         plumedQuantityToMD( "energy", getBias(), val );
+     793        7051 :         break;
+     794             :       case cmd_checkAction:
+     795           2 :         CHECK_NOTNULL(val,word);
+     796           2 :         plumed_assert(nw==2);
+     797           3 :         val.set(int(actionRegister().check(dlloader.getHandles(), std::string(words[1])) ? 1:0));
+     798           2 :         break;
+     799             :       case cmd_setExtraCV:
+     800             :       {
+     801          30 :         CHECK_NOTNULL(val,word);
+     802          30 :         plumed_assert(nw==2);
+     803          90 :         if( valueExists(std::string(words[1])) ) setInputValue( std::string(words[1]), 0, 1, val );
+     804             :       }
+     805             :       break;
+     806             :       case cmd_setExtraCVForce:
+     807             :       {
+     808          30 :         CHECK_NOTNULL(val,word); plumed_assert(nw==2);
+     809         120 :         if( valueExists(std::string(words[1])) ) setInputForce( std::string(words[1]), val );
+     810             :       }
+     811             :       break;
+     812             :       /* ADDED WITH API==10 */
+     813             :       case cmd_isExtraCVNeeded:
+     814          10 :         CHECK_NOTNULL(val,word);
+     815          10 :         plumed_assert(nw==2); val.set(int(0));
+     816          56 :         for(const auto & p : inputs) {
+     817          50 :           if( p->getLabel()==words[1] && p->isActive() ) { val.set(int(1)); break; }
+     818             :         }
+     819             :         break;
+     820        1077 :       case cmd_GREX:
+     821        1281 :         if(!grex) grex=Tools::make_unique<GREX>(*this);
+     822        1077 :         plumed_massert(grex,"error allocating grex");
+     823             :         {
+     824        1077 :           std::string kk=std::string(words[1]);
+     825        1419 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+std::string(words[i]);
+     826        1077 :           grex->cmd(kk.c_str(),val);
+     827             :         }
+     828        1077 :         break;
+     829       16329 :       case cmd_CLTool:
+     830       16329 :         CHECK_NOTINIT(initialized,word);
+     831       21677 :         if(!cltool) cltool=Tools::make_unique<CLToolMain>();
+     832             :         {
+     833       16329 :           std::string kk(words[1]);
+     834       16329 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+std::string(words[i]);
+     835       16329 :           cltool->cmd(kk.c_str(),val);
+     836             :         }
+     837       16329 :         break;
+     838             :         break;
+     839             :       /* ADDED WITH API==7 */
+     840             :       case cmd_convert:
+     841             :       {
+     842             :         double v;
+     843          57 :         plumed_assert(words.size()==2);
+     844         280 :         if(Tools::convertNoexcept(std::string(words[1]),v)) passtools->double2MD(v,val);
+     845             :       }
+     846          57 :       break;
+     847           7 :       default:
+     848          14 :         plumed_error() << "cannot interpret cmd(\"" << word << "\"). check plumed developers manual to see the available commands.";
+     849             :         break;
+     850             :       }
+     851             :     }
+     852             : 
+     853     1329332 :   } catch (...) {
+     854         166 :     if(log.isOpen()) {
+     855             :       try {
+     856          92 :         log<<"\n################################################################################\n";
+     857          92 :         log<<Tools::concatenateExceptionMessages();
+     858          92 :         log<<"\n################################################################################\n";
+     859          92 :         log.flush();
+     860           0 :       } catch(...) {
+     861             :         // ignore errors here.
+     862             :         // in any case, we are rethrowing this below
+     863           0 :       }
+     864             :     }
+     865         166 :     throw;
+     866         166 :   }
+     867     1329000 : }
+     868             : 
+     869             : ////////////////////////////////////////////////////////////////////////
+     870             : 
+     871        1286 : void PlumedMain::init() {
+     872             : // check that initialization just happens once
+     873        1286 :   initialized=true;
+     874        1286 :   if(!log.isOpen()) log.link(stdout);
+     875        1286 :   log<<"PLUMED is starting\n";
+     876        3858 :   log<<"Version: "<<config::getVersionLong()<<" (git: "<<config::getVersionGit()<<") "
+     877        5144 :      <<"compiled on " <<config::getCompilationDate() << " at " << config::getCompilationTime() << "\n";
+     878        1286 :   log<<"Please cite these papers when using PLUMED ";
+     879        2572 :   log<<cite("The PLUMED consortium, Nat. Methods 16, 670 (2019)");
+     880        2572 :   log<<cite("Tribello, Bonomi, Branduardi, Camilloni, and Bussi, Comput. Phys. Commun. 185, 604 (2014)");
+     881        1286 :   log<<"\n";
+     882        1286 :   log<<"For further information see the PLUMED web page at http://www.plumed.org\n";
+     883        1286 :   log<<"Root: "<<config::getPlumedRoot()<<"\n";
+     884        1286 :   log<<"LibraryPath: "<<config::getLibraryPath()<<"\n";
+     885        2572 :   log<<"For installed feature, see "<<config::getPlumedRoot() + "/src/config/config.txt\n";
+     886        1286 :   log.printf("Molecular dynamics engine: %s\n",MDEngine.c_str());
+     887        1286 :   log.printf("Precision of reals: %d\n",passtools->getRealPrecision());
+     888        2332 :   log.printf("Running over %d %s\n",comm.Get_size(),(comm.Get_size()>1?"nodes":"node"));
+     889        1286 :   log<<"Number of threads: "<<OpenMP::getNumThreads()<<"\n";
+     890        1286 :   log<<"Cache line size: "<<OpenMP::getCachelineSize()<<"\n";
+     891        4766 :   for(const auto & pp : inputs ) {
+     892        3480 :     plumed_assert(pp);
+     893        3480 :     DomainDecomposition* dd=pp->castToDomainDecomposition();
+     894        3480 :     if ( dd ) log.printf("Number of atoms: %d\n",dd->getNumberOfAtoms());
+     895             :   }
+     896        1286 :   if(grex) log.printf("GROMACS-like replica exchange is on\n");
+     897        1286 :   log.printf("File suffix: %s\n",getSuffix().c_str());
+     898        1286 :   if(plumedDat.length()>0) {
+     899        1003 :     readInputFile(plumedDat);
+     900             :     plumedDat="";
+     901             :   }
+     902        1286 :   setUnits( passtools->usingNaturalUnits, passtools->units );
+     903        1286 :   ActionToPutData* ts = actionSet.selectWithLabel<ActionToPutData*>("timestep");
+     904        1286 :   if(ts) log.printf("Timestep: %f\n",(ts->copyOutput(0))->get());
+     905        1286 :   ActionToPutData* kb = actionSet.selectWithLabel<ActionToPutData*>("kBT");
+     906        1286 :   if(kb)
+     907          61 :     log.printf("KbT: %f\n",(kb->copyOutput(0))->get());
+     908             :   else {
+     909        1225 :     log.printf("KbT has not been set by the MD engine\n");
+     910        1225 :     log.printf("It should be set by hand where needed\n");
+     911             :   }
+     912        1286 :   log<<"Relevant bibliography:\n";
+     913        1286 :   log<<citations;
+     914        1286 :   log<<"Please read and cite where appropriate!\n";
+     915        1286 :   log<<"Finished setup\n";
+     916        1286 : }
+     917             : 
+     918       52074 : void PlumedMain::setupInterfaceActions() {
+     919      102880 :   inputs.clear(); std::vector<ActionForInterface*> ap=actionSet.select<ActionForInterface*>();
+     920      422088 :   for(unsigned i=0; i<ap.size(); ++i) {
+     921      370014 :     if( ap[i]->getName()=="ENERGY" || ap[i]->getDependencies().size()==0 ) inputs.push_back( ap[i] );
+     922             :   }
+     923       52074 : }
+     924             : 
+     925        1026 : void PlumedMain::readInputFile(const std::string & str) {
+     926        1026 :   plumed_assert(initialized);
+     927        1026 :   log<<"FILE: "<<str<<"\n";
+     928        1026 :   IFile ifile;
+     929        1026 :   ifile.link(*this);
+     930        1026 :   ifile.open(str);
+     931        1026 :   ifile.allowNoEOL();
+     932        1026 :   readInputFile(ifile);
+     933        1026 :   log<<"END FILE: "<<str<<"\n";
+     934        1026 :   log.flush();
+     935             : 
+     936        1026 : }
+     937             : 
+     938        1028 : void PlumedMain::readInputFile(IFile & ifile) {
+     939             :   std::vector<std::string> words;
+     940       19451 :   while(Tools::getParsedLine(ifile,words) && !endPlumed) readInputWords(words,false);
+     941        1028 :   endPlumed=false;
+     942        1028 :   pilots=actionSet.select<ActionPilot*>();
+     943        1028 :   setupInterfaceActions();
+     944        1028 : }
+     945             : 
+     946       32800 : void PlumedMain::readInputLine(const std::string & str, const bool& before_init) {
+     947       32800 :   if( !before_init ) plumed_assert(initialized);
+     948       32800 :   if(str.empty()) return;
+     949       32800 :   std::vector<std::string> words=Tools::getWords(str);
+     950       32800 :   citations.clear();
+     951       32800 :   readInputWords(words,before_init);
+     952       32745 :   if(!citations.empty()) {
+     953         487 :     log<<"Relevant bibliography:\n";
+     954         487 :     log<<citations;
+     955         487 :     log<<"Please read and cite where appropriate!\n";
+     956             :   }
+     957       32800 : }
+     958             : 
+     959           2 : void PlumedMain::readInputLines(const std::string & str) {
+     960           2 :   plumed_assert(initialized);
+     961           2 :   if(str.empty()) return;
+     962             : 
+     963           2 :   log<<"FILE: (temporary)\n";
+     964             : 
+     965             :   // Open a temporary file
+     966           2 :   auto fp=std::tmpfile();
+     967           2 :   plumed_assert(fp);
+     968             : 
+     969             :   // make sure file is closed (and thus deleted) also if an exception occurs
+     970           2 :   auto deleter=[](auto fp) { std::fclose(fp); };
+     971             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     972             : 
+     973           2 :   auto ret=std::fputs(str.c_str(),fp);
+     974           2 :   plumed_assert(ret!=EOF);
+     975             : 
+     976           2 :   std::rewind(fp);
+     977             : 
+     978           2 :   IFile ifile;
+     979           2 :   ifile.link(*this);
+     980           2 :   ifile.link(fp);
+     981           2 :   ifile.allowNoEOL();
+     982             : 
+     983           2 :   readInputFile(ifile);
+     984           2 :   log<<"END FILE: (temporary)\n";
+     985           2 : }
+     986             : 
+     987       51273 : void PlumedMain::readInputWords(const std::vector<std::string> & words, const bool& before_init) {
+     988       51273 :   if( !before_init ) plumed_assert(initialized);
+     989       51273 :   if(words.empty())return;
+     990       51101 :   else if(words[0]=="_SET_SUFFIX") {
+     991           3 :     plumed_assert(words.size()==2);
+     992             :     setSuffix(words[1]);
+     993             :   } else {
+     994       51098 :     std::vector<std::string> interpreted(words);
+     995       51098 :     Tools::interpretLabel(interpreted);
+     996      102141 :     auto action=actionRegister().create(dlloader.getHandles(),ActionOptions(*this,interpreted));
+     997       51043 :     if(!action) {
+     998             :       std::string msg;
+     999             :       msg ="ERROR\nI cannot understand line:";
+    1000           0 :       for(unsigned i=0; i<interpreted.size(); ++i) msg+=" "+interpreted[i];
+    1001             :       msg+="\nMaybe a missing space or a typo?";
+    1002           0 :       log << msg;
+    1003           0 :       log.flush();
+    1004           0 :       plumed_merror(msg);
+    1005             :     }
+    1006       51043 :     action->checkRead();
+    1007       51043 :     actionSet.emplace_back(std::move(action));
+    1008       51098 :   };
+    1009             : 
+    1010       51046 :   pilots=actionSet.select<ActionPilot*>();
+    1011       51046 :   setupInterfaceActions();
+    1012             : }
+    1013             : 
+    1014             : ////////////////////////////////////////////////////////////////////////
+    1015             : 
+    1016           0 : void PlumedMain::exit(int c) {
+    1017           0 :   comm.Abort(c);
+    1018           0 : }
+    1019             : 
+    1020       51096 : Log& PlumedMain::getLog() {
+    1021       51096 :   return log;
+    1022             : }
+    1023             : 
+    1024      277801 : void PlumedMain::calc() {
+    1025      277801 :   prepareCalc();
+    1026      277785 :   performCalc();
+    1027      277783 : }
+    1028             : 
+    1029      284752 : void PlumedMain::prepareCalc() {
+    1030      284752 :   prepareDependencies();
+    1031      284752 :   shareData();
+    1032      284736 : }
+    1033             : 
+    1034             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    1035             : // here we have the main steps in "calc()"
+    1036             : // they can be called individually, but the standard thing is to
+    1037             : // traverse them in this order:
+    1038      285079 : void PlumedMain::prepareDependencies() {
+    1039             : 
+    1040             : // Stopwatch is stopped when sw goes out of scope
+    1041      285079 :   auto sw=stopwatch.startStop("1 Prepare dependencies");
+    1042             : 
+    1043             : // activate all the actions which are on step
+    1044             : // activation is recursive and enables also the dependencies
+    1045             : // before doing that, the prepare() method is called to see if there is some
+    1046             : // new/changed dependency (up to now, only useful for dependences on virtual atoms,
+    1047             : // which can be dynamically changed).
+    1048             : 
+    1049             : // First switch off all actions
+    1050     4639022 :   for(const auto & p : actionSet) {
+    1051     4353943 :     p->deactivate();
+    1052             :   }
+    1053             : 
+    1054             : // for optimization, an "active" flag remains false if no action at all is active
+    1055      285079 :   active=false;
+    1056     1719442 :   for(unsigned i=0; i<pilots.size(); ++i) {
+    1057     1434363 :     if(pilots[i]->onStep()) {
+    1058     1341292 :       pilots[i]->activate();
+    1059     1341292 :       active=true;
+    1060             :     }
+    1061             :   };
+    1062             : 
+    1063             : // This stops the driver calculation if there is not a read action
+    1064      285079 :   if( !active && !inputsAreActive() ) stopFlag.set(int(1));
+    1065             : 
+    1066             : // also, if one of them is the total energy, tell to atoms that energy should be collected
+    1067     4639022 :   for(const auto & p : actionSet) {
+    1068     4353943 :     if(p->isActive()) {
+    1069     2618148 :       if(p->checkNeedsGradients()) p->setOption("GRADIENTS");
+    1070             :     }
+    1071             :   }
+    1072             : 
+    1073      285079 : }
+    1074             : 
+    1075        1763 : bool PlumedMain::inputsAreActive() const {
+    1076        5178 :   for(const auto & ip : inputs) {
+    1077        5122 :     if( ip->onStep() ) return true;
+    1078             :   }
+    1079             :   return false;
+    1080             : }
+    1081             : 
+    1082         114 : void PlumedMain::shareAll() {
+    1083         456 :   for(const auto & ip : inputs) ip->shareAll();
+    1084         114 : }
+    1085             : 
+    1086      284836 : void PlumedMain::shareData() {
+    1087             : // atom positions are shared (but only if there is something to do)
+    1088      284836 :   if(!active)return;
+    1089             : // Stopwatch is stopped when sw goes out of scope
+    1090      283133 :   auto sw=stopwatch.startStop("2 Sharing data");
+    1091      742954 :   for(const auto & ip : inputs) ip->share();
+    1092      283133 : }
+    1093             : 
+    1094        7011 : void PlumedMain::performCalcNoUpdate() {
+    1095        7011 :   waitData();
+    1096        7011 :   justCalculate();
+    1097        7011 :   backwardPropagate();
+    1098        7011 :   resetInputs();
+    1099        7011 : }
+    1100             : 
+    1101          10 : void PlumedMain::performCalcNoForces() {
+    1102          10 :   waitData();
+    1103          10 :   justCalculate();
+    1104          10 : }
+    1105             : 
+    1106      277795 : void PlumedMain::performCalc() {
+    1107      277795 :   waitData();
+    1108      277795 :   justCalculate();
+    1109      277795 :   backwardPropagate();
+    1110      277793 :   update();
+    1111      277793 :   resetInputs();
+    1112      277793 : }
+    1113             : 
+    1114      284930 : void PlumedMain::waitData() {
+    1115      284930 :   if(!active)return;
+    1116             : // Stopwatch is stopped when sw goes out of scope
+    1117      283227 :   auto sw=stopwatch.startStop("3 Waiting for data");
+    1118      743366 :   for(const auto & ip : inputs) {
+    1119      460139 :     if( ip->isActive() && ip->hasBeenSet() ) ip->wait();
+    1120      300178 :     else if( ip->isActive() ) ip->warning("input requested but this quantity has not been set");
+    1121             :   }
+    1122      283227 : }
+    1123             : 
+    1124      284930 : void PlumedMain::justCalculate() {
+    1125      284930 :   if(!active)return;
+    1126             : // Stopwatch is stopped when sw goes out of scope
+    1127      283227 :   auto sw=stopwatch.startStop("4 Calculating (forward loop)");
+    1128      283227 :   bias=0.0;
+    1129      283227 :   work=0.0;
+    1130             : 
+    1131             :   // Check the input actions to determine if we need to calculate constants that
+    1132             :   // depend on masses and charges
+    1133             :   bool firststep=false;
+    1134      743366 :   for(const auto & ip : inputs) {
+    1135      460139 :     if( ip->firststep ) firststep=true;
+    1136             :   }
+    1137      286525 :   if( firststep ) { for(const auto & ip : inputs) ip->firststep=false; }
+    1138             : 
+    1139             :   int iaction=0;
+    1140             : // calculate the active actions in order (assuming *backward* dependence)
+    1141     4606172 :   for(const auto & pp : actionSet) {
+    1142             :     Action* p(pp.get());
+    1143     4322945 :     plumed_assert(p);
+    1144             :     try {
+    1145     4322945 :       if(p->isActive()) {
+    1146             : // Stopwatch is stopped when sw goes out of scope.
+    1147             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+    1148     2616067 :         Stopwatch::Handler sw;
+    1149     2616067 :         if(detailedTimers) {
+    1150        2481 :           auto actionNumberLabel=std::to_string(iaction);
+    1151        2481 :           const unsigned m=actionSet.size();
+    1152        7443 :           unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+    1153        2481 :           auto spaces=std::string(k-actionNumberLabel.length(),' ');
+    1154        2481 :           sw=stopwatch.startStop("4A " + spaces + actionNumberLabel+" "+p->getLabel());
+    1155             :         }
+    1156     2616067 :         ActionWithValue*av=p->castToActionWithValue();
+    1157     2616067 :         ActionAtomistic*aa=p->castToActionAtomistic();
+    1158             :         {
+    1159     2616067 :           if(av) av->clearInputForces();
+    1160     2616067 :           if(av) av->clearDerivatives();
+    1161     2616067 :           if( av && av->calculateOnUpdate() ) continue ;
+    1162             :         }
+    1163             :         {
+    1164     2612052 :           if(aa) if(aa->isActive()) aa->retrieveAtoms();
+    1165             :         }
+    1166     2612052 :         if(p->checkNumericalDerivatives()) p->calculateNumericalDerivatives();
+    1167     2611802 :         else p->calculate();
+    1168             :         // This retrieves components called bias
+    1169     2612052 :         if(av) {
+    1170     2334970 :           bias+=av->getOutputQuantity("bias");
+    1171     2334970 :           work+=av->getOutputQuantity("work");
+    1172     2334970 :           av->setGradientsIfNeeded();
+    1173             :         }
+    1174             :         // This makes all values that depend on the (fixed) masses and charges constant
+    1175     2612052 :         if( firststep ) p->setupConstantValues( true );
+    1176     2612052 :         ActionWithVirtualAtom*avv=p->castToActionWithVirtualAtom();
+    1177     2612052 :         if(avv)avv->setGradientsIfNeeded();
+    1178     2616067 :       }
+    1179           0 :     } catch(...) {
+    1180           0 :       plumed_error_nested() << "An error happened while calculating " << p->getLabel();
+    1181           0 :     }
+    1182     4318930 :     iaction++;
+    1183             :   }
+    1184      283227 : }
+    1185             : 
+    1186           0 : void PlumedMain::justApply() {
+    1187           0 :   backwardPropagate();
+    1188           0 :   update();
+    1189           0 :   resetInputs();
+    1190           0 : }
+    1191             : 
+    1192      284806 : void PlumedMain::backwardPropagate() {
+    1193      284806 :   if(!active)return;
+    1194             :   int iaction=0;
+    1195             : // Stopwatch is stopped when sw goes out of scope
+    1196      283103 :   auto sw=stopwatch.startStop("5 Applying (backward loop)");
+    1197             : // apply them in reverse order
+    1198     4603706 :   for(auto pp=actionSet.rbegin(); pp!=actionSet.rend(); ++pp) {
+    1199             :     const auto & p(pp->get());
+    1200     4320605 :     if(p->isActive()) {
+    1201             : 
+    1202             : // Stopwatch is stopped when sw goes out of scope.
+    1203             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+    1204     2614391 :       Stopwatch::Handler sw;
+    1205     2614391 :       if(detailedTimers) {
+    1206        2481 :         auto actionNumberLabel=std::to_string(iaction);
+    1207        2481 :         const unsigned m=actionSet.size();
+    1208        7443 :         unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+    1209        2481 :         auto spaces=std::string(k-actionNumberLabel.length(),' ');
+    1210        2481 :         sw=stopwatch.startStop("5A " + spaces + actionNumberLabel+" "+p->getLabel());
+    1211             :       }
+    1212             : 
+    1213     2614391 :       p->apply();
+    1214     2614391 :     }
+    1215     4320603 :     iaction++;
+    1216             :   }
+    1217             : 
+    1218             : // Stopwatch is stopped when sw goes out of scope.
+    1219             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+    1220      283101 :   Stopwatch::Handler sw1;
+    1221      283101 :   if(detailedTimers) sw1=stopwatch.startStop("5B Update forces");
+    1222      283103 : }
+    1223             : 
+    1224      277872 : void PlumedMain::update() {
+    1225      277872 :   if(!active)return;
+    1226             : 
+    1227             : // Stopwatch is stopped when sw goes out of scope
+    1228      276169 :   auto sw=stopwatch.startStop("6 Update");
+    1229             : 
+    1230             : // update step (for statistics, etc)
+    1231      276169 :   updateFlags.push(true);
+    1232     4379487 :   for(const auto & p : actionSet) {
+    1233     4103318 :     p->beforeUpdate();
+    1234     6622700 :     if(p->isActive() && p->checkUpdate() && updateFlagsTop()) {
+    1235     2519362 :       ActionWithValue* av=dynamic_cast<ActionWithValue*>(p.get());
+    1236     2519362 :       if( av && av->calculateOnUpdate() ) { p->prepare(); p->calculate(); }
+    1237     2515347 :       else p->update();
+    1238             :     }
+    1239             :   }
+    1240      552342 :   while(!updateFlags.empty()) updateFlags.pop();
+    1241             :   if(!updateFlags.empty()) plumed_merror("non matching changes in the update flags");
+    1242             : // Check that no action has told the calculation to stop
+    1243      276169 :   if(stopNow) {
+    1244          65 :     if(stopFlag) stopFlag.set(int(1));
+    1245           0 :     else plumed_merror("your md code cannot handle plumed stop events - add a call to plumed.comm(stopFlag,stopCondition)");
+    1246             :   }
+    1247             : 
+    1248             : // flush by default every 10000 steps
+    1249             : // hopefully will not affect performance
+    1250             : // also if receive checkpointing signal
+    1251      276169 :   if(step%10000==0||doCheckPoint) {
+    1252        1201 :     fflush();
+    1253        1201 :     log.flush();
+    1254       53221 :     for(const auto & p : actionSet) p->fflush();
+    1255             :   }
+    1256      276169 : }
+    1257             : 
+    1258          42 : void PlumedMain::load(const std::string& fileName) {
+    1259          42 :   if(DLLoader::installed()) {
+    1260          42 :     std::string libName=fileName;
+    1261          42 :     size_t n=libName.find_last_of(".");
+    1262          43 :     std::string extension="";
+    1263          42 :     std::string base=libName;
+    1264          42 :     if(n!=std::string::npos && n<libName.length()-1)
+    1265          84 :       extension=libName.substr(n+1);
+    1266          42 :     if(n!=std::string::npos && n<libName.length())
+    1267          84 :       base=libName.substr(0,n);
+    1268             : 
+    1269          42 :     if(extension=="cpp") {
+    1270          46 :       libName="./"+base+"."+config::getVersionLong()+"."+config::getSoExt();
+    1271             : // full path command, including environment setup
+    1272             : // this will work even if plumed is not in the execution path or if it has been
+    1273             : // installed with a name different from "plumed"
+    1274          46 :       std::string cmd=config::getEnvCommand()+" \""+config::getPlumedRoot()+"\"/scripts/mklib.sh -n -o "+libName+" "+fileName;
+    1275             : 
+    1276          23 :       if(std::getenv("PLUMED_LOAD_ACTION_DEBUG")) log<<"Executing: "<<cmd;
+    1277          23 :       else log<<"Compiling: "<<fileName<<" to "<<libName;
+    1278             : 
+    1279          23 :       if(comm.Get_size()>0) log<<" (only on master node)";
+    1280          23 :       log<<"\n";
+    1281             : 
+    1282             :       // On MPI process (intracomm), we use Get_rank to make sure a single process does the compilation
+    1283             :       // Processes from multiple replicas might simultaneously do the compilation.
+    1284          23 :       if(comm.Get_rank()==0) {
+    1285          23 :         static Tools::CriticalSectionWithKey<std::string> section;
+    1286             :         // This is only locking commands that are running with identical arguments.
+    1287             :         // It is not necessary for correctness (a second mklib would just result in a no op since
+    1288             :         // the library is already there, even if running simultaneously).
+    1289             :         // It however decreases the system load if many threads are used.
+    1290             :         auto s=section.startStop(cmd);
+    1291          23 :         int ret=std::system(cmd.c_str());
+    1292          24 :         if(ret!=0) plumed_error() <<"An error happened while executing command "<<cmd<<"\n";
+    1293          23 :       }
+    1294          22 :       comm.Barrier();
+    1295             :     } else {
+    1296          38 :       libName=base+"."+config::getSoExt();
+    1297             :     }
+    1298             : 
+    1299             :     // If we have multiple threads (each holding a Plumed object), each of them
+    1300             :     // will load the library, but each of them will only see actions registered
+    1301             :     // from the owned library
+    1302          41 :     auto *p=dlloader.load(libName);
+    1303          42 :     log<<"Loading shared library "<<libName.c_str()<<" at "<<p<<"\n";
+    1304          41 :     log<<"Here is the list of new actions\n";
+    1305          41 :     log<<"\n";
+    1306          82 :     for(const auto & a : actionRegister().getKeysWithDLHandle(p)) log<<a<<"\n";
+    1307          41 :     log<<"\n";
+    1308             :   } else {
+    1309           0 :     plumed_error()<<"While loading library "<< fileName << " loading was not enabled, please check if dlopen was found at configure time";
+    1310             :   }
+    1311          41 : }
+    1312             : 
+    1313      284804 : void PlumedMain::resetInputs() {
+    1314      749702 :   for(const auto & ip : inputs) {
+    1315      464898 :     if( ip->isActive() && ip->hasBeenSet() ) ip->reset();
+    1316             :   }
+    1317      284804 : }
+    1318             : 
+    1319        7684 : double PlumedMain::getBias() const {
+    1320        7684 :   return bias;
+    1321             : }
+    1322             : 
+    1323         450 : double PlumedMain::getWork() const {
+    1324         450 :   return work;
+    1325             : }
+    1326             : 
+    1327          82 : FILE* PlumedMain::fopen(const char *path, const char *mode) {
+    1328          82 :   std::string mmode(mode);
+    1329          83 :   std::string ppath(path);
+    1330          82 :   std::string suffix(getSuffix());
+    1331          82 :   std::string ppathsuf=ppath+suffix;
+    1332          82 :   FILE*fp=std::fopen(const_cast<char*>(ppathsuf.c_str()),const_cast<char*>(mmode.c_str()));
+    1333          82 :   if(!fp) fp=std::fopen(const_cast<char*>(ppath.c_str()),const_cast<char*>(mmode.c_str()));
+    1334          84 :   plumed_massert(fp,"file " + ppath + " cannot be found");
+    1335          81 :   return fp;
+    1336             : }
+    1337             : 
+    1338          99 : int PlumedMain::fclose(FILE*fp) {
+    1339          99 :   return std::fclose(fp);
+    1340             : }
+    1341             : 
+    1342        4684 : std::string PlumedMain::cite(const std::string&item) {
+    1343        4684 :   return citations.cite(item);
+    1344             : }
+    1345             : 
+    1346        1762 : void PlumedMain::fflush() {
+    1347        5272 :   for(const auto  & p : files) {
+    1348        3510 :     p->flush();
+    1349             :   }
+    1350        1762 : }
+    1351             : 
+    1352        5076 : void PlumedMain::insertFile(FileBase&f) {
+    1353        5076 :   files.insert(&f);
+    1354        5076 : }
+    1355             : 
+    1356        5338 : void PlumedMain::eraseFile(FileBase&f) {
+    1357        5338 :   files.erase(&f);
+    1358        5338 : }
+    1359             : 
+    1360          65 : void PlumedMain::stop() {
+    1361          65 :   stopNow=true;
+    1362          65 : }
+    1363             : 
+    1364         943 : void PlumedMain::runJobsAtEndOfCalculation() {
+    1365       47556 :   for(const auto & p : actionSet) {
+    1366       46613 :     ActionWithValue* av=dynamic_cast<ActionWithValue*>(p.get());
+    1367       46613 :     if( av && av->calculateOnUpdate() ) p->activate();
+    1368             :   }
+    1369       47556 :   for(const auto & p : actionSet) {
+    1370       46613 :     ActionPilot* ap=dynamic_cast<ActionPilot*>(p.get());
+    1371       46613 :     ActionWithValue* av=dynamic_cast<ActionWithValue*>(p.get());
+    1372       46613 :     if( av && av->calculateOnUpdate() ) { p->calculate(); }
+    1373       46199 :     else if( ap && !av && ap->getStride()==0 ) { p->update(); }
+    1374       46129 :     else p->runFinalJobs();
+    1375             :   }
+    1376         943 : }
+    1377             : 
+    1378     8807351 : unsigned PlumedMain::increaseReferenceCounter() noexcept {
+    1379     8807351 :   return ++referenceCounter;
+    1380             : }
+    1381             : 
+    1382     8806275 : unsigned PlumedMain::decreaseReferenceCounter() noexcept {
+    1383     8806275 :   return --referenceCounter;
+    1384             : }
+    1385             : 
+    1386          42 : unsigned PlumedMain::useCountReferenceCounter() const noexcept {
+    1387          42 :   return referenceCounter;
+    1388             : }
+    1389             : 
+    1390          60 : bool PlumedMain::valueExists( const std::string& name ) const {
+    1391         240 :   for(const auto & p : inputs) {
+    1392         240 :     if( p->getLabel()==name ) return true;
+    1393             :   }
+    1394             :   return false;
+    1395             : }
+    1396             : 
+    1397      449858 : void PlumedMain::setInputValue( const std::string& name, const unsigned& start, const unsigned& stride, const TypesafePtr & val ) {
+    1398             :   bool found=false;
+    1399     1218081 :   for(const auto & pp : inputs) {
+    1400     1218081 :     if( pp->setValuePointer( name, val ) ) { pp->setStart(name, start); pp->setStride(name, stride); found=true; break; }
+    1401             :   }
+    1402           0 :   plumed_massert( found, "found no action to set named " + name );
+    1403      449854 : }
+    1404             : 
+    1405      281875 : void PlumedMain::setInputForce( const std::string& name, const TypesafePtr & val ) {
+    1406             :   bool found=false;
+    1407      756782 :   for(const auto & pp : inputs) {
+    1408      756782 :     if( pp->setForcePointer( name, val ) ) { found=true; break; }
+    1409             :   }
+    1410      281857 :   plumed_massert( found, "found no action to set named " + name );
+    1411      281857 : }
+    1412             : 
+    1413        1323 : void PlumedMain::setUnits( const bool& natural, const Units& u ) {
+    1414        1323 :   passtools->usingNaturalUnits = natural; passtools->units=u;
+    1415        1323 :   std::vector<ActionToPutData*> idata = actionSet.select<ActionToPutData*>();
+    1416        9849 :   for(const auto & ip : idata) ip->updateUnits( passtools.get() );
+    1417       50901 :   for(const auto & p : actionSet ) p->resetStoredTimestep();
+    1418        1323 : }
+    1419             : 
+    1420      284749 : void PlumedMain::startStep() {
+    1421      749439 :   for(const auto & ip : inputs) ip->resetForStepStart();
+    1422      284749 : }
+    1423             : 
+    1424         114 : void PlumedMain::writeBinary(std::ostream&o)const {
+    1425         456 :   for(const auto & ip : inputs) ip->writeBinary(o);
+    1426         114 : }
+    1427             : 
+    1428         114 : void PlumedMain::readBinary(std::istream&i) {
+    1429         456 :   for(const auto & ip : inputs) ip->readBinary(i);
+    1430         114 : }
+    1431             : 
+    1432          40 : void PlumedMain::setEnergyValue( const std::string& name ) {
+    1433          40 :   name_of_energy = name;
+    1434          40 : }
+    1435             : 
+    1436        9433 : int PlumedMain::getRealPrecision() const {
+    1437        9433 :   return passtools->getRealPrecision();
+    1438             : }
+    1439             : 
+    1440        5021 : bool PlumedMain::usingNaturalUnits() const {
+    1441        5021 :   return passtools->usingNaturalUnits;
+    1442             : }
+    1443             : 
+    1444    15935469 : const Units& PlumedMain::getUnits() {
+    1445    15935469 :   return passtools->units;
+    1446             : }
+    1447             : 
+    1448           4 : PlumedMain::DeprecatedAtoms& PlumedMain::getAtoms() {
+    1449           4 :   return datoms;
+    1450             : }
+    1451             : 
+    1452        7222 : void PlumedMain::plumedQuantityToMD( const std::string& unit, const double& eng, const TypesafePtr & m) const {
+    1453        7222 :   passtools->double2MD( eng/passtools->getUnitConversion(unit),m );
+    1454        7222 : }
+    1455             : 
+    1456           0 : double PlumedMain::MDQuantityToPLUMED( const std::string& unit, const TypesafePtr & m) const {
+    1457           0 :   double x=passtools->MD2double(m);
+    1458           0 :   return x*passtools->getUnitConversion(unit);
+    1459             : }
+    1460             : 
+    1461           1 : double PlumedMain::DeprecatedAtoms::getKBoltzmann() const {
+    1462           1 :   if( plumed.usingNaturalUnits() ) return 1.0;
+    1463           1 :   return kBoltzmann/plumed.getUnits().getEnergy();
+    1464             : }
+    1465             : 
+    1466           1 : double PlumedMain::DeprecatedAtoms::getKbT() const {
+    1467           1 :   ActionForInterface* kb=plumed.getActionSet().selectWithLabel<ActionForInterface*>("kBT");
+    1468           1 :   if( kb ) return (kb->copyOutput(0))->get();
+    1469             :   return 0.0;
+    1470             : }
+    1471             : 
+    1472           1 : int PlumedMain::DeprecatedAtoms::getNatoms() const {
+    1473           1 :   std::vector<ActionToPutData*> inputs=plumed.getActionSet().select<ActionToPutData*>();
+    1474           1 :   for(const auto & pp : inputs ) {
+    1475           2 :     if( pp->getRole()=="x" ) return (pp->copyOutput(0))->getShape()[0];
+    1476             :   }
+    1477             :   return 0;
+    1478             : }
+    1479             : 
+    1480           1 : bool PlumedMain::DeprecatedAtoms::usingNaturalUnits() const {
+    1481           1 :   return plumed.usingNaturalUnits();
+    1482             : }
+    1483             : 
+    1484           0 : void PlumedMain::DeprecatedAtoms::setCollectEnergy(bool b) const {
+    1485           0 :   plumed.readInputLine( plumed.MDEngine + "_energy: ENERGY" );
+    1486           0 :   plumed.setEnergyValue( plumed.MDEngine + "_energy" );
+    1487           0 : }
+    1488             : 
+    1489           0 : double PlumedMain::DeprecatedAtoms::getEnergy() const {
+    1490           0 :   ActionToPutData* av = plumed.getActionSet().selectWithLabel<ActionToPutData*>( plumed.MDEngine + "_energy" );
+    1491           0 :   return (av->copyOutput(0))->get();
+    1492             : }
+    1493             : 
+    1494           5 : void PlumedMain::activateParseOnlyMode() {
+    1495           5 :   doParseOnly=true;
+    1496           5 : }
+    1497             : 
+    1498        2160 : bool PlumedMain::parseOnlyMode() const {
+    1499        2160 :   return doParseOnly;
+    1500             : }
+    1501             : 
+    1502          97 : void PlumedMain::getKeywordsForAction( const std::string& action, Keywords& keys ) const {
+    1503          97 :   actionRegister().getKeywords( dlloader.getHandles(), action, keys );
+    1504          97 : }
+    1505             : 
+    1506             : #ifdef __PLUMED_HAS_PYTHON
+    1507             : // This is here to stop cppcheck throwing an error
+    1508             : #endif
+    1509             : 
+    1510             : #ifdef __PLUMED_HAS_DLADDR
+    1511             : // This is here to stop cppcheck throwing an error
+    1512             : #endif
+    1513             : 
+    1514             : }
+    1515             : 
+    1516             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+ + + + +
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 000000000..db9ba306a --- /dev/null +++ b/coverage/core/PlumedMain.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - core/PlumedMain.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..32a12aecf --- /dev/null +++ b/coverage/core/PlumedMain.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - core/PlumedMain.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..5b41113c5 --- /dev/null +++ b/coverage/core/PlumedMain.h.gcov.html @@ -0,0 +1,692 @@ + + + + + + + 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:171894.4 %
Date:2024-10-17 16:45:00Functions: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 Keywords;
+      72             : class DataPassingTools;
+      73             : 
+      74             : /**
+      75             : Main plumed object.
+      76             : In MD engines this object is not manipulated directly but it is wrapped in
+      77             : plumed or PLMD::Plumed objects. Its main method is cmd(),
+      78             : which defines completely the external plumed interface.
+      79             : It does not contain any static data.
+      80             : */
+      81             : class PlumedMain:
+      82             :   public WithCmd
+      83             : {
+      84             : /// Pointers to files opened in actions associated to this object.
+      85             : /// Notice that with the current implementation this should be at the top of this
+      86             : /// structure. Indeed, this should be destroyed *after* all the actions allocated
+      87             : /// in this PlumedMain object have been destroyed.
+      88             :   std::set<FileBase*> files;
+      89             : /// Forward declaration.
+      90             :   ForwardDecl<Communicator> comm_fwd;
+      91             : public:
+      92             : /// Communicator for plumed.
+      93             : /// Includes all the processors used by plumed.
+      94             :   Communicator&comm=*comm_fwd;
+      95             : 
+      96             : private:
+      97             :   class DeprecatedAtoms {
+      98             :   private:
+      99             :     PlumedMain & plumed;
+     100             :   public:
+     101      806680 :     explicit DeprecatedAtoms(PlumedMain& p): plumed(p) {}
+     102             :     [[deprecated("Use Action::getKBoltzmann().")]]
+     103             :     double getKBoltzmann() const ;
+     104             :     [[deprecated("Use Action::getkBT() N.B. this function also reads the TEMP keyword from the input for you.")]]
+     105             :     double getKbT() const ;
+     106             :     [[deprecated]]
+     107             :     int getNatoms() const ;
+     108             :     [[deprecated("Use Action::usingNaturalUnits().")]]
+     109             :     bool usingNaturalUnits() const ;
+     110             :     [[deprecated]]
+     111             :     void setCollectEnergy(bool b) const;
+     112             :     [[deprecated]]
+     113             :     double getEnergy() const ;
+     114             :   };
+     115             : /// Forward declaration.
+     116             :   ForwardDecl<DeprecatedAtoms> datoms_fwd;
+     117             : /// Object containing old bits of atoms that are used by many folks
+     118             :   DeprecatedAtoms&    datoms=*datoms_fwd;
+     119             : /// Forward declaration.
+     120             :   ForwardDecl<Communicator> multi_sim_comm_fwd;
+     121             : public:
+     122             :   DeprecatedAtoms& getAtoms();
+     123             :   Communicator&multi_sim_comm=*multi_sim_comm_fwd;
+     124             : 
+     125             : private:
+     126             : /// Error handler.
+     127             : /// Pointer to a function that is called an exception thrown within
+     128             : /// the library is about to leave the library.
+     129             : /// Can be used to remap exceptions in case the plumed wrapper was compiled
+     130             : /// with a different version of the C++ standard library.
+     131             : /// Should only be called from \ref plumed_plumedmain_cmd().
+     132             :   typedef struct {
+     133             :     void* ptr;
+     134             :     void(*handler)(void* ptr,int code,const char*);
+     135             :   } plumed_error_handler;
+     136             : 
+     137             :   plumed_error_handler error_handler= {NULL,NULL};
+     138             : 
+     139             :   bool nestedExceptions=false;
+     140             : 
+     141             : /// Forward declaration.
+     142             :   ForwardDecl<DLLoader> dlloader_fwd;
+     143             :   DLLoader& dlloader=*dlloader_fwd;
+     144             : 
+     145             :   std::unique_ptr<WithCmd> cltool;
+     146             : 
+     147             :   std::unique_ptr<WithCmd> grex;
+     148             : /// Flag to avoid double initialization
+     149             :   bool  initialized=false;
+     150             : /// Name of MD engine
+     151             :   std::string MDEngine{"mdcode"};
+     152             : 
+     153             : /// Forward declaration.
+     154             :   ForwardDecl<Log> log_fwd;
+     155             : /// Log stream
+     156             :   Log& log=*log_fwd;
+     157             : 
+     158             : /// Forward declaration.
+     159             : /// Should be placed after log since its constructor takes a log reference as an argument.
+     160             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+     161             :   Stopwatch& stopwatch=*stopwatch_fwd;
+     162             : 
+     163             : /// Forward declaration.
+     164             :   ForwardDecl<Citations> citations_fwd;
+     165             : /// tools/Citations.holder
+     166             :   Citations& citations=*citations_fwd;
+     167             : 
+     168             : /// Present step number.
+     169             :   long long int step=0;
+     170             : 
+     171             : /// Condition for plumed to be active.
+     172             : /// At every step, PlumedMain is checking if there are Action's requiring some work.
+     173             : /// If at least one Action requires some work, this variable is set to true.
+     174             :   bool active=false;
+     175             : 
+     176             : /// Name of the input file
+     177             :   std::string plumedDat;
+     178             : 
+     179             : /// End of input file.
+     180             : /// Set to true to terminate reading
+     181             :   bool endPlumed=false;
+     182             : 
+     183             : /// Forward declaration.
+     184             :   ForwardDecl<ActionSet> actionSet_fwd;
+     185             : /// Set of actions found in plumed.dat file
+     186             :   ActionSet& actionSet=*actionSet_fwd;
+     187             : 
+     188             : /// These are tools to pass data to PLUMED
+     189             :   std::unique_ptr<DataPassingTools> passtools;
+     190             : 
+     191             : /// Vector of actions that are passed data from the MD code
+     192             :   std::vector<ActionForInterface*> inputs;
+     193             : 
+     194             : /// Set of Pilot actions.
+     195             : /// These are the action the, if they are Pilot::onStep(), can trigger execution
+     196             :   std::vector<ActionPilot*> pilots;
+     197             : 
+     198             : /// Suffix string for file opening, useful for multiple simulations in the same directory
+     199             :   std::string suffix;
+     200             : 
+     201             : /// The total bias (=total energy of the restraints)
+     202             :   double bias=0.0;
+     203             : 
+     204             : /// The total work.
+     205             : /// This computed by accumulating the change in external potentials.
+     206             :   double work=0.0;
+     207             : 
+     208             : /// Forward declaration.
+     209             :   ForwardDecl<ExchangePatterns> exchangePatterns_fwd;
+     210             : /// Class of possible exchange patterns, used for BIASEXCHANGE but also for future parallel tempering
+     211             :   ExchangePatterns& exchangePatterns=*exchangePatterns_fwd;
+     212             : 
+     213             : /// Set to true if on an exchange step
+     214             :   bool exchangeStep=false;
+     215             : 
+     216             : /// Flag for restart
+     217             :   bool restart=false;
+     218             : 
+     219             : /// Flag for checkpointig
+     220             :   bool doCheckPoint=false;
+     221             : 
+     222             : /// A string that holds the name of the action that gets the energy from the MD
+     223             : /// code.  Set empty if energy is not used.
+     224             :   std::string name_of_energy{""};
+     225             : 
+     226             : /// This sets up the values that are set from the MD code
+     227             :   void startStep();
+     228             : 
+     229             : /// This sets up the vector that contains the interface to the MD code
+     230             :   void setupInterfaceActions();
+     231             : 
+     232             : /// Flag for parse only mode -- basically just forces restart to turn off
+     233             :   bool doParseOnly=false;
+     234             : 
+     235             : private:
+     236             : /// Forward declaration.
+     237             :   ForwardDecl<TypesafePtr> stopFlag_fwd;
+     238             : public:
+     239             : /// Stuff to make plumed stop the MD code cleanly
+     240             :   TypesafePtr& stopFlag=*stopFlag_fwd;
+     241             :   bool stopNow=false;
+     242             : 
+     243             : /// Stack for update flags.
+     244             : /// Store information used in class \ref generic::UpdateIf
+     245             :   std::stack<bool> updateFlags;
+     246             : 
+     247             : public:
+     248             : /// This determines if the user has created a value to hold the quantity that is being passed
+     249             :   bool valueExists( const std::string& name ) const ;
+     250             : 
+     251             : /// This sets the the value with a particular name to the pointer to the data in the MD code
+     252             :   void setInputValue( const std::string& name, const unsigned& start, const unsigned& stride, const TypesafePtr & val );
+     253             : 
+     254             : /// This sets the the forces with a particular name to the pointer to the data in the MD code
+     255             :   void setInputForce( const std::string& name, const TypesafePtr & val );
+     256             : 
+     257             : /// This updates the units of the input quantities
+     258             :   void setUnits( const bool& natural, const Units& u );
+     259             : 
+     260             : /// Flag to switch off virial calculation (for debug and MD codes with no barostat)
+     261             :   bool novirial=false;
+     262             : 
+     263             : /// Flag to switch on detailed timers
+     264             :   bool detailedTimers=false;
+     265             : 
+     266             : /// GpuDevice Identifier
+     267             :   int gpuDeviceId=-1;
+     268             : 
+     269             : /// Generic map string -> double
+     270             : /// intended to pass information across Actions
+     271             :   std::map<std::string,double> passMap;
+     272             : 
+     273             : /// Add a citation, returning a string containing the reference number, something like "[10]"
+     274             :   std::string cite(const std::string&);
+     275             : 
+     276             : /// Get number of threads that can be used by openmp
+     277             :   unsigned getNumThreads()const;
+     278             : 
+     279             : /// Get a reasonable number of threads so as to access to an array of size s located at x
+     280             :   template<typename T>
+     281             :   unsigned getGoodNumThreads(const T*x,unsigned s)const;
+     282             : 
+     283             : /// Get a reasonable number of threads so as to access to vector v;
+     284             :   template<typename T>
+     285             :   unsigned getGoodNumThreads(const std::vector<T> & v)const;
+     286             : 
+     287             : public:
+     288             :   PlumedMain();
+     289             : // this is to access to WithCmd versions of cmd (allowing overloading of a virtual method)
+     290             :   using WithCmd::cmd;
+     291             :   /**
+     292             :    cmd method, accessible with standard Plumed.h interface.
+     293             :    \param key The name of the command to be executed.
+     294             :    \param val The argument of the command to be executed.
+     295             :    It is called as plumed_cmd() or as PLMD::Plumed::cmd()
+     296             :    It is the interpreter for plumed commands. It basically contains the definition of the plumed interface.
+     297             :    If you want to add a new functionality to the interface between plumed
+     298             :    and an MD engine, this is the right place
+     299             :    Notice that this interface should always keep retro-compatibility
+     300             :   */
+     301             :   void cmd(std::string_view key,const TypesafePtr & val) override;
+     302             :   ~PlumedMain();
+     303             :   /**
+     304             :     Turn on parse only mode to deactivate restart in all actions.
+     305             :     This is only used by plumed driver --parse-only
+     306             :   */
+     307             :   void activateParseOnlyMode();
+     308             :   /**
+     309             :     This checks if parse only mode is active and turns off any restart.
+     310             :   */
+     311             :   bool parseOnlyMode() const ;
+     312             :   /**
+     313             :     Read an input file.
+     314             :     \param str name of the file
+     315             :   */
+     316             :   void readInputFile(const std::string & str);
+     317             :   /**
+     318             :     Read an input file.
+     319             :     \param ifile
+     320             :   */
+     321             :   void readInputFile(IFile & ifile);
+     322             :   /**
+     323             :     Read an input string.
+     324             :     \param str name of the string
+     325             :   */
+     326             :   void readInputWords(const std::vector<std::string> &  str, const bool& before_init);
+     327             : 
+     328             :   /**
+     329             :     Read an input string.
+     330             :     \param str name of the string
+     331             :     At variance with readInputWords(), this is splitting the string into words
+     332             :   */
+     333             :   void readInputLine(const std::string & str, const bool& before_init=false);
+     334             : 
+     335             :   /**
+     336             :     Read an input buffer.
+     337             :     \param str name of the string
+     338             :     Same as readInputFile, but first write str on a temporary file and then read
+     339             :     that files. At variance with readInputLine, it can take care of comments and
+     340             :     continuation lines.
+     341             :   */
+     342             :   void readInputLines(const std::string & str);
+     343             : 
+     344             :   /**
+     345             :     Initialize the object.
+     346             :     Should be called once.
+     347             :   */
+     348             :   void init();
+     349             :   /**
+     350             :     Prepare the calculation.
+     351             :     Here it is checked which are the active Actions and communication of the relevant atoms is initiated.
+     352             :     Shortcut for prepareDependencies() + shareData()
+     353             :   */
+     354             :   void prepareCalc();
+     355             :   /**
+     356             :     Prepare the list of active Actions and needed atoms.
+     357             :     Scan the Actions to see which are active and which are not, so as to prepare a list of
+     358             :     the atoms needed at this step.
+     359             :   */
+     360             :   void prepareDependencies();
+     361             :   /**
+     362             :     Ensure that all the atoms are shared.
+     363             :     This is used in GREX to ensure that we transfer all the positions from the MD code to PLUMED.
+     364             :   */
+     365             :   void shareAll();
+     366             :   /**
+     367             :     Share the needed atoms.
+     368             :     In asynchronous implementations, this method sends the required atoms to all the plumed processes,
+     369             :     without waiting for the communication to complete.
+     370             :   */
+     371             :   void shareData();
+     372             :   /**
+     373             :     Perform the calculation.
+     374             :     Shortcut for waitData() + justCalculate() + justApply().
+     375             :     Equivalently: waitData() + justCalculate() + backwardPropagate() + update().
+     376             :   */
+     377             :   void performCalc();
+     378             :   /**
+     379             :     Perform the calculation without update()
+     380             :     Shortcut for: waitData() + justCalculate() + backwardPropagate()
+     381             :   */
+     382             :   void performCalcNoUpdate();
+     383             :   /**
+     384             :     Perform the calculation without backpropagation nor update()
+     385             :     Shortcut for: waitData() + justCalculate()
+     386             :   */
+     387             :   void performCalcNoForces();
+     388             :   /**
+     389             :     Complete PLUMED calculation.
+     390             :     Shortcut for prepareCalc() + performCalc()
+     391             :   */
+     392             :   void calc();
+     393             :   /**
+     394             :     Scatters the needed atoms.
+     395             :     In asynchronous implementations, this method waits for the communications started in shareData()
+     396             :     to be completed. Otherwise, just send around needed atoms.
+     397             :   */
+     398             :   void waitData();
+     399             :   /**
+     400             :     Perform the forward loop on active actions.
+     401             :   */
+     402             :   void justCalculate();
+     403             :   /**
+     404             :     Backward propagate and update.
+     405             :     Shortcut for backwardPropagate() + update()
+     406             :     I leave it here for backward compatibility
+     407             :   */
+     408             :   void justApply();
+     409             :   /**
+     410             :     Perform the backward loop on active actions.
+     411             :     Needed to apply the forces back.
+     412             :   */
+     413             :   void backwardPropagate();
+     414             :   /**
+     415             :     Call the update() method.
+     416             :   */
+     417             :   void update();
+     418             :   /**
+     419             :     If there are calculations that need to be done at the very end of the calculations this
+     420             :     makes sures they are done
+     421             :   */
+     422             :   /**
+     423             :     This function does clearInputForces for the list of atoms that have a force on them. This
+     424             :     is an optimisation to prevent calling std::fill over a large array
+     425             :   */
+     426             :   void resetInputs();
+     427             :   void runJobsAtEndOfCalculation();
+     428             : /// Reference to the list of Action's
+     429             :   const ActionSet & getActionSet()const;
+     430             : /// Referenge to the log stream
+     431             :   Log & getLog();
+     432             : /// Return the number of the step
+     433     5397811 :   long long int getStep()const {return step;}
+     434             : /// Stop the run
+     435             :   void exit(int c=0);
+     436             : /// Load a shared library
+     437             :   void load(const std::string&);
+     438             : /// Get the suffix string
+     439             :   const std::string & getSuffix()const;
+     440             : /// Set the suffix string
+     441             :   void setSuffix(const std::string&);
+     442             : /// get the value of the bias
+     443             :   double getBias()const;
+     444             : /// get the value of the work
+     445             :   double getWork()const;
+     446             : /// Opens a file.
+     447             : /// Similar to plain fopen, but, if it finds an error in opening the file, it also tries with
+     448             : /// path+suffix.  This trick is useful for multiple replica simulations.
+     449             :   FILE* fopen(const char *path, const char *mode);
+     450             : /// Closes a file opened with PlumedMain::fopen()
+     451             :   int fclose(FILE*fp);
+     452             : /// Insert a file
+     453             :   void insertFile(FileBase&);
+     454             : /// Erase a file
+     455             :   void eraseFile(FileBase&);
+     456             : /// Flush all files
+     457             :   void fflush();
+     458             : /// Check if restarting
+     459             :   bool getRestart()const;
+     460             : /// Set restart flag
+     461          56 :   void setRestart(bool f) {if(!doParseOnly) restart=f;}
+     462             : /// Check if checkpointing
+     463             :   bool getCPT()const;
+     464             : /// Set exchangeStep flag
+     465             :   void setExchangeStep(bool f);
+     466             : /// Get exchangeStep flag
+     467             :   bool getExchangeStep()const;
+     468             : /// Stop the calculation cleanly (both the MD code and plumed)
+     469             :   void stop();
+     470             : /// Enforce active flag.
+     471             : /// This is a (bit dirty) hack to solve a bug. When there is no active ActionPilot,
+     472             : /// several shortcuts are used. However, these shortcuts can block GREX module.
+     473             : /// This function allows to enforce active plumed when doing exchanges,
+     474             : /// thus fixing the bug.
+     475             :   void resetActive(bool active);
+     476             : 
+     477             : /// Access to exchange patterns
+     478           0 :   ExchangePatterns& getExchangePatterns() {return exchangePatterns;}
+     479             : 
+     480             : /// Push a state to update flags
+     481             :   void updateFlagsPush(bool);
+     482             : /// Pop a state from update flags
+     483             :   void updateFlagsPop();
+     484             : /// Get top of update flags
+     485             :   bool updateFlagsTop();
+     486             : /// Set end of input file
+     487             :   void setEndPlumed();
+     488             : /// Get the value of the end plumed flag
+     489             :   bool getEndPlumed() const ;
+     490             : /// Get the value of the gpuDeviceId
+     491             :   int getGpuDeviceId() const ;
+     492             : /// Call error handler.
+     493             : /// Should only be called from \ref plumed_plumedmain_cmd().
+     494             : /// If the error handler was not set, returns false.
+     495             :   bool callErrorHandler(int code,const char* msg)const;
+     496             : private:
+     497             :   std::atomic<unsigned> referenceCounter{};
+     498             : public:
+     499             : /// Atomically increase reference counter and return the new value
+     500             :   unsigned increaseReferenceCounter() noexcept;
+     501             : /// Atomically decrease reference counter and return the new value
+     502             :   unsigned decreaseReferenceCounter() noexcept;
+     503             : /// Report the reference counter
+     504             :   unsigned useCountReferenceCounter() const noexcept;
+     505             :   void enableNestedExceptions();
+     506             :   bool getNestedExceptions()const {
+     507         166 :     return nestedExceptions;
+     508             :   }
+     509             : /// Check if there is active input in the action set
+     510             :   bool inputsAreActive() const ;
+     511             : /// Transfer information from input MD code
+     512             :   void writeBinary(std::ostream&)const;
+     513             :   void readBinary(std::istream&);
+     514             : /// Used to set the name of the action that holds the energy
+     515             :   void setEnergyValue( const std::string& name );
+     516             : /// Get the real preicision
+     517             :   int getRealPrecision() const;
+     518             : /// Are we using natural units
+     519             :   bool usingNaturalUnits() const ;
+     520             : /// Get the units that are being used
+     521             :   const Units& getUnits();
+     522             : /// Take an energy that is calculated by PLUMED and pass it to a typesafe pointer
+     523             : /// that the MD code can access.
+     524             :   void plumedQuantityToMD( const std::string& unit, const double& eng, const TypesafePtr & m) const ;
+     525             : /// Take a typesafe pointer from the MD code and convert it to a double
+     526             :   double MDQuantityToPLUMED( const std::string& unit, const TypesafePtr & m) const ;
+     527             : /// Get the keywords for a particular action
+     528             :   void getKeywordsForAction( const std::string& action, Keywords& keys ) const ;
+     529             : };
+     530             : 
+     531             : /////
+     532             : // FAST INLINE METHODS:
+     533             : 
+     534             : inline
+     535             : const ActionSet & PlumedMain::getActionSet()const {
+     536     1579281 :   return actionSet;
+     537             : }
+     538             : 
+     539             : inline
+     540             : const std::string & PlumedMain::getSuffix()const {
+     541        5298 :   return suffix;
+     542             : }
+     543             : 
+     544             : inline
+     545             : void PlumedMain::setSuffix(const std::string&s) {
+     546         411 :   suffix=s;
+     547         411 : }
+     548             : 
+     549             : inline
+     550             : bool PlumedMain::getRestart()const {
+     551       51152 :   return restart;
+     552             : }
+     553             : 
+     554             : inline
+     555             : bool PlumedMain::getCPT()const {
+     556       51096 :   return doCheckPoint;
+     557             : }
+     558             : 
+     559             : inline
+     560             : void PlumedMain::setExchangeStep(bool s) {
+     561         228 :   exchangeStep=s;
+     562             : }
+     563             : 
+     564             : inline
+     565             : bool PlumedMain::getExchangeStep()const {
+     566       28109 :   return exchangeStep;
+     567             : }
+     568             : 
+     569             : inline
+     570             : void PlumedMain::resetActive(bool active) {
+     571         114 :   this->active=active;
+     572             : }
+     573             : 
+     574             : inline
+     575             : void PlumedMain::updateFlagsPush(bool on) {
+     576             :   updateFlags.push(on);
+     577             : }
+     578             : 
+     579             : inline
+     580             : void PlumedMain::updateFlagsPop() {
+     581             :   updateFlags.pop();
+     582          12 : }
+     583             : 
+     584             : inline
+     585             : bool PlumedMain::updateFlagsTop() {
+     586     2519389 :   return updateFlags.top();
+     587             : }
+     588             : 
+     589             : inline
+     590             : void PlumedMain::setEndPlumed() {
+     591         281 :   endPlumed=true;
+     592             : }
+     593             : 
+     594             : inline
+     595             : bool PlumedMain::getEndPlumed() const {
+     596          24 :   return endPlumed;
+     597             : }
+     598             : 
+     599             : inline
+     600             : int PlumedMain::getGpuDeviceId() const {
+     601             :   return gpuDeviceId;
+     602             : }
+     603             : 
+     604             : inline
+     605             : bool PlumedMain::callErrorHandler(int code,const char* msg)const {
+     606             :   if(error_handler.handler) {
+     607             :     error_handler.handler(error_handler.ptr,code,msg);
+     608             :     return true;
+     609             :   } else return false;
+     610             : }
+     611             : 
+     612             : 
+     613             : }
+     614             : 
+     615             : #endif
+     616             : 
+
+
+
+ + + + +
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 000000000..37ef5e36a --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - plumed test coverage - core/PlumedMainInitializer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMainInitializer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22326982.9 %
Date:2024-10-17 16:45:00Functions: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_xPPvPKc178
plumed_plumedmain_cmd357
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev5301
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev5301
plumed_plumedmain_cmd_safe_nothrow19997
_ZL19getenvTypesafeDebugv20092
plumed_plumedmain_create805604
plumed_plumedmain_finalize805604
plumed_symbol_table_init810874
plumed_plumedmain_create_reference8000671
plumed_plumedmain_delete_reference8806275
+
+
+ + + +
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 000000000..f2637cebf --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - plumed test coverage - core/PlumedMainInitializer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMainInitializer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22326982.9 %
Date:2024-10-17 16:45:00Functions: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_xPPvPKc178
_ZL19getenvTypesafeDebugv20092
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev5301
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev5301
plumed_plumedmain_cmd357
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_cmd_safe95
plumed_plumedmain_cmd_safe_nothrow19997
plumed_plumedmain_create805604
plumed_plumedmain_create_reference8000671
plumed_plumedmain_delete_reference8806275
plumed_plumedmain_finalize805604
plumed_plumedmain_use_count42
plumed_symbol_table_init810874
+
+
+ + + +
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 000000000..409e2cd23 --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.gcov.html @@ -0,0 +1,566 @@ + + + + + + + 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-10-17 16:45:00Functions: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       20092 : static bool getenvTypesafeDebug() noexcept {
+      52       20092 :   static const auto* res=std::getenv("PLUMED_TYPESAFE_DEBUG");
+      53       20092 :   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      805604 : extern "C" void*plumed_plumedmain_create() {
+      76             :   try {
+      77      805604 :     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     8000671 : extern "C" unsigned plumed_plumedmain_create_reference(void*plumed) {
+      89     8000671 :   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     8000671 :   return p->increaseReferenceCounter();
+      92             : }
+      93             : 
+      94     8806275 : extern "C" unsigned plumed_plumedmain_delete_reference(void*plumed) {
+      95     8806275 :   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     8806275 :   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         178 : static void translate_current(plumed_nothrow_handler_x nothrow,void**nested=nullptr,const char*msg=nullptr) {
+     127         178 :   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         178 :     throw;
+     132         178 :   } catch(const PLMD::ExceptionTypeError & e) {
+     133          52 :     if(!msg) msg=e.what();
+     134          52 :     nothrow.handler(nothrow.ptr,20300,msg,opt);
+     135         105 :   } catch(const PLMD::ExceptionError & e) {
+     136          53 :     if(!msg) msg=e.what();
+     137          53 :     nothrow.handler(nothrow.ptr,20200,msg,opt);
+     138          54 :   } catch(const PLMD::ExceptionDebug & e) {
+     139           1 :     if(!msg) msg=e.what();
+     140           1 :     nothrow.handler(nothrow.ptr,20100,msg,opt);
+     141          24 :   } catch(const PLMD::Exception & e) {
+     142          23 :     if(!msg) msg=e.what();
+     143          23 :     nothrow.handler(nothrow.ptr,20000,msg,opt);
+     144          24 :   } 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         178 : }
+     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       19997 :   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       19997 :     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       19997 :       plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     360       19997 :       if(getenvTypesafeDebug()) typesafeDebug(key,safe);
+     361       19997 :       p->cmd(key,PLMD::TypesafePtr::fromSafePtr(&safe));
+     362         166 :     } catch(...) {
+     363         166 :       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         110 :         auto msg=PLMD::Tools::concatenateExceptionMessages();
+     370         110 :         translate_current(nothrow,nullptr,msg.c_str());
+     371             :       }
+     372         166 :     }
+     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      805604 : extern "C" void plumed_plumedmain_finalize(void*plumed) {
+     390      805604 :   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      805604 :   delete static_cast<PLMD::PlumedMain*>(plumed);
+     394      805604 : }
+     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      810874 : extern "C" void plumed_symbol_table_init() {
+     410      810874 :   plumed_symbol_table.version=4;
+     411      810874 :   plumed_symbol_table.functions.create=plumed_plumedmain_create;
+     412      810874 :   plumed_symbol_table.functions.cmd=plumed_plumedmain_cmd;
+     413      810874 :   plumed_symbol_table.functions.finalize=plumed_plumedmain_finalize;
+     414      810874 :   plumed_symbol_table.cmd_nothrow=plumed_plumedmain_cmd_nothrow;
+     415      810874 :   plumed_symbol_table.cmd_safe=plumed_plumedmain_cmd_safe;
+     416      810874 :   plumed_symbol_table.cmd_safe_nothrow=plumed_plumedmain_cmd_safe_nothrow;
+     417      810874 :   plumed_symbol_table.create_reference=plumed_plumedmain_create_reference;
+     418      810874 :   plumed_symbol_table.delete_reference=plumed_plumedmain_delete_reference;
+     419      810874 :   plumed_symbol_table.use_count=plumed_plumedmain_use_count;
+     420      810874 : }
+     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        5301 :   PlumedMainInitializer():
+     439        5301 :     debug(std::getenv("PLUMED_LOAD_DEBUG"))
+     440             :   {
+     441             : // make sure static plumed_function_pointers is initialized here
+     442        5301 :     plumed_symbol_table_init();
+     443        5301 :     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        5301 :     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        5301 :     if(debug) std::fprintf(stderr,"+++ Registering functions. Looking in RTLD_DEFAULT +++\n");
+     454        5301 :     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        5301 :     *(void **)(&plumed_kernel_register)=dls;
+     461        5301 :     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        5301 :     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        5301 :     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        5301 :   ~PlumedMainInitializer() {
+     483        5301 :     if(debug) std::fprintf(stderr,"+++ Finalizing PLUMED with plumed_symbol_table at %p\n",(void*)&plumed_symbol_table);
+     484        5301 :   }
+     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 000000000..65a40363f --- /dev/null +++ b/coverage/core/RegisterBase.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZN4PLMD8Register13imageToStringB5cxx11EPv246
_ZN4PLMDlsERSoRKNS_8RegisterE878
_ZN4PLMD8RegisterC2Ev10602
_ZN4PLMD8RegisterD2Ev10602
_ZN4PLMD8Register15isDLRegisteringEv2422580
_ZN4PLMD8Register22getRegisteringFullPathB5cxx11Ev2422580
_ZN4PLMD12_GLOBAL__N_112getSingletonEv4866517
+
+
+ + + +
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 000000000..78198ddbf --- /dev/null +++ b/coverage/core/RegisterBase.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-10-17 16:45:00Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_112getSingletonEv4866517
_ZN4PLMD8Register13imageToStringB5cxx11EPv246
_ZN4PLMD8Register15isDLRegisteringEv2422580
_ZN4PLMD8Register16RegistrationLockC2EOS1_0
_ZN4PLMD8Register16RegistrationLockC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register16RegistrationLockD2Ev51
_ZN4PLMD8Register16registrationLockERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register17popDLRegistrationEv51
_ZN4PLMD8Register18pushDLRegistrationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register22getRegisteringFullPathB5cxx11Ev2422580
_ZN4PLMD8Register24completeAllRegistrationsEPv51
_ZN4PLMD8RegisterC2Ev10602
_ZN4PLMD8RegisterD0Ev0
_ZN4PLMD8RegisterD2Ev10602
_ZN4PLMDlsERSoRKNS_8RegisterE878
_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 000000000..32ef5c559 --- /dev/null +++ b/coverage/core/RegisterBase.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + 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-10-17 16:45:00Functions: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        5301 : 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     4866517 : Singleton & getSingleton() {
+      47     4866517 :   static Singleton singleton;
+      48     4866517 :   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         246 : std::string Register::imageToString(void* image) {
+      97         246 :   std::stringstream ss;
+      98             :   ss << image;
+      99         246 :   return ss.str();
+     100         246 : }
+     101             : 
+     102     2422580 : bool Register::isDLRegistering() noexcept {
+     103     2422580 :   auto & singleton=getSingleton();
+     104     2422580 :   return singleton.registeringCounter>0;
+     105             : }
+     106             : 
+     107     2422580 : const std::string Register::getRegisteringFullPath() noexcept {
+     108     2422580 :   auto & singleton=getSingleton();
+     109     2422580 :   return singleton.fullPath;
+     110             : }
+     111             : 
+     112       10602 : Register::Register() {
+     113       10602 :   auto & singleton=getSingleton();
+     114             :   // this is to protect insertion
+     115       10602 :   std::unique_lock lock(singleton.registeringMutex);
+     116       10602 :   singleton.registers.push_back(this);
+     117       10602 : }
+     118             : 
+     119       10602 : Register::~Register() noexcept {
+     120       10602 :   auto & singleton=getSingleton();
+     121             :   // this is to protect removal
+     122       10602 :   std::unique_lock lock(singleton.registeringMutex);
+     123       10602 :   auto it=std::find(singleton.registers.begin(),singleton.registers.end(),this);
+     124       10602 :   if(it!=singleton.registers.end()) singleton.registers.erase(it);
+     125       10602 : }
+     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       18073 :   for(auto & k : getKeys()) {
+     131       18032 :     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         878 : std::ostream & operator<<(std::ostream &log,const Register &reg) {
+     140         878 :   std::vector<std::string> s(reg.getKeys());
+     141      201501 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+     142         878 :   return log;
+     143         878 : }
+     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 000000000..af4c7a866 --- /dev/null +++ b/coverage/core/RegisterBase.h.func-sort-c.html @@ -0,0 +1,160 @@ + + + + + + + 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:627286.1 %
Date:2024-10-17 16:45:00Functions: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_22ActionRegisterPointersEE7getKeysB5cxx11Ev482
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3847
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE7getKeysB5cxx11Ev4996
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEED2Ev5301
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEED2Ev5301
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22942
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34561
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE11getFullPathERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51096
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51195
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE6removeENS2_2IDE100719
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_100729
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE6removeENS2_2IDE2321838
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_2321851
+
+
+ + + +
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 000000000..9ffc1eeb8 --- /dev/null +++ b/coverage/core/RegisterBase.h.func.html @@ -0,0 +1,160 @@ + + + + + + + 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:627286.1 %
Date:2024-10-17 16:45:00Functions:192286.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE11clearStagedEv51
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE20completeRegistrationEPv51
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_2321851
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE6removeENS2_2IDE2321838
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEED0Ev0
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEED2Ev5301
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE11clearStagedEv51
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE20completeRegistrationEPv51
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_100729
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE6removeENS2_2IDE100719
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEED0Ev0
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEED2Ev5301
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE11getFullPathERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51096
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22942
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51195
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34561
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE5checkERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE7getKeysB5cxx11Ev482
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3847
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE7getKeysB5cxx11Ev4996
+
+
+ + + +
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 000000000..f89cf5289 --- /dev/null +++ b/coverage/core/RegisterBase.h.gcov.html @@ -0,0 +1,401 @@ + + + + + + + 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:627286.1 %
Date:2024-10-17 16:45:00Functions: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 <string_view>
+      28             : #include <map>
+      29             : #include <memory>
+      30             : #include <iostream>
+      31             : #include <vector>
+      32             : #include <algorithm>
+      33             : #include <mutex>
+      34             : #include <shared_mutex>
+      35             : 
+      36             : namespace PLMD {
+      37             : 
+      38             : /// Base class, with type independent information.
+      39             : /// Actual registers should inherit through the RegisterBase class below
+      40             : class Register {
+      41             :   /// Initialize registration - only used by registrationLock()
+      42             :   static void pushDLRegistration(const std::string & fullpath);
+      43             :   /// Finalize registration - only used by registrationLock()
+      44             :   static void popDLRegistration() noexcept;
+      45             : 
+      46             : protected:
+      47             :   /// Mutex protecting access to map
+      48             :   mutable std::shared_mutex mutex;
+      49             :   /// Internal tool to format image addresses
+      50             :   static std::string imageToString(void* image);
+      51             :   /// Check if we are in a dlopen section
+      52             :   static bool isDLRegistering() noexcept;
+      53             :   /// Return the path of the currently-loading library
+      54             :   static const std::string getRegisteringFullPath() noexcept;
+      55             :   /// Save all staged objects from a register
+      56             :   virtual void completeRegistration(void* image)=0;
+      57             :   /// Clear staged objects.
+      58             :   /// Should be used when leaving the dlopen section to remove
+      59             :   /// any dangling object.
+      60             :   virtual void clearStaged() noexcept =0;
+      61             :   /// Get all registered keys.
+      62             :   /// These are the keys in the map, not the plumed keywords!
+      63             :   virtual std::vector<std::string> getKeys() const =0;
+      64             : 
+      65             : public:
+      66             :   /// Constructor.
+      67             :   /// This keeps track of all created instances.
+      68             :   Register();
+      69             :   /// Destructor.
+      70             :   virtual ~Register() noexcept;
+      71             :   /// Disable move
+      72             :   Register(Register &&) = delete;
+      73             :   /// Disable copy
+      74             :   Register(const Register &) = delete;
+      75             : 
+      76             :   /// Small class to manage registration lock
+      77             :   /// This is used during dlopen, to avoid data races in registrations
+      78             :   class RegistrationLock {
+      79             :     bool active;
+      80             :   public:
+      81             :     RegistrationLock(const std::string & fullpath);
+      82             :     RegistrationLock(const RegistrationLock&) = delete;
+      83             :     RegistrationLock(RegistrationLock&& other) noexcept;
+      84             :     ~RegistrationLock() noexcept;
+      85             :   };
+      86             : 
+      87             :   /// return a registration lock
+      88             :   static RegistrationLock registrationLock(const std::string & fullpath);
+      89             : 
+      90             :   /// Save all staged objects in all registers
+      91             :   static void completeAllRegistrations(void* image);
+      92             : 
+      93             :   /// Get only keys registered specifically by a given image
+      94             :   std::vector<std::string> getKeysWithDLHandle(void* handle) const;
+      95             : 
+      96             :   friend std::ostream & operator<<(std::ostream &log,const Register &reg);
+      97             : };
+      98             : 
+      99             : /// Class representing an error in a register
+     100           2 : class ExceptionRegisterError :
+     101             :   public Exception {
+     102             :   /// The missing key
+     103             :   std::string missingKey;
+     104             : public:
+     105             :   using Exception::Exception;
+     106             :   /// Sets the missing key
+     107             :   /// \param key The missing key
+     108             :   /// \return This exception
+     109             :   ///
+     110             :   /// ExceptionRegisterError can be used as a builder pattern:
+     111             :   /// `throw ExceptionRegisterError().setMissingKey(key);`
+     112             :   ///
+     113             :   /// the key can be retrieved with ExceptionRegisterError::getMissingKey()
+     114             :   ExceptionRegisterError& setMissingKey (std::string_view key) {
+     115             :     missingKey=key;
+     116             :     return *this;
+     117             :   }
+     118             :   /// Returns the missing key
+     119           2 :   const std::string& getMissingKey() const {return missingKey;}
+     120             :   template<typename T>
+     121             :   ExceptionRegisterError& operator<<(const T & x) {
+     122           2 :     *static_cast<Exception*>(this) <<x;
+     123           2 :     return *this;
+     124             :   }
+     125             : };
+     126             : 
+     127             : /// General register.
+     128             : /// This class provide a generic implementation based on the content of the Register
+     129             : template<class Content>
+     130             : class RegisterBase :
+     131             :   public Register {
+     132             : 
+     133             : public:
+     134             : /// auxiliary class
+     135     4845127 :   struct ContentAndFullPath {
+     136             :     Content content;
+     137             :     std::string fullPath;
+     138             :   };
+     139             : 
+     140             : private:
+     141             : /// Main register map
+     142             :   std::map<std::string,std::unique_ptr<ContentAndFullPath>> m;
+     143             : /// Map of staged keys
+     144             :   std::map<std::string,std::unique_ptr<ContentAndFullPath>> staged_m;
+     145             : 
+     146             : public:
+     147             : 
+     148             :   struct ID {
+     149             :     ContentAndFullPath* ptr{nullptr};
+     150             :   };
+     151             : /// Register a new class.
+     152             : /// \param key The name of the directive to be used in the input file
+     153             : /// \param content The registered content
+     154             : /// \param ID A returned ID that can be used to remove the directive later
+     155             :   ID add(std::string key,const Content & content);
+     156             : 
+     157             : /// Verify if a key is present in the register, accessing to registered images
+     158             :   bool check(const std::vector<void*> & images,const std::string & key) const;
+     159             : 
+     160             : /// Verify if a key is present in the register, only considering the default image
+     161             :   bool check(const std::string & key) const;
+     162             : 
+     163             : /// Return the content associated to a key in the register, accessing to registerd images
+     164             :   const Content & get(const std::vector<void*> & images,const std::string & key) const;
+     165             : 
+     166             : /// Return the full path associated to a key in the register, accessing to registerd images
+     167             :   const std::string & getFullPath(const std::vector<void*> & images,const std::string & key) const;
+     168             : 
+     169             : /// Return the content associated to a key in the register, only considering the default image
+     170             :   const Content & get(const std::string & key) const;
+     171             : 
+     172             : /// Remove a registered keyword.
+     173             : /// Use the ID returned by add().
+     174             :   void remove(ID id);
+     175             : 
+     176             : /// Get a list of keys
+     177             : /// Notice that these are the keys in the map, not the plumed keywords!
+     178             : /// Also notice that this list includes keys from all images, including the
+     179             : /// textual version of the image void*
+     180             :   std::vector<std::string> getKeys() const override;
+     181             : 
+     182             :   ~RegisterBase() noexcept override;
+     183             : 
+     184             :   /// complete registration
+     185             :   /// all staged keys will be enabled
+     186             :   /// Should be called after dlopen has been completed correctly.
+     187             :   void completeRegistration(void*handle) override;
+     188             : 
+     189             :   void clearStaged() noexcept override;
+     190             : 
+     191             : };
+     192             : 
+     193             : template<class Content>
+     194     2422580 : typename RegisterBase<Content>::ID RegisterBase<Content>::add(std::string key,const Content & content) {
+     195             : 
+     196     4845160 :   auto ptr=std::make_unique<ContentAndFullPath>(ContentAndFullPath{content,getRegisteringFullPath()});
+     197             :   ID id{ptr.get()};
+     198             : 
+     199             :   // lock map for writing
+     200     2422580 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     201             : 
+     202     2422580 :   if(isDLRegistering()) {
+     203           0 :     plumed_assert(!staged_m.count(key)) << "cannot stage key twice with the same name "<< key<<"\n";
+     204          23 :     staged_m.insert({key, std::move(ptr)});
+     205             :   } else {
+     206           0 :     plumed_assert(!m.count(key)) << "cannot register key twice with the same name "<< key<<"\n";
+     207     2422557 :     m.insert({key, std::move(ptr)});
+     208             :   }
+     209     4845160 :   return id;
+     210     2422580 : }
+     211             : std::ostream & operator<<(std::ostream &log,const Register &reg);
+     212             : 
+     213             : template<class Content>
+     214           2 : bool RegisterBase<Content>::check(const std::vector<void*> & images,const std::string & key) const {
+     215             :   // lock map for reading
+     216           2 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     217           1 :   if(m.count(key)>0) return true;
+     218           1 :   for(auto image : images) {
+     219           0 :     std::string k=imageToString(image)+":"+key;
+     220             :     if(m.count(k)>0) return true;
+     221             :   }
+     222             :   return false;
+     223             : }
+     224             : 
+     225             : template<class Content>
+     226       34562 : bool RegisterBase<Content>::check(const std::string & key) const {
+     227             :   // lock map for reading
+     228       34562 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     229       34562 :   return m.count(key)>0;
+     230             : }
+     231             : 
+     232             : template<class Content>
+     233       55042 : const Content & RegisterBase<Content>::get(const std::vector<void*> & images,const std::string & key) const {
+     234             :   // lock map for reading
+     235       55042 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     236       55087 :   for(auto image = images.rbegin(); image != images.rend(); ++image) {
+     237         194 :     auto qualified_key=imageToString(*image) + ":" + key;
+     238          51 :     if(m.count(qualified_key)>0) return m.find(qualified_key)->second->content;
+     239             :   }
+     240             :   if (m.count(key) == 0 ) {
+     241           4 :     throw ExceptionRegisterError().setMissingKey(key);
+     242             :   }
+     243       54989 :   return m.find(key)->second->content;
+     244             : }
+     245             : 
+     246             : template<class Content>
+     247       51096 : const std::string & RegisterBase<Content>::getFullPath(const std::vector<void*> & images,const std::string & key) const {
+     248             :   // lock map for reading
+     249       51096 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     250       51141 :   for(auto image = images.rbegin(); image != images.rend(); ++image) {
+     251         172 :     auto qualified_key=imageToString(*image) + ":" + key;
+     252          41 :     if(m.count(qualified_key)>0) return m.find(qualified_key)->second->fullPath;
+     253             :   }
+     254             :   if (m.count(key) == 0 ) {
+     255           0 :     throw ExceptionRegisterError().setMissingKey(key);
+     256             :   }
+     257       51055 :   return m.find(key)->second->fullPath;
+     258             : }
+     259             : 
+     260             : template<class Content>
+     261       22942 : const Content & RegisterBase<Content>::get(const std::string & key) const {
+     262             :   // lock map for reading
+     263       22942 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     264             :   if (m.count(key) == 0 ) {
+     265           0 :     throw ExceptionRegisterError().setMissingKey(key);
+     266             :   }
+     267       22942 :   return m.find(key)->second->content;
+     268             : }
+     269             : 
+     270             : template<class Content>
+     271     2422557 : void RegisterBase<Content>::remove(ID id) {
+     272             :   // lock map for writing
+     273     2422557 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     274     2422557 :   if(id.ptr) {
+     275   295684479 :     for(auto p=m.begin(); p!=m.end(); ++p) {
+     276   295684479 :       if(p->second.get()==id.ptr) {
+     277     2422557 :         m.erase(p); break;
+     278             :       }
+     279             :     }
+     280             :   }
+     281     2422557 : }
+     282             : 
+     283             : template<class Content>
+     284        5478 : std::vector<std::string> RegisterBase<Content>::getKeys() const {
+     285             :   // lock map for reading
+     286        5478 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     287             :   std::vector<std::string> s;
+     288      311606 :   for(const auto & it : m) s.push_back(it.first);
+     289        5478 :   std::sort(s.begin(),s.end());
+     290        5478 :   return s;
+     291           0 : }
+     292             : 
+     293             : template<class Content>
+     294       10602 : RegisterBase<Content>::~RegisterBase() noexcept {
+     295       10602 :   if(m.size()>0) {
+     296           0 :     std::string names="";
+     297           0 :     for(const auto & p : m) names+=p.first+" ";
+     298           0 :     std::cerr<<"WARNING: Directive "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
+     299             :   }
+     300       21204 : }
+     301             : 
+     302             : template<class Content>
+     303         102 : void RegisterBase<Content>::completeRegistration(void*handle) {
+     304             :   // lock map for writing
+     305         102 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     306         125 :   for (auto iter = staged_m.begin(); iter != staged_m.end(); ) {
+     307          46 :     auto key = imageToString(handle) + ":" + iter->first;
+     308           0 :     plumed_assert(!m.count(key)) << "cannot register key twice with the same name "<< key<<"\n";
+     309          23 :     m[key] = std::move(iter->second);
+     310             :     // Since we've moved out the value, we can safely erase the element from the original map
+     311             :     // This also avoids invalidating our iterator since erase returns the next iterator
+     312          23 :     iter = staged_m.erase(iter);
+     313             :   }
+     314         102 :   plumed_assert(staged_m.empty());
+     315         102 : }
+     316             : 
+     317             : template<class Content>
+     318         102 : void RegisterBase<Content>::clearStaged() noexcept {
+     319             :   // lock map for writing
+     320         102 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     321             :   staged_m.clear();
+     322         102 : }
+     323             : }
+     324             : 
+     325             : #endif
+
+
+
+ + + + +
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 000000000..e10dcf67b --- /dev/null +++ b/coverage/core/TargetDist.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - core/TargetDist.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - TargetDist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:0270.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..e73eb3f23 --- /dev/null +++ b/coverage/core/TargetDist.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - core/TargetDist.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - TargetDist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:0270.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..44aeef0be --- /dev/null +++ b/coverage/core/TargetDist.cpp.gcov.html @@ -0,0 +1,147 @@ + + + + + + + LCOV - plumed test coverage - core/TargetDist.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - TargetDist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:0270.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..128d474df --- /dev/null +++ b/coverage/core/Value.cpp.func-sort-c.html @@ -0,0 +1,212 @@ + + + + + + + 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:25426496.2 %
Date:2024-10-17 16:45:00Functions:3535100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5ValueC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE18
_ZNK4PLMD5Value9getDomainERdS1_34
_ZNK4PLMD5Value12getValueTypeB5cxx11Ev132
_ZN4PLMD5ValueC2Ev164
_ZN4PLMD5Value12setGradientsEPNS_15ActionAtomisticERj190
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZNK4PLMD5Value13passGradientsERKdRSt3mapINS_10AtomNumberENS_13VectorGenericILj3EEESt4lessIS4_ESaISt4pairIKS4_S6_EEE283
_ZN4PLMD5Value10setValTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE455
_ZN4PLMD5Value10readBinaryERSi456
_ZNK4PLMD5Value11writeBinaryERSo456
_ZN4PLMD5Value12setSymmetricERKb1274
_ZN4PLMD5Value16retrieveEdgeListERjRSt6vectorISt4pairIjjESaIS4_EERS2_IdSaIdEE2220
_ZN4PLMD5Value11setConstantEv5501
_ZN4PLMD5Value18reshapeMatrixStoreERKj7079
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7745
_ZN4PLMD5Value14buildDataStoreEb12044
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_16759
_ZN4PLMD5Value24setPositionInMatrixStashERKj35389
_ZN4PLMD5Value9push_backERKd74915
_ZN4PLMD5Value16setupPeriodicityEv109691
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbRKSt6vectorIjSaIjEE118613
_ZN4PLMD5Value8setShapeERKSt6vectorIjSaIjEE130924
_ZNK4PLMD5Value17getGoodNumThreadsERKjS2_232389
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE404396
_ZNK4PLMD5Value5printERNS_5OFileE548042
_ZNK4PLMD5Value21convertIndexToindicesERKmRSt6vectorIjSaIjEE775666
_ZN4PLMD5Value14setNotPeriodicEv1102168
_ZNK4PLMD5Value10isPeriodicEv1684843
_ZNK4PLMD5Value15getIndexInStoreERKm3223564
_ZN4PLMD5Value3setERKmRKd4948688
_ZNK4PLMD5Value17calculateOnUpdateEv7508060
_ZNK4PLMD5Value17ignoreStoredValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15990662
_ZN4PLMD5Value15getPntrToActionEv18713566
_ZN4PLMD5Value8addForceERKmdb39291023
_ZNK4PLMD5Value3getERKmb557633435
+
+
+ + + +
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 000000000..68b59396f --- /dev/null +++ b/coverage/core/Value.cpp.func.html @@ -0,0 +1,212 @@ + + + + + + + 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:25426496.2 %
Date:2024-10-17 16:45:00Functions:3535100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZN4PLMD5Value10readBinaryERSi456
_ZN4PLMD5Value10setValTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE455
_ZN4PLMD5Value11setConstantEv5501
_ZN4PLMD5Value12setGradientsEPNS_15ActionAtomisticERj190
_ZN4PLMD5Value12setSymmetricERKb1274
_ZN4PLMD5Value14buildDataStoreEb12044
_ZN4PLMD5Value14setNotPeriodicEv1102168
_ZN4PLMD5Value15getPntrToActionEv18713566
_ZN4PLMD5Value16retrieveEdgeListERjRSt6vectorISt4pairIjjESaIS4_EERS2_IdSaIdEE2220
_ZN4PLMD5Value16setupPeriodicityEv109691
_ZN4PLMD5Value18reshapeMatrixStoreERKj7079
_ZN4PLMD5Value24setPositionInMatrixStashERKj35389
_ZN4PLMD5Value3setERKmRKd4948688
_ZN4PLMD5Value8addForceERKmdb39291023
_ZN4PLMD5Value8setShapeERKSt6vectorIjSaIjEE130924
_ZN4PLMD5Value9push_backERKd74915
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7745
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbRKSt6vectorIjSaIjEE118613
_ZN4PLMD5ValueC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE18
_ZN4PLMD5ValueC2Ev164
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE404396
_ZNK4PLMD5Value10isPeriodicEv1684843
_ZNK4PLMD5Value11writeBinaryERSo456
_ZNK4PLMD5Value12getValueTypeB5cxx11Ev132
_ZNK4PLMD5Value13passGradientsERKdRSt3mapINS_10AtomNumberENS_13VectorGenericILj3EEESt4lessIS4_ESaISt4pairIKS4_S6_EEE283
_ZNK4PLMD5Value15getIndexInStoreERKm3223564
_ZNK4PLMD5Value17calculateOnUpdateEv7508060
_ZNK4PLMD5Value17getGoodNumThreadsERKjS2_232389
_ZNK4PLMD5Value17ignoreStoredValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15990662
_ZNK4PLMD5Value21convertIndexToindicesERKmRSt6vectorIjSaIjEE775666
_ZNK4PLMD5Value3getERKmb557633435
_ZNK4PLMD5Value5printERNS_5OFileE548042
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_16759
_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 000000000..2ef0786a5 --- /dev/null +++ b/coverage/core/Value.cpp.gcov.html @@ -0,0 +1,480 @@ + + + + + + + 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:25426496.2 %
Date:2024-10-17 16:45:00Functions:3535100.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 "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      118613 : Value::Value(ActionWithValue* av, const std::string& name, const bool withderiv, const std::vector<unsigned>&ss):
+      86      118613 :   action(av),
+      87      118613 :   value_set(false),
+      88      118613 :   hasForce(false),
+      89      118613 :   name(name),
+      90      118613 :   storedata(false),
+      91      118613 :   hasDeriv(withderiv),
+      92      118613 :   bufstart(0),
+      93      118613 :   streampos(0),
+      94      118613 :   ngrid_der(0),
+      95      118613 :   matpos(0),
+      96      118613 :   ncols(0),
+      97      118613 :   book_start(0),
+      98      118613 :   symmetric(false),
+      99      118613 :   periodicity(unset),
+     100      118613 :   min(0.0),
+     101      118613 :   max(0.0),
+     102      118613 :   max_minus_min(0.0),
+     103      118613 :   inv_max_minus_min(0.0),
+     104      118613 :   derivativeIsZeroWhenValueIsZero(false)
+     105             : {
+     106      118613 :   if( action ) {
+     107      118157 :     if( action->getName()=="ACCUMULATE" || action->getName()=="COLLECT" ) valtype=average;
+     108             :   }
+     109      229548 :   if( action ) storedata=action->getName()=="PUT" || valtype==average;
+     110      118613 :   if( ss.size() && withderiv ) storedata=true;
+     111      118613 :   setShape( ss );
+     112      118613 : }
+     113             : 
+     114         455 : void Value::setValType( const std::string& vtype ) {
+     115         455 :   if( vtype=="normal" ) valtype=normal;
+     116         455 :   else if( vtype=="constant" ) valtype=constant;
+     117         455 :   else if( vtype=="average" ) valtype=average;
+     118         455 :   else if( vtype=="calcFromAverage" ) valtype=calcFromAverage;
+     119           0 :   else plumed_merror("invalid valtype " + vtype );
+     120         455 : }
+     121             : 
+     122      130924 : void Value::setShape( const std::vector<unsigned>&ss ) {
+     123      130924 :   std::size_t tot=1; shape.resize( ss.size() );
+     124      161697 :   for(unsigned i=0; i<shape.size(); ++i) { tot = tot*ss[i]; shape[i]=ss[i]; }
+     125             : 
+     126      130924 :   if( shape.size()>0 && hasDeriv ) {
+     127             :     // This is for grids
+     128        2005 :     ngrid_der = shape.size();
+     129        2005 :     if( action ) ngrid_der = action->getNumberOfDerivatives();
+     130        2005 :     std::size_t ndata = tot*(1+ngrid_der);
+     131        2005 :     data.resize( ndata ); inputForce.resize( tot );
+     132      128919 :   } else if( shape.size()==0 ) {
+     133             :     // This is for scalars
+     134      106424 :     data.resize(1); inputForce.resize(1);
+     135       22495 :   } else if( storedata && shape.size()<2 ) {
+     136             :     // This is for vectors (matrices have special version because we have sparse storage)
+     137       12398 :     data.resize( tot ); inputForce.resize( tot );
+     138             :   }
+     139      130924 : }
+     140             : 
+     141      109691 : void Value::setupPeriodicity() {
+     142      109691 :   if( min==0 && max==0 ) {
+     143      101946 :     periodicity=notperiodic;
+     144             :   } else {
+     145        7745 :     periodicity=periodic;
+     146        7745 :     max_minus_min=max-min;
+     147        7745 :     plumed_massert(max_minus_min>0, "your function has a very strange domain?");
+     148        7745 :     inv_max_minus_min=1.0/max_minus_min;
+     149             :   }
+     150      109691 : }
+     151             : 
+     152     1684843 : bool Value::isPeriodic()const {
+     153     1684843 :   plumed_massert(periodicity!=unset,"periodicity should be set");
+     154     1684843 :   return periodicity==periodic;
+     155             : }
+     156             : 
+     157      404396 : bool Value::applyForce(std::vector<double>& forces ) const {
+     158      404396 :   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     1102168 : void Value::setNotPeriodic() {
+     166     1102168 :   min=0; max=0; periodicity=notperiodic;
+     167     1102168 : }
+     168             : 
+     169        7745 : void Value::setDomain(const std::string& pmin,const std::string& pmax) {
+     170        7745 :   str_min=pmin;
+     171        7745 :   if( !Tools::convertNoexcept(str_min,min) ) action->error("could not convert period string " + str_min + " to real");
+     172        7745 :   str_max=pmax;
+     173        7745 :   if( !Tools::convertNoexcept(str_max,max) ) action->error("could not convert period string " + str_max + " to read");
+     174        7745 :   setupPeriodicity();
+     175        7745 : }
+     176             : 
+     177       16759 : void Value::getDomain(std::string&minout,std::string&maxout) const {
+     178       16759 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     179       16759 :   minout=str_min;
+     180       16759 :   maxout=str_max;
+     181       16759 : }
+     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    18713566 : ActionWithValue* Value::getPntrToAction() {
+     219    18713566 :   plumed_assert( action!=NULL );
+     220    18713566 :   return action;
+     221             : }
+     222             : 
+     223     4948688 : void Value::set(const std::size_t& n, const double& v ) {
+     224     4948688 :   value_set=true;
+     225     4948688 :   if( getRank()==0 ) { plumed_assert( n==0 ); data[n]=v; applyPeriodicity(n); }
+     226     4923013 :   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     4948688 : }
+     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     3223564 : std::size_t Value::getIndexInStore( const std::size_t& ival ) const {
+     241     3223564 :   if( shape.size()==2 && ncols<shape[1] ) {
+     242     2712800 :     unsigned irow = std::floor( ival / shape[1] ), jcol = ival%shape[1];
+     243    11801200 :     for(unsigned i=0; i<getRowLength(irow); ++i) {
+     244    11801200 :       if( getRowIndex(irow,i)==jcol ) return irow*ncols+i;
+     245             :     }
+     246           0 :     plumed_merror("cannot get store index");
+     247             :   }
+     248      510764 :   return ival;
+     249             : }
+     250             : 
+     251   557633435 : double Value::get(const std::size_t& ival, const bool trueind) const {
+     252   557633435 :   if( hasDeriv ) return data[ival*(1+ngrid_der)];
+     253             : #ifdef DNDEBUG
+     254             :   if( action ) plumed_dbg_massert( ival<getNumberOfValues(), "could not get value from " + name );
+     255             : #endif
+     256   542724005 :   if( shape.size()==2 && ncols<shape[1] && trueind ) {
+     257     2000962 :     unsigned irow = std::floor( ival / shape[1] ), jcol = ival%shape[1];
+     258             :     // This is a special treatment for the lower triangular matrices that are used when
+     259             :     // we do ITRE with COLLECT_FRAMES
+     260     2000962 :     if( ncols==0 ) {
+     261           0 :       if( jcol<=irow ) return data[0.5*irow*(irow+1) + jcol];
+     262             :       return 0;
+     263             :     }
+     264    20655470 :     for(unsigned i=0; i<getRowLength(irow); ++i) {
+     265    19057356 :       if( getRowIndex(irow,i)==jcol ) return data[irow*ncols+i];
+     266             :     }
+     267             :     return 0.0;
+     268             :   }
+     269   540723043 :   plumed_massert( ival<data.size(), "cannot get value from " + name );
+     270   540723043 :   return data[ival];
+     271             : }
+     272             : 
+     273    39291023 : void Value::addForce(const std::size_t& iforce, double f, const bool trueind) {
+     274    39291023 :   hasForce=true;
+     275    39291023 :   if( shape.size()==2 && !hasDeriv && ncols<shape[1] && trueind ) {
+     276           0 :     unsigned irow = std::floor( iforce / shape[0] ), jcol = iforce%shape[0];
+     277           0 :     for(unsigned i=0; i<getRowLength(irow); ++i) {
+     278           0 :       if( getRowIndex(irow,i)==jcol ) { inputForce[irow*ncols+i]+=f; return; }
+     279             :     }
+     280           0 :     plumed_assert( fabs(f)<epsilon ); return;
+     281             :   }
+     282    39291023 :   plumed_massert( iforce<inputForce.size(), "can't add force to " + name );
+     283    39291023 :   inputForce[iforce]+=f;
+     284             : }
+     285             : 
+     286             : 
+     287       12044 : void Value::buildDataStore( const bool forprint ) {
+     288       12044 :   if( getRank()==0 ) return;
+     289        5286 :   storedata=true; setShape( shape );
+     290        5286 :   if( !forprint ) return ;
+     291         192 :   ActionWithVector* av=dynamic_cast<ActionWithVector*>( action );
+     292         192 :   if( av ) (av->getFirstActionInChain())->never_reduce_tasks=true;
+     293             : }
+     294             : 
+     295        7079 : void Value::reshapeMatrixStore( const unsigned& n ) {
+     296             :   plumed_dbg_assert( shape.size()==2 && !hasDeriv );
+     297        7079 :   if( !storedata ) return ;
+     298        7079 :   ncols=n; if( ncols>shape[1] ) ncols=shape[1];
+     299        7079 :   unsigned size=shape[0]*ncols;
+     300        7079 :   if( matrix_bookeeping.size()!=(size+shape[0]) ) {
+     301        2559 :     data.resize( size ); inputForce.resize( size );
+     302        2559 :     matrix_bookeeping.resize( size + shape[0], 0 );
+     303        2559 :     if( ncols>=shape[1] ) {
+     304      248536 :       for(unsigned i=0; i<shape[0]; ++i) {
+     305      246040 :         matrix_bookeeping[(1+ncols)*i] = shape[1];
+     306    23653091 :         for(unsigned j=0; j<shape[1]; ++j) matrix_bookeeping[(1+ncols)*i+1+j]=j;
+     307             :       }
+     308             :     }
+     309             :   }
+     310        7079 :   if( ncols<shape[1] ) std::fill(matrix_bookeeping.begin(), matrix_bookeeping.end(), 0);
+     311             : }
+     312             : 
+     313       35389 : void Value::setPositionInMatrixStash( const unsigned& p ) {
+     314             :   plumed_dbg_assert( shape.size()==2 && !hasDeriv );
+     315       35389 :   matpos=p;
+     316       35389 : }
+     317             : 
+     318    15990662 : bool Value::ignoreStoredValue(const std::string& c) const {
+     319    15990662 :   if( !storedata && shape.size()>0 ) return true;
+     320     6831104 :   ActionWithVector* av=dynamic_cast<ActionWithVector*>(action);
+     321     6831104 :   if( av ) return (av->getFirstActionInChain())->getLabel()==c;
+     322             :   return false;
+     323             : }
+     324             : 
+     325        5501 : void Value::setConstant() {
+     326        5501 :   valtype=constant; storedata=true; setShape( shape );
+     327        5501 :   if( getRank()==2 && !hasDeriv ) reshapeMatrixStore( shape[1] );
+     328        5501 : }
+     329             : 
+     330         456 : void Value::writeBinary(std::ostream&o) const {
+     331         456 :   o.write(reinterpret_cast<const char*>(&data[0]),data.size()*sizeof(double));
+     332         456 : }
+     333             : 
+     334        1274 : void Value::setSymmetric( const bool& sym ) {
+     335        1274 :   plumed_assert( shape.size()==2 && !hasDeriv );
+     336        1274 :   if( sym && shape[0]!=shape[1] ) plumed_merror("non-square matrix cannot be symmetric");
+     337        1274 :   symmetric=sym;
+     338        1274 : }
+     339             : 
+     340        2220 : void Value::retrieveEdgeList( unsigned& nedge, std::vector<std::pair<unsigned,unsigned> >& active, std::vector<double>& elems ) {
+     341        2220 :   nedge=0; plumed_dbg_assert( shape.size()==2 && !hasDeriv );
+     342             :   // Check we have enough space to store the edge list
+     343        2220 :   if( elems.size()<shape[0]*ncols ) { elems.resize( shape[0]*ncols ); active.resize( shape[0]*ncols ); }
+     344             : 
+     345      269579 :   for(unsigned i=0; i<shape[0]; ++i) {
+     346             :     unsigned ncol = getRowLength(i);
+     347    15002116 :     for(unsigned j=0; j<ncol; ++j) {
+     348    14734757 :       if( fabs(get(i*ncols+j,false))<epsilon ) continue;
+     349     3265037 :       if( symmetric && getRowIndex(i,j)>i ) continue;
+     350     3213497 :       active[nedge].first = i; active[nedge].second = getRowIndex(i,j);
+     351     3213497 :       elems[nedge] = get(i*ncols+j,false); nedge++;
+     352             :     }
+     353             :   }
+     354        2220 : }
+     355             : 
+     356         456 : void Value::readBinary(std::istream&i) {
+     357         456 :   i.read(reinterpret_cast<char*>(&data[0]),data.size()*sizeof(double));
+     358         456 : }
+     359             : 
+     360      775666 : void Value::convertIndexToindices(const std::size_t& index, std::vector<unsigned>& indices ) const {
+     361      775666 :   if( hasDeriv || getRank()==1 ) {
+     362       12302 :     std::size_t kk=index; indices[0]=index%shape[0];
+     363       12302 :     for(unsigned i=1; i<shape.size()-1; ++i) {
+     364           0 :       kk=(kk-indices[i-1])/shape[i-1];
+     365           0 :       indices[i]=kk%shape[i];
+     366             :     }
+     367       12302 :     if(shape.size()>=2) indices[shape.size()-1]=(kk-indices[shape.size()-2])/shape[shape.size()-2];
+     368      763364 :   } else if( getRank()==2 ) {
+     369      763364 :     indices[0]=std::floor( index/shape[1] ); indices[1] = index%shape[1];
+     370             :   }
+     371      775666 : }
+     372             : 
+     373      548042 : void Value::print( OFile& ofile ) const {
+     374      571116 :   if( isPeriodic() ) { ofile.printField( "min_" + name, str_min ); ofile.printField("max_" + name, str_max ); }
+     375      548042 :   if( shape.size()==0 || getNumberOfValues()==1 ) {
+     376      546723 :     ofile.printField( name, get(0) );
+     377             :   } else {
+     378        1319 :     std::vector<unsigned> indices( shape.size() );
+     379      776985 :     for(unsigned i=0; i<getNumberOfValues(); ++i) {
+     380      775666 :       convertIndexToindices( i, indices ); std::string num, fname = name;
+     381     2314696 :       for(unsigned i=0; i<shape.size(); ++i) { Tools::convert( indices[i]+1, num ); fname += "." + num; }
+     382      775666 :       ofile.printField( fname, get(i) );
+     383             :     }
+     384             :   }
+     385      548042 : }
+     386             : 
+     387      232389 : unsigned Value::getGoodNumThreads( const unsigned& j, const unsigned& k ) const {
+     388      232389 :   return OpenMP::getGoodNumThreads( &data[j], (k-j) );
+     389             : }
+     390             : 
+     391     7508060 : bool Value::calculateOnUpdate() const {
+     392     7508060 :   return (valtype==average || valtype==calcFromAverage);
+     393             : }
+     394             : 
+     395         132 : std::string Value::getValueType() const {
+     396         132 :   if( getRank()==0 ) return "scalar";
+     397          99 :   if( getRank()>0 && hasDerivatives() ) return "grid";
+     398          94 :   if( getRank()==1 ) return "vector";
+     399          21 :   if( getRank()==2 ) return "matrix";
+     400           0 :   plumed_merror("unknown type for value " + getName() );
+     401             :   return "";
+     402             : }
+     403             : 
+     404             : }
+
+
+
+ + + + +
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 000000000..42cea94b1 --- /dev/null +++ b/coverage/core/Value.h.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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:848697.7 %
Date:2024-10-17 16:45:00Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value3addEd2144
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZN4PLMD5Value15clearInputForceERKSt6vectorINS_10AtomNumberESaIS2_EE115715
_ZN4PLMD5Value18addGridDerivativesERKjS2_RKd1089247
_ZNK4PLMD5Value23getNumberOfStoredValuesEv2712561
_ZN4PLMD5Value16clearDerivativesEb2802509
_ZNK4PLMD5Value10differenceEd3989526
_ZN4PLMD5Value17resizeDerivativesEi4447764
_ZNK4PLMD5Value22getNumberOfDerivativesEv16294106
_ZNK4PLMD5Value17getNumberOfValuesEv45657112
_ZN4PLMD5Value3addERKmRKd46452643
_ZN4PLMD5Value16applyPeriodicityERKj56813692
_ZNK4PLMD5Value10differenceEdd135678759
+
+
+ + + +
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 000000000..3f63bd879 --- /dev/null +++ b/coverage/core/Value.h.func.html @@ -0,0 +1,124 @@ + + + + + + + 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:848697.7 %
Date:2024-10-17 16:45:00Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value15clearInputForceERKSt6vectorINS_10AtomNumberESaIS2_EE115715
_ZN4PLMD5Value16applyPeriodicityERKj56813692
_ZN4PLMD5Value16clearDerivativesEb2802509
_ZN4PLMD5Value17resizeDerivativesEi4447764
_ZN4PLMD5Value18addGridDerivativesERKjS2_RKd1089247
_ZN4PLMD5Value3addERKmRKd46452643
_ZN4PLMD5Value3addEd2144
_ZNK4PLMD5Value10differenceEd3989526
_ZNK4PLMD5Value10differenceEdd135678759
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZNK4PLMD5Value17getNumberOfValuesEv45657112
_ZNK4PLMD5Value22getNumberOfDerivativesEv16294106
_ZNK4PLMD5Value23getNumberOfStoredValuesEv2712561
+
+
+ + + +
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 000000000..115610b52 --- /dev/null +++ b/coverage/core/Value.h.gcov.html @@ -0,0 +1,583 @@ + + + + + + + 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:848697.7 %
Date:2024-10-17 16:45:00Functions:1313100.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             : private:
+      58             : /// The action in which this quantity is calculated
+      59             :   ActionWithValue* action;
+      60             : /// Had the value been set
+      61             :   bool value_set;
+      62             : /// The value of the quantity
+      63             :   std::vector<double> data;
+      64             : /// The force acting on this quantity
+      65             :   std::vector<double> inputForce;
+      66             : /// A flag telling us we have a force acting on this quantity
+      67             :   bool hasForce;
+      68             : /// The way this value is used in the code
+      69             : /// normal = regular value that is determined during calculate
+      70             : /// constant = constnt value that is determined during startup and that doesn't change during simulation
+      71             : /// average = value that is averaged/collected over multiple steps of trajectory
+      72             : /// calcFromAverage = value that is calculated from an average value
+      73             :   enum {normal,constant,average,calcFromAverage} valtype=normal;
+      74             : /// This is used by ActionWithValue to set the valtype
+      75             :   void setValType( const std::string& vtype );
+      76             : /// This is used by ActionWithValue to determine if we need to calculate on update
+      77             :   bool calculateOnUpdate() const ;
+      78             : /// The derivatives of the quantity stored in value
+      79             :   std::map<AtomNumber,Vector> gradients;
+      80             : /// The name of this quantiy
+      81             :   std::string name;
+      82             : /// Are we storing the data for this value if it is vector or matrix
+      83             :   bool storedata;
+      84             : /// What is the shape of the value (0 dimensional=scalar, n dimensional with derivatives=grid, 1 dimensional no derivatives=vector, 2 dimensional no derivatives=matrix)
+      85             :   std::vector<unsigned> shape;
+      86             : /// Does this quanity have derivatives
+      87             :   bool hasDeriv;
+      88             : /// Variables for storing data
+      89             :   unsigned bufstart, streampos, matpos, ngrid_der, ncols, book_start;
+      90             : /// If we are storing a matrix is it symmetric?
+      91             :   bool symmetric;
+      92             : /// This is a bookeeping array that holds the non-zero elements of the "sparse" matrix
+      93             :   std::vector<unsigned> matrix_bookeeping;
+      94             : /// Is this quantity periodic
+      95             :   enum {unset,periodic,notperiodic} periodicity;
+      96             : /// Various quantities that describe the domain of this value
+      97             :   std::string str_min, str_max;
+      98             :   double min,max;
+      99             :   double max_minus_min;
+     100             :   double inv_max_minus_min;
+     101             : /// Is the derivative of this quantity zero when the value is zero
+     102             :   bool derivativeIsZeroWhenValueIsZero;
+     103             : /// Complete the setup of the periodicity
+     104             :   void setupPeriodicity();
+     105             : // bring value within PBCs
+     106             :   void applyPeriodicity( const unsigned& ival );
+     107             : public:
+     108             : /// A constructor that can be used to make Vectors of values
+     109             :   Value();
+     110             : /// A constructor that can be used to make Vectors of named values
+     111             :   explicit Value(const std::string& name);
+     112             : /// A constructor that is used throughout the code to setup the value poiters
+     113             :   Value(ActionWithValue* av, const std::string& name, const bool withderiv,const std::vector<unsigned>&ss=std::vector<unsigned>());
+     114             : /// Set the shape of the Value
+     115             :   void setShape( const std::vector<unsigned>&ss );
+     116             : /// Set the value of the function
+     117             :   void set(double);
+     118             : /// Set the value of the stored data
+     119             :   void set(const std::size_t& n, const double& v );
+     120             : /// Add something to the value of the function
+     121             :   void add(double);
+     122             : /// Add something to the ith element of the data array
+     123             :   void add(const std::size_t& n, const double& v );
+     124             : /// Get the location of this element of in the store
+     125             :   std::size_t getIndexInStore( const std::size_t& ival ) const ;
+     126             : /// Get the value of the function
+     127     6835456 :   double get( const std::size_t& ival=0, const bool trueind=true ) const;
+     128             : /// Find out if the value has been set
+     129             :   bool valueHasBeenSet() const;
+     130             : /// Check if the value is periodic
+     131             :   bool isPeriodic() const;
+     132             : /// Set the function not periodic
+     133             :   void setNotPeriodic();
+     134             : /// Set the domain of the function
+     135             :   void setDomain(const std::string&, const std::string&);
+     136             : /// Get the domain of the quantity
+     137             :   void getDomain(std::string&,std::string&) const;
+     138             : /// Get the domain of the quantity
+     139             :   void getDomain(double&,double&) const;
+     140             : /// Get the name of the quantity
+     141             :   const std::string& getName() const;
+     142             : /// Check whether or not this particular quantity has derivatives
+     143             :   bool hasDerivatives()const;
+     144             : /// Get the number of derivatives that this particular value has
+     145             :   unsigned getNumberOfDerivatives() const;
+     146             : /// Set the number of derivatives
+     147             :   void resizeDerivatives(int n);
+     148             : /// Set all the derivatives to zero
+     149             :   void clearDerivatives( const bool force=false );
+     150             : /// Add some derivative to the ith component of the derivatives array
+     151             :   void addDerivative(unsigned i,double d);
+     152             : /// Set the value of the ith component of the derivatives array
+     153             :   void setDerivative(unsigned i, double d);
+     154             : /// Get the derivative with respect to component n
+     155             :   double getDerivative(const unsigned n) const;
+     156             : /// Clear the input force on the variable
+     157             :   void clearInputForce();
+     158             : /// Special method for clearing forces on variables used by DataPassingObject
+     159             :   void clearInputForce( const std::vector<AtomNumber>& index );
+     160             : /// Add some force on this value
+     161             :   void addForce(double f);
+     162             : /// Add some force on the ival th component of this value
+     163             :   void addForce( const std::size_t& ival, double f, const bool trueind=true );
+     164             : /// Get the value of the force on this colvar
+     165             :   double getForce( const std::size_t& ival=0 ) const ;
+     166             : /// Apply the forces to the derivatives using the chain rule (if there are no forces this routine returns false)
+     167             :   bool applyForce( std::vector<double>& forces ) const ;
+     168             : /// Calculate the difference between the instantaneous value of the function and some other point: other_point-inst_val
+     169             :   double difference(double)const;
+     170             : /// Calculate the difference between two values of this function: d2 -d1
+     171             :   double difference(double d1,double d2)const;
+     172             : /// This returns the pointer to the action where this value is calculated
+     173             :   ActionWithValue* getPntrToAction();
+     174             : /// Bring back one value into the correct pbc if needed, else give back the value
+     175             :   double bringBackInPbc(double d1)const;
+     176             : /// Get the difference between max and minimum of domain
+     177             :   double getMaxMinusMin()const;
+     178             : /// This sets up the gradients
+     179             :   void setGradients( ActionAtomistic* aa, unsigned& start );
+     180             : /// This passes gradients from one action to another
+     181             :   void passGradients( const double& der, std::map<AtomNumber,Vector>& g ) const ;
+     182             :   static double projection(const Value&,const Value&);
+     183             : /// Get the rank of the object that is contained in this value
+     184             :   unsigned getRank() const ;
+     185             : /// Get the shape of the object that is contained in this value
+     186             :   const std::vector<unsigned>& getShape() const ;
+     187             : /// This turns on storing of vectors/matrices
+     188             :   void buildDataStore( const bool forprint=false );
+     189             : /// Reshape the storage for sparse matrices
+     190             :   void reshapeMatrixStore( const unsigned& n );
+     191             : /// Set the symmetric flag equal true for this matrix
+     192             :   void setSymmetric( const bool& sym );
+     193             : /// Get the total number of scalars that are stored here
+     194             :   unsigned getNumberOfValues() const ;
+     195             : /// Get the number of values that are actually stored here once sparse matrices are taken into account
+     196             :   unsigned getNumberOfStoredValues() const ;
+     197             : /// Get the number of threads to use when assigning this value
+     198             :   unsigned getGoodNumThreads( const unsigned& j, const unsigned& k ) const ;
+     199             : /// These are used for passing around the data in this value when we are doing replica exchange
+     200             :   void writeBinary(std::ostream&o) const ;
+     201             :   void readBinary(std::istream&i);
+     202             : /// These are used for making constant values
+     203             :   bool isConstant() const ;
+     204             :   void setConstant();
+     205             : /// Check if forces have been added on this value
+     206             :   bool forcesWereAdded() const ;
+     207             : /// Set a bool that tells us if the derivative is zero when the value is zero true
+     208             :   void setDerivativeIsZeroWhenValueIsZero();
+     209             : /// Return a bool that tells us if the derivative is zero when the value is zero
+     210             :   bool isDerivativeZeroWhenValueIsZero() const ;
+     211             : ///
+     212             :   unsigned getPositionInStream() const ;
+     213             : /// This stuff handles where to look for the start of the row that contains the row of the matrix
+     214             :   void setPositionInMatrixStash( const unsigned& p );
+     215             :   unsigned getPositionInMatrixStash() const ;
+     216             : /// This stuff handles where to keep the bookeeping stuff for storing the sparse matrix
+     217             :   void setMatrixBookeepingStart( const unsigned& b );
+     218             :   unsigned getMatrixBookeepingStart() const ;
+     219             : /// Convert the input index to its corresponding indices
+     220             :   void convertIndexToindices(const std::size_t& index, std::vector<unsigned>& indices ) const ;
+     221             : /// Print out all the values in this Value
+     222             :   void print( OFile& ofile ) const ;
+     223             : /// Are we to ignore the stored value
+     224             :   bool ignoreStoredValue(const std::string& n) const ;
+     225             : /// Set a matrix element to be non zero
+     226             :   void setMatrixBookeepingElement( const unsigned& i, const unsigned& n );
+     227             : ///
+     228             :   unsigned getRowLength( const unsigned& irow ) const ;
+     229             : ///
+     230             :   unsigned getRowIndex( const unsigned& irow, const unsigned& jind ) const ;
+     231             : /// Are we storing this value
+     232             :   bool valueIsStored() const ;
+     233             : ///
+     234             :   unsigned getNumberOfColumns() const ;
+     235             : ///
+     236             :   bool isSymmetric() const ;
+     237             : /// Retrieve the non-zero edges in a matrix
+     238             :   void retrieveEdgeList( unsigned& nedge, std::vector<std::pair<unsigned,unsigned> >& active, std::vector<double>& elems );
+     239             : /// Get the number of derivatives that the grid has
+     240             :   unsigned getNumberOfGridDerivatives() const ;
+     241             : /// get the derivative of a grid at a point n with resepct to argument j
+     242             :   double getGridDerivative(const unsigned& n, const unsigned& j ) const ;
+     243             : /// Add the derivatives of the grid to the corner
+     244             :   void addGridDerivatives( const unsigned& n, const unsigned& j, const double& val );
+     245             : ///
+     246             :   void setGridDerivatives( const unsigned& n, const unsigned& j, const double& val );
+     247             : /// Add another value to the end of the data vector held by this value.  This is used in COLLECT
+     248             :   void push_back( const double& val );
+     249             : /// Get the type of value that is stored here
+     250             :   std::string getValueType() const ;
+     251             : };
+     252             : 
+     253             : inline
+     254    56813692 : void Value::applyPeriodicity(const unsigned& ival) {
+     255    56813692 :   if(periodicity==periodic) {
+     256     2384799 :     data[ival]=min+difference(min,data[ival]);
+     257     2384799 :     if(data[ival]<min)data[ival]+=max_minus_min;
+     258             :   }
+     259    56813692 : }
+     260             : 
+     261             : inline
+     262             : void Value::set(double v) {
+     263     5307411 :   value_set=true;
+     264     5526217 :   data[0]=v;
+     265     5483469 :   applyPeriodicity(0);
+     266       64133 : }
+     267             : 
+     268             : inline
+     269        2144 : void Value::add(double v) {
+     270        2144 :   value_set=true;
+     271        2144 :   data[0]+=v;
+     272        2144 :   applyPeriodicity(0);
+     273        2144 : }
+     274             : 
+     275             : inline
+     276    46452643 : void Value::add(const std::size_t& n, const double& v ) {
+     277    46452643 :   value_set=true; data[n]+=v; applyPeriodicity(n);
+     278    46452643 : }
+     279             : 
+     280             : inline
+     281             : bool Value::valueHasBeenSet() const {
+     282   231208647 :   return value_set;
+     283             : }
+     284             : 
+     285             : inline
+     286             : const std::string& Value::getName()const {
+     287     5373334 :   return name;
+     288             : }
+     289             : 
+     290             : inline
+     291    16294106 : unsigned Value::getNumberOfDerivatives() const {
+     292    16294106 :   plumed_massert(hasDeriv,"the derivatives array for this value has zero size");
+     293    16294106 :   if( shape.size()>0 ) return shape.size();
+     294    16294106 :   return data.size() - 1;
+     295             : }
+     296             : 
+     297             : inline
+     298             : double Value::getDerivative(const unsigned n) const {
+     299             :   plumed_dbg_massert(n<getNumberOfDerivatives(),"you are asking for a derivative that is out of bounds");
+     300    19322011 :   return data[1+n];
+     301             : }
+     302             : 
+     303             : inline
+     304             : bool Value::hasDerivatives() const {
+     305   225345096 :   return hasDeriv;
+     306             : }
+     307             : 
+     308             : inline
+     309     4447764 : void Value::resizeDerivatives(int n) {
+     310     4447764 :   if( shape.size()>0 ) return;
+     311     3551725 :   if(hasDeriv) data.resize(1+n);
+     312             : }
+     313             : 
+     314             : inline
+     315             : void Value::addDerivative(unsigned i,double d) {
+     316             :   plumed_dbg_massert(i<getNumberOfDerivatives(),"derivative is out of bounds");
+     317    20051321 :   data[1+i]+=d;
+     318             : }
+     319             : 
+     320             : inline
+     321             : void Value::setDerivative(unsigned i, double d) {
+     322             :   plumed_dbg_massert(i<getNumberOfDerivatives(),"derivative is out of bounds");
+     323    17649718 :   data[1+i]=d;
+     324             : }
+     325             : 
+     326             : inline
+     327             : void Value::clearInputForce() {
+     328     3247214 :   if( !hasForce ) return;
+     329      545974 :   hasForce=false; std::fill(inputForce.begin(),inputForce.end(),0);
+     330             : }
+     331             : 
+     332             : inline
+     333      115715 : void Value::clearInputForce( const std::vector<AtomNumber>& index ) {
+     334      115715 :   if( !hasForce ) return;
+     335     1993569 :   hasForce=false; for(const auto & p : index) inputForce[p.index()]=0;
+     336             : }
+     337             : 
+     338             : inline
+     339     2802509 : void Value::clearDerivatives( const bool force ) {
+     340     2802509 :   if( !force && (valtype==constant || valtype==average) ) return;
+     341             : 
+     342     2782406 :   value_set=false;
+     343     2782406 :   if( data.size()>1 ) std::fill(data.begin()+1, data.end(), 0);
+     344             : }
+     345             : 
+     346             : inline
+     347             : void Value::addForce(double f) {
+     348      177572 :   hasForce=true;
+     349      177572 :   inputForce[0]+=f;
+     350        2623 : }
+     351             : 
+     352             : inline
+     353             : bool Value::forcesWereAdded() const {
+     354    19676510 :   return hasForce;
+     355             : }
+     356             : 
+     357             : inline
+     358             : double Value::getForce( const std::size_t& ival ) const {
+     359             :   plumed_dbg_assert( ival<inputForce.size() );
+     360    24545219 :   return inputForce[ival];
+     361             : }
+     362             : 
+     363             : /// d2-d1
+     364             : inline
+     365   135678759 : double Value::difference(double d1,double d2)const {
+     366   135678759 :   if(periodicity==notperiodic) {
+     367    33852482 :     return d2-d1;
+     368   101826277 :   } else if(periodicity==periodic) {
+     369   101826277 :     double s=(d2-d1)*inv_max_minus_min;
+     370             :     // remember: pbc brings the difference in a range of -0.5:0.5
+     371   101826277 :     s=Tools::pbc(s);
+     372   101826277 :     return s*max_minus_min;
+     373           0 :   } else plumed_merror("periodicity should be set to compute differences");
+     374             : }
+     375             : 
+     376             : inline
+     377        3173 : double Value::bringBackInPbc(double d1)const {
+     378        3173 :   return min+max_minus_min/2.+difference(min+max_minus_min/2., d1);
+     379             : }
+     380             : 
+     381             : inline
+     382     3989526 : double Value::difference(double d)const {
+     383     3989526 :   return difference(get(),d);
+     384             : }
+     385             : 
+     386             : inline
+     387             : double Value::getMaxMinusMin()const {
+     388             :   plumed_dbg_assert( periodicity==periodic );
+     389           0 :   return max_minus_min;
+     390             : }
+     391             : 
+     392             : inline
+     393             : unsigned Value::getRank() const {
+     394   708193461 :   return shape.size();
+     395             : }
+     396             : 
+     397             : inline
+     398             : const std::vector<unsigned>& Value::getShape() const {
+     399      470408 :   return shape;
+     400             : }
+     401             : 
+     402             : inline
+     403    45657112 : unsigned Value::getNumberOfValues() const {
+     404    55645787 :   unsigned size=1; for(unsigned i=0; i<shape.size(); ++i) size *= shape[i];
+     405    45657112 :   return size;
+     406             : }
+     407             : 
+     408             : inline
+     409     2712561 : unsigned Value::getNumberOfStoredValues() const {
+     410     2712561 :   if( getRank()==2 && !hasDeriv ) return shape[0]*ncols;
+     411      448190 :   return getNumberOfValues();
+     412             : }
+     413             : 
+     414             : inline
+     415             : bool Value::isConstant() const {
+     416      394583 :   return valtype==constant;
+     417             : }
+     418             : 
+     419             : inline
+     420             : void Value::setDerivativeIsZeroWhenValueIsZero() {
+     421        1199 :   derivativeIsZeroWhenValueIsZero=true;
+     422          15 : }
+     423             : 
+     424             : inline
+     425             : bool Value::isDerivativeZeroWhenValueIsZero() const {
+     426        1798 :   return derivativeIsZeroWhenValueIsZero;
+     427             : }
+     428             : 
+     429             : inline
+     430             : unsigned Value::getPositionInStream() const {
+     431  1052590383 :   return streampos;
+     432             : }
+     433             : 
+     434             : inline
+     435             : unsigned Value::getPositionInMatrixStash() const {
+     436    28657011 :   return matpos;
+     437             : }
+     438             : 
+     439             : inline
+     440             : void Value::setMatrixBookeepingStart( const unsigned& b ) {
+     441        7794 :   book_start = b;
+     442             : }
+     443             : 
+     444             : inline
+     445             : unsigned Value::getMatrixBookeepingStart() const {
+     446    14169812 :   return book_start;
+     447             : }
+     448             : 
+     449             : inline
+     450             : void Value::setMatrixBookeepingElement( const unsigned& i, const unsigned& n ) {
+     451             :   plumed_dbg_assert( i<matrix_bookeeping.size() );
+     452     5060232 :   matrix_bookeeping[i]=n;
+     453             : }
+     454             : 
+     455             : inline
+     456             : bool Value::valueIsStored() const {
+     457   117898873 :   return storedata;
+     458             : }
+     459             : 
+     460             : inline
+     461             : unsigned Value::getRowLength( const unsigned& irow ) const {
+     462             :   plumed_dbg_assert( (1+ncols)*irow<matrix_bookeeping.size() );
+     463    34407153 :   return matrix_bookeeping[(1+ncols)*irow];
+     464             : }
+     465             : 
+     466             : inline
+     467             : unsigned Value::getRowIndex( const unsigned& irow, const unsigned& jind ) const {
+     468             :   plumed_dbg_assert( (1+ncols)*irow+1+jind<matrix_bookeeping.size() && jind<matrix_bookeeping[(1+ncols)*irow] );
+     469    54232896 :   return matrix_bookeeping[(1+ncols)*irow+1+jind];
+     470             : }
+     471             : 
+     472             : inline
+     473             : unsigned Value::getNumberOfColumns() const {
+     474    17498698 :   return ncols;
+     475             : }
+     476             : 
+     477             : inline
+     478             : bool Value::isSymmetric() const {
+     479        1456 :   return symmetric;
+     480             : }
+     481             : 
+     482             : inline
+     483             : unsigned Value::getNumberOfGridDerivatives() const {
+     484     1911185 :   return ngrid_der;
+     485             : }
+     486             : 
+     487             : inline
+     488             : double Value::getGridDerivative(const unsigned& n, const unsigned& j ) const {
+     489             :   plumed_dbg_assert( hasDeriv && n*(1+ngrid_der) + 1 + j < data.size() );
+     490     8329578 :   return data[n*(1+ngrid_der) + 1 + j];
+     491             : }
+     492             : 
+     493             : inline
+     494     1089247 : void Value::addGridDerivatives( const unsigned& n, const unsigned& j, const double& val ) {
+     495             :   plumed_dbg_assert( hasDeriv && n*(1+ngrid_der) + 1 + j < data.size() );
+     496     1089247 :   data[n*(1+ngrid_der) + 1 + j] += val;
+     497     1089247 : }
+     498             : 
+     499             : inline
+     500             : void Value::setGridDerivatives( const unsigned& n, const unsigned& j, const double& val ) {
+     501             :   plumed_dbg_assert( hasDeriv && n*(1+ngrid_der) + 1 + j < data.size() );
+     502       48400 :   data[n*(1+ngrid_der) + 1 + j] = val;
+     503             : }
+     504             : 
+     505             : }
+     506             : #endif
+     507             : 
+
+
+
+ + + + +
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 000000000..31452ce3b --- /dev/null +++ b/coverage/core/WithCmd.h.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:222781.5 %
Date:2024-10-17 16:45:00Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE0
_ZN4PLMD7WithCmdD0Ev0
_ZN4PLMD7WithCmdD2Ev0
_ZN4PLMD7WithCmd3cmdImLi0EEEvSt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrET_PKm74
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE315
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrEPKm386686
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrESt16initializer_listINS0_8SizeLikeEE386686
_ZN4PLMD7WithCmd3cmdEPKcRKNS_11TypesafePtrE959719
+
+
+ + + +
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 000000000..0ff521ddd --- /dev/null +++ b/coverage/core/WithCmd.h.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:222781.5 %
Date:2024-10-17 16:45:00Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdEPKcRKNS_11TypesafePtrE959719
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE315
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE0
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrEPKm386686
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrESt16initializer_listINS0_8SizeLikeEE386686
_ZN4PLMD7WithCmd3cmdImLi0EEEvSt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrET_PKm74
_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 000000000..ff6490511 --- /dev/null +++ b/coverage/core/WithCmd.h.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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:222781.5 %
Date:2024-10-17 16:45:00Functions: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             : #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             :   /// Small structure used to pass elements of a shape initializer_list
+      36             :   struct SizeLike {
+      37             :     std::size_t size;
+      38             :     SizeLike(short unsigned size): size(size) {}
+      39             :     SizeLike(unsigned size): size(size) {}
+      40         170 :     SizeLike(long unsigned size): size(size) {}
+      41             :     SizeLike(long long unsigned size): size(size) {}
+      42             :     SizeLike(short size): size(std::size_t(size)) {}
+      43      386516 :     SizeLike(int size): size(std::size_t(size)) {}
+      44             :     SizeLike(long int size): size(std::size_t(size)) {}
+      45             :     SizeLike(long long int size): size(std::size_t(size)) {}
+      46             :   };
+      47             : public:
+      48             :   /// This is the preferred method as it avoid allocations of temporaries.
+      49             :   /// If this is not overridded, it will call the legacy method.
+      50           0 :   virtual void cmd(std::string_view key,const TypesafePtr & val=nullptr) {
+      51           0 :     cmd(std::string(key),val);
+      52           0 :   }
+      53             :   /// This is the legacy method we used in older plumed versions, so it is still possible.
+      54             :   /// If this is not overridden, it will call the preferred method
+      55         315 :   virtual void cmd(const std::string& key,const TypesafePtr & val=nullptr) {
+      56         315 :     cmd(std::string_view(key),val);
+      57         315 :   }
+      58      386686 :   void cmd(std::string_view key,const TypesafePtr & val,const std::size_t* shape) {
+      59      386686 :     cmd(key,TypesafePtr::setNelemAndShape(val,0,shape));
+      60      386686 :   }
+      61      386686 :   void cmd(std::string_view key,const TypesafePtr & val,std::initializer_list<SizeLike> shape) {
+      62      386686 :     if(shape.size()>4) plumed_error() << "Maximum shape size is 4";
+      63             :     std::array<std::size_t,5> shape_;
+      64             :     unsigned j=0;
+      65     1030486 :     for(auto i : shape) {
+      66      643800 :       shape_[j]=i.size;
+      67      643800 :       j++;
+      68             :     }
+      69      386686 :     shape_[j]=0;
+      70      386686 :     cmd(key,val,shape_.data());
+      71      386686 :   }
+      72             :   template<typename I, typename std::enable_if<std::is_integral<I>::value, int>::type = 0>
+      73          74 :   void cmd(std::string_view key,const TypesafePtr & val,I nelem, const std::size_t* shape=nullptr) {
+      74          74 :     cmd(key,TypesafePtr::setNelemAndShape(val,nelem,shape));
+      75          74 :   }
+      76             :   /// This is needed to avoid ambiguities
+      77      959719 :   void cmd(const char* key,const TypesafePtr & val=nullptr) {
+      78      959719 :     cmd(std::string_view(key),val);
+      79      959553 :   }
+      80             :   virtual ~WithCmd();
+      81             : };
+      82             : 
+      83             : inline
+      84           0 : WithCmd::~WithCmd() {
+      85             : // do nothing
+      86             : // here just to allow inheriting from this class properly
+      87           0 : }
+      88             : 
+      89             : }
+      90             : 
+      91             : #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 000000000..0fab785dd --- /dev/null +++ b/coverage/core/index-sort-f.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:4775532689.7 %
Date:2024-10-17 16:45:00Functions:1791192093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
ActionSetup.h +
0.0%
+
0.0 %0 / 30.0 %0 / 2
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 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
ActionShortcut.h +
33.3%33.3%
+
33.3 %1 / 333.3 %1 / 3
DataPassingObject.cpp +
91.9%91.9%
+
91.9 %68 / 7448.3 %14 / 29
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
WithCmd.h +
81.5%81.5%
+
81.5 %22 / 2762.5 %5 / 8
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 +
52.9%52.9%
+
52.9 %18 / 3471.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 +
73.9%73.9%
+
73.9 %34 / 4677.8 %7 / 9
ActionAtomistic.cpp +
94.7%94.7%
+
94.7 %287 / 30382.1 %23 / 28
PbcAction.cpp +
100.0%
+
100.0 %26 / 2683.3 %5 / 6
ActionPilot.cpp +
93.3%93.3%
+
93.3 %14 / 1583.3 %5 / 6
GenericMolInfo.cpp +
85.6%85.6%
+
85.6 %190 / 22283.3 %15 / 18
Action.cpp +
84.1%84.1%
+
84.1 %174 / 20784.2 %32 / 38
ActionWithValue.cpp +
92.4%92.4%
+
92.4 %158 / 17184.8 %28 / 33
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %63 / 6385.7 %6 / 7
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
ActionWithValue.h +
95.2%95.2%
+
95.2 %20 / 2185.7 %6 / 7
ActionWithVector.h +
88.9%88.9%
+
88.9 %8 / 985.7 %6 / 7
ActionForInterface.h +
87.5%87.5%
+
87.5 %7 / 885.7 %6 / 7
Colvar.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
ActionToGetData.cpp +
90.6%90.6%
+
90.6 %29 / 3285.7 %6 / 7
ActionWithArguments.cpp +
88.8%88.8%
+
88.8 %182 / 20585.7 %12 / 14
ActionWithMatrix.cpp +
100.0%
+
100.0 %138 / 13886.4 %19 / 22
RegisterBase.h +
86.1%86.1%
+
86.1 %62 / 7286.4 %19 / 22
CLTool.h +
73.5%73.5%
+
73.5 %25 / 3486.7 %13 / 15
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
Action.h +
94.0%94.0%
+
94.0 %79 / 8489.5 %34 / 38
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
ActionShortcut.cpp +
93.3%93.3%
+
93.3 %139 / 14992.3 %12 / 13
ActionWithVector.cpp +
98.6%98.6%
+
98.6 %420 / 42692.6 %50 / 54
PlumedMain.cpp +
89.8%89.8%
+
89.8 %848 / 94492.9 %65 / 70
DomainDecomposition.cpp +
94.3%94.3%
+
94.3 %264 / 28093.9 %31 / 33
ActionRegister.h +
100.0%
+
100.0 %7 / 798.3 %1144 / 1164
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
CLToolRegister.h +
100.0%
+
100.0 %2 / 2-0 / 0
PlumedMain.h +
94.4%94.4%
+
94.4 %17 / 18-0 / 0
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
ModuleMap.cpp +
100.0%
+
100.0 %3 / 3100.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.3%84.3%
+
84.3 %113 / 134100.0 %5 / 5
ActionWithVirtualAtom.h +
100.0%
+
100.0 %22 / 22100.0 %6 / 6
ActionWithMatrix.h +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
GREX.cpp +
75.2%75.2%
+
75.2 %100 / 133100.0 %6 / 6
ActionWithArguments.h +
100.0%
+
100.0 %17 / 17100.0 %7 / 7
ActionAtomistic.h +
100.0%
+
100.0 %48 / 48100.0 %10 / 10
Value.h +
97.7%97.7%
+
97.7 %84 / 86100.0 %13 / 13
ActionToPutData.cpp +
92.4%92.4%
+
92.4 %97 / 105100.0 %17 / 17
Value.cpp +
96.2%96.2%
+
96.2 %254 / 264100.0 %35 / 35
+
+
+ + + + +
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 000000000..00d18d46f --- /dev/null +++ b/coverage/core/index-sort-l.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:4775532689.7 %
Date:2024-10-17 16:45:00Functions:1791192093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
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
ActionShortcut.h +
33.3%33.3%
+
33.3 %1 / 333.3 %1 / 3
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 +
52.9%52.9%
+
52.9 %18 / 3471.4 %5 / 7
CLTool.h +
73.5%73.5%
+
73.5 %25 / 3486.7 %13 / 15
ActionRegister.cpp +
73.9%73.9%
+
73.9 %34 / 4677.8 %7 / 9
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
WithCmd.h +
81.5%81.5%
+
81.5 %22 / 2762.5 %5 / 8
DataPassingTools.cpp +
82.6%82.6%
+
82.6 %19 / 2375.0 %6 / 8
PlumedMainInitializer.cpp +
82.9%82.9%
+
82.9 %223 / 26987.5 %14 / 16
Action.cpp +
84.1%84.1%
+
84.1 %174 / 20784.2 %32 / 38
CLToolMain.cpp +
84.3%84.3%
+
84.3 %113 / 134100.0 %5 / 5
GenericMolInfo.cpp +
85.6%85.6%
+
85.6 %190 / 22283.3 %15 / 18
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
RegisterBase.h +
86.1%86.1%
+
86.1 %62 / 7286.4 %19 / 22
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.cpp +
89.8%89.8%
+
89.8 %848 / 94492.9 %65 / 70
ActionToGetData.cpp +
90.6%90.6%
+
90.6 %29 / 3285.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
DataPassingObject.cpp +
91.9%91.9%
+
91.9 %68 / 7448.3 %14 / 29
ActionToPutData.cpp +
92.4%92.4%
+
92.4 %97 / 105100.0 %17 / 17
ActionWithValue.cpp +
92.4%92.4%
+
92.4 %158 / 17184.8 %28 / 33
ActionShortcut.cpp +
93.3%93.3%
+
93.3 %139 / 14992.3 %12 / 13
ActionPilot.cpp +
93.3%93.3%
+
93.3 %14 / 1583.3 %5 / 6
Action.h +
94.0%94.0%
+
94.0 %79 / 8489.5 %34 / 38
DomainDecomposition.cpp +
94.3%94.3%
+
94.3 %264 / 28093.9 %31 / 33
PlumedMain.h +
94.4%94.4%
+
94.4 %17 / 18-0 / 0
ActionAtomistic.cpp +
94.7%94.7%
+
94.7 %287 / 30382.1 %23 / 28
ActionWithValue.h +
95.2%95.2%
+
95.2 %20 / 2185.7 %6 / 7
Value.cpp +
96.2%96.2%
+
96.2 %254 / 264100.0 %35 / 35
Value.h +
97.7%97.7%
+
97.7 %84 / 86100.0 %13 / 13
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
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
CLToolRegister.h +
100.0%
+
100.0 %2 / 2-0 / 0
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
ModuleMap.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
DomainDecomposition.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
ActionAnyorder.cpp +
100.0%
+
100.0 %6 / 666.7 %2 / 3
ActionRegister.h +
100.0%
+
100.0 %7 / 798.3 %1144 / 1164
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 %26 / 2683.3 %5 / 6
ActionWithMatrix.h +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
Colvar.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
ActionAtomistic.h +
100.0%
+
100.0 %48 / 48100.0 %10 / 10
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %63 / 6385.7 %6 / 7
ActionWithMatrix.cpp +
100.0%
+
100.0 %138 / 13886.4 %19 / 22
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/index.html b/coverage/core/index.html new file mode 100644 index 000000000..45ec36b4d --- /dev/null +++ b/coverage/core/index.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:4775532689.7 %
Date:2024-10-17 16:45:00Functions:1791192093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Action.cpp +
84.1%84.1%
+
84.1 %174 / 20784.2 %32 / 38
Action.h +
94.0%94.0%
+
94.0 %79 / 8489.5 %34 / 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.7%94.7%
+
94.7 %287 / 30382.1 %23 / 28
ActionAtomistic.h +
100.0%
+
100.0 %48 / 48100.0 %10 / 10
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 +
73.9%73.9%
+
73.9 %34 / 4677.8 %7 / 9
ActionRegister.h +
100.0%
+
100.0 %7 / 798.3 %1144 / 1164
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 +
93.3%93.3%
+
93.3 %139 / 14992.3 %12 / 13
ActionShortcut.h +
33.3%33.3%
+
33.3 %1 / 333.3 %1 / 3
ActionToGetData.cpp +
90.6%90.6%
+
90.6 %29 / 3285.7 %6 / 7
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
ActionToPutData.cpp +
92.4%92.4%
+
92.4 %97 / 105100.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
ActionWithMatrix.cpp +
100.0%
+
100.0 %138 / 13886.4 %19 / 22
ActionWithMatrix.h +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
ActionWithValue.cpp +
92.4%92.4%
+
92.4 %158 / 17184.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.3%84.3%
+
84.3 %113 / 134100.0 %5 / 5
CLToolRegister.cpp +
52.9%52.9%
+
52.9 %18 / 3471.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 +
91.9%91.9%
+
91.9 %68 / 7448.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.3%94.3%
+
94.3 %264 / 28093.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 +
85.6%85.6%
+
85.6 %190 / 22283.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
ModuleMap.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
PbcAction.cpp +
100.0%
+
100.0 %26 / 2683.3 %5 / 6
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
PlumedMain.cpp +
89.8%89.8%
+
89.8 %848 / 94492.9 %65 / 70
PlumedMain.h +
94.4%94.4%
+
94.4 %17 / 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 +
86.1%86.1%
+
86.1 %62 / 7286.4 %19 / 22
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.0 %0 / 3
Value.cpp +
96.2%96.2%
+
96.2 %254 / 264100.0 %35 / 35
Value.h +
97.7%97.7%
+
97.7 %84 / 86100.0 %13 / 13
WithCmd.h +
81.5%81.5%
+
81.5 %22 / 2762.5 %5 / 8
+
+
+ + + + +
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 000000000..db6611c9a --- /dev/null +++ b/coverage/crystdistrib/BopsShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:515494.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..f871f0239 --- /dev/null +++ b/coverage/crystdistrib/BopsShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:515494.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..55a676022 --- /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:515494.4 %
Date:2024-10-17 16:45:00Functions: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           3 :   keys.setValueDescription("the values of the bops order parameters");
+      67           9 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("QUATERNION_BOND_PRODUCT_MATRIX"); keys.needsAction("CUSTOM");
+      68           6 :   keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      69           3 : }
+      70             : 
+      71           1 : BopsShortcut::BopsShortcut(const ActionOptions&ao):
+      72             :   Action(ao),
+      73           1 :   ActionShortcut(ao)
+      74             : {
+      75             :   // Open a file and read in the kernels
+      76             :   double h_dops,h_bops; std::string kfunc, kfunc_dops,kfunc_bops,fname_dops,fname_bops;
+      77           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);
+      78          10 :   for(unsigned k=0;; ++k) {
+      79          21 :     if( !ifile_dops.scanField("height",h_dops) || !ifile_bops.scanField("height",h_bops) ) break;//checks eof
+      80          30 :     std::string ktype_dops, ktype_bops;  ifile_dops.scanField("kerneltype",ktype_dops); ifile_bops.scanField("kerneltype",ktype_bops);
+      81          10 :     if( ktype_dops!="gaussian" ) error("cannot process kernels of type " + ktype_dops );//straightup error
+      82          10 :     if( ktype_bops!="gaussian" ) error("cannot process kernels of type " + ktype_bops );
+      83             : 
+      84             :     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;
+      85             : 
+      86             : 
+      87          10 :     Tools::convert( h_dops, hstr_dops );
+      88          10 :     Tools::convert( h_bops, hstr_bops );
+      89             : 
+      90          20 :     ifile_dops.scanField("mu",mu_dops); Tools::convert( mu_dops, smu_dops );
+      91             :     //ifile_bops.scanField("mu_w",mu_w); Tools::convert( mu_w, smu_w );
+      92          20 :     ifile_bops.scanField("mu_i",mu_i); Tools::convert( mu_i, smu_i );
+      93          20 :     ifile_bops.scanField("mu_j",mu_j); Tools::convert( mu_j, smu_j );
+      94          20 :     ifile_bops.scanField("mu_k",mu_k); Tools::convert( mu_k, smu_k );
+      95             : 
+      96             : 
+      97             :     double sigma,kappa;
+      98          20 :     ifile_dops.scanField("sigma",sigma); Tools::convert( sigma, sigmastr );
+      99          20 :     ifile_bops.scanField("kappa",kappa); Tools::convert( kappa, kappastr );
+     100             : 
+     101             : 
+     102             : 
+     103          10 :     ifile_dops.scanField(); /*if( k==0 )*/ kfunc_dops =  hstr_dops; //else kfunc_dops += "+" + hstr;
+     104          10 :     ifile_bops.scanField(); /*if( k==0 )*/ kfunc_bops =  hstr_bops; //else kfunc_bops += "+" + hstr;
+     105             : 
+     106          20 :     kfunc_bops += "*exp(" + kappastr + "*(i*" + smu_i + "+j*" + smu_j + "+k*" + smu_k + "))";
+     107          20 :     kfunc_dops += "*exp(-(x-" + smu_dops +")^2/" + "(2*" + sigmastr +"*" +sigmastr + "))";
+     108          20 :     if (k==0) kfunc = kfunc_dops + "*" + kfunc_bops; else kfunc+= "+" + kfunc_dops + "*" + kfunc_bops;
+     109          10 :   }
+     110             :   std::string sp_str, specA, specB, grpinfo;
+     111             :   double cutoff;
+     112           5 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB); parse("CUTOFF",cutoff);
+     113           1 :   if( sp_str.length()>0 ) {
+     114           2 :     grpinfo="GROUP=" + sp_str;
+     115             :   } else {//not sure how to use this
+     116           0 :     if( specA.length()==0 || specB.length()==0 ) error("no atoms were specified in input use either SPECIES or SPECIESA + SPECIESB");
+     117           0 :     grpinfo="GROUPA=" + specA + " GROUPB=" + specB;
+     118             :   }
+     119           1 :   std::string cutstr; Tools::convert( cutoff, cutstr );
+     120             :   // Setup the contact matrix
+     121             : //  std::string switchstr; parse("SWITCH",switchstr);
+     122           2 :   readInputLine( getShortcutLabel() + "_cmat: DISTANCE_MATRIX  " + grpinfo + " CUTOFF=" + cutstr + " COMPONENTS");
+     123             : 
+     124           1 :   if( specA.length()==0 ) {
+     125           1 :     std::string quatstr; parse("QUATERNIONS",quatstr);
+     126           2 :     readInputLine( getShortcutLabel() + "_quatprod: QUATERNION_BOND_PRODUCT_MATRIX ARG=" + quatstr + ".*," + getShortcutLabel() + "_cmat.*" );
+     127             :   }  else {
+     128           0 :     plumed_error();
+     129             :   }
+     130             :   //
+     131             : 
+     132             :   ///////////////////
+     133             :   ///replace/////
+     134           2 :   readInputLine( getShortcutLabel() + "_dist: CUSTOM ARG=" + getShortcutLabel() + "_cmat.x," + getShortcutLabel() + "_cmat.y," + getShortcutLabel() + "_cmat.z " +
+     135             :                  "FUNC=sqrt((x^2)+(y^2)+(z^2)) PERIODIC=NO");
+     136           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");
+     137             : 
+     138             : //replace ^^^ to remove distance hack
+     139             : //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");
+     140             : ///end replace////
+     141             : 
+     142             :   // Element wise product of cmat and kfunc
+     143             : //  readInputLine( getShortcutLabel() + "_kdmat: CUSTOM ARG=" + getShortcutLabel() + "_cmat.w," + getShortcutLabel() + "_kfunc FUNC=x*y PERIODIC=NO");
+     144             :   // Find the number of ones we need to multiply by
+     145           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmat");
+     146           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     147           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     148           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     149             :   //
+     150           2 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_kfunc," + getShortcutLabel() + "_ones");
+     151           2 : }
+     152             : 
+     153             : }
+     154             : }
+     155             : 
+     156             : 
+     157             : 
+
+
+
+ + + + +
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 000000000..9dc76432d --- /dev/null +++ b/coverage/crystdistrib/DopsShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:373994.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..4a777ab72 --- /dev/null +++ b/coverage/crystdistrib/DopsShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:373994.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..c1b472f5a --- /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:373994.9 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("the values of the DOPS order parameters");
+      64          16 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("CUSTOM"); keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      65           4 : }
+      66             : 
+      67           2 : DopsShortcut::DopsShortcut(const ActionOptions&ao):
+      68             :   Action(ao),
+      69           2 :   ActionShortcut(ao)
+      70             : {
+      71             :   // Open a file and read in the kernels
+      72           2 :   double cutoff=0, h; std::string kfunc,fname; double dp2cutoff; parse("CUTOFF",dp2cutoff);
+      73           4 :   parse("KERNELFILE",fname); IFile ifile; ifile.open(fname);
+      74          20 :   for(unsigned k=0;; ++k) {
+      75          44 :     if( !ifile.scanField("height",h) ) break;
+      76          40 :     std::string ktype; ifile.scanField("kerneltype",ktype); if( ktype!="gaussian" ) error("cannot process kernels of type " + ktype );
+      77          60 :     double mu, sigma; ifile.scanField("mu",mu); ifile.scanField("sigma",sigma); ifile.scanField();
+      78          20 :     std::string hstr, mustr, sigmastr; Tools::convert( h, hstr );
+      79          20 :     Tools::convert( 2*sigma*sigma, sigmastr ); Tools::convert( mu, mustr );
+      80             :     // Get a sensible value for the cutoff
+      81          20 :     double support = sqrt(2.0*dp2cutoff)*(1.0/sigma);
+      82          20 :     if( mu+support>cutoff ) cutoff= mu + support;
+      83             :     // And make the kernel
+      84          38 :     if( k==0 ) kfunc = hstr; else kfunc += "+" + hstr;
+      85          40 :     kfunc += "*exp(-(x-" + mustr +")^2/" + sigmastr + ")";
+      86          20 :   }
+      87             :   std::string sp_str, specA, specB, grpinfo;
+      88           8 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+      89           2 :   if( sp_str.length()>0 ) {
+      90           4 :     grpinfo="GROUP=" + sp_str;
+      91             :   } else {
+      92           0 :     if( specA.length()==0 || specB.length()==0 ) error("no atoms were specified in input use either SPECIES or SPECIESA + SPECIESB");
+      93           0 :     grpinfo="GROUPA=" + specA + " GROUPB=" + specB;
+      94             :   }
+      95           2 :   std::string cutstr; Tools::convert( cutoff, cutstr );
+      96             :   // Setup the contact matrix
+      97           4 :   readInputLine( getShortcutLabel() + "_cmat: DISTANCE_MATRIX  " + grpinfo + " CUTOFF=" + cutstr);
+      98             :   // And the kernels
+      99           4 :   readInputLine( getShortcutLabel() + "_kval: CUSTOM ARG=" + getShortcutLabel() + "_cmat PERIODIC=NO FUNC=" + kfunc );
+     100             :   // Find the number of ones we need to multiply by
+     101           2 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmat");
+     102           2 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     103           2 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     104           4 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     105             :   // And the final order parameters
+     106           4 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_kval," + getShortcutLabel() + "_ones");
+     107           4 : }
+     108             : 
+     109             : }
+     110             : }
+     111             : 
+     112             : 
+     113             : 
+
+
+
+ + + + +
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 000000000..cb3e4cf49 --- /dev/null +++ b/coverage/crystdistrib/Quaternion.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib10QuaternionC2ERKNS_13ActionOptionsE0
_ZN4PLMD12crystdistrib10QuaternionC1ERKNS_13ActionOptionsE5
_ZN4PLMD12crystdistrib10Quaternion21getModeAndSetupValuesEPNS_15ActionWithValueE17
_ZN4PLMD12crystdistrib10Quaternion9calculateEv45
_ZN4PLMD12crystdistrib10Quaternion16registerKeywordsERNS_8KeywordsE86
_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 000000000..bc395b2b1 --- /dev/null +++ b/coverage/crystdistrib/Quaternion.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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_8KeywordsE86
_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 000000000..9b3f2e319 --- /dev/null +++ b/coverage/crystdistrib/Quaternion.cpp.gcov.html @@ -0,0 +1,470 @@ + + + + + + + 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-10-17 16:45:00Functions: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          86 : void Quaternion::registerKeywords( Keywords& keys ) {
+     122          86 :   Colvar::registerKeywords( keys ); keys.setDisplayName("QUATERNION");
+     123         172 :   keys.add("atoms","ATOMS","the three atom that we are using to calculate the quaternion");
+     124         172 :   keys.addOutputComponent("w","default","the real component of quaternion");
+     125         172 :   keys.addOutputComponent("i","default","the i component of the quaternion");
+     126         172 :   keys.addOutputComponent("j","default","the j component of the quaternion");
+     127         172 :   keys.addOutputComponent("k","default","the k component of the quaternion");
+     128         172 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     129          86 : }
+     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 000000000..5df3357cd --- /dev/null +++ b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrixC1ERKNS_13ActionOptionsE4
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrix16registerKeywordsERNS_8KeywordsE7
_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 000000000..a6b01ad3b --- /dev/null +++ b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrix16registerKeywordsERNS_8KeywordsE7
_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 000000000..389dcadc5 --- /dev/null +++ b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.gcov.html @@ -0,0 +1,460 @@ + + + + + + + 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-10-17 16:45:00Functions: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 "core/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 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           7 : void QuaternionBondProductMatrix::registerKeywords( Keywords& keys ) {
+      76           7 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      77          14 :   keys.addOutputComponent("w","default","the real component of quaternion");
+      78          14 :   keys.addOutputComponent("i","default","the i component of the quaternion");
+      79          14 :   keys.addOutputComponent("j","default","the j component of the quaternion");
+      80          14 :   keys.addOutputComponent("k","default","the k component of the quaternion");
+      81           7 : }
+      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 000000000..2be77efe2 --- /dev/null +++ b/coverage/crystdistrib/QuaternionProductMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib23QuaternionProductMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD12crystdistrib23QuaternionProductMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD12crystdistrib23QuaternionProductMatrix16registerKeywordsERNS_8KeywordsE9
_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 000000000..088015d65 --- /dev/null +++ b/coverage/crystdistrib/QuaternionProductMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib23QuaternionProductMatrix16registerKeywordsERNS_8KeywordsE9
_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 000000000..8479316e9 --- /dev/null +++ b/coverage/crystdistrib/QuaternionProductMatrix.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + 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-10-17 16:45:00Functions: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/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 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           9 : void QuaternionProductMatrix::registerKeywords( Keywords& keys ) {
+      53           9 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      54          18 :   keys.addOutputComponent("w","default","the real component of quaternion");
+      55          18 :   keys.addOutputComponent("i","default","the i component of the quaternion");
+      56          18 :   keys.addOutputComponent("j","default","the j component of the quaternion");
+      57          18 :   keys.addOutputComponent("k","default","the k component of the quaternion");
+      58           9 : }
+      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 000000000..774325ea1 --- /dev/null +++ b/coverage/crystdistrib/RopsShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:515494.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..83f893558 --- /dev/null +++ b/coverage/crystdistrib/RopsShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:515494.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..672a23a05 --- /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:515494.4 %
Date:2024-10-17 16:45:00Functions: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           3 :   keys.setValueDescription("the values of the ROPS order parameters");
+      67           6 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("QUATERNION_PRODUCT_MATRIX");
+      68           9 :   keys.needsAction("ONES"); keys.needsAction("CUSTOM"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      69           3 : }
+      70             : 
+      71           1 : RopsShortcut::RopsShortcut(const ActionOptions&ao):
+      72             :   Action(ao),
+      73           1 :   ActionShortcut(ao)
+      74             : {
+      75             :   // Open a file and read in the kernels
+      76             :   double h_dops,h_rops; std::string kfunc, kfunc_dops,kfunc_rops,fname_dops,fname_rops;
+      77           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);
+      78          10 :   for(unsigned k=0;; ++k) {
+      79          21 :     if( !ifile_dops.scanField("height",h_dops) || !ifile_rops.scanField("height",h_rops) ) break;//checks eof
+      80          30 :     std::string ktype_dops, ktype_rops;  ifile_dops.scanField("kerneltype",ktype_dops); ifile_rops.scanField("kerneltype",ktype_rops);
+      81          10 :     if( ktype_dops!="gaussian" ) error("cannot process kernels of type " + ktype_dops );//straightup error
+      82          10 :     if( ktype_rops!="gaussian" ) error("cannot process kernels of type " + ktype_rops );
+      83             : 
+      84             :     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;
+      85             : 
+      86             : 
+      87          10 :     Tools::convert( h_dops, hstr_dops );
+      88          10 :     Tools::convert( h_rops, hstr_rops );
+      89             : 
+      90          20 :     ifile_dops.scanField("mu",mu_dops); Tools::convert( mu_dops, smu_dops );
+      91          20 :     ifile_rops.scanField("mu_w",mu_w); Tools::convert( mu_w, smu_w );
+      92          20 :     ifile_rops.scanField("mu_i",mu_i); Tools::convert( mu_i, smu_i );
+      93          20 :     ifile_rops.scanField("mu_j",mu_j); Tools::convert( mu_j, smu_j );
+      94          20 :     ifile_rops.scanField("mu_k",mu_k); Tools::convert( mu_k, smu_k );
+      95             : 
+      96             : 
+      97             :     double sigma,kappa;
+      98          20 :     ifile_dops.scanField("sigma",sigma); Tools::convert( sigma, sigmastr );
+      99          20 :     ifile_rops.scanField("kappa",kappa); Tools::convert( kappa, kappastr );
+     100             : 
+     101             : 
+     102             : 
+     103          10 :     ifile_dops.scanField(); /*if( k==0 )*/ kfunc_dops =  hstr_dops; //else kfunc_dops += "+" + hstr;
+     104          10 :     ifile_rops.scanField(); /*if( k==0 )*/ kfunc_rops =  hstr_rops; //else kfunc_rops += "+" + hstr;
+     105             : 
+     106          20 :     kfunc_rops += "*exp(" + kappastr + "*(w*" + smu_w + "+i*" + smu_i + "+j*" + smu_j + "+k*" + smu_k + ")^2)";
+     107          20 :     kfunc_dops += "*exp(-(x-" + smu_dops +")^2/" + "(2*" + sigmastr +"*" +sigmastr + "))";
+     108          20 :     if (k==0) kfunc = kfunc_dops + "*" + kfunc_rops; else kfunc+= "+" + kfunc_dops + "*" + kfunc_rops;
+     109          10 :   }
+     110             :   std::string sp_str, specA, specB, grpinfo;
+     111             :   double cutoff;
+     112           5 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB); parse("CUTOFF",cutoff);
+     113           1 :   if( sp_str.length()>0 ) {
+     114           2 :     grpinfo="GROUP=" + sp_str;
+     115             :   } else {//not sure how to use this
+     116           0 :     if( specA.length()==0 || specB.length()==0 ) error("no atoms were specified in input use either SPECIES or SPECIESA + SPECIESB");
+     117           0 :     grpinfo="GROUPA=" + specA + " GROUPB=" + specB;
+     118             :   }
+     119           1 :   std::string cutstr; Tools::convert( cutoff, cutstr );
+     120             :   // Setup the contact matrix
+     121             : //  std::string switchstr; parse("SWITCH",switchstr);
+     122           2 :   readInputLine( getShortcutLabel() + "_cmat: DISTANCE_MATRIX  " + grpinfo + " CUTOFF=" + cutstr);
+     123             : 
+     124           1 :   if( specA.length()==0 ) {
+     125           1 :     std::string quatstr; parse("QUATERNIONS",quatstr);
+     126           2 :     readInputLine( getShortcutLabel() + "_quatprod: QUATERNION_PRODUCT_MATRIX ARG=" + quatstr + ".*," + quatstr + ".*" );
+     127             :   }  else {
+     128           0 :     plumed_error();
+     129             :   }
+     130             :   //
+     131           2 :   readInputLine( getShortcutLabel() + "_kfunc: CUSTOM ARG=" + getShortcutLabel() + "_cmat,"+ getShortcutLabel() + "_quatprod.* " + "VAR=x,w,i,j,k PERIODIC=NO FUNC=" + kfunc );
+     132             :   // Element wise product of cmat and kfunc
+     133             : //  readInputLine( getShortcutLabel() + "_kdmat: CUSTOM ARG=" + getShortcutLabel() + "_cmat.w," + getShortcutLabel() + "_kfunc FUNC=x*y PERIODIC=NO");
+     134             :   // Find the number of ones we need to multiply by
+     135           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmat");
+     136           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     137           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     138           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     139             :   //
+     140           2 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_kfunc," + getShortcutLabel() + "_ones");
+     141           2 : }
+     142             : 
+     143             : }
+     144             : }
+     145             : 
+     146             : 
+     147             : 
+
+
+
+ + + + +
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 000000000..ade812b98 --- /dev/null +++ b/coverage/crystdistrib/index-sort-f.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - plumed test coverage - crystdistrib + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistribHitTotalCoverage
Test:plumed test coverageLines:51856392.0 %
Date:2024-10-17 16:45:00Functions:253278.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
RopsShortcut.cpp +
94.4%94.4%
+
94.4 %51 / 5466.7 %2 / 3
DopsShortcut.cpp +
94.9%94.9%
+
94.9 %37 / 3966.7 %2 / 3
BopsShortcut.cpp +
94.4%94.4%
+
94.4 %51 / 5466.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 000000000..90d9593d6 --- /dev/null +++ b/coverage/crystdistrib/index-sort-l.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - plumed test coverage - crystdistrib + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistribHitTotalCoverage
Test:plumed test coverageLines:51856392.0 %
Date:2024-10-17 16:45:00Functions: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.4%94.4%
+
94.4 %51 / 5466.7 %2 / 3
BopsShortcut.cpp +
94.4%94.4%
+
94.4 %51 / 5466.7 %2 / 3
DopsShortcut.cpp +
94.9%94.9%
+
94.9 %37 / 3966.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 000000000..05b72568d --- /dev/null +++ b/coverage/crystdistrib/index.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - plumed test coverage - crystdistrib + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistribHitTotalCoverage
Test:plumed test coverageLines:51856392.0 %
Date:2024-10-17 16:45:00Functions:253278.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BopsShortcut.cpp +
94.4%94.4%
+
94.4 %51 / 5466.7 %2 / 3
DopsShortcut.cpp +
94.9%94.9%
+
94.9 %37 / 3966.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.4%94.4%
+
94.4 %51 / 5466.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 000000000..eb8943d5a --- /dev/null +++ b/coverage/dimred/ArrangePoints.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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:17317598.9 %
Date:2024-10-17 16:45:00Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ArrangePoints22getNumberOfDerivativesEv0
_ZN4PLMD6dimred13ArrangePointsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13ArrangePoints5applyEv2
_ZNK4PLMD6dimred13ArrangePoints24recalculateSmacofWeightsERKSt6vectorIdSaIdEERNS0_6SMACOFE2
_ZN4PLMD6dimred13ArrangePointsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6dimred13ArrangePoints8optimizeERSt6vectorIdSaIdEE7
_ZN4PLMD6dimred13ArrangePoints9calculateEv7
_ZN4PLMD6dimred13ArrangePoints7prepareEv8
_ZN4PLMD6dimred13ArrangePoints16registerKeywordsERNS_8KeywordsE12
_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 000000000..0b028129f --- /dev/null +++ b/coverage/dimred/ArrangePoints.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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:17317598.9 %
Date:2024-10-17 16:45:00Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ArrangePoints15calculateStressERKSt6vectorIdSaIdEERS4_24600
_ZN4PLMD6dimred13ArrangePoints16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD6dimred13ArrangePoints19calculateFullStressERKSt6vectorIdSaIdEERS4_1932
_ZN4PLMD6dimred13ArrangePoints22getNumberOfDerivativesEv0
_ZN4PLMD6dimred13ArrangePoints5applyEv2
_ZN4PLMD6dimred13ArrangePoints7prepareEv8
_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 000000000..614ab4f5f --- /dev/null +++ b/coverage/dimred/ArrangePoints.cpp.gcov.html @@ -0,0 +1,409 @@ + + + + + + + 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:17317598.9 %
Date:2024-10-17 16:45:00Functions:101283.3 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE13
+
+
+ + + +
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 000000000..b483337da --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:414297.6 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE13
_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 000000000..45bc4530b --- /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:414297.6 %
Date:2024-10-17 16:45:00Functions: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          13 : void ClassicalMultiDimensionalScaling::registerKeywords( Keywords& keys ) {
+     175          13 :   ActionShortcut::registerKeywords( keys );
+     176          26 :   keys.add("compulsory","ARG","the arguments that you would like to make the histogram for");
+     177          26 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+     178          13 :   keys.setValueDescription("the low dimensional projections for the input data points");
+     179          52 :   keys.needsAction("TRANSPOSE"); keys.needsAction("DISSIMILARITIES"); keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("VSTACK");
+     180          52 :   keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("DIAGONALIZE");
+     181          13 : }
+     182             : 
+     183           7 : ClassicalMultiDimensionalScaling::ClassicalMultiDimensionalScaling( const ActionOptions& ao):
+     184             :   Action(ao),
+     185           7 :   ActionShortcut(ao)
+     186             : {
+     187             :   // Find the argument name
+     188          14 :   std::string argn; parse("ARG",argn); std::string dissimilarities="";
+     189           7 :   ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
+     190           7 :   if( !as ) error("found no action with name " + argn );
+     191           7 :   if( as->getName()!="COLLECT_FRAMES" ) {
+     192           1 :     if( as->getName().find("LANDMARK_SELECT")==std::string::npos ) {
+     193           0 :       error("found no COLLECT_FRAMES or LANDMARK_SELECT action with label " + argn );
+     194             :     } else {
+     195           1 :       ActionWithValue* dissims = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_sqrdissims");
+     196           2 :       if( dissims ) dissimilarities = argn + "_sqrdissims";
+     197             :     }
+     198             :   }
+     199           7 :   if( dissimilarities.length()==0 ) {
+     200           6 :     dissimilarities = getShortcutLabel() + "_mat";
+     201             :     // Transpose matrix of stored data values
+     202          12 :     readInputLine( argn + "_dataT: TRANSPOSE ARG=" + argn + "_data");
+     203             :     // Calculate the dissimilarity matrix
+     204          12 :     readInputLine( getShortcutLabel() + "_mat: DISSIMILARITIES SQUARED ARG=" + argn + "_data," + argn + "_dataT");
+     205             :   }
+     206             :   // Center the matrix
+     207             :   // Step 1: calculate the sum of the rows and duplicate them into a matrix
+     208          14 :   readInputLine( getShortcutLabel() + "_rsums: MATRIX_VECTOR_PRODUCT ARG=" + dissimilarities + "," + argn + "_ones" );
+     209          14 :   readInputLine( getShortcutLabel() + "_nones: SUM ARG=" + argn + "_ones PERIODIC=NO");
+     210          14 :   readInputLine( getShortcutLabel() + "_rsumsn: CUSTOM ARG=" + getShortcutLabel() + "_rsums," + getShortcutLabel() + "_nones FUNC=x/y PERIODIC=NO");
+     211          14 :   readInputLine( getShortcutLabel() + "_rsummat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_rsumsn," + argn + "_ones");
+     212             :   // Step 2: Multiply matrix by -0.5 and subtract row sums
+     213          14 :   readInputLine( getShortcutLabel() + "_int: CUSTOM ARG=" + getShortcutLabel() + "_rsummat," + dissimilarities + " FUNC=-0.5*y+0.5*x PERIODIC=NO");
+     214             :   // Step 3: Calculate column sums for new matrix and duplicate them into a matrix
+     215          14 :   readInputLine( getShortcutLabel() + "_intT: TRANSPOSE ARG=" + getShortcutLabel() + "_int");
+     216          14 :   readInputLine( getShortcutLabel() + "_csums: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_intT," + argn + "_ones" );
+     217          14 :   readInputLine( getShortcutLabel() + "_csumsn: CUSTOM ARG=" + getShortcutLabel() + "_csums," + getShortcutLabel() + "_nones FUNC=x/y PERIODIC=NO");
+     218          14 :   readInputLine( getShortcutLabel() + "_csummat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_csumsn," + argn + "_ones");
+     219             :   // Step 4: subtract the column sums
+     220          14 :   readInputLine( getShortcutLabel() + "_cmat: CUSTOM ARG=" + getShortcutLabel() + "_csummat," + getShortcutLabel() + "_intT FUNC=y-x PERIODIC=NO");
+     221             :   // And generate the multidimensional scaling projection
+     222           7 :   unsigned ndim; parse("NLOW_DIM",ndim);
+     223          19 :   std::string vecstr="1"; for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); vecstr += "," + num; }
+     224          14 :   readInputLine( getShortcutLabel() + "_eig: DIAGONALIZE ARG=" + getShortcutLabel() + "_cmat VECTORS=" + vecstr );
+     225          20 :   for(unsigned i=0; i<ndim; ++i) {
+     226          13 :     std::string num; Tools::convert( i+1, num );
+     227          26 :     readInputLine( getShortcutLabel() + "-" +  num + ": CUSTOM ARG=" + getShortcutLabel() + "_eig.vals-" + num + "," + getShortcutLabel() + "_eig.vecs-" + num + " FUNC=sqrt(x)*y PERIODIC=NO");
+     228             :   }
+     229           7 :   std::string eigvec_args = " ARG=" + getShortcutLabel() + "-1";
+     230             :   // The final output is a stack of all the low dimensional coordinates
+     231          19 :   for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); eigvec_args += "," + getShortcutLabel() + "-" + num; }
+     232          14 :   readInputLine( getShortcutLabel() + ": VSTACK" + eigvec_args );
+     233           7 : }
+     234             : 
+     235             : }
+     236             : }
+
+
+
+ + + + +
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 000000000..7b106ce21 --- /dev/null +++ b/coverage/dimred/PCA.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:5757100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d7d564a45 --- /dev/null +++ b/coverage/dimred/PCA.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:5757100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d8e28ef56 --- /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:5757100.0 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("the projections of the input coordinates on the PCA components that were found from the covariance matrix");
+     117          12 :   keys.needsAction("LOGSUMEXP"); keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+     118          16 :   keys.needsAction("CONSTANT"); keys.needsAction("COLLECT"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("CUSTOM");
+     119          16 :   keys.needsAction("MATRIX_PRODUCT"); keys.needsAction("DIAGONALIZE"); keys.needsAction("VSTACK"); keys.needsAction("DUMPPDB");
+     120           4 : }
+     121             : 
+     122             : 
+     123           2 : PCA::PCA(const ActionOptions&ao):
+     124             :   Action(ao),
+     125           2 :   ActionShortcut(ao)
+     126             : {
+     127             :   // Find the argument name
+     128           2 :   std::string argn; parse("ARG",argn);
+     129           2 :   ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
+     130           2 :   if( !as || as->getName()!="COLLECT_FRAMES" ) error("found no COLLECT_FRAMES action with label " + argn );
+     131             :   // Get the final weights using the logsumexp trick
+     132           4 :   readInputLine( getShortcutLabel() + "_weights: LOGSUMEXP ARG=" + argn + "_logweights");
+     133             :   // Now transpose the collected frames
+     134           4 :   readInputLine( getShortcutLabel() + "_dataT: TRANSPOSE ARG=" + argn + "_data");
+     135             :   // And multiply the transpose by the weights to get the averages
+     136           4 :   readInputLine( getShortcutLabel() + "_mean: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_dataT," + getShortcutLabel() + "_weights");
+     137             :   // Make a matrix of averages
+     138           4 :   readInputLine( getShortcutLabel() + "_averages: OUTER_PRODUCT ARG=" + argn + "_ones," + getShortcutLabel() + "_mean");
+     139             :   // Make a matrix of weights
+     140           2 :   ActionWithValue* av2 = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_data" );
+     141           2 :   if( !av2 ) error("count not find data");
+     142           2 :   unsigned nones = (av2->copyOutput(0))->getShape()[1];
+     143          68 :   std::string ones="1"; for(unsigned i=1; i<nones; ++i) ones += ",1";
+     144           4 :   readInputLine( getShortcutLabel() + "_wones: CONSTANT VALUES=" + ones );
+     145           4 :   readInputLine( getShortcutLabel() + "_wmat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_wones");
+     146             :   // And compute the data substract the mean
+     147           4 :   readInputLine( getShortcutLabel() + "_diff: CUSTOM ARG=" + argn + "_data," + getShortcutLabel() + "_averages FUNC=(x-y) PERIODIC=NO");
+     148           4 :   readInputLine( getShortcutLabel() + "_wdiff: CUSTOM ARG=" + getShortcutLabel() + "_wmat," + getShortcutLabel() + "_diff FUNC=sqrt(x)*y PERIODIC=NO");
+     149             :   // And the covariance
+     150           4 :   readInputLine( getShortcutLabel() + "_wdiffT: TRANSPOSE ARG=" + getShortcutLabel() + "_wdiff");
+     151           4 :   readInputLine( getShortcutLabel() + "_covar: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_wdiffT," + getShortcutLabel() + "_wdiff");
+     152             :   // Read the dimensionality of the low dimensional space
+     153           4 :   unsigned ndim; parse("NLOW_DIM",ndim); std::string vecstr="1";
+     154           2 :   if( ndim<=0 || ndim>nones ) error("cannot generate projection in space of dimension higher than input coordinates");
+     155           6 :   for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); vecstr += "," + num; }
+     156           4 :   readInputLine( getShortcutLabel() + "_eig: DIAGONALIZE ARG=" + getShortcutLabel() + "_covar VECTORS=" + vecstr );
+     157             :   // Now create a matrix to hold the output data
+     158           2 :   std::string outd = "ARG=" + getShortcutLabel() + "_mean";
+     159          10 :   for(unsigned i=0; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); outd += "," + getShortcutLabel() + "_eig.vecs-" + num; }
+     160           4 :   readInputLine( getShortcutLabel() + "_pcaT: VSTACK " + outd );
+     161           4 :   readInputLine( getShortcutLabel() + "_pca: TRANSPOSE ARG=" + getShortcutLabel() + "_pcaT");
+     162             :   // And output it all
+     163           6 :   std::string filename, pstride; parse("STRIDE",pstride); parse("FILE",filename);
+     164           2 :   if( filename.length()>0 && av2->getName()=="VSTACK" ) {
+     165           1 :     std::vector<std::string> argnames; av2->getMatrixColumnTitles( argnames );
+     166           2 :     std::string argname_str=argnames[0]; for(unsigned i=1; i<argnames.size(); ++i) argname_str += "," + argnames[i];
+     167           3 :     std::string fmt; parse("FMT",fmt); if( fmt.length()>0 ) fmt=" FMT=" + fmt;
+     168           2 :     readInputLine("DUMPPDB DESCRIPTION=PCA ARG_NAMES=" + argname_str + " ARG=" + getShortcutLabel() + "_pca FILE=" + filename + " STRIDE=" + pstride + fmt );
+     169           1 :   } else {
+     170           1 :     if( av2->getName()!="COLLECT" ) error("input data should be VSTACK if list of arguments of COLLECT if atom positions");
+     171           1 :     ActionAtomistic* rmsdact = plumed.getActionSet().selectWithLabel<ActionAtomistic*>( argn + "_getposx" );
+     172           1 :     if( !rmsdact ) error("could not find action that gets positions from trajectory for RMSD");
+     173           1 :     std::vector<AtomNumber> atoms( rmsdact->getAbsoluteIndexes() ); std::string indices; Tools::convert( atoms[0].serial(), indices );
+     174          22 :     for(unsigned i=1; i<atoms.size(); ++i) { std::string jnum; Tools::convert( atoms[i].serial(), jnum ); indices += "," + jnum; }
+     175           2 :     readInputLine("DUMPPDB DESCRIPTION=PCA ATOM_INDICES=" + indices + " ATOMS=" + getShortcutLabel() + "_pca FILE=" + filename + " STRIDE=" + pstride );
+     176             :   }
+     177           4 :   outd = "ARG=" + getShortcutLabel() + "_eig.vecs-1";
+     178           6 :   for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); outd += "," + getShortcutLabel() + "_eig.vecs-" + num; }
+     179           4 :   readInputLine( getShortcutLabel() + "_eigv: VSTACK " + outd );
+     180           4 :   readInputLine( getShortcutLabel() + ": MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_diff," + getShortcutLabel() + "_eigv");
+     181           2 : }
+     182             : 
+     183             : }
+     184             : }
+
+
+
+ + + + +
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 000000000..91836b930 --- /dev/null +++ b/coverage/dimred/ProjectPoints.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ProjectPoints22getNumberOfDerivativesEv0
_ZN4PLMD6dimred13ProjectPointsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13ProjectPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred13ProjectPoints16registerKeywordsERNS_8KeywordsE6
_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 000000000..e5834d7e2 --- /dev/null +++ b/coverage/dimred/ProjectPoints.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ProjectPoints15calculateStressERKSt6vectorIdSaIdEERS4_24180
_ZN4PLMD6dimred13ProjectPoints16registerKeywordsERNS_8KeywordsE6
_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 000000000..fd09d1167 --- /dev/null +++ b/coverage/dimred/ProjectPoints.cpp.gcov.html @@ -0,0 +1,259 @@ + + + + + + + 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-10-17 16:45:00Functions: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           6 : void ProjectPoints::registerKeywords( Keywords& keys ) {
+      63           6 :   ActionWithVector::registerKeywords( keys ); keys.use("ARG");
+      64          12 :   keys.add("numbered","TARGET","the matrix of target quantities that you would like to match");
+      65          12 :   keys.add("numbered","FUNC","a function that is applied on the distances between the points in the low dimensional space");
+      66          12 :   keys.add("numbered","WEIGHTS","the matrix with the weights of the target quantities");
+      67          12 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      68          12 :   keys.addOutputComponent("coord","default","the coordinates of the points in the low dimensional space");
+      69           6 : }
+      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 000000000..7081029a4 --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6dc65a9e1 --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6583cbcf5 --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f565f64d9 --- /dev/null +++ b/coverage/dimred/SMACOF.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5cfd912cb --- /dev/null +++ b/coverage/dimred/SMACOF.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a210602e2 --- /dev/null +++ b/coverage/dimred/SMACOF.h.gcov.html @@ -0,0 +1,131 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1f4cd963e --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:737696.1 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE4
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
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 000000000..8f6b2253a --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:737696.1 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE9
_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 000000000..32483eff8 --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + 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:737696.1 %
Date:2024-10-17 16:45:00Functions: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           9 : void SketchMap::registerKeywords( Keywords& keys ) {
+      49           9 :   ActionShortcut::registerKeywords( keys );
+      50          18 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+      51          18 :   keys.add("optional","WEIGHTS","a vector containing the weights of the points");
+      52          18 :   keys.add("compulsory","ARG","the matrix of high dimensional coordinates that you want to project in the low dimensional space");
+      53          18 :   keys.add("compulsory","HIGH_DIM_FUNCTION","the parameters of the switching function in the high dimensional space");
+      54          18 :   keys.add("compulsory","LOW_DIM_FUNCTION","the parameters of the switching function in the low dimensional space");
+      55          18 :   keys.add("compulsory","CGTOL","1E-6","The tolerance for the conjugate gradient minimization that finds the projection of the landmarks");
+      56          18 :   keys.add("compulsory","MAXITER","1000","maximum number of optimization cycles for optimisation algorithms");
+      57          18 :   keys.add("compulsory","NCYCLES","0","The number of cycles of pointwise global optimisation that are required");
+      58          18 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      59          18 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      60          18 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      61          18 :   keys.addFlag("PROJECT_ALL",false,"if the input are landmark coordinates then project the out of sample configurations");
+      62          18 :   keys.add("compulsory","OS_CGTOL","1E-6","The tolerance for the conjugate gradient minimization that finds the out of sample projections");
+      63          18 :   keys.addFlag("USE_SMACOF",false,"find the projection in the low dimensional space using the SMACOF algorithm");
+      64          18 :   keys.add("compulsory","SMACTOL","1E-4","the tolerance for the smacof algorithm");
+      65          18 :   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           9 :   keys.setValueDescription("the sketch-map projection of the input points");
+      67          18 :   keys.addOutputComponent("osample","PROJECT_ALL","the out-of-sample projections");
+      68          36 :   keys.needsAction("CLASSICAL_MDS"); keys.needsAction("MORE_THAN"); keys.needsAction("SUM"); keys.needsAction("CUSTOM");
+      69          36 :   keys.needsAction("OUTER_PRODUCT"); keys.needsAction("ARRANGE_POINTS"); keys.needsAction("PROJECT_POINTS"); keys.needsAction("VSTACK");
+      70           9 : }
+      71             : 
+      72           4 : SketchMap::SketchMap( const ActionOptions& ao):
+      73             :   Action(ao),
+      74           4 :   ActionShortcut(ao)
+      75             : {
+      76             :   // Get the high dimensioal data
+      77           8 :   std::string argn; parse("ARG",argn); std::string dissimilarities = getShortcutLabel() + "_mds_mat";
+      78           4 :   ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
+      79           4 :   if( !as ) error("found no action with name " + argn );
+      80           4 :   if( as->getName()!="COLLECT_FRAMES" ) {
+      81           1 :     if( as->getName().find("LANDMARK_SELECT")==std::string::npos ) {
+      82           0 :       error("found no COLLECT_FRAMES or LANDMARK_SELECT action with label " + argn );
+      83             :     } else {
+      84           1 :       ActionWithValue* dissims = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_sqrdissims");
+      85           2 :       if( dissims ) dissimilarities = argn + "_sqrdissims";
+      86             :     }
+      87             :   }
+      88           8 :   unsigned ndim; parse("NLOW_DIM",ndim);
+      89           4 :   std::string str_ndim; Tools::convert( ndim, str_ndim );
+      90             :   // Construct a projection using classical MDS
+      91           8 :   readInputLine( getShortcutLabel() + "_mds: CLASSICAL_MDS ARG=" + argn + " NLOW_DIM=" + str_ndim );
+      92             :   // Transform the dissimilarities using the switching function
+      93           4 :   std::string hdfunc; parse("HIGH_DIM_FUNCTION",hdfunc);
+      94           8 :   readInputLine( getShortcutLabel() + "_hdmat: MORE_THAN ARG=" + dissimilarities + " SQUARED SWITCH={" + hdfunc + "}");
+      95             :   // Now for the weights - read the vector of weights first
+      96           9 :   std::string wvec; parse("WEIGHTS",wvec); if( wvec.length()==0 ) wvec = argn + "_weights";
+      97             :   // Now calculate the sum of thse weights
+      98           8 :   readInputLine( wvec + "_sum: SUM ARG=" + wvec + " PERIODIC=NO");
+      99             :   // And normalise the vector of weights using this sum
+     100           8 :   readInputLine( wvec + "_normed: CUSTOM ARG=" + wvec + "_sum," + wvec + " FUNC=y/x PERIODIC=NO");
+     101             :   // And now create the matrix of weights
+     102           8 :   readInputLine( wvec + "_mat: OUTER_PRODUCT ARG=" + wvec + "_normed," + wvec + "_normed");
+     103             :   // Run the arrange points object
+     104          20 :   std::string ldfunc, cgtol, maxiter; parse("LOW_DIM_FUNCTION",ldfunc); parse("CGTOL",cgtol); parse("MAXITER",maxiter); unsigned ncycles; parse("NCYCLES",ncycles);
+     105           5 :   std::string num, argstr, lname=getShortcutLabel() + "_ap"; if( ncycles>0 ) lname = getShortcutLabel() + "_cg";
+     106          12 :   argstr = "ARG=" + getShortcutLabel() + "_mds-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + "_mds-" + num; }
+     107           4 :   bool usesmacof; parseFlag("USE_SMACOF",usesmacof);
+     108           4 :   if( usesmacof ) {
+     109           2 :     std::string smactol, smacreg; parse("SMACTOL",smactol); parse("SMACREG",smacreg);
+     110           3 :     readInputLine( lname + ": ARRANGE_POINTS " + argstr  + " MINTYPE=smacof TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_mat" +
+     111           3 :                    " MAXITER=" + maxiter + " SMACTOL=" + smactol + " SMACREG=" + smacreg + " TARGET2=" + getShortcutLabel() + "_mds_mat WEIGHTS2=" + wvec + "_mat");
+     112             :   } else {
+     113           6 :     readInputLine( lname + ": ARRANGE_POINTS " + argstr  + " MINTYPE=conjgrad TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_mat CGTOL=" + cgtol);
+     114           3 :     if( ncycles>0 ) {
+     115           2 :       std::string buf; parse("BUFFER",buf);
+     116           2 :       std::vector<std::string> fgrid; parseVector("FGRID_SIZE",fgrid);
+     117           2 :       std::string ncyc; Tools::convert(ncycles,ncyc); std::string pwise_args=" NCYCLES=" + ncyc + " BUFFER=" + buf;
+     118           1 :       if( fgrid.size()>0 ) {
+     119           1 :         if( fgrid.size()!=ndim ) error("number of elements of fgrid is not correct");
+     120           3 :         pwise_args += " FGRID_SIZE=" + fgrid[0];  for(unsigned i=1; i<fgrid.size(); ++i) pwise_args += "," + fgrid[i];
+     121             :       }
+     122           2 :       std::vector<std::string> cgrid(ndim); parseVector("CGRID_SIZE",cgrid);
+     123           3 :       pwise_args += " CGRID_SIZE=" + cgrid[0]; for(unsigned i=1; i<cgrid.size(); ++i) pwise_args += "," + cgrid[i];
+     124           3 :       argstr="ARG=" + getShortcutLabel() + "_cg.coord-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + "_cg.coord-" + num; }
+     125           2 :       readInputLine( getShortcutLabel() + "_ap: ARRANGE_POINTS " + argstr  + pwise_args + " MINTYPE=pointwise TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_mat CGTOL=" + cgtol);
+     126           2 :     }
+     127             :   }
+     128          12 :   argstr="ARG=" + getShortcutLabel() + "_ap.coord-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + "_ap.coord-" + num; }
+     129           8 :   readInputLine( getShortcutLabel() + ": VSTACK " + argstr );
+     130           8 :   bool projall; parseFlag("PROJECT_ALL",projall); if( !projall ) return ;
+     131           4 :   parse("OS_CGTOL",cgtol); argstr = getShortcutLabel() + "_ap.coord-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + "_ap.coord-" + num; }
+     132           1 :   if( as->getName().find("LANDMARK_SELECT")==std::string::npos ) {
+     133           0 :     readInputLine( getShortcutLabel() + "_osample_pp: PROJECT_POINTS " + argstr + " TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_normed CGTOL=" + cgtol );
+     134             :   } else {
+     135           1 :     ActionWithValue* dissims = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_rectdissims");
+     136           1 :     if( !dissims ) error("cannot PROJECT_ALL as " + as->getName() + " with label " + argn + " was involved without the DISSIMILARITIES keyword");
+     137           2 :     readInputLine( getShortcutLabel() + "_lhdmat: MORE_THAN ARG=" + argn + "_rectdissims SQUARED SWITCH={" + hdfunc + "}");
+     138           2 :     readInputLine( getShortcutLabel() + "_osample_pp: PROJECT_POINTS ARG=" + argstr + " TARGET1=" + getShortcutLabel() + "_lhdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_normed CGTOL=" + cgtol );
+     139             :   }
+     140           3 :   argstr="ARG=" + getShortcutLabel() + "_osample_pp.coord-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + "_osample_pp.coord-" + num; }
+     141           2 :   readInputLine( getShortcutLabel() + "_osample: VSTACK " + argstr );
+     142           0 : }
+     143             : 
+     144             : }
+     145             : }
+
+
+
+ + + + +
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 000000000..bcede60e1 --- /dev/null +++ b/coverage/dimred/SketchMapProjection.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2929100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..cd666bb7c --- /dev/null +++ b/coverage/dimred/SketchMapProjection.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2929100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..abe72ef46 --- /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:2929100.0 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("the out-of-sample projections of the input arguments using the input sketch-map projection");
+      54          16 :   keys.needsAction("RMSD"); keys.needsAction("PDB2CONSTANT"); keys.needsAction("CONSTANT"); keys.needsAction("CUSTOM");
+      55           8 :   keys.needsAction("EUCLIDEAN_DISTANCE"); keys.needsAction("NORMALIZED_EUCLIDEAN_DISTANCE");
+      56          12 :   keys.needsAction("SUM"); keys.needsAction("MORE_THAN"); keys.needsAction("PROJECT_POINTS");
+      57           4 : }
+      58             : 
+      59           1 : SketchMapProjection::SketchMapProjection( const ActionOptions& ao):
+      60             :   Action(ao),
+      61           1 :   ActionShortcut(ao)
+      62             : {
+      63             :   // Use path to read in the projections
+      64             :   std::string refname, refactions, metric;
+      65           2 :   std::vector<std::string> argnames; parseVector("ARG",argnames);
+      66           2 :   std::string type, reference_data, reference; parse("REFERENCE",reference); parse("TYPE",type);
+      67           1 :   mapping::Path::readInputFrames( reference, type, argnames, false, this, reference_data );
+      68             :   // And read in the data that we want on the projections
+      69           2 :   std::vector<std::string> pnames; parseVector("PROPERTY",pnames);
+      70           2 :   std::string weights; parse("WEIGHT",weights); pnames.push_back( weights );
+      71             :   // Now create fixed vectors using some sort of reference action
+      72           1 :   mapping::Path::readPropertyInformation( pnames, getShortcutLabel(), reference, this );
+      73             :   // Normalise the vector of weights
+      74           2 :   readInputLine( getShortcutLabel() + "_wsum: SUM PERIODIC=NO ARG=" + weights + "_ref");
+      75           2 :   readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + getShortcutLabel() + "_wsum," +  weights + "_ref FUNC=y/x PERIODIC=NO");
+      76             :   // Transform the high dimensional distances
+      77           1 :   std::string hdfunc; parse("HIGH_DIM_FUNCTION",hdfunc);
+      78           2 :   readInputLine( getShortcutLabel() + "_targ: MORE_THAN ARG=" + getShortcutLabel() + "_data SQUARED SWITCH={" + hdfunc + "}");
+      79             :   // Create the projection object
+      80           3 :   std::string ldfunc, cgtol; parse("LOW_DIM_FUNCTION",ldfunc); parse("CGTOL",cgtol);
+      81           3 :   std::string argstr="ARG=" + pnames[0] + "_ref"; for(unsigned i=1; i<pnames.size()-1; ++i) argstr += "," + pnames[i] + "_ref";
+      82           3 :   readInputLine( getShortcutLabel() + ": PROJECT_POINTS " + argstr + " TARGET1=" + getShortcutLabel() + "_targ " +
+      83           3 :                  "FUNC1={" + ldfunc + "} WEIGHTS1=" + getShortcutLabel() + "_weights CGTOL=" + cgtol );
+      84           3 : }
+      85             : 
+      86             : }
+      87             : }
+
+
+
+ + + + +
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 000000000..18eed4c0c --- /dev/null +++ b/coverage/dimred/index-sort-f.html @@ -0,0 +1,163 @@ + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:50551598.1 %
Date:2024-10-17 16:45:00Functions:303878.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PCA.cpp +
100.0%
+
100.0 %57 / 5766.7 %2 / 3
SketchMap.cpp +
96.1%96.1%
+
96.1 %73 / 7666.7 %2 / 3
SketchMapProjection.cpp +
100.0%
+
100.0 %29 / 2966.7 %2 / 3
ClassicalMultiDimensionalScaling.cpp +
97.6%97.6%
+
97.6 %41 / 4266.7 %2 / 3
ProjectPoints.cpp +
96.6%96.6%
+
96.6 %85 / 8880.0 %8 / 10
ArrangePoints.cpp +
98.9%98.9%
+
98.9 %173 / 17583.3 %10 / 12
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 000000000..b951f17e0 --- /dev/null +++ b/coverage/dimred/index-sort-l.html @@ -0,0 +1,163 @@ + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:50551598.1 %
Date:2024-10-17 16:45:00Functions:303878.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SketchMap.cpp +
96.1%96.1%
+
96.1 %73 / 7666.7 %2 / 3
ProjectPoints.cpp +
96.6%96.6%
+
96.6 %85 / 8880.0 %8 / 10
ClassicalMultiDimensionalScaling.cpp +
97.6%97.6%
+
97.6 %41 / 4266.7 %2 / 3
SMACOF.cpp +
97.7%97.7%
+
97.7 %42 / 43100.0 %3 / 3
ArrangePoints.cpp +
98.9%98.9%
+
98.9 %173 / 17583.3 %10 / 12
SMACOF.h +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
SketchMapProjection.cpp +
100.0%
+
100.0 %29 / 2966.7 %2 / 3
PCA.cpp +
100.0%
+
100.0 %57 / 5766.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 000000000..8eadc39b3 --- /dev/null +++ b/coverage/dimred/index.html @@ -0,0 +1,163 @@ + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:50551598.1 %
Date:2024-10-17 16:45:00Functions:303878.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ArrangePoints.cpp +
98.9%98.9%
+
98.9 %173 / 17583.3 %10 / 12
ClassicalMultiDimensionalScaling.cpp +
97.6%97.6%
+
97.6 %41 / 4266.7 %2 / 3
PCA.cpp +
100.0%
+
100.0 %57 / 5766.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 +
96.1%96.1%
+
96.1 %73 / 7666.7 %2 / 3
SketchMapProjection.cpp +
100.0%
+
100.0 %29 / 2966.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 000000000..09a2155ee --- /dev/null +++ b/coverage/drr/DRR.cpp.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..ce8b3721b --- /dev/null +++ b/coverage/drr/DRR.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..f16d67792 --- /dev/null +++ b/coverage/drr/DRR.cpp.gcov.html @@ -0,0 +1,634 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1be52ef72 --- /dev/null +++ b/coverage/drr/DRR.h.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage - drr/DRR.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4632c7838 --- /dev/null +++ b/coverage/drr/DRR.h.func.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage - drr/DRR.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d4fcae86c --- /dev/null +++ b/coverage/drr/DRR.h.gcov.html @@ -0,0 +1,434 @@ + + + + + + + LCOV - plumed test coverage - drr/DRR.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..181170ff4 --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:40344291.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..f707e5cf4 --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:40344291.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..bb77c8514 --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html @@ -0,0 +1,967 @@ + + + + + + + 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:40344291.2 %
Date:2024-10-17 16:45:00Functions: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             :            "k_BT/(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          28 :   keys.addOutputComponent(
+     313             :     "_fict", "default",
+     314             :     "one or multiple instances of this quantity can be referenced "
+     315             :     "elsewhere in the input file. "
+     316             :     "These quantities will named with the arguments of the bias followed by "
+     317             :     "the character string _tilde. It is possible to add forces on these "
+     318             :     "variable.");
+     319          28 :   keys.addOutputComponent(
+     320             :     "_vfict", "default",
+     321             :     "one or multiple instances of this quantity can be referenced "
+     322             :     "elsewhere in the input file. "
+     323             :     "These quantities will named with the arguments of the bias followed by "
+     324             :     "the character string _tilde. It is NOT possible to add forces on these "
+     325             :     "variable.");
+     326          28 :   keys.addOutputComponent(
+     327             :     "_biasforce", "default",
+     328             :     "The bias force from eABF/DRR of the fictitious particle.");
+     329          28 :   keys.addOutputComponent("_springforce", "default", "Spring force between real CVs and extended CVs");
+     330          28 :   keys.addOutputComponent("_fictNoPBC", "default",
+     331             :                           "the positions of fictitious particles (without PBC).");
+     332          14 : }
+     333             : 
+     334          12 : DynamicReferenceRestraining::DynamicReferenceRestraining(
+     335          12 :   const ActionOptions &ao)
+     336          12 :   : PLUMED_BIAS_INIT(ao), firsttime(true), nobias(false),
+     337          12 :     fictNoPBC(getNumberOfArguments(), 0.0), real(getNumberOfArguments(), 0.0),
+     338          12 :     springlength(getNumberOfArguments(), 0.0),
+     339          12 :     fict(getNumberOfArguments(), 0.0), vfict(getNumberOfArguments(), 0.0),
+     340          12 :     vfict_laststep(getNumberOfArguments(), 0.0),
+     341          12 :     ffict(getNumberOfArguments(), 0.0), fbias(getNumberOfArguments(), 0.0),
+     342          12 :     kappa(getNumberOfArguments(), 0.0), tau(getNumberOfArguments(), 0.0),
+     343          12 :     friction(getNumberOfArguments(), 0.0), etemp(getNumberOfArguments(), 0.0),
+     344          12 :     ffict_measured(getNumberOfArguments(), 0.0),
+     345          12 :     biasforceValue(getNumberOfArguments(), NULL),
+     346          12 :     springforceValue(getNumberOfArguments(), NULL),
+     347          12 :     fictValue(getNumberOfArguments(), NULL),
+     348          12 :     vfictValue(getNumberOfArguments(), NULL),
+     349          12 :     fictNoPBCValue(getNumberOfArguments(), NULL),
+     350          12 :     externalForceValue(getNumberOfArguments(), NULL),
+     351          12 :     externalFictValue(getNumberOfArguments(), NULL),
+     352          12 :     c1(getNumberOfArguments(), 0.0),
+     353          12 :     c2(getNumberOfArguments(), 0.0), mass(getNumberOfArguments(), 0.0),
+     354          12 :     delim(getNumberOfArguments()), outputname(""), cptname(""),
+     355          12 :     outputprefix(""), fmt_("%.9f"), ndims(getNumberOfArguments()), dt(0.0), kbt(0.0),
+     356          12 :     outputfreq(0.0), historyfreq(-1.0), isRestart(false),
+     357          12 :     useCZARestimator(true), useUIestimator(false), mergeHistoryFiles(false),
+     358          12 :     textoutput(false), withExternalForce(false), withExternalFict(false),
+     359          12 :     reflectingWall(getNumberOfArguments(), 0),
+     360          36 :     maxFactors(getNumberOfArguments(), 1.0)
+     361             : {
+     362          12 :   log << "eABF/DRR: You now are using the extended adaptive biasing "
+     363             :       "force(eABF) method."
+     364          12 :       << '\n';
+     365          12 :   log << "eABF/DRR: Some people also refer to it as dynamic reference "
+     366             :       "restraining(DRR) method."
+     367          12 :       << '\n';
+     368          12 :   log << "eABF/DRR: Currently the CZAR and naive(ABF on extended variables) "
+     369             :       "estimator is enabled by default."
+     370          12 :       << '\n';
+     371          12 :   log << "eABF/DRR: For reasons of performance, the umbrella integration "
+     372             :       "estimator is not enabled by default."
+     373          12 :       << '\n';
+     374          12 :   log << "eABF/DRR: This method is originally implemented in "
+     375             :       "colvars(https://github.com/colvars/colvars)."
+     376          12 :       << '\n';
+     377          12 :   log << "eABF/DRR: The code in plumed is heavily modified from "
+     378             :       "ExtendedLagrangian.cpp and doesn't implemented all variants of "
+     379             :       "eABF/DRR."
+     380          12 :       << '\n';
+     381          12 :   log << "eABF/DRR: The thermostat used here may be different from Colvars."
+     382          12 :       << '\n';
+     383          12 :   log << "eABF/DRR: To integrate the gradients file, you can use abf_integrate "
+     384             :       "from https://github.com/colvars/colvars/tree/master/colvartools."
+     385          12 :       << '\n';
+     386          12 :   log << "eABF/DRR: Please read relevant articles and use this biasing "
+     387             :       "method carefully!"
+     388          12 :       << '\n';
+     389          12 :   parseFlag("NOBIAS", nobias);
+     390          12 :   parseFlag("UI", useUIestimator);
+     391          12 :   bool noCZAR = false;
+     392          12 :   parseFlag("NOCZAR", noCZAR);
+     393             : //   noCZAR == false ? useCZARestimator = true : useCZARestimator = false;
+     394          12 :   parseFlag("TEXTOUTPUT", textoutput);
+     395          12 :   parseFlag("MERGEHISTORYFILES", mergeHistoryFiles);
+     396          12 :   parseVector("TAU", tau);
+     397          12 :   parseVector("FRICTION", friction);
+     398          12 :   parseVector("EXTTEMP", etemp);
+     399          12 :   parseVector("KAPPA", kappa);
+     400          12 :   parseVector("REFLECTINGWALL", reflectingWall);
+     401          12 :   parse("FULLSAMPLES", fullsamples);
+     402          12 :   parseVector("MAXFACTOR", maxFactors);
+     403          12 :   parse("OUTPUTFREQ", outputfreq);
+     404          12 :   parse("HISTORYFREQ", historyfreq);
+     405          24 :   parse("OUTPUTPREFIX", outputprefix);
+     406             :   string restart_prefix;
+     407          24 :   parse("DRR_RFILE", restart_prefix);
+     408             :   string uirprefix;
+     409          12 :   parse("UIRESTARTPREFIX", uirprefix);
+     410          12 :   parseArgumentList("EXTERNAL_FORCE", externalForceValue);
+     411          12 :   parseArgumentList("EXTERNAL_FICT", externalFictValue);
+     412          24 :   parse("FMT",fmt_);
+     413          12 :   if (externalForceValue.empty()) {
+     414          11 :     withExternalForce = false;
+     415           1 :   } else if (externalForceValue.size() != ndims) {
+     416           0 :     error("eABF/DRR: Number of forces doesn't match ARGS!");
+     417             :   } else {
+     418           1 :     withExternalForce = true;
+     419             :   }
+     420          12 :   if (withExternalForce && useUIestimator) {
+     421           1 :     if (externalFictValue.empty()) {
+     422           0 :       error("eABF/DRR: No external fictitious particles specified. UI estimator needs it.");
+     423           1 :     } else if(externalFictValue.size() != ndims) {
+     424           0 :       error("eABF/DRR: Number of fictitious particles doesn't match ARGS!");
+     425             :     } else {
+     426           1 :       withExternalFict = true;
+     427             :     }
+     428             :   }
+     429          12 :   kbt = getkBT();
+     430          12 :   if (kbt <= std::numeric_limits<double>::epsilon()) {
+     431           0 :     error("eABF/DRR: It seems the MD engine does not setup the temperature correctly for PLUMED."
+     432             :           "Please set it by the TEMP keyword manually.");
+     433             :   }
+     434          12 :   if (fullsamples < 0.5) {
+     435           0 :     fullsamples = 500.0;
+     436           0 :     log << "eABF/DRR: The fullsamples parametre is not set. Set it to "
+     437             :         "500(default)."
+     438           0 :         << '\n';
+     439             :   }
+     440          12 :   if (getRestart()) {
+     441           1 :     if (restart_prefix.length() != 0) {
+     442           1 :       isRestart = true;
+     443           1 :       firsttime = false;
+     444           1 :       load(restart_prefix);
+     445             :     } else {
+     446           0 :       log << "eABF/DRR: You don't specify the file for restarting." << '\n';
+     447           0 :       log << "eABF/DRR: So I assume you are splitting windows." << '\n';
+     448           0 :       isRestart = false;
+     449           0 :       firsttime = true;
+     450             :     }
+     451             :   }
+     452             : 
+     453          12 :   vector<string> gmin(ndims);
+     454          12 :   vector<string> zgmin(ndims);
+     455          12 :   parseVector("GRID_MIN", gmin);
+     456          24 :   parseVector("ZGRID_MIN", zgmin);
+     457          12 :   if (gmin.size() != ndims)
+     458           0 :     error("eABF/DRR: not enough values for GRID_MIN");
+     459          12 :   if (zgmin.size() != ndims) {
+     460          33 :     log << "eABF/DRR: You didn't specify ZGRID_MIN. " << '\n'
+     461          11 :         << "eABF/DRR: The GRID_MIN will be used instead.";
+     462          11 :     zgmin = gmin;
+     463             :   }
+     464          12 :   vector<string> gmax(ndims);
+     465          12 :   vector<string> zgmax(ndims);
+     466          12 :   parseVector("GRID_MAX", gmax);
+     467          24 :   parseVector("ZGRID_MAX", zgmax);
+     468          12 :   if (gmax.size() != ndims)
+     469           0 :     error("eABF/DRR: not enough values for GRID_MAX");
+     470          12 :   if (zgmax.size() != ndims) {
+     471          33 :     log << "eABF/DRR: You didn't specify ZGRID_MAX. " << '\n'
+     472          11 :         << "eABF/DRR: The GRID_MAX will be used instead.";
+     473          11 :     zgmax = gmax;
+     474             :   }
+     475          12 :   vector<unsigned> gbin(ndims);
+     476          12 :   vector<unsigned> zgbin(ndims);
+     477          12 :   vector<double> gspacing(ndims);
+     478          12 :   vector<double> zgspacing(ndims);
+     479          12 :   parseVector("GRID_BIN", gbin);
+     480          12 :   parseVector("ZGRID_BIN", zgbin);
+     481          12 :   parseVector("GRID_SPACING", gspacing);
+     482          24 :   parseVector("ZGRID_SPACING", zgspacing);
+     483          12 :   if (gbin.size() != ndims) {
+     484           3 :     log << "eABF/DRR: You didn't specify GRID_BIN. Trying to use GRID_SPACING "
+     485             :         "instead."
+     486           3 :         << '\n';
+     487           3 :     if (gspacing.size() != ndims) {
+     488           0 :       error("eABF/DRR: not enough values for GRID_BIN");
+     489             :     } else {
+     490           3 :       gbin.resize(ndims);
+     491           6 :       for (size_t i = 0; i < ndims; ++i) {
+     492             :         double l, h;
+     493           3 :         PLMD::Tools::convert(gmin[i], l);
+     494           3 :         PLMD::Tools::convert(gmax[i], h);
+     495           3 :         gbin[i] = std::nearbyint((h - l) / gspacing[i]);
+     496           3 :         gspacing[i] = (h - l) / gbin[i];
+     497           3 :         log << "GRID_BIN[" << i << "] is " << gbin[i] << '\n';
+     498             :       }
+     499             :     }
+     500             :   }
+     501          12 :   if (zgbin.size() != ndims) {
+     502          11 :     log << "eABF/DRR: You didn't specify ZGRID_BIN. Trying to use ZGRID_SPACING instead." << '\n';
+     503          11 :     if (zgspacing.size() != ndims) {
+     504          11 :       log << "eABF/DRR: You didn't specify ZGRID_SPACING. Trying to use GRID_SPACING or GRID_BIN instead." << '\n';
+     505          11 :       zgbin = gbin;
+     506          11 :       zgspacing = gspacing;
+     507             :     } else {
+     508           0 :       zgbin.resize(ndims);
+     509           0 :       for (size_t i = 0; i < ndims; ++i) {
+     510             :         double l, h;
+     511           0 :         PLMD::Tools::convert(zgmin[i], l);
+     512           0 :         PLMD::Tools::convert(zgmax[i], h);
+     513           0 :         zgbin[i] = std::nearbyint((h - l) / zgspacing[i]);
+     514           0 :         zgspacing[i] = (h - l) / zgbin[i];
+     515           0 :         log << "ZGRID_BIN[" << i << "] is " << zgbin[i] << '\n';
+     516             :       }
+     517             :     }
+     518             :   }
+     519          12 :   checkRead();
+     520             : 
+     521             :   // Set up kbt for extended system
+     522          12 :   log << "eABF/DRR: The fullsamples is " << fullsamples << '\n';
+     523          12 :   log << "eABF/DRR: The kbt(real system) is " << kbt << '\n';
+     524          12 :   dt = getTimeStep() * getStride();
+     525          12 :   log << "eABF/DRR: timestep = " << getTimeStep() << " ps with stride = " << getStride() << " steps\n";
+     526          12 :   vector<double> ekbt(ndims, 0.0);
+     527          12 :   if (etemp.size() != ndims) {
+     528          12 :     etemp.assign(ndims, kbt / getKBoltzmann());
+     529             :   }
+     530          12 :   if (tau.size() != ndims) {
+     531           0 :     tau.assign(ndims, 0.5);
+     532             :   }
+     533          12 :   if (friction.size() != ndims) {
+     534           0 :     friction.assign(ndims, 8.0);
+     535             :   }
+     536          12 :   if (maxFactors.size() != ndims) {
+     537           0 :     maxFactors.assign(ndims, 1.0);
+     538             :   }
+     539          31 :   for (size_t i = 0; i < ndims; ++i) {
+     540          19 :     log << "eABF/DRR: The maximum scaling factor [" << i << "] is " << maxFactors[i] << '\n';
+     541          19 :     if (maxFactors[i] > 1.0) {
+     542           0 :       log << "eABF/DRR: Warning! The maximum scaling factor larger than 1.0 is not recommended!" << '\n';
+     543             :     }
+     544             :   }
+     545          31 :   for (size_t i = 0; i < ndims; ++i) {
+     546          19 :     ekbt[i] = etemp[i] * getKBoltzmann();
+     547          19 :     log << "eABF/DRR: The kbt(extended system) of [" << i << "] is " << ekbt[i]
+     548          19 :         << '\n';
+     549          19 :     log << "eABF/DRR: relaxation time tau [" << i << "] is " << tau[i] << '\n';
+     550          19 :     log << "eABF/DRR: Extended variable [" << i << "] has friction: " << friction[i] << '\n';
+     551             :   }
+     552             : 
+     553             :   // Set up the force grid
+     554          12 :   vector<DRRAxis> zdelim(ndims);
+     555          31 :   for (size_t i = 0; i < ndims; ++i) {
+     556          19 :     log << "eABF/DRR: The " << i << " dimensional grid minimum is " << gmin[i]
+     557          19 :         << '\n';
+     558          19 :     log << "eABF/DRR: The " << i << " dimensional grid maximum is " << gmax[i]
+     559          19 :         << '\n';
+     560          19 :     log << "eABF/DRR: The " << i << " dimensional grid has " << gbin[i]
+     561          19 :         << " bins" << '\n';
+     562          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid minimum is " << zgmin[i]
+     563          19 :         << '\n';
+     564          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid maximum is " << zgmax[i]
+     565          19 :         << '\n';
+     566          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid has " << zgbin[i]
+     567          19 :         << " bins" << '\n';
+     568             :     double l, h;
+     569          19 :     PLMD::Tools::convert(gmin[i], l);
+     570          19 :     PLMD::Tools::convert(gmax[i], h);
+     571          19 :     delim[i].set(l, h, gbin[i]);
+     572             :     double zl,zh;
+     573          19 :     PLMD::Tools::convert(zgmin[i], zl);
+     574          19 :     PLMD::Tools::convert(zgmax[i], zh);
+     575          19 :     zdelim[i].set(zl, zh, zgbin[i]);
+     576             :   }
+     577          12 :   if (kappa.size() != ndims) {
+     578           9 :     kappa.resize(ndims, 0.0);
+     579          25 :     for (size_t i = 0; i < ndims; ++i) {
+     580          16 :       if (kappa[i] <= 0) {
+     581          16 :         log << "eABF/DRR: The spring force constant kappa[" << i
+     582          16 :             << "] is not set." << '\n';
+     583          16 :         kappa[i] = ekbt[i] / (delim[i].getWidth() * delim[i].getWidth());
+     584          16 :         log << "eABF/DRR: set kappa[" << i
+     585          16 :             << "] according to bin width(ekbt/(binWidth^2))." << '\n';
+     586             :       }
+     587          16 :       log << "eABF/DRR: The spring force constant kappa[" << i << "] is "
+     588          16 :           << std::fixed << std::setprecision(10) << kappa[i] << '\n';
+     589             :     }
+     590             :   } else {
+     591           3 :     log << "eABF/DRR: The kappa have been set manually." << '\n';
+     592           6 :     for (size_t i = 0; i < ndims; ++i) {
+     593           3 :       log << "eABF/DRR: The spring force constant kappa[" << i << "] is "
+     594           3 :           << std::fixed << std::setprecision(10) << kappa[i] << '\n';
+     595             :     }
+     596             :   }
+     597             : 
+     598          31 :   for (size_t i = 0; i < ndims; ++i) {
+     599          19 :     mass[i] = kappa[i] * tau[i] * tau[i] / (4 * pi * pi);
+     600          19 :     log << "eABF/DRR: Fictitious mass[" << i << "] is " << mass[i] << '\n';
+     601          19 :     c1[i] = exp(-0.5 * friction[i] * dt);
+     602          19 :     c2[i] = sqrt(ekbt[i] * (1.0 - c1[i] * c1[i]) / mass[i]);
+     603             :   }
+     604             : 
+     605          31 :   for (size_t i = 0; i < ndims; ++i) {
+     606             :     // Position output
+     607          19 :     string comp = getPntrToArgument(i)->getName() + "_fict";
+     608          38 :     addComponentWithDerivatives(comp);
+     609          19 :     if (getPntrToArgument(i)->isPeriodic()) {
+     610             :       string a, b;
+     611             :       double c, d;
+     612          16 :       getPntrToArgument(i)->getDomain(a, b);
+     613          16 :       getPntrToArgument(i)->getDomain(c, d);
+     614          16 :       componentIsPeriodic(comp, a, b);
+     615          16 :       delim[i].setPeriodicity(c, d);
+     616             :       zdelim[i].setPeriodicity(c, d);
+     617             :     } else
+     618           3 :       componentIsNotPeriodic(comp);
+     619          19 :     fictValue[i] = getPntrToComponent(comp);
+     620             :     // Velocity output
+     621          38 :     comp = getPntrToArgument(i)->getName() + "_vfict";
+     622          19 :     addComponent(comp);
+     623          19 :     componentIsNotPeriodic(comp);
+     624          19 :     vfictValue[i] = getPntrToComponent(comp);
+     625             :     // Bias force from eABF/DRR output
+     626          38 :     comp = getPntrToArgument(i)->getName() + "_biasforce";
+     627          19 :     addComponent(comp);
+     628          19 :     componentIsNotPeriodic(comp);
+     629          19 :     biasforceValue[i] = getPntrToComponent(comp);
+     630             :     // Spring force output, useful for perform egABF and other analysis
+     631          38 :     comp = getPntrToArgument(i)->getName() + "_springforce";
+     632          19 :     addComponent(comp);
+     633          19 :     componentIsNotPeriodic(comp);
+     634          19 :     springforceValue[i] = getPntrToComponent(comp);
+     635             :     // Position output, no pbc-aware
+     636          38 :     comp = getPntrToArgument(i)->getName() + "_fictNoPBC";
+     637          19 :     addComponent(comp);
+     638          19 :     componentIsNotPeriodic(comp);
+     639          19 :     fictNoPBCValue[i] = getPntrToComponent(comp);
+     640             :   }
+     641             : 
+     642          12 :   if (outputprefix.length() == 0) {
+     643           0 :     outputprefix = getLabel();
+     644             :   }
+     645             :   // Support multiple replica
+     646          12 :   string replica_suffix = plumed.getSuffix();
+     647          12 :   if (replica_suffix.empty() == false) {
+     648           4 :     outputprefix = outputprefix + replica_suffix;
+     649             :   }
+     650          12 :   outputname = outputprefix + ".drrstate";
+     651          12 :   cptname = outputprefix + ".cpt.drrstate";
+     652             : 
+     653          12 :   if (!isRestart) {
+     654             :     // If you want to use on-the-fly text output for CZAR and naive estimator,
+     655             :     // you should turn it to true first!
+     656          11 :     ABFGrid = ABF(delim, ".abf", fullsamples, maxFactors, textoutput);
+     657             :     // Just initialize it even useCZARestimator is off.
+     658          22 :     CZARestimator = CZAR(zdelim, ".czar", kbt, textoutput);
+     659          11 :     log << "eABF/DRR: The init function of the grid is finished." << '\n';
+     660             :   } else {
+     661             :     // ABF Parametres are not saved in binary files
+     662             :     // So manully set them up
+     663           1 :     ABFGrid.setParameters(fullsamples, maxFactors);
+     664             :   }
+     665          12 :   if (useCZARestimator) {
+     666          12 :     log << "eABF/DRR: Using corrected z-average restraint estimator of gradients" << '\n';
+     667          24 :     log << "  Bibliography " << plumed.cite("Lesage, Lelièvre, Stoltz and Hénin, "
+     668          24 :                                             "J. Phys. Chem. B 3676, 121 (2017)");
+     669          12 :     log << plumed.cite("Darve and Pohorille, J. Chem. Phys. 9169, 115 (2001)") << '\n';
+     670             :   }
+     671          12 :   if (useUIestimator) {
+     672           9 :     log << "eABF/DRR: Using umbrella integration(Zheng and Yang's) estimator "
+     673             :         "of gradients."
+     674           9 :         << '\n';
+     675           9 :     log << "eABF/DRR: The UI estimator code is contributed by Haohao Fu."
+     676           9 :         << '\n';
+     677          18 :     log << "  Bibliography " << plumed.cite(
+     678          18 :           "Fu, Shao, Chipot and Cai, J. Chem. Theory Comput. 3506, 12 (2016)");
+     679          18 :     log << plumed.cite("Zheng and Yang, J. Chem. Theory Comput. 810, 8 (2012)");
+     680           9 :     log << plumed.cite("Darve and Pohorille, J. Chem. Phys. 9169, 115 (2001)") << '\n';
+     681           9 :     vector<double> lowerboundary(zdelim.size(), 0);
+     682           9 :     vector<double> upperboundary(zdelim.size(), 0);
+     683           9 :     vector<double> width(zdelim.size(), 0);
+     684          24 :     for (size_t i = 0; i < zdelim.size(); ++i) {
+     685          15 :       lowerboundary[i] = zdelim[i].getMin();
+     686          15 :       upperboundary[i] = zdelim[i].getMax();
+     687          15 :       width[i] = zdelim[i].getWidth();
+     688             :     }
+     689             :     vector<string> input_filename;
+     690             :     bool uirestart = false;
+     691           9 :     if (isRestart && (uirprefix.length() != 0)) {
+     692           1 :       input_filename.push_back(uirprefix);
+     693             :       uirestart = true;
+     694             :     }
+     695           9 :     if (isRestart && (uirprefix.length() == 0)) {
+     696           0 :       input_filename.push_back(outputprefix);
+     697             :     }
+     698           9 :     eabf_UI = UIestimator::UIestimator(
+     699           9 :                 lowerboundary, upperboundary, width, kappa, outputprefix, int(outputfreq),
+     700          18 :                 uirestart, input_filename, kbt / getKBoltzmann());
+     701           9 :   }
+     702          24 : }
+     703             : 
+     704         123 : void DynamicReferenceRestraining::calculate() {
+     705         123 :   long long int step_now = getStep();
+     706         123 :   if (firsttime) {
+     707          28 :     for (size_t i = 0; i < ndims; ++i) {
+     708          17 :       fict[i] = getArgument(i);
+     709          17 :       if(reflectingWall[i] && (fict[i]>=delim[i].getMax() || fict[i]<=delim[i].getMin())) {
+     710           0 :         error("eABF/DRR: initial position not in the range of [gmin, gmax]!");
+     711             :       }
+     712             :     }
+     713          11 :     firsttime = false;
+     714             :   }
+     715         123 :   if (step_now != 0) {
+     716         111 :     if ((step_now % int(outputfreq)) == 0) {
+     717          15 :       save(outputname, step_now);
+     718          15 :       if (textoutput) {
+     719          10 :         ABFGrid.writeAll(outputprefix, fmt_);
+     720          10 :         if (useCZARestimator) {
+     721          10 :           CZARestimator.writeAll(outputprefix, fmt_);
+     722          10 :           CZARestimator.writeZCountZGrad(outputprefix);
+     723             :         }
+     724             :       }
+     725             :     }
+     726         111 :     if (historyfreq > 0 && (step_now % int(historyfreq)) == 0) {
+     727           4 :       if (textoutput) {
+     728             :         const string filename =
+     729           4 :           outputprefix + ".another.drrstate";
+     730           4 :         save(filename, step_now);
+     731             :         const string textfilename =
+     732           4 :           mergeHistoryFiles ? (outputprefix + ".hist") : (outputprefix + "." + std::to_string(step_now));
+     733           4 :         ABFGrid.writeAll(textfilename, fmt_, mergeHistoryFiles);
+     734           4 :         if (useCZARestimator) {
+     735           4 :           CZARestimator.writeAll(textfilename, fmt_, mergeHistoryFiles);
+     736           4 :           CZARestimator.writeZCountZGrad(textfilename, mergeHistoryFiles);
+     737             :         }
+     738             :       } else {
+     739             :         const string filename =
+     740           0 :           outputprefix + "." + std::to_string(step_now) + ".drrstate";
+     741           0 :         save(filename, step_now);
+     742             :       }
+     743             :     }
+     744         111 :     if (getCPT()) {
+     745           0 :       log << "eABF/DRR: The MD engine is writing checkpoint so we also write a "
+     746             :           "DRR state file at step: "
+     747           0 :           << step_now << ".\n";
+     748           0 :       save(cptname, step_now);
+     749             :     }
+     750             :   }
+     751         123 :   if (withExternalForce == false) {
+     752             :     double ene = 0.0;
+     753         294 :     for (size_t i = 0; i < ndims; ++i) {
+     754         183 :       real[i] = getArgument(i);
+     755         183 :       springlength[i] = difference(i, fict[i], real[i]);
+     756         183 :       fictNoPBC[i] = real[i] - springlength[i];
+     757         183 :       double f = -kappa[i] * springlength[i];
+     758         183 :       ffict_measured[i] = -f;
+     759         183 :       ene += 0.5 * kappa[i] * springlength[i] * springlength[i];
+     760         183 :       setOutputForce(i, f);
+     761         183 :       ffict[i] = -f;
+     762         183 :       fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
+     763         183 :       fictValue[i]->set(fict[i]);
+     764         183 :       vfictValue[i]->set(vfict_laststep[i]);
+     765         183 :       springforceValue[i]->set(ffict_measured[i]);
+     766         183 :       fictNoPBCValue[i]->set(fictNoPBC[i]);
+     767             :     }
+     768         111 :     setBias(ene);
+     769         111 :     ABFGrid.store_getbias(fict, ffict_measured, fbias);
+     770             :   } else {
+     771          36 :     for (size_t i = 0; i < ndims; ++i) {
+     772          24 :       real[i] = getArgument(i);
+     773          24 :       ffict_measured[i] = externalForceValue[i]->get();
+     774          24 :       if (withExternalFict) {
+     775          24 :         fictNoPBC[i] = externalFictValue[i]->get();
+     776             :       }
+     777          24 :       springforceValue[i]->set(ffict_measured[i]);
+     778          24 :       fictNoPBCValue[i]->set(fictNoPBC[i]);
+     779             :     }
+     780          12 :     ABFGrid.store_getbias(real, ffict_measured, fbias);
+     781          12 :     if (!nobias) {
+     782           0 :       for (size_t i = 0; i < ndims; ++i) {
+     783           0 :         setOutputForce(i, fbias[i]);
+     784             :       }
+     785             :     }
+     786             :   }
+     787         123 :   if (useCZARestimator) {
+     788         123 :     CZARestimator.store(real, ffict_measured);
+     789             :   }
+     790         123 :   if (useUIestimator) {
+     791          87 :     eabf_UI.update_output_filename(outputprefix);
+     792         174 :     eabf_UI.update(int(step_now), real, fictNoPBC);
+     793             :   }
+     794         123 : }
+     795             : 
+     796         123 : void DynamicReferenceRestraining::update() {
+     797         123 :   if (withExternalForce == false) {
+     798         294 :     for (size_t i = 0; i < ndims; ++i) {
+     799             :       // consider additional forces on the fictitious particle
+     800             :       // (e.g. MetaD stuff)
+     801         183 :       ffict[i] += fictValue[i]->getForce();
+     802         183 :       if (!nobias) {
+     803         183 :         ffict[i] += fbias[i];
+     804             :       }
+     805         183 :       biasforceValue[i]->set(fbias[i]);
+     806             :       // update velocity (half step)
+     807         183 :       vfict[i] += ffict[i] * 0.5 * dt / mass[i];
+     808             :       // thermostat (half step)
+     809         183 :       vfict[i] = c1[i] * vfict[i] + c2[i] * rand.Gaussian();
+     810             :       // save full step velocity to be dumped at next step
+     811         183 :       vfict_laststep[i] = vfict[i];
+     812             :       // thermostat (half step)
+     813         183 :       vfict[i] = c1[i] * vfict[i] + c2[i] * rand.Gaussian();
+     814             :       // update velocity (half step)
+     815         183 :       vfict[i] += ffict[i] * 0.5 * dt / mass[i];
+     816             :       // update position (full step)
+     817         183 :       fict[i] += vfict[i] * dt;
+     818             :       // reflecting boundary
+     819         183 :       if (reflectingWall[i]) {
+     820          24 :         if (fict[i]<delim[i].getMin()) {
+     821           1 :           fict[i]=delim[i].getMin()+(delim[i].getMin()-fict[i]);
+     822           1 :           vfict[i]*=-1.0;
+     823          23 :         } else if (fict[i]>delim[i].getMax()) {
+     824           0 :           fict[i]=delim[i].getMax()-(fict[i]-delim[i].getMax());
+     825           0 :           vfict[i]*=-1.0;
+     826             :         }
+     827             :       }
+     828             :     }
+     829             :   }
+     830         123 : }
+     831             : 
+     832          19 : void DynamicReferenceRestraining::save(const string &filename,
+     833             :                                        long long int step) {
+     834          19 :   std::ofstream out;
+     835          19 :   out.open(filename.c_str(), std::ios::binary);
+     836          19 :   boost::archive::binary_oarchive oa(out);
+     837          19 :   oa << step << fict << vfict << vfict_laststep << ffict << ABFGrid
+     838          19 :      << CZARestimator;
+     839          19 :   out.close();
+     840          19 : }
+     841             : 
+     842           1 : void DynamicReferenceRestraining::load(const string &rfile_prefix) {
+     843           1 :   string replica_suffix = plumed.getSuffix();
+     844             :   string filename;
+     845           1 :   if (replica_suffix.empty() == true) {
+     846           2 :     filename = rfile_prefix + ".drrstate";
+     847             :   } else {
+     848           0 :     filename = rfile_prefix + "." + replica_suffix + ".drrstate";
+     849             :   }
+     850           1 :   std::ifstream in;
+     851             :   long long int step;
+     852           1 :   in.open(filename.c_str(), std::ios::binary);
+     853           1 :   log << "eABF/DRR: Read restart file: " << filename << '\n';
+     854           1 :   boost::archive::binary_iarchive ia(in);
+     855           1 :   ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> ABFGrid >>
+     856           1 :      CZARestimator;
+     857           1 :   in.close();
+     858           1 :   log << "eABF/DRR: Restart at step: " << step << '\n';
+     859           1 :   backupFile(filename);
+     860           2 : }
+     861             : 
+     862           1 : void DynamicReferenceRestraining::backupFile(const string &filename) {
+     863             :   bool isSuccess = false;
+     864             :   long int i = 0;
+     865           2 :   while (!isSuccess) {
+     866             :     // If libstdc++ support C++17 we can simplify following code.
+     867           2 :     const string bckname = "bck." + filename + "." + std::to_string(i);
+     868           1 :     if (is_file_exist(bckname.c_str())) {
+     869           0 :       ++i;
+     870             :     } else {
+     871           1 :       log << "eABF/DRR: Backup original restart file to " << bckname << '\n';
+     872           1 :       std::ifstream src(filename.c_str(), std::ios::binary);
+     873           1 :       std::ofstream dst(bckname.c_str(), std::ios::binary);
+     874           1 :       dst << src.rdbuf();
+     875           1 :       src.close();
+     876           1 :       dst.close();
+     877             :       isSuccess = true;
+     878           1 :     }
+     879             :   }
+     880           1 : }
+     881             : 
+     882             : // Copy from
+     883             : // stackoverflow(https://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c)
+     884           1 : bool DynamicReferenceRestraining::is_file_exist(const char *fileName) {
+     885           1 :   std::ifstream infile(fileName);
+     886           1 :   return infile.good();
+     887           1 : }
+     888             : }
+     889             : }
+     890             : 
+     891             : #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 000000000..2be2a19bf --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.func-sort-c.html @@ -0,0 +1,208 @@ + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..9f3512782 --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.func.html @@ -0,0 +1,208 @@ + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..7fa3c56c3 --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.gcov.html @@ -0,0 +1,931 @@ + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3828a3a63 --- /dev/null +++ b/coverage/drr/drrtool.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-10-17 16:45:00Functions: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_117drrtoolRegisterMeC2Ev5301
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev5301
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..3554ddb97 --- /dev/null +++ b/coverage/drr/drrtool.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-10-17 16:45:00Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev5301
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev5301
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_1
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE5301
_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 000000000..f2fc3dcb6 --- /dev/null +++ b/coverage/drr/drrtool.cpp.gcov.html @@ -0,0 +1,344 @@ + + + + + + + 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-10-17 16:45:00Functions: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       15912 : PLUMED_REGISTER_CLTOOL(drrtool, "drr_tool")
+      90             : 
+      91        5301 : void drrtool::registerKeywords(Keywords &keys) {
+      92        5301 :   CLTool::registerKeywords(keys);
+      93       10602 :   keys.add("optional", "--extract", "Extract drrstate file(s)");
+      94       10602 :   keys.add("optional", "--merge", "Merge eABF windows");
+      95       10602 :   keys.add("optional", "--merge_output", "The output filename of the merged result");
+      96       10602 :   keys.add("optional", "--divergence", "Calculate divergence of gradient field (experimental)");
+      97       10602 :   keys.add("optional","--dump-fmt","( default=%%f ) the format to use to dump the output");
+      98       10602 :   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       10602 :   keys.addFlag("-v", false, "Verbose output");
+     100        5301 : }
+     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 000000000..012e04341 --- /dev/null +++ b/coverage/drr/index-sort-f.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1200127094.5 %
Date:2024-10-17 16:45:00Functions: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 %403 / 44288.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 000000000..0669f96a7 --- /dev/null +++ b/coverage/drr/index-sort-l.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1200127094.5 %
Date:2024-10-17 16:45:00Functions:899494.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DynamicReferenceRestraining.cpp +
91.2%91.2%
+
91.2 %403 / 44288.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 000000000..9ea193567 --- /dev/null +++ b/coverage/drr/index.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1200127094.5 %
Date:2024-10-17 16:45:00Functions: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 %403 / 44288.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 000000000..589fa1353 --- /dev/null +++ b/coverage/eds/EDS.cpp.func-sort-c.html @@ -0,0 +1,152 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5f59bfead --- /dev/null +++ b/coverage/eds/EDS.cpp.func.html @@ -0,0 +1,152 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c7a4adb45 --- /dev/null +++ b/coverage/eds/EDS.cpp.gcov.html @@ -0,0 +1,1250 @@ + + + + + + + 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-10-17 16:45:00Functions: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 k_B T/[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 000000000..10b2e9581 --- /dev/null +++ b/coverage/eds/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..c61ae3ae6 --- /dev/null +++ b/coverage/eds/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..5729c9d9c --- /dev/null +++ b/coverage/eds/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..fee5579be --- /dev/null +++ b/coverage/envsim/EnvironmentSimilarity.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d8d11a4be --- /dev/null +++ b/coverage/envsim/EnvironmentSimilarity.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..9042b66a6 --- /dev/null +++ b/coverage/envsim/EnvironmentSimilarity.cpp.gcov.html @@ -0,0 +1,523 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7cb36439d --- /dev/null +++ b/coverage/envsim/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - envsim + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsimHitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..4ddc5fb04 --- /dev/null +++ b/coverage/envsim/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - envsim + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsimHitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..706224817 --- /dev/null +++ b/coverage/envsim/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - envsim + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsimHitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..e29bfddf5 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8847e0f72 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3638e8d9f --- /dev/null +++ b/coverage/fisst/FISST.cpp.gcov.html @@ -0,0 +1,735 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7ca9a6485 --- /dev/null +++ b/coverage/fisst/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..13fe3e807 --- /dev/null +++ b/coverage/fisst/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..171d98052 --- /dev/null +++ b/coverage/fisst/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..74b401b71 --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..068d3364d --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..bb714ca3a --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.gcov.html @@ -0,0 +1,641 @@ + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..aa6f7ff84 --- /dev/null +++ b/coverage/fourier/FourierTransform.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:8710087.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..6b707b775 --- /dev/null +++ b/coverage/fourier/FourierTransform.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:8710087.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..fec15de78 --- /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:8710087.0 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the fourier transform of the input grid");
+      98           3 : }
+      99             : 
+     100           1 : FourierTransform::FourierTransform(const ActionOptions&ao):
+     101             :   Action(ao),
+     102             :   ActionWithGrid(ao),
+     103           1 :   firsttime(true),
+     104           1 :   real_output(true),
+     105           1 :   store_norm(false),
+     106           1 :   fourier_params(2)
+     107             : {
+     108           1 :   if( getPntrToArgument(0)->getRank()!=2 ) error("fourier transform currently only works with two dimensional grids");
+     109             : 
+     110             :   // Get the type of FT
+     111           2 :   parse("FT_TYPE",output_type);
+     112           1 :   if (output_type.length()==0) {
+     113           0 :     log<<"  keyword FT_TYPE unset. By default output grid will contain REAL Fourier coefficients\n";
+     114           2 :   } else if ( output_type=="ABS" || output_type=="abs") {
+     115           0 :     log << "  keyword FT_TYPE is '"<< output_type << "' : will compute the MODULUS of Fourier coefficients\n";
+     116           2 :   } else if ( output_type=="NORM" || output_type=="norm") {
+     117           0 :     log << "  keyword FT_TYPE is '"<< output_type << "' : will compute the NORM of Fourier coefficients\n";
+     118           0 :     store_norm=true;
+     119           2 :   } else if ( output_type=="COMPLEX" || output_type=="complex" ) {
+     120           1 :     log<<"  keyword FT_TYPE is '"<< output_type <<"' : output grid will contain the COMPLEX Fourier coefficients\n";
+     121           1 :     real_output=false;
+     122           0 :   } else error("keyword FT_TYPE unrecognized!");
+     123             : 
+     124             :   // Normalize output?
+     125           2 :   std::string params_str; parse("FOURIER_PARAMETERS",params_str);
+     126           1 :   if (params_str=="default") {
+     127           0 :     fourier_params.assign( fourier_params.size(), 1 );
+     128           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]);
+     129             :   } else {
+     130           1 :     std::vector<std::string> fourier_str = Tools::getWords(params_str, "\t\n ,");
+     131           1 :     if (fourier_str.size()>2) error("FOURIER_PARAMETERS can take just two values");
+     132           3 :     for (unsigned i=0; i<fourier_str.size(); ++i) {
+     133           2 :       Tools::convert(fourier_str[i],fourier_params[i]);
+     134           2 :       if (fourier_params[i]>1 || fourier_params[i]<-1) error("values accepted for FOURIER_PARAMETERS are only -1, 1 or 0");
+     135             :     }
+     136           1 :     log.printf("  Fourier parameters are A=%i, B=%i \n", fourier_params[0],fourier_params[1]);
+     137           1 :   }
+     138             : 
+     139           1 :   std::vector<unsigned> shape( getPntrToArgument(0)->getRank() );
+     140           1 :   if (real_output) {
+     141           0 :     addValueWithDerivatives( shape );
+     142             :   } else {
+     143           1 :     addComponentWithDerivatives( "real", shape );
+     144           2 :     addComponentWithDerivatives( "imag", shape );
+     145             :   }
+     146             : 
+     147             :   unsigned dimension = getPntrToArgument(0)->getRank();
+     148           1 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     149           1 :   if( !ag ) error("input action should be a grid");
+     150           1 :   const gridtools::GridCoordinatesObject & gcoords( ag->getGridCoordinatesObject() );
+     151           2 :   if( gcoords.getGridType()=="fibonacci" ) error("cannot fourier transform fibonacci grids");
+     152           3 :   std::vector<bool> ipbc( dimension ); for(unsigned i=0; i<dimension; ++i) ipbc[i] = gcoords.isPeriodic(i);
+     153           2 :   gridcoords.setup( "flat", ipbc, 0, 0.0 ); checkRead();
+     154             : #ifndef __PLUMED_HAS_FFTW
+     155             :   error("this feature is only available if you compile PLUMED with FFTW");
+     156             : #endif
+     157           1 : }
+     158             : 
+     159           4 : unsigned FourierTransform::getNumberOfDerivatives() {
+     160           4 :   return 2;
+     161             : }
+     162             : 
+     163           7 : const gridtools::GridCoordinatesObject& FourierTransform::getGridCoordinatesObject() const {
+     164           7 :   return gridcoords;
+     165             : }
+     166             : 
+     167           2 : std::vector<std::string> FourierTransform::getGridCoordinateNames() const {
+     168           2 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     169           2 :   return ag->getGridCoordinateNames();
+     170             : }
+     171             : 
+     172           1 : void FourierTransform::calculate() {
+     173           1 :   if( firsttime ) {
+     174           1 :     gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     175           1 :     const gridtools::GridCoordinatesObject & gcoords( ag->getGridCoordinatesObject() );
+     176           1 :     std::vector<double> fspacing; std::vector<unsigned> snbins( getGridCoordinatesObject().getDimension() );
+     177           1 :     std::vector<std::string> smin( gcoords.getDimension() ), smax( gcoords.getDimension() );
+     178           3 :     for(unsigned i=0; i<getGridCoordinatesObject().getDimension(); ++i) {
+     179           6 :       smin[i]=gcoords.getMin()[i]; smax[i]=gcoords.getMax()[i];
+     180             :       // Compute k-grid extents
+     181           2 :       double dmin, dmax; snbins[i]=gcoords.getNbin(false)[i];
+     182           2 :       Tools::convert(smin[i],dmin); Tools::convert(smax[i],dmax);
+     183           2 :       dmax=2.0*pi*snbins[i]/( dmax - dmin ); dmin=0.0;
+     184           2 :       Tools::convert(dmin,smin[i]); Tools::convert(dmax,smax[i]);
+     185             :     }
+     186           1 :     gridcoords.setBounds( smin, smax, snbins, fspacing ); firsttime=false;
+     187           3 :     for(unsigned i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setShape( gcoords.getNbin(true) );
+     188           1 :   }
+     189             : 
+     190             : #ifdef __PLUMED_HAS_FFTW
+     191             :   // *** CHECK CORRECT k-GRID BOUNDARIES ***
+     192             :   //log<<"Real grid boundaries: \n"
+     193             :   //    <<"  min_x: "<<mygrid->getMin()[0]<<"  min_y: "<<mygrid->getMin()[1]<<"\n"
+     194             :   //    <<"  max_x: "<<mygrid->getMax()[0]<<"  max_y: "<<mygrid->getMax()[1]<<"\n"
+     195             :   //    <<"K-grid boundaries:"<<"\n"
+     196             :   //    <<"  min_x: "<<ft_min[0]<<"  min_y: "<<ft_min[1]<<"\n"
+     197             :   //    <<"  max_x: "<<ft_max[0]<<"  max_y: "<<ft_max[1]<<"\n";
+     198             : 
+     199             :   // Get the size of the input data arrays (to allocate FFT data)
+     200           1 :   std::vector<unsigned> N_input_data( gridcoords.getNbin(true) );
+     201           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] );
+     202             :   // FFT arrays
+     203           1 :   std::vector<std::complex<double> > input_data(fft_dimension), fft_data(fft_dimension);
+     204             : 
+     205             :   // Fill real input with the data on the grid
+     206             :   Value* arg=getPntrToArgument(0);
+     207           1 :   unsigned nargs=arg->getNumberOfValues();
+     208           1 :   std::vector<unsigned> ind( arg->getRank() );
+     209       10202 :   for (unsigned i=0; i<arg->getNumberOfValues(); ++i) {
+     210             :     // Get point indices
+     211       10201 :     gridcoords.getIndices(i, ind);
+     212             :     // Fill input data in row-major order
+     213       10201 :     input_data[ind[0]*N_input_data[0]+ind[1]].real( arg->get( i ) );
+     214       10201 :     input_data[ind[0]*N_input_data[0]+ind[1]].imag( 0.0 );
+     215             :   }
+     216             : 
+     217             :   // *** 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 ...
+     218           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);
+     219             : 
+     220             :   // Compute FT
+     221           1 :   fftw_execute( plan_complex );
+     222             : 
+     223             :   // Compute the normalization constant
+     224             :   double norm=1.0;
+     225           3 :   for (unsigned i=0; i<N_input_data.size(); ++i) {
+     226           2 :     norm *= pow( N_input_data[i], (1-fourier_params[0])/2 );
+     227             :   }
+     228             : 
+     229             :   // Save FT data to output grid
+     230           1 :   std::vector<unsigned> N_out_data ( getGridCoordinatesObject().getNbin(true) );
+     231           1 :   std::vector<unsigned> out_ind ( getPntrToArgument(0)->getRank() );
+     232       10202 :   for(unsigned i=0; i<getPntrToArgument(0)->getNumberOfValues(); ++i) {
+     233       10201 :     gridcoords.getIndices( i, out_ind );
+     234       10201 :     if (real_output) {
+     235             :       double ft_value;
+     236             :       // Compute abs/norm and fix normalization
+     237           0 :       if (!store_norm) ft_value=std::abs( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     238           0 :       else ft_value=std::norm( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     239             :       // Set the value
+     240           0 :       getPntrToComponent(0)->set( i, ft_value);
+     241             :     } else {
+     242             :       double ft_value_real, ft_value_imag;
+     243       10201 :       ft_value_real=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].real() / norm;
+     244       10201 :       ft_value_imag=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].imag() / norm;
+     245             :       // Set values
+     246       10201 :       getPntrToComponent(0)->set( i, ft_value_real );
+     247       10201 :       getPntrToComponent(1)->set( i, ft_value_imag );
+     248             :     }
+     249             :   }
+     250             : 
+     251             :   // Free FFTW stuff
+     252           1 :   fftw_destroy_plan(plan_complex);
+     253             : #endif
+     254           1 : }
+     255             : 
+     256             : } // end namespace 'gridtools'
+     257             : } // 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 000000000..27df54aac --- /dev/null +++ b/coverage/fourier/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - fourier + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourierHitTotalCoverage
Test:plumed test coverageLines:8710087.0 %
Date:2024-10-17 16:45:00Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FourierTransform.cpp +
87.0%87.0%
+
87.0 %87 / 10066.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 000000000..2823fe09e --- /dev/null +++ b/coverage/fourier/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - fourier + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourierHitTotalCoverage
Test:plumed test coverageLines:8710087.0 %
Date:2024-10-17 16:45:00Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FourierTransform.cpp +
87.0%87.0%
+
87.0 %87 / 10066.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 000000000..bb2a7e91d --- /dev/null +++ b/coverage/fourier/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - fourier + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourierHitTotalCoverage
Test:plumed test coverageLines:8710087.0 %
Date:2024-10-17 16:45:00Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FourierTransform.cpp +
87.0%87.0%
+
87.0 %87 / 10066.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 000000000..e18534f83 --- /dev/null +++ b/coverage/function/Bessel.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:343694.4 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Bessel22derivativesImplementedEv0
_ZN4PLMD8function6Bessel17fill_coefficientsEv7
_ZN4PLMD8function6Bessel4readEPNS_19ActionWithArgumentsE7
_ZNK4PLMD8function6Bessel4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE14
_ZNK4PLMD8function6Bessel6chbevlEdRSt6vectorIdSaIdEE14
_ZN4PLMD8function6Bessel16registerKeywordsERNS_8KeywordsE34
+
+
+ + + +
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 000000000..c88e60b97 --- /dev/null +++ b/coverage/function/Bessel.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:343694.4 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Bessel16registerKeywordsERNS_8KeywordsE34
_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 000000000..0b42d9e53 --- /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:343694.4 %
Date:2024-10-17 16:45:00Functions: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          48 : 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          34 : void Bessel::registerKeywords(Keywords& keys) {
+      86          68 :   keys.add("compulsory","ORDER","0","the order of Bessel function to use.  Can only be zero at the moment.");
+      87          34 :   keys.setValueDescription("the value of the bessel function");
+      88          34 : }
+      89             : 
+      90           7 : void Bessel::read( ActionWithArguments* action ) {
+      91           7 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to bessel actions");
+      92           7 :   if( action->getPntrToArgument(0)->isPeriodic() ) action->error("cannot use this function on periodic functions");
+      93          14 :   action->parse("ORDER",order); action->log.printf("  computing %dth order bessel function \n", order );
+      94           7 :   if( order!=0 ) action->error("only zero order bessel function is implemented");
+      95           7 :   fill_coefficients();
+      96           7 : }
+      97             : 
+      98          14 : double Bessel::chbevl(double x,std::vector<double>& array) const {
+      99             :   double b0, b1, b2;
+     100          14 :   int n = array.size();
+     101             : 
+     102          14 :   b0 = array[0];
+     103             :   b1 = 0.0;
+     104             :   b2 = b1 ;
+     105             : 
+     106         375 :   for(int index = 1 ; index < n ; index++) {
+     107             :     b2 = b1;
+     108             :     b1 = b0;
+     109         361 :     b0 = x * b1 - b2 + array[index];
+     110             :   }
+     111          14 :   return (0.5 * (b0 - b2));
+     112             : }
+     113             : 
+     114             : 
+     115          14 : void Bessel::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     116             :   plumed_dbg_assert( args.size()==1 );
+     117          14 :   if( order==0 ) {
+     118          14 :     double x = fabs(args[0]);
+     119          14 :     if (x <= 8.0) {
+     120           5 :       double y = (x / 2.0) - 2.0;
+     121           5 :       vals[0] =  chbevl(y, A) ;
+     122           5 :       return;
+     123             :     }
+     124           9 :     vals[0] = chbevl(32.0 / x - 2.0, B) / sqrt(x) ;
+     125           0 :   } else plumed_error();
+     126             : }
+     127             : 
+     128             : std::vector<double> Bessel::A;
+     129             : std::vector<double> Bessel::B;
+     130             : 
+     131           7 : void Bessel::fill_coefficients() {
+     132           7 :   A.resize(30);
+     133          14 :   A = {-4.41534164647933937950E-18,
+     134             :        3.33079451882223809783E-17,
+     135             :        -2.43127984654795469359E-16,
+     136             :        1.71539128555513303061E-15,
+     137             :        -1.16853328779934516808E-14,
+     138             :        7.67618549860493561688E-14,
+     139             :        -4.85644678311192946090E-13,
+     140             :        2.95505266312963983461E-12,
+     141             :        -1.72682629144155570723E-11,
+     142             :        9.67580903537323691224E-11,
+     143             :        -5.18979560163526290666E-10,
+     144             :        2.65982372468238665035E-9,
+     145             :        -1.30002500998624804212E-8,
+     146             :        6.04699502254191894932E-8,
+     147             :        -2.67079385394061173391E-7,
+     148             :        1.11738753912010371815E-6,
+     149             :        -4.41673835845875056359E-6,
+     150             :        1.64484480707288970893E-5,
+     151             :        -5.75419501008210370398E-5,
+     152             :        1.88502885095841655729E-4,
+     153             :        -5.76375574538582365885E-4,
+     154             :        1.63947561694133579842E-3,
+     155             :        -4.32430999505057594430E-3,
+     156             :        1.05464603945949983183E-2,
+     157             :        -2.37374148058994688156E-2,
+     158             :        4.93052842396707084878E-2,
+     159             :        -9.49010970480476444210E-2,
+     160             :        1.71620901522208775349E-1,
+     161             :        -3.04682672343198398683E-1,
+     162             :        6.76795274409476084995E-1
+     163           7 :       };
+     164           7 :   B.resize(25);
+     165          14 :   B = {-7.23318048787475395456E-18,
+     166             :        -4.83050448594418207126E-18,
+     167             :        4.46562142029675999901E-17,
+     168             :        3.46122286769746109310E-17,
+     169             :        -2.82762398051658348494E-16,
+     170             :        -3.42548561967721913462E-16,
+     171             :        1.77256013305652638360E-15,
+     172             :        3.81168066935262242075E-15,
+     173             :        -9.55484669882830764870E-15,
+     174             :        -4.15056934728722208663E-14,
+     175             :        1.54008621752140982691E-14,
+     176             :        3.85277838274214270114E-13,
+     177             :        7.18012445138366623367E-13,
+     178             :        -1.79417853150680611778E-12,
+     179             :        -1.32158118404477131188E-11,
+     180             :        -3.14991652796324136454E-11,
+     181             :        1.18891471078464383424E-11,
+     182             :        4.94060238822496958910E-10,
+     183             :        3.39623202570838634515E-9,
+     184             :        2.26666899049817806459E-8,
+     185             :        2.04891858946906374183E-7,
+     186             :        2.89137052083475648297E-6,
+     187             :        6.88975834691682398426E-5,
+     188             :        3.36911647825569408990E-3,
+     189             :        8.04490411014108831608E-1
+     190           7 :       };
+     191           7 : }
+     192             : 
+     193             : }
+     194             : }
+     195             : 
+     196             : 
+
+
+
+ + + + +
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 000000000..f6cb45e8d --- /dev/null +++ b/coverage/function/Between.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2626100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Between4readEPNS_19ActionWithArgumentsE53
_ZN4PLMD8function7Between16registerKeywordsERNS_8KeywordsE213
_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 000000000..9d88c043d --- /dev/null +++ b/coverage/function/Between.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2626100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Between16registerKeywordsERNS_8KeywordsE213
_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 000000000..6dfe5d11a --- /dev/null +++ b/coverage/function/Between.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + 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:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 "FunctionOfMatrix.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : //+PLUMEDOC FUNCTION BETWEEN
+      34             : /*
+      35             : Use a switching function to determine how many of the input variables are within a certain range.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC FUNCTION BETWEEN_VECTOR
+      43             : /*
+      44             : Use a switching function to determine how many of the input components are within a certain range
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : //+PLUMEDOC COLVAR BETWEEN_MATRIX
+      52             : /*
+      53             : Transform all the elements of a matrix using a switching function that is oen when the input value is within a particular range
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : typedef FunctionShortcut<Between> BetweenShortcut;
+      61             : PLUMED_REGISTER_ACTION(BetweenShortcut,"BETWEEN")
+      62             : typedef FunctionOfVector<Between> VectorBetween;
+      63             : PLUMED_REGISTER_ACTION(VectorBetween,"BETWEEN_VECTOR")
+      64             : typedef FunctionOfMatrix<Between> MatrixBetween;
+      65             : PLUMED_REGISTER_ACTION(MatrixBetween,"BETWEEN_MATRIX")
+      66             : 
+      67         213 : void Between::registerKeywords(Keywords& keys) {
+      68         426 :   keys.add("compulsory","LOWER","the lower boundary for this particular bin");
+      69         426 :   keys.add("compulsory","UPPER","the upper boundary for this particular bin");
+      70         426 :   keys.add("compulsory","SMEAR","0.5","the ammount to smear the Gaussian for each value in the distribution");
+      71         426 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous function defined above. "
+      72             :            "The following provides information on the \\ref histogrambead that are available. "
+      73             :            "When this keyword is present you no longer need the LOWER, UPPER, SMEAR and KERNEL keywords.");
+      74         213 :   keys.setValueDescription("a function that is one if the input falls within a particular range and zero otherwise");
+      75         213 : }
+      76             : 
+      77          53 : void Between::read( ActionWithArguments* action ) {
+      78          53 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to between actions");
+      79             : 
+      80             :   std::string str_min, str_max, tstr_min, tstr_max;
+      81          53 :   bool isPeriodic = action->getPntrToArgument(0)->isPeriodic();
+      82          53 :   if( isPeriodic ) action->getPntrToArgument(0)->getDomain( str_min, str_max );
+      83             : 
+      84         106 :   std::string hinput; action->parse("SWITCH",hinput);
+      85          53 :   if(hinput.length()==0) {
+      86             :     std::string low, up, sme;
+      87          15 :     action->parse("LOWER",low); action->parse("UPPER",up); action->parse("SMEAR",sme);
+      88          10 :     hinput = "GAUSSIAN LOWER=" + low + " UPPER=" + up + " SMEAR=" + sme;
+      89             :   }
+      90          53 :   std::string errors; hist.set( hinput, errors );
+      91          53 :   if( errors.size()!=0 ) action->error( errors );
+      92          53 :   action->log.printf("  %s \n", hist.description().c_str() );
+      93             : 
+      94          53 :   if( !isPeriodic ) hist.isNotPeriodic();
+      95             :   else {
+      96           1 :     double min; Tools::convert( str_min, min );
+      97           1 :     double max; Tools::convert( str_max, max );
+      98           1 :     hist.isPeriodic( min, max );
+      99             :   }
+     100          53 : }
+     101             : 
+     102       49226 : void Between::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     103       49226 :   plumed_dbg_assert( args.size()==1 ); vals[0] = hist.calculate( args[0], derivatives(0,0) );
+     104       49226 : }
+     105             : 
+     106             : }
+     107             : }
+     108             : 
+     109             : 
+
+
+
+ + + + +
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 000000000..2a82393eb --- /dev/null +++ b/coverage/function/Between.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..96d8a2ead --- /dev/null +++ b/coverage/function/Between.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..096f05a68 --- /dev/null +++ b/coverage/function/Between.h.gcov.html @@ -0,0 +1,118 @@ + + + + + + + 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-10-17 16:45:00Functions: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         319 : 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 000000000..fdee8a996 --- /dev/null +++ b/coverage/function/Combine.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Combine4readEPNS_19ActionWithArgumentsE305
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE1069
_ZNK4PLMD8function7Combine4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE4369194
+
+
+ + + +
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 000000000..4dbf475e4 --- /dev/null +++ b/coverage/function/Combine.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE1069
_ZN4PLMD8function7Combine4readEPNS_19ActionWithArgumentsE305
_ZNK4PLMD8function7Combine4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE4369194
+
+
+ + + +
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 000000000..7678863c3 --- /dev/null +++ b/coverage/function/Combine.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + 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:3434100.0 %
Date:2024-10-17 16:45:00Functions: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 "FunctionOfMatrix.h"
+      28             : #include "core/ActionRegister.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : //+PLUMEDOC FUNCTION COMBINE
+      34             : /*
+      35             : Calculate a polynomial combination of a set of other variables.
+      36             : 
+      37             : The functional form of this function is
+      38             : \f[
+      39             : C=\sum_{i=1}^{N_{arg}} c_i (x_i-a_i)^{p_i}
+      40             : \f]
+      41             : 
+      42             : The coefficients c, the parameters a and the powers p are provided as vectors.
+      43             : 
+      44             : Notice that COMBINE is not able to predict which will be periodic domain
+      45             : of the computed value automatically. The user is thus forced to specify it
+      46             : explicitly. Use PERIODIC=NO if the resulting variable is not periodic,
+      47             : and PERIODIC=A,B where A and B are the two boundaries if the resulting variable
+      48             : is periodic.
+      49             : 
+      50             : 
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following input tells plumed to print the distance between atoms 3 and 5
+      55             : its square (as computed from the x,y,z components) and the distance
+      56             : again as computed from the square root of the square.
+      57             : \plumedfile
+      58             : DISTANCE LABEL=dist      ATOMS=3,5 COMPONENTS
+      59             : COMBINE  LABEL=distance2 ARG=dist.x,dist.y,dist.z POWERS=2,2,2 PERIODIC=NO
+      60             : COMBINE  LABEL=distance  ARG=distance2 POWERS=0.5 PERIODIC=NO
+      61             : PRINT ARG=distance,distance2
+      62             : \endplumedfile
+      63             : (See also \ref PRINT and \ref DISTANCE).
+      64             : 
+      65             : The following input tells plumed to add a restraint on the
+      66             : cube of a dihedral angle. Notice that since the angle has a
+      67             : periodic domain
+      68             : -pi,pi its cube has a domain -pi**3,pi**3.
+      69             : \plumedfile
+      70             : t: TORSION ATOMS=1,3,5,7
+      71             : c: COMBINE ARG=t POWERS=3 PERIODIC=-31.0062766802998,31.0062766802998
+      72             : RESTRAINT ARG=c KAPPA=10 AT=0
+      73             : \endplumedfile
+      74             : 
+      75             : 
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : //+PLUMEDOC FUNCTION COMBINE_SCALAR
+      81             : /*
+      82             : Calculate a polynomial combination of a set of other variables.
+      83             : 
+      84             : \par Examples
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : //+PLUMEDOC FUNCTION COMBINE_VECTOR
+      90             : /*
+      91             : Add together the elements of a set of vectors elementwise
+      92             : 
+      93             : \par Examples
+      94             : 
+      95             : */
+      96             : //+ENDPLUMEDOC
+      97             : 
+      98             : //+PLUMEDOC COLVAR COMBINE_MATRIX
+      99             : /*
+     100             : Calculate the sum of a number of matrices
+     101             : 
+     102             : \par Examples
+     103             : 
+     104             : */
+     105             : //+ENDPLUMEDOC
+     106             : 
+     107             : typedef FunctionShortcut<Combine> CombineShortcut;
+     108             : PLUMED_REGISTER_ACTION(CombineShortcut,"COMBINE")
+     109             : typedef FunctionOfScalar<Combine> ScalarCombine;
+     110             : PLUMED_REGISTER_ACTION(ScalarCombine,"COMBINE_SCALAR")
+     111             : typedef FunctionOfVector<Combine> VectorCombine;
+     112             : PLUMED_REGISTER_ACTION(VectorCombine,"COMBINE_VECTOR")
+     113             : typedef FunctionOfMatrix<Combine> MatrixCombine;
+     114             : PLUMED_REGISTER_ACTION(MatrixCombine,"COMBINE_MATRIX")
+     115             : 
+     116        1069 : void Combine::registerKeywords(Keywords& keys) {
+     117        1069 :   keys.use("PERIODIC");
+     118        2138 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients of the arguments in your function");
+     119        2138 :   keys.add("compulsory","PARAMETERS","0.0","the parameters of the arguments in your function");
+     120        2138 :   keys.add("compulsory","POWERS","1.0","the powers to which you are raising each of the arguments in your function");
+     121        2138 :   keys.addFlag("NORMALIZE",false,"normalize all the coefficients so that in total they are equal to one");
+     122        1069 :   keys.setValueDescription("a linear compbination");
+     123        1069 : }
+     124             : 
+     125         305 : void Combine::read( ActionWithArguments* action ) {
+     126         305 :   coefficients.resize( action->getNumberOfArguments() ); parameters.resize( action->getNumberOfArguments() ); powers.resize( action->getNumberOfArguments() );
+     127         609 :   parseVector(action,"COEFFICIENTS",coefficients);
+     128         304 :   if(coefficients.size()!=static_cast<unsigned>(action->getNumberOfArguments())) action->error("Size of COEFFICIENTS array should be the same as number for arguments");
+     129         607 :   parseVector(action,"PARAMETERS",parameters);
+     130         303 :   if(parameters.size()!=static_cast<unsigned>(action->getNumberOfArguments())) action->error("Size of PARAMETERS array should be the same as number for arguments");
+     131         605 :   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");
+     132             : 
+     133         302 :   parseFlag(action,"NORMALIZE",normalize);
+     134         302 :   if(normalize) {
+     135             :     double n=0.0;
+     136          43 :     for(unsigned i=0; i<coefficients.size(); i++) n+=coefficients[i];
+     137          43 :     for(unsigned i=0; i<coefficients.size(); i++) coefficients[i]*=(1.0/n);
+     138             :   }
+     139             : 
+     140         302 :   action->log.printf("  with coefficients:");
+     141        1503 :   for(unsigned i=0; i<coefficients.size(); i++) action->log.printf(" %f",coefficients[i]);
+     142         302 :   action->log.printf("\n  with parameters:");
+     143        1503 :   for(unsigned i=0; i<parameters.size(); i++) action->log.printf(" %f",parameters[i]);
+     144         302 :   action->log.printf("\n  and powers:");
+     145        1503 :   for(unsigned i=0; i<powers.size(); i++) action->log.printf(" %f",powers[i]);
+     146         302 :   action->log.printf("\n");
+     147         302 : }
+     148             : 
+     149     4369194 : void Combine::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     150     4369194 :   vals[0]=0.0;
+     151    10983373 :   for(unsigned i=0; i<coefficients.size(); ++i) {
+     152     6614179 :     double cv = action->difference( i, parameters[i], args[i] );
+     153     6614179 :     vals[0] += coefficients[i]*pow( cv, powers[i] );
+     154     6614179 :     derivatives(0,i) = coefficients[i]*powers[i]*pow(cv,powers[i]-1.0);
+     155             :   }
+     156     4369194 : }
+     157             : 
+     158             : }
+     159             : }
+     160             : 
+     161             : 
+
+
+
+ + + + +
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 000000000..ba8251ddb --- /dev/null +++ b/coverage/function/Combine.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ad23177e5 --- /dev/null +++ b/coverage/function/Combine.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b0a41d01d --- /dev/null +++ b/coverage/function/Combine.h.gcov.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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        1679 : 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 000000000..ec29eb64a --- /dev/null +++ b/coverage/function/Custom.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:6565100.0 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function6Custom12getGraphInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD8function6Custom19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE966
_ZNK4PLMD8function6Custom30getDerivativeZeroIfValueIsZeroEv1819
_ZN4PLMD8function6Custom4readEPNS_19ActionWithArgumentsE2991
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE10764
_ZNK4PLMD8function6Custom4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE20476599
+
+
+ + + +
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 000000000..807d35cdc --- /dev/null +++ b/coverage/function/Custom.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:6565100.0 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE10764
_ZN4PLMD8function6Custom19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE966
_ZN4PLMD8function6Custom4readEPNS_19ActionWithArgumentsE2991
_ZNK4PLMD8function6Custom12getGraphInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZNK4PLMD8function6Custom30getDerivativeZeroIfValueIsZeroEv1819
_ZNK4PLMD8function6Custom4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE20476599
+
+
+ + + +
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 000000000..d74eed32c --- /dev/null +++ b/coverage/function/Custom.cpp.gcov.html @@ -0,0 +1,445 @@ + + + + + + + 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:6565100.0 %
Date:2024-10-17 16:45:00Functions: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 "FunctionOfMatrix.h"
+      28             : #include "tools/OpenMP.h"
+      29             : #include "tools/LeptonCall.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace function {
+      33             : 
+      34             : //+PLUMEDOC FUNCTION CUSTOM
+      35             : /*
+      36             : Calculate a combination of variables using a custom expression.
+      37             : 
+      38             : This action computes an  arbitrary function of one or more
+      39             : collective variables. Arguments are chosen with the ARG keyword,
+      40             : and the function is provided with the FUNC string. Notice that this
+      41             : string should contain no space. Within FUNC, one can refer to the
+      42             : arguments as x,y,z, and t (up to four variables provided as ARG).
+      43             : This names can be customized using the VAR keyword (see examples below).
+      44             : 
+      45             : This function is implemented using the Lepton library, that allows to evaluate
+      46             : algebraic expressions and to automatically differentiate them.
+      47             : 
+      48             : If you want a function that depends not only on collective variables
+      49             : but also on time you can use the \subpage TIME action.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : The following input tells plumed to perform a metadynamics
+      54             : using as a CV the difference between two distances.
+      55             : \plumedfile
+      56             : dAB: DISTANCE ATOMS=10,12
+      57             : dAC: DISTANCE ATOMS=10,15
+      58             : diff: CUSTOM ARG=dAB,dAC FUNC=y-x PERIODIC=NO
+      59             : # notice: the previous line could be replaced with the following
+      60             : # diff: COMBINE ARG=dAB,dAC COEFFICIENTS=-1,1
+      61             : METAD ARG=diff SIGMA=0.1 HEIGHT=0.5 BIASFACTOR=10 PACE=100
+      62             : \endplumedfile
+      63             : (see also \ref DISTANCE, \ref COMBINE, and \ref METAD).
+      64             : Notice that forces applied to diff will be correctly propagated
+      65             : to atoms 10, 12, and 15.
+      66             : Also notice that since CUSTOM is used without the VAR option
+      67             : the two arguments should be referred to as x and y in the expression FUNC.
+      68             : For simple functions
+      69             : such as this one it is possible to use \ref COMBINE.
+      70             : 
+      71             : The following input tells plumed to print the angle between vectors
+      72             : identified by atoms 1,2 and atoms 2,3
+      73             : its square (as computed from the x,y,z components) and the distance
+      74             : again as computed from the square root of the square.
+      75             : \plumedfile
+      76             : DISTANCE LABEL=d1 ATOMS=1,2 COMPONENTS
+      77             : DISTANCE LABEL=d2 ATOMS=2,3 COMPONENTS
+      78             : CUSTOM ...
+      79             :   LABEL=theta
+      80             :   ARG=d1.x,d1.y,d1.z,d2.x,d2.y,d2.z
+      81             :   VAR=ax,ay,az,bx,by,bz
+      82             :   FUNC=acos((ax*bx+ay*by+az*bz)/sqrt((ax*ax+ay*ay+az*az)*(bx*bx+by*by+bz*bz)))
+      83             :   PERIODIC=NO
+      84             : ... CUSTOM
+      85             : PRINT ARG=theta
+      86             : \endplumedfile
+      87             : (See also \ref PRINT and \ref DISTANCE).
+      88             : 
+      89             : Notice that this action implements a large number of functions (trigonometric, exp, log, etc).
+      90             : Among the useful functions, have a look at the step function (that is the Heaviside function).
+      91             : `step(x)` is defined as 1 when `x` is positive and `0` when x is negative. This allows for
+      92             : a straightforward implementation of if clauses.
+      93             : 
+      94             : For example, imagine that you want to implement a restraint that only acts when a
+      95             : distance is larger than 0.5. You can do it with
+      96             : \plumedfile
+      97             : d: DISTANCE ATOMS=10,15
+      98             : m: CUSTOM ARG=d FUNC=0.5*step(0.5-x)+x*step(x-0.5) PERIODIC=NO
+      99             : # check the function you are applying:
+     100             : PRINT ARG=d,m FILE=checkme
+     101             : RESTRAINT ARG=d AT=0.5 KAPPA=10.0
+     102             : \endplumedfile
+     103             : (see also \ref DISTANCE, \ref PRINT, and \ref RESTRAINT)
+     104             : 
+     105             : The meaning of the function `0.5*step(0.5-x)+x*step(x-0.5)` is:
+     106             : - If x<0.5 (step(0.5-x)!=0) use 0.5
+     107             : - If x>0.5 (step(x-0.5)!=0) use x
+     108             : Notice that the same could have been obtained using an \ref UPPER_WALLS
+     109             : However, with CUSTOM you can create way more complex definitions.
+     110             : 
+     111             : \warning If you apply forces on the variable (as in the previous example) you should
+     112             : make sure that the variable is continuous!
+     113             : Conversely, if you are just analyzing a trajectory you can safely use
+     114             : discontinuous variables.
+     115             : 
+     116             : A possible continuity check with gnuplot is
+     117             : \verbatim
+     118             : # this allow to step function to be used in gnuplot:
+     119             : gnuplot> step(x)=0.5*(erf(x*10000000)+1)
+     120             : # here you can test your function
+     121             : gnuplot> p 0.5*step(0.5-x)+x*step(x-0.5)
+     122             : \endverbatim
+     123             : 
+     124             : Also notice that you can easily make logical operations on the conditions that you
+     125             : create. The equivalent of the AND operator is the product: `step(1.0-x)*step(x-0.5)` is
+     126             : 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,
+     127             : `1-step(1.0-x)*step(x-0.5)` is only equal to 1 when x is outside the 0.5-1.0 interval.
+     128             : 
+     129             : CUSTOM can be used in combination with \ref DISTANCE to implement variants of the
+     130             : DISTANCE keyword that were present in PLUMED 1.3 and that allowed to compute
+     131             : the distance of a point from a line defined by two other points, or the progression
+     132             : along that line.
+     133             : \plumedfile
+     134             : # take center of atoms 1 to 10 as reference point 1
+     135             : p1: CENTER ATOMS=1-10
+     136             : # take center of atoms 11 to 20 as reference point 2
+     137             : p2: CENTER ATOMS=11-20
+     138             : # take center of atoms 21 to 30 as reference point 3
+     139             : p3: CENTER ATOMS=21-30
+     140             : 
+     141             : # compute distances
+     142             : d12: DISTANCE ATOMS=p1,p2
+     143             : d13: DISTANCE ATOMS=p1,p3
+     144             : d23: DISTANCE ATOMS=p2,p3
+     145             : 
+     146             : # compute progress variable of the projection of point p3
+     147             : # along the vector joining p1 and p2
+     148             : # notice that progress is measured from the middle point
+     149             : onaxis: CUSTOM ARG=d13,d23,d12 FUNC=(0.5*(y^2-x^2)/z) PERIODIC=NO
+     150             : 
+     151             : # compute between point p3 and the vector joining p1 and p2
+     152             : 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
+     153             : 
+     154             : PRINT ARG=onaxis,fromaxis
+     155             : 
+     156             : \endplumedfile
+     157             : 
+     158             : Notice that these equations have been used to combine \ref RMSD
+     159             : from different snapshots of a protein so as to define
+     160             : progression (S) and distance (Z) variables \cite perez2015atp.
+     161             : 
+     162             : 
+     163             : */
+     164             : //+ENDPLUMEDOC
+     165             : 
+     166             : //+PLUMEDOC FUNCTION MATHEVAL_SCALAR
+     167             : /*
+     168             : Calculate a function of a set of input scalars
+     169             : 
+     170             : See \ref MATHEVAL
+     171             : 
+     172             : \par Examples
+     173             : 
+     174             : */
+     175             : //+ENDPLUMEDOC
+     176             : 
+     177             : //+PLUMEDOC FUNCTION CUSTOM_SCALAR
+     178             : /*
+     179             : Calculate a function of a set of input scalars
+     180             : 
+     181             : See \ref CUSTOM
+     182             : 
+     183             : \par Examples
+     184             : 
+     185             : */
+     186             : //+ENDPLUMEDOC
+     187             : 
+     188             : //+PLUMEDOC FUNCTION MATHEVAL_VECTOR
+     189             : /*
+     190             : Calculate a function of a set of input vectors elementwise
+     191             : 
+     192             : See \ref MATHEVAL
+     193             : 
+     194             : \par Examples
+     195             : 
+     196             : */
+     197             : //+ENDPLUMEDOC
+     198             : 
+     199             : //+PLUMEDOC FUNCTION CUSTOM_VECTOR
+     200             : /*
+     201             : Calculate a function of a set of input vectors elementwise
+     202             : 
+     203             : See \ref CUSTOM
+     204             : 
+     205             : \par Examples
+     206             : 
+     207             : */
+     208             : //+ENDPLUMEDOC
+     209             : 
+     210             : //+PLUMEDOC COLVAR CUSTOM_MATRIX
+     211             : /*
+     212             : Calculate an arbitrary function piecewise for one or multiple input matrices.
+     213             : 
+     214             : \par Examples
+     215             : 
+     216             : */
+     217             : //+ENDPLUMEDOC
+     218             : 
+     219             : //+PLUMEDOC COLVAR MATHEVAL_MATRIX
+     220             : /*
+     221             : Calculate an arbitrary function piecewise for one or multiple input matrices.
+     222             : 
+     223             : \par Examples
+     224             : 
+     225             : */
+     226             : //+ENDPLUMEDOC
+     227             : 
+     228             : typedef FunctionShortcut<Custom> CustomShortcut;
+     229             : PLUMED_REGISTER_ACTION(CustomShortcut,"CUSTOM")
+     230             : PLUMED_REGISTER_ACTION(CustomShortcut,"MATHEVAL")
+     231             : typedef FunctionOfScalar<Custom> ScalarCustom;
+     232             : PLUMED_REGISTER_ACTION(ScalarCustom,"CUSTOM_SCALAR")
+     233             : PLUMED_REGISTER_ACTION(ScalarCustom,"MATHEVAL_SCALAR")
+     234             : typedef FunctionOfVector<Custom> VectorCustom;
+     235             : PLUMED_REGISTER_ACTION(VectorCustom,"CUSTOM_VECTOR")
+     236             : PLUMED_REGISTER_ACTION(VectorCustom,"MATHEVAL_VECTOR")
+     237             : typedef FunctionOfMatrix<Custom> MatrixCustom;
+     238             : PLUMED_REGISTER_ACTION(MatrixCustom,"CUSTOM_MATRIX")
+     239             : PLUMED_REGISTER_ACTION(MatrixCustom,"MATHEVAL_MATRIX")
+     240             : 
+     241             : //+PLUMEDOC FUNCTION MATHEVAL
+     242             : /*
+     243             : An alias to the CUSTOM function that can also be used to calaculate combinations of variables using a custom expression.
+     244             : 
+     245             : Documentation for this action is identical to that for \ref CUSTOM
+     246             : 
+     247             : This alias is kept in order to maintain compatibility with previous PLUMED versions.
+     248             : However, notice that as of PLUMED 2.5 the libmatheval library is not linked anymore,
+     249             : and the \ref MATHEVAL function is implemented using the Lepton library.
+     250             : 
+     251             : \par Examples
+     252             : 
+     253             : Just replace \ref CUSTOM with \ref MATHEVAL.
+     254             : 
+     255             : \plumedfile
+     256             : d: DISTANCE ATOMS=10,15
+     257             : m: MATHEVAL ARG=d FUNC=0.5*step(0.5-x)+x*step(x-0.5) PERIODIC=NO
+     258             : # check the function you are applying:
+     259             : PRINT ARG=d,m FILE=checkme
+     260             : RESTRAINT ARG=d AT=0.5 KAPPA=10.0
+     261             : \endplumedfile
+     262             : (see also \ref DISTANCE, \ref PRINT, and \ref RESTRAINT)
+     263             : 
+     264             : */
+     265             : //+ENDPLUMEDOC
+     266             : 
+     267       10764 : void Custom::registerKeywords(Keywords& keys) {
+     268       10764 :   keys.use("PERIODIC");
+     269       21528 :   keys.add("compulsory","FUNC","the function you wish to evaluate");
+     270       21528 :   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.");
+     271       10764 :   keys.setValueDescription("an arbitrary function");
+     272       10764 : }
+     273             : 
+     274        2991 : void Custom::read( ActionWithArguments* action ) {
+     275             :   // Read in the variables
+     276        8973 :   std::vector<std::string> var; parseVector(action,"VAR",var); parse(action,"FUNC",func);
+     277        2991 :   if(var.size()==0) {
+     278        2932 :     var.resize(action->getNumberOfArguments());
+     279        2932 :     if(var.size()>3) action->error("Using more than 3 arguments you should explicitly write their names with VAR");
+     280        2932 :     if(var.size()>0) var[0]="x";
+     281        2932 :     if(var.size()>1) var[1]="y";
+     282        2932 :     if(var.size()>2) var[2]="z";
+     283             :   }
+     284        2991 :   if(var.size()!=action->getNumberOfArguments()) action->error("Size of VAR array should be the same as number of arguments");
+     285             :   // Check for operations that are not multiplication (this can probably be done much more cleverly)
+     286        2991 :   bool onlymultiplication = func.find("*")!=std::string::npos;
+     287             :   // Find first bracket in expression
+     288        2991 :   if( func.find("(")!=std::string::npos ) {
+     289        1591 :     std::size_t br = func.find_first_of("("); std::string subexpr=func.substr(0,br); onlymultiplication = func.find("*")!=std::string::npos;
+     290        1591 :     if( subexpr.find("/")!=std::string::npos ) { std::size_t sl = func.find_first_of("/"); std::string aa = subexpr.substr(0,sl); subexpr=aa; }
+     291        1591 :     if( subexpr.find("+")!=std::string::npos || subexpr.find("-")!=std::string::npos ) onlymultiplication=false;
+     292             :     // Now work out which vars are in multiplication
+     293        1484 :     if( onlymultiplication ) {
+     294        2293 :       for(unsigned i=0; i<var.size(); ++i) {
+     295        1451 :         if( subexpr.find(var[i])!=std::string::npos &&
+     296         316 :             action->getPntrToArgument(i)->isDerivativeZeroWhenValueIsZero() ) check_multiplication_vars.push_back(i);
+     297             :       }
+     298             :     }
+     299        1400 :   } else if( func.find("/")!=std::string::npos ) {
+     300         821 :     onlymultiplication=true; if( func.find("+")!=std::string::npos || func.find("-")!=std::string::npos ) onlymultiplication=false;
+     301             :     if( onlymultiplication ) {
+     302         820 :       std::size_t br = func.find_first_of("/"); std::string subexpr=func.substr(0,br);
+     303        2280 :       for(unsigned i=0; i<var.size(); ++i) {
+     304        1460 :         if( subexpr.find(var[i])!=std::string::npos &&
+     305          31 :             action->getPntrToArgument(i)->isDerivativeZeroWhenValueIsZero() ) check_multiplication_vars.push_back(i);
+     306             :       }
+     307             :     }
+     308         579 :   } else if( func.find("+")!=std::string::npos || func.find("-")!=std::string::npos ) {
+     309             :     onlymultiplication=false;
+     310             :   } else {
+     311        1028 :     for(unsigned i=0; i<var.size(); ++i) {
+     312         624 :       if( action->getPntrToArgument(i)->isDerivativeZeroWhenValueIsZero() ) check_multiplication_vars.push_back(i);
+     313             :     }
+     314             :   }
+     315        2991 :   if( check_multiplication_vars.size()>0 ) {
+     316         451 :     action->log.printf("  optimizing implementation as function only involves multiplication \n");
+     317             :   }
+     318             : 
+     319        2991 :   action->log.printf("  with function : %s\n",func.c_str());
+     320        2991 :   action->log.printf("  with variables :");
+     321        7799 :   for(unsigned i=0; i<var.size(); i++) action->log.printf(" %s",var[i].c_str());
+     322        2991 :   action->log.printf("\n"); function.set( func, var, action );
+     323        2991 :   std::vector<double> zeros( action->getNumberOfArguments(), 0 ); double fval = abs(function.evaluate(zeros));
+     324        2991 :   zerowhenallzero=(fval<epsilon );
+     325        2991 :   if( zerowhenallzero ) action->log.printf("  not calculating when all arguments are zero \n");
+     326        2991 : }
+     327             : 
+     328           5 : std::string Custom::getGraphInfo( const std::string& name ) const {
+     329          10 :   return FunctionTemplateBase::getGraphInfo( name ) + + "\n" + "FUNC=" + func;
+     330             : }
+     331             : 
+     332        1819 : bool Custom::getDerivativeZeroIfValueIsZero() const {
+     333        1819 :   return check_multiplication_vars.size()>0;
+     334             : }
+     335             : 
+     336         966 : std::vector<Value*> Custom::getArgumentsToCheck( const std::vector<Value*>& args ) {
+     337         966 :   std::vector<Value*> fargs( check_multiplication_vars.size() );
+     338        2093 :   for(unsigned i=0; i<check_multiplication_vars.size(); ++i) fargs[i] = args[check_multiplication_vars[i]];
+     339         966 :   return fargs;
+     340             : }
+     341             : 
+     342    20476599 : void Custom::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     343    20476599 :   if( args.size()>1 ) {
+     344             :     bool allzero=false;
+     345    15780962 :     if( check_multiplication_vars.size()>0 ) {
+     346    17313345 :       for(unsigned i=0; i<check_multiplication_vars.size(); ++i) {
+     347    10885579 :         if( fabs(args[check_multiplication_vars[i]])<epsilon ) { allzero=true; break; }
+     348             :       }
+     349     5142171 :     } else if( zerowhenallzero ) {
+     350     2860794 :       allzero=(fabs(args[0])<epsilon);
+     351     3296324 :       for(unsigned i=1; i<args.size(); ++i) {
+     352     3151815 :         if( fabs(args[i])>epsilon ) { allzero=false; break; }
+     353             :       }
+     354             :     }
+     355    13499585 :     if( allzero ) {
+     356    13352933 :       vals[0]=0; for(unsigned i=0; i<args.size(); i++) derivatives(0,i) = 0.0;
+     357             :       return;
+     358             :     }
+     359             :   }
+     360    16125005 :   vals[0] = function.evaluate( args );
+     361    16125005 :   if( !noderiv ) {
+     362    47275437 :     for(unsigned i=0; i<args.size(); i++) derivatives(0,i) = function.evaluateDeriv( i, args );
+     363             :   }
+     364             : }
+     365             : 
+     366             : }
+     367             : }
+     368             : 
+     369             : 
+
+
+
+ + + + +
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 000000000..a29ab2037 --- /dev/null +++ b/coverage/function/Ensemble.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:8013260.6 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8function8Ensemble29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_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 000000000..10882d78d --- /dev/null +++ b/coverage/function/Ensemble.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:8013260.6 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8function8Ensemble9calculateEv125
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8function8Ensemble29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
+
+
+ + + +
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 000000000..5d23c9576 --- /dev/null +++ b/coverage/function/Ensemble.cpp.gcov.html @@ -0,0 +1,349 @@ + + + + + + + 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:8013260.6 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "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             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      67             :   void     calculate() override;
+      68             :   static void registerKeywords(Keywords& keys);
+      69             : };
+      70             : 
+      71             : 
+      72             : PLUMED_REGISTER_ACTION(Ensemble,"ENSEMBLE")
+      73             : 
+      74          29 : void Ensemble::registerKeywords(Keywords& keys) {
+      75          29 :   Function::registerKeywords(keys);
+      76          29 :   keys.use("ARG");
+      77          58 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+      78          58 :   keys.addFlag("CENTRAL",false,"calculate a central moment instead of a standard moment");
+      79          58 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are reweighting");
+      80          58 :   keys.add("optional","MOMENT","the moment you want to calculate in alternative to the mean or the variance");
+      81          58 :   keys.add("optional","POWER","the power of the mean (and moment)");
+      82          29 :   ActionWithValue::useCustomisableComponents(keys);
+      83          29 : }
+      84             : 
+      85          27 : Ensemble::Ensemble(const ActionOptions&ao):
+      86             :   Action(ao),
+      87             :   Function(ao),
+      88          27 :   do_reweight(false),
+      89          27 :   do_moments(false),
+      90          27 :   do_central(false),
+      91          27 :   do_powers(false),
+      92          27 :   kbt(-1.0),
+      93          27 :   moment(0),
+      94          27 :   power(0)
+      95             : {
+      96          27 :   parseFlag("REWEIGHT", do_reweight);
+      97          27 :   if(do_reweight) {
+      98          12 :     kbt=getkBT();
+      99          12 :     if(kbt==0.0) error("Unless the MD engine passes the temperature to plumed, with REWEIGHT you must specify TEMP");
+     100          30 :   } else { double temp=0.0; parse("TEMP",temp); }
+     101             : 
+     102          27 :   parse("MOMENT",moment);
+     103          27 :   if(moment==1) error("MOMENT can be any number but for 0 and 1");
+     104          27 :   if(moment!=0) do_moments=true;
+     105          27 :   parseFlag("CENTRAL", do_central);
+     106          27 :   if(!do_moments&&do_central) error("To calculate a CENTRAL moment you need to define for which MOMENT");
+     107             : 
+     108          27 :   parse("POWER",power);
+     109          27 :   if(power==1) error("POWER can be any number but for 0 and 1");
+     110          27 :   if(power!=0) do_powers=true;
+     111             : 
+     112          27 :   checkRead();
+     113             : 
+     114          27 :   master = (comm.Get_rank()==0);
+     115          27 :   ens_dim=0;
+     116          27 :   my_repl=0;
+     117          27 :   if(master) {
+     118          17 :     ens_dim=multi_sim_comm.Get_size();
+     119          17 :     my_repl=multi_sim_comm.Get_rank();
+     120             :   }
+     121          27 :   comm.Bcast(ens_dim,0);
+     122          27 :   comm.Bcast(my_repl,0);
+     123          27 :   if(ens_dim<2) log.printf("WARNING: ENSEMBLE with one replica is not doing any averaging!\n");
+     124             : 
+     125             :   // prepare output components, the number depending on reweighing or not
+     126          27 :   narg = getNumberOfArguments();
+     127          27 :   if(do_reweight) narg--;
+     128             : 
+     129             :   // these are the averages
+     130        3044 :   for(unsigned i=0; i<narg; i++) {
+     131        3017 :     std::string s=getPntrToArgument(i)->getName();
+     132        3017 :     addComponentWithDerivatives(s);
+     133        3017 :     getPntrToComponent(i)->setNotPeriodic();
+     134             :   }
+     135             :   // these are the moments
+     136          27 :   if(do_moments) {
+     137           0 :     for(unsigned i=0; i<narg; i++) {
+     138           0 :       std::string s=getPntrToArgument(i)->getName()+"_m";
+     139           0 :       addComponentWithDerivatives(s);
+     140           0 :       getPntrToComponent(i+narg)->setNotPeriodic();
+     141             :     }
+     142             :   }
+     143             : 
+     144          27 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     145          27 :   if(do_reweight) log.printf("  doing simple REWEIGHT using the latest ARGUMENT as energy.\n");
+     146          27 :   if(do_moments&&!do_central)  log.printf("  calculating also the %lf standard moment\n", moment);
+     147          27 :   if(do_moments&&do_central)   log.printf("  calculating also the %lf central moment\n", moment);
+     148          27 :   if(do_powers)                log.printf("  calculating the %lf power of the mean (and moment)\n", power);
+     149          27 : }
+     150             : 
+     151           0 : std::string Ensemble::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     152           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     153           0 :     if( cname==getPntrToArgument(i)->getName() ) return "the average for argument " + cname;
+     154           0 :     if( cname==getPntrToArgument(i)->getName() + "_m" ) return "the moment for argument " + cname;
+     155             :   }
+     156           0 :   plumed_error(); return "";
+     157             : }
+     158             : 
+     159             : 
+     160         125 : void Ensemble::calculate() {
+     161             :   double norm = 0.0;
+     162         125 :   double fact = 0.0;
+     163             : 
+     164             :   // calculate the weights either from BIAS
+     165         125 :   if(do_reweight) {
+     166             :     std::vector<double> bias;
+     167           0 :     bias.resize(ens_dim);
+     168           0 :     if(master) {
+     169           0 :       bias[my_repl] = getArgument(narg);
+     170           0 :       if(ens_dim>1) multi_sim_comm.Sum(&bias[0], ens_dim);
+     171             :     }
+     172           0 :     comm.Sum(&bias[0], ens_dim);
+     173           0 :     const double maxbias = *(std::max_element(bias.begin(), bias.end()));
+     174           0 :     for(unsigned i=0; i<ens_dim; ++i) {
+     175           0 :       bias[i] = exp((bias[i]-maxbias)/kbt);
+     176           0 :       norm += bias[i];
+     177             :     }
+     178           0 :     fact = bias[my_repl]/norm;
+     179             :     // or arithmetic ones
+     180             :   } else {
+     181         125 :     norm = static_cast<double>(ens_dim);
+     182         125 :     fact = 1.0/norm;
+     183             :   }
+     184             : 
+     185         125 :   const double fact_kbt = fact/kbt;
+     186             : 
+     187         125 :   std::vector<double> mean(narg);
+     188         125 :   std::vector<double> dmean(narg,fact);
+     189             :   // calculate the mean
+     190         125 :   if(master) {
+     191        2106 :     for(unsigned i=0; i<narg; ++i) mean[i] = fact*getArgument(i);
+     192          99 :     if(ens_dim>1) multi_sim_comm.Sum(&mean[0], narg);
+     193             :   }
+     194         125 :   comm.Sum(&mean[0], narg);
+     195             : 
+     196             :   std::vector<double> v_moment, dv_moment;
+     197             :   // calculate other moments
+     198         125 :   if(do_moments) {
+     199           0 :     v_moment.resize(narg);
+     200           0 :     dv_moment.resize(narg);
+     201             :     // standard moment
+     202           0 :     if(!do_central) {
+     203           0 :       if(master) {
+     204           0 :         for(unsigned i=0; i<narg; ++i) {
+     205           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     206           0 :           v_moment[i]      = tmp*getArgument(i);
+     207           0 :           dv_moment[i]     = moment*tmp;
+     208             :         }
+     209           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     210             :       } else {
+     211           0 :         for(unsigned i=0; i<narg; ++i) {
+     212           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     213           0 :           dv_moment[i]     = moment*tmp;
+     214             :         }
+     215             :       }
+     216             :       // central moment
+     217             :     } else {
+     218           0 :       if(master) {
+     219           0 :         for(unsigned i=0; i<narg; ++i) {
+     220           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     221           0 :           v_moment[i]      = fact*tmp*(getArgument(i)-mean[i]);
+     222           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     223             :         }
+     224           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     225             :       } else {
+     226           0 :         for(unsigned i=0; i<narg; ++i) {
+     227           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     228           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     229             :         }
+     230             :       }
+     231             :     }
+     232           0 :     comm.Sum(&v_moment[0], narg);
+     233             :   }
+     234             : 
+     235             :   // calculate powers of moments
+     236         125 :   if(do_powers) {
+     237          72 :     for(unsigned i=0; i<narg; ++i) {
+     238          48 :       const double tmp1 = std::pow(mean[i],power-1);
+     239          48 :       mean[i]          *= tmp1;
+     240          48 :       dmean[i]         *= power*tmp1;
+     241          48 :       if(do_moments) {
+     242           0 :         const double tmp2 = std::pow(v_moment[i],power-1);
+     243           0 :         v_moment[i]      *= tmp2;
+     244           0 :         dv_moment[i]     *= power*tmp2;
+     245             :       }
+     246             :     }
+     247             :   }
+     248             : 
+     249             :   // set components
+     250        3358 :   for(unsigned i=0; i<narg; ++i) {
+     251             :     // set mean
+     252        3233 :     Value* v=getPntrToComponent(i);
+     253        3233 :     v->set(mean[i]);
+     254        3233 :     setDerivative(v, i, dmean[i]);
+     255        3233 :     if(do_reweight) {
+     256           0 :       const double w_tmp = fact_kbt*(getArgument(i) - mean[i]);
+     257           0 :       setDerivative(v, narg, w_tmp);
+     258             :     }
+     259        3233 :     if(do_moments) {
+     260             :       // set moments
+     261           0 :       Value* u=getPntrToComponent(i+narg);
+     262           0 :       u->set(v_moment[i]);
+     263           0 :       setDerivative(u, i, dv_moment[i]);
+     264           0 :       if(do_reweight) {
+     265           0 :         const double w_tmp = fact_kbt*(pow(getArgument(i),moment) - v_moment[i]);
+     266           0 :         setDerivative(u, narg, w_tmp);
+     267             :       }
+     268             :     }
+     269             :   }
+     270         125 : }
+     271             : 
+     272             : }
+     273             : }
+
+
+
+ + + + +
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 000000000..476e382de --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:9912877.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..6836db200 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:9912877.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..10a24c623 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.gcov.html @@ -0,0 +1,416 @@ + + + + + + + LCOV - plumed test coverage - function/FuncPathGeneral.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathGeneral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9912877.3 %
Date:2024-10-17 16:45:00Functions: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           6 :   keys.addOutputComponent("s", "default", "Position on the path");
+     166           6 :   keys.addOutputComponent("z", "default", "Distance from the path");
+     167           3 : }
+     168             : 
+     169           1 : FuncPathGeneral::FuncPathGeneral(const ActionOptions&ao):
+     170             :   Action(ao),
+     171             :   Function(ao),
+     172           1 :   neigh_size(-1),
+     173           1 :   neigh_stride(-1.)
+     174             : {
+     175           1 :   parse("LAMBDA", lambda);
+     176           1 :   parse("NEIGH_SIZE", neigh_size);
+     177           1 :   parse("NEIGH_STRIDE", neigh_stride);
+     178           1 :   parse("REFERENCE", reference);
+     179           1 :   parseVector("COEFFICIENTS", coefficients);
+     180           1 :   parseVector("COLUMNS", columns);
+     181           1 :   checkRead();
+     182           1 :   log.printf("  lambda is %f\n", lambda);
+     183           1 :   if (getNumberOfArguments() != coefficients.size())
+     184           0 :     plumed_merror("The numbers of coefficients and CVs are different!");
+     185           1 :   if (!columns.empty()) {
+     186           0 :     if (columns.size() != coefficients.size())
+     187           0 :       plumed_merror("The numbers of coefficients and columns are different!");
+     188             :   }
+     189           1 :   log.printf("  Consistency check completed! Your path cvs look good!\n");
+     190             : 
+     191             :   // Load the reference colvar file
+     192           1 :   loadReference();
+     193             : 
+     194             :   // Do some neighbour printout
+     195           1 :   if (neigh_stride > 0. || neigh_size > 0) {
+     196           0 :     if (static_cast<unsigned>(neigh_size) > path_cv_values.size()) {
+     197           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of arg required: %d  \n", neigh_size, getNumberOfArguments());
+     198           0 :       neigh_size = path_cv_values.size();
+     199             :     }
+     200           0 :     log.printf("  Neighbour list enabled: \n");
+     201           0 :     log.printf("                 size   :  %d elements\n", neigh_size);
+     202           0 :     log.printf("                 stride :  %f time \n", neigh_stride);
+     203             :   } else {
+     204           1 :     log.printf("  Neighbour list NOT enabled \n");
+     205             :   }
+     206             : 
+     207           2 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+     208           3 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     209             : 
+     210             :   // Initialise vectors
+     211           1 :   std::vector<double> temp (coefficients.size());
+     212          17 :   for (unsigned i = 0; i < path_cv_values.size(); ++i) {
+     213          16 :     numerators.push_back(temp);
+     214          16 :     expdists.push_back(0.);
+     215          16 :     s_path_ders.push_back(0.);
+     216          16 :     z_path_ders.push_back(0.);
+     217             :   }
+     218             : 
+     219             :   // Store the arguments
+     220           7 :   for (unsigned i=0; i<getNumberOfArguments(); i++)
+     221           6 :     allArguments.push_back(getPntrToArgument(i));
+     222             : 
+     223             :   // Get periodic domains, negative for not periodic, stores half the domain length (maximum difference)
+     224           7 :   for (unsigned i = 0; i < allArguments.size(); ++i) {
+     225           6 :     if (allArguments[i]->isPeriodic()) {
+     226             :       double min_lim, max_lim;
+     227           0 :       allArguments[i]->getDomain(min_lim, max_lim);
+     228           0 :       domains.push_back((max_lim - min_lim) / 2);
+     229             :     }
+     230             :     else
+     231           6 :       domains.push_back(-1.);
+     232             :   }
+     233           1 : }
+     234             : 
+     235             : // Calculator
+     236      175001 : void FuncPathGeneral::calculate() {
+     237             :   double s_path = 0.;
+     238             :   double partition = 0.;
+     239             :   double tmp, value, diff, expdist, s_der, z_der;
+     240             :   int ii;
+     241             : 
+     242             :   typedef std::vector< std::pair< int,double> >::iterator pairiter;
+     243             : 
+     244     2975001 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     245     2800000 :     (*it).second = 0.;
+     246             :   }
+     247             : 
+     248      175001 :   if (neighpair.empty()) {
+     249             :     // Resize at the first step
+     250           1 :     neighpair.resize(path_cv_values.size());
+     251          17 :     for (unsigned i = 0; i < path_cv_values.size(); ++i)
+     252          16 :       neighpair[i].first = i;
+     253             :   }
+     254             : 
+     255      175001 :   Value* val_s_path=getPntrToComponent("s");
+     256      175001 :   Value* val_z_path=getPntrToComponent("z");
+     257             : 
+     258     1225007 :   for(unsigned j = 0; j < allArguments.size(); ++j) {
+     259     1050006 :     value = allArguments[j]->get();
+     260    17850102 :     for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     261    16800096 :       diff = (value - path_cv_values[(*it).first][j]);
+     262    16800096 :       if (domains[j] > 0) {
+     263           0 :         if (diff > domains[j])
+     264           0 :           diff -= 2 * domains[j];
+     265           0 :         if (diff < -domains[j])
+     266           0 :           diff += 2 * domains[j];
+     267             :       }
+     268    33600192 :       (*it).second += Tools::fastpow(coefficients[j] * diff, 2);
+     269    33600192 :       numerators[(*it).first][j] = 2 * Tools::fastpow(coefficients[j], 2) * diff;
+     270             :     }
+     271             :   }
+     272             : 
+     273     2975017 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     274     2800016 :     expdist = std::exp(-lambda * (*it).second);
+     275     2800016 :     expdists[(*it).first] = expdist;
+     276     2800016 :     s_path += ((*it).first + 1) * expdist;
+     277     2800016 :     partition += expdist;
+     278             :   }
+     279             : 
+     280      175001 :   if(partition==0.0) partition=std::numeric_limits<double>::min();
+     281             : 
+     282      175001 :   s_path /= partition;
+     283             :   val_s_path->set(s_path);
+     284      175001 :   val_z_path->set(-(1. / lambda) * std::log(partition));
+     285             : 
+     286             :   // Derivatives
+     287     2975017 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     288     2800016 :     ii = (*it).first;
+     289     2800016 :     tmp = lambda * expdists[ii] * (s_path - (ii + 1)) / partition;
+     290     2800016 :     s_path_ders[ii] = tmp;
+     291     2800016 :     z_path_ders[ii] = expdists[ii] / partition;
+     292             :   }
+     293     1225007 :   for (unsigned i = 0; i < coefficients.size(); ++i) {
+     294             :     s_der = 0.;
+     295             :     z_der = 0.;
+     296    17850102 :     for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     297    16800096 :       ii = (*it).first;
+     298    16800096 :       s_der += s_path_ders[ii] * numerators[ii][i];
+     299    16800096 :       z_der += z_path_ders[ii] * numerators[ii][i];
+     300             :     }
+     301             :     setDerivative(val_s_path, i, s_der);
+     302             :     setDerivative(val_z_path, i, z_der);
+     303             :   }
+     304      175001 : }
+     305             : 
+     306             : // Prepare the required arguments
+     307      175001 : void FuncPathGeneral::prepare() {
+     308             :   // Neighbour list: rank and activate the chain for the next step
+     309             : 
+     310             :   // Neighbour list: if neigh_size < 0 never sort and keep the full vector
+     311             :   // Neighbour list: if neigh_size > 0
+     312             :   //                 if the size is full -> sort the vector and decide the dependencies for next step
+     313             :   //                 if the size is not full -> check if next step will need the full dependency otherwise keep these dependencies
+     314             : 
+     315      175001 :   if (neigh_size > 0) {
+     316           0 :     if (neighpair.size() == path_cv_values.size()) {
+     317             :       // The complete round has been done: need to sort, shorten and give it a go
+     318             :       // Sort the values
+     319           0 :       std::sort(neighpair.begin(), neighpair.end(), pairordering());
+     320             :       // Resize the effective list
+     321           0 :       neighpair.resize(neigh_size);
+     322           0 :       log.printf("  NEIGHBOUR LIST NOW INCLUDES INDICES: ");
+     323           0 :       for (int i = 0; i < neigh_size; ++i)
+     324           0 :         log.printf(" %i ",neighpair[i].first);
+     325           0 :       log.printf(" \n");
+     326             :     } else {
+     327           0 :       if (int(getStep()) % int(neigh_stride / getTimeStep()) == 0) {
+     328           0 :         log.printf(" Time %f : recalculating full neighbour list \n", getStep() * getTimeStep());
+     329           0 :         neighpair.resize(path_cv_values.size());
+     330           0 :         for (unsigned i = 0; i < path_cv_values.size(); ++i)
+     331           0 :           neighpair[i].first = i;
+     332             :       }
+     333             :     }
+     334             :   }
+     335             : 
+     336      175001 :   requestArguments(allArguments);
+     337      175001 : }
+     338             : 
+     339             : }
+     340             : }
+
+
+
+ + + + +
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 000000000..2539c9134 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:737992.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..f2bb7f2d6 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:737992.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..c9a7f5d05 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.gcov.html @@ -0,0 +1,443 @@ + + + + + + + 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:737992.4 %
Date:2024-10-17 16:45:00Functions: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           8 :   keys.addOutputComponent("s","default","the position on the path");
+     227           8 :   keys.addOutputComponent("z","default","the distance from the path");
+     228           4 : }
+     229           2 : FuncPathMSD::FuncPathMSD(const ActionOptions&ao):
+     230             :   Action(ao),
+     231             :   Function(ao),
+     232           2 :   neigh_size(-1),
+     233           2 :   neigh_stride(-1.)
+     234             : {
+     235             : 
+     236           2 :   parse("LAMBDA",lambda);
+     237           2 :   parse("NEIGH_SIZE",neigh_size);
+     238           2 :   parse("NEIGH_STRIDE",neigh_stride);
+     239           2 :   checkRead();
+     240           2 :   log.printf("  lambda is %f\n",lambda);
+     241             :   // list the action involved and check the type
+     242           2 :   std::string myname=getPntrToArgument(0)->getPntrToAction()->getName();
+     243           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!!!");
+     244           6 :   for(unsigned i=1; i<getNumberOfArguments(); i++) {
+     245             :     // for each value get the name and the label of the corresponding action
+     246           4 :     if( getPntrToArgument(i)->getPntrToAction()->getName()!=myname ) error("mismatch between the types of arguments");
+     247             :   }
+     248           2 :   log.printf("  Consistency check completed! Your path cvs look good!\n");
+     249             :   // do some neighbor printout
+     250           2 :   if(neigh_stride>0. || neigh_size>0) {
+     251           1 :     if(neigh_size>static_cast<int>(getNumberOfArguments())) {
+     252           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of arg required: %d  \n",neigh_size,getNumberOfArguments());
+     253           0 :       neigh_size=getNumberOfArguments();
+     254             :     }
+     255           1 :     log.printf("  Neighbor list enabled: \n");
+     256           1 :     log.printf("                size   :  %d elements\n",neigh_size);
+     257           1 :     log.printf("                stride :  %f time \n",neigh_stride);
+     258             :   } else {
+     259           1 :     log.printf("  Neighbor list NOT enabled \n");
+     260             :   }
+     261             : 
+     262           4 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+     263           4 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     264             : 
+     265             :   // now backup the arguments
+     266           8 :   for(unsigned i=0; i<getNumberOfArguments(); i++)allArguments.push_back(getPntrToArgument(i));
+     267             :   double i=1.;
+     268           8 :   for(const auto & it : allArguments) {
+     269           6 :     indexmap[it]=i; i+=1.;
+     270             :   }
+     271             : 
+     272           2 : }
+     273             : // calculator
+     274        1092 : void FuncPathMSD::calculate() {
+     275             : // log.printf("NOW CALCULATE! \n");
+     276             :   double s_path=0.;
+     277             :   double partition=0.;
+     278        1092 :   if(neighpair.empty()) { // at first step, resize it
+     279           0 :     neighpair.resize(allArguments.size());
+     280           0 :     for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     281             :   }
+     282             : 
+     283        1092 :   Value* val_s_path=getPntrToComponent("s");
+     284        2184 :   Value* val_z_path=getPntrToComponent("z");
+     285             : 
+     286        3959 :   for(auto & it : neighpair) {
+     287        2867 :     it.second=std::exp(-lambda*(it.first->get()));
+     288        2867 :     s_path+=(indexmap[it.first])*it.second;
+     289        2867 :     partition+=it.second;
+     290             :   }
+     291        1092 :   s_path/=partition;
+     292             :   val_s_path->set(s_path);
+     293        1092 :   val_z_path->set(-(1./lambda)*std::log(partition));
+     294             :   int n=0;
+     295        3959 :   for(const auto & it : neighpair) {
+     296        2867 :     double expval=it.second;
+     297        2867 :     double tmp=lambda*expval*(s_path-(indexmap[it.first]))/partition;
+     298             :     setDerivative(val_s_path,n,tmp);
+     299        2867 :     setDerivative(val_z_path,n,expval/partition);
+     300        2867 :     n++;
+     301             :   }
+     302             : 
+     303             : //  log.printf("CALCULATION DONE! \n");
+     304        1092 : }
+     305             : ///
+     306             : /// this function updates the needed argument list
+     307             : ///
+     308        1092 : void FuncPathMSD::prepare() {
+     309             : 
+     310             :   // neighbor list: rank and activate the chain for the next step
+     311             : 
+     312             :   // neighbor list: if neigh_size<0 never sort and keep the full vector
+     313             :   // neighbor list: if neigh_size>0
+     314             :   //                if the size is full -> sort the vector and decide the dependencies for next step
+     315             :   //                if the size is not full -> check if next step will need the full dependency otherwise keep this dependencies
+     316             : 
+     317             :   // here just resize the neighpair. The real resizing of reinit will be done by the prepare stage that will modify the  list of arguments
+     318        1092 :   if (neigh_size>0) {
+     319         546 :     if(neighpair.size()==allArguments.size()) { // I just did the complete round: need to sort, shorten and give it a go
+     320             :       // sort the values
+     321         137 :       std::sort(neighpair.begin(),neighpair.end(),pairordering());
+     322             :       // resize the effective list
+     323         137 :       neighpair.resize(neigh_size);
+     324         137 :       log.printf("  NEIGH LIST NOW INCLUDE INDEXES: ");
+     325         411 :       for(int i=0; i<neigh_size; ++i) {log.printf(" %f ",indexmap[neighpair[i].first]);} log.printf(" \n");
+     326             :     } else {
+     327         409 :       if( int(getStep())%int(neigh_stride/getTimeStep())==0 ) {
+     328         137 :         log.printf(" Time %f : recalculating full neighlist \n",getStep()*getTimeStep());
+     329         137 :         neighpair.resize(allArguments.size());
+     330         548 :         for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     331             :       }
+     332             :     }
+     333             :   } else {
+     334         546 :     if( int(getStep())==0) {
+     335           1 :       neighpair.resize(allArguments.size());
+     336           4 :       for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     337             :     }
+     338             :   }
+     339             :   std::vector<Value*> argstocall;
+     340             : //log.printf("PREPARING \n");
+     341             :   argstocall.clear();
+     342        1092 :   if(!neighpair.empty()) {
+     343        3959 :     for(const auto & it : neighpair) {
+     344        2867 :       argstocall.push_back( it.first );
+     345             :       //     log.printf("CALLING %p %f ",(*it).first ,indexmap[(*it).first] );
+     346             :     }
+     347             :   } else {
+     348           0 :     for(unsigned i=0; i<allArguments.size(); i++) {
+     349           0 :       argstocall.push_back(allArguments[i]);
+     350             :     }
+     351             :   }
+     352             : // now the list of argument changes
+     353        1092 :   requestArguments(argstocall);
+     354             : //now resize the derivatives as well
+     355             : //for each value in this action
+     356        3276 :   for(int i=0; i< getNumberOfComponents(); i++) {
+     357             :     //resize the derivative to the number   the
+     358        2184 :     getPntrToComponent(i)->clearDerivatives();
+     359        2184 :     getPntrToComponent(i)->resizeDerivatives(getNumberOfArguments());
+     360             :   }
+     361             : //log.printf("PREPARING DONE! \n");
+     362        1092 : }
+     363             : 
+     364             : }
+     365             : }
+     366             : 
+     367             : 
+
+
+
+ + + + +
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 000000000..f4519cdf0 --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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:29332689.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..a9155e294 --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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:29332689.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..9145295ec --- /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:29332689.9 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("a scalar");
+     225          11 : }
+     226             : 
+     227           9 : FuncSumHills::FuncSumHills(const ActionOptions&ao):
+     228             :   Action(ao),
+     229             :   Function(ao),
+     230           9 :   initstride(-1),
+     231           9 :   iscltool(false),
+     232           9 :   integratehills(false),
+     233           9 :   integratehisto(false),
+     234           9 :   parallelread(false),
+     235           9 :   negativebias(false),
+     236           9 :   nohistory(false),
+     237           9 :   minTOzero(false),
+     238           9 :   doInt(false),
+     239           9 :   lowI_(-1.),
+     240           9 :   uppI_(-1.),
+     241           9 :   beta(-1.),
+     242           9 :   fmt("%14.9f")
+     243             : {
+     244             : 
+     245             :   // format
+     246           9 :   parse("FMT",fmt);
+     247           9 :   log<<"  Output format is "<<fmt<<"\n";
+     248             :   // here read
+     249             :   // Grid Stuff
+     250             :   std::vector<std::string> gmin;
+     251          18 :   parseVector("GRID_MIN",gmin);
+     252           9 :   if(gmin.size()!=getNumberOfArguments() && gmin.size()!=0) error("not enough values for GRID_MIN");
+     253           9 :   plumed_massert(gmin.size()==getNumberOfArguments() || gmin.size()==0,"need GRID_MIN argument for this") ;
+     254             :   std::vector<std::string> gmax;
+     255          18 :   parseVector("GRID_MAX",gmax);
+     256           9 :   if(gmax.size()!=getNumberOfArguments() && gmax.size()!=0) error("not enough values for GRID_MAX");
+     257           9 :   plumed_massert(gmax.size()==getNumberOfArguments() || gmax.size()==0,"need GRID_MAX argument for this") ;
+     258             :   std::vector<unsigned> gbin;
+     259             :   std::vector<double>   gspacing;
+     260          18 :   parseVector("GRID_BIN",gbin);
+     261           9 :   plumed_massert(gbin.size()==getNumberOfArguments() || gbin.size()==0,"need GRID_BIN argument for this") ;
+     262           9 :   if(gbin.size()!=getNumberOfArguments() && gbin.size()!=0) error("not enough values for GRID_BIN");
+     263          18 :   parseVector("GRID_SPACING",gspacing);
+     264           9 :   plumed_massert(gspacing.size()==getNumberOfArguments() || gspacing.size()==0,"need GRID_SPACING argument for this") ;
+     265           9 :   if(gspacing.size()!=getNumberOfArguments() && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     266           9 :   if(gspacing.size()!=0 && gbin.size()==0) {
+     267           1 :     log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     268           8 :   } else if(gspacing.size()!=0 && gbin.size()!=0) {
+     269           0 :     log<<"  You specified both GRID_BIN and GRID_SPACING\n";
+     270           0 :     log<<"  The more conservative (highest) number of bins will be used for each variable\n";
+     271             :   }
+     272          10 :   if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     273           1 :       if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     274             :       double a,b;
+     275           1 :       Tools::convert(gmin[i],a);
+     276           1 :       Tools::convert(gmax[i],b);
+     277           1 :       unsigned n=std::ceil((b-a)/gspacing[i]);
+     278           1 :       if(gbin[i]<n) gbin[i]=n;
+     279             :     }
+     280             : 
+     281             :   // Inteval keyword
+     282           9 :   std::vector<double> tmpI(2);
+     283          18 :   parseVector("INTERVAL",tmpI);
+     284           9 :   if(tmpI.size()!=2&&tmpI.size()!=0) error("both a lower and an upper limits must be provided with INTERVAL");
+     285           9 :   else if(tmpI.size()==2) {
+     286           0 :     lowI_=tmpI.at(0);
+     287           0 :     uppI_=tmpI.at(1);
+     288           0 :     if(getNumberOfArguments()!=1) error("INTERVAL limits correction works only for monodimensional metadynamics!");
+     289           0 :     if(uppI_<lowI_) error("The Upper limit must be greater than the Lower limit!");
+     290           0 :     doInt=true;
+     291             :   }
+     292           9 :   if(doInt) {
+     293           0 :     log << "  Upper and Lower limits boundaries for the bias are activated at " << lowI_ << " - " << uppI_<<"\n";
+     294           0 :     log << "  Using the same values as boundaries for the grid if not other value was defined (default: 200 bins)\n";
+     295           0 :     std::ostringstream strsmin, strsmax;
+     296           0 :     strsmin << lowI_;
+     297           0 :     strsmax << uppI_;
+     298           0 :     if(gmin.size()==0) gmin.push_back(strsmin.str());
+     299           0 :     if(gmax.size()==0) gmax.push_back(strsmax.str());
+     300           0 :     if(gbin.size()==0) gbin.push_back(200);
+     301           0 :   }
+     302             : 
+     303             : 
+     304             :   // hills file:
+     305          18 :   parseVector("HILLSFILES",hillsFiles);
+     306           9 :   if(hillsFiles.size()==0) {
+     307           1 :     integratehills=false; // default behaviour
+     308             :   } else {
+     309           8 :     integratehills=true;
+     310          17 :     for(unsigned i=0; i<hillsFiles.size(); i++) log<<"  hillsfile  : "<<hillsFiles[i]<<"\n";
+     311             :   }
+     312             :   // histo file:
+     313          18 :   parseVector("HISTOFILES",histoFiles);
+     314           9 :   if(histoFiles.size()==0) {
+     315           8 :     integratehisto=false;
+     316             :   } else {
+     317           1 :     integratehisto=true;
+     318           2 :     for(unsigned i=0; i<histoFiles.size(); i++) log<<"  histofile  : "<<histoFiles[i]<<"\n";
+     319             :   }
+     320             :   std::vector<double> histoSigma;
+     321           9 :   if(integratehisto) {
+     322           1 :     parseVector("HISTOSIGMA",histoSigma);
+     323           3 :     for(unsigned i=0; i<histoSigma.size(); i++) log<<"  histosigma  : "<<histoSigma[i]<<"\n";
+     324             :   }
+     325             : 
+     326             :   // needs a projection?
+     327             :   proj.clear();
+     328           9 :   parseVector("PROJ",proj);
+     329           9 :   if(integratehills) {
+     330           8 :     plumed_massert(proj.size()<getNumberOfArguments()," The number of projection must be less than the full list of arguments ");
+     331             :   }
+     332           9 :   if(integratehisto) {
+     333           1 :     plumed_massert(proj.size()<=getNumberOfArguments()," The number of projection must be less or equal to the full list of arguments ");
+     334             :   }
+     335           9 :   if(integratehisto&&proj.size()==0) {
+     336           3 :     for(unsigned i=0; i<getNumberOfArguments(); i++) proj.push_back(getPntrToArgument(i)->getName());
+     337             :   }
+     338             : 
+     339             :   // add some automatic hills width: not in case stride is defined
+     340             :   // since when you start from zero the automatic size will be zero!
+     341           9 :   if(gmin.size()==0 || gmax.size()==0) {
+     342           5 :     log<<"   \n";
+     343           5 :     log<<"  No boundaries defined: need to do a prescreening of hills \n";
+     344             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     345           5 :     if(integratehills) {
+     346          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++)tmphillsvalues.push_back( getPntrToArgument(i) );
+     347             :     }
+     348           5 :     if(integratehisto) {
+     349           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     350           2 :         std::string ss = getPntrToArgument(i)->getName();
+     351           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     352           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     353             :         }
+     354             :       }
+     355             :     }
+     356             : 
+     357           5 :     if(integratehills) {
+     358           4 :       FilesHandler hillsHandler(hillsFiles,parallelread,*this, log);
+     359             :       std::vector<double> vmin,vmax;
+     360             :       std::vector<unsigned> vbin;
+     361           4 :       hillsHandler.getMinMaxBin(tmphillsvalues,comm,vmin,vmax,vbin);
+     362           4 :       log<<"  found boundaries from hillsfile: \n";
+     363           4 :       gmin.resize(vmin.size());
+     364           4 :       gmax.resize(vmax.size());
+     365           4 :       if(gbin.size()==0) {
+     366           3 :         gbin=vbin;
+     367             :       } else {
+     368           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     369             :       }
+     370          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     371           8 :         Tools::convert(vmin[i],gmin[i]);
+     372           8 :         Tools::convert(vmax[i],gmax[i]);
+     373           8 :         log<<"  variable "<< getPntrToArgument(i)->getName()<<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     374             :       }
+     375             :     }
+     376             :     // if at this stage bins are not there then do it with histo
+     377           5 :     if(gmin.size()==0) {
+     378           1 :       FilesHandler histoHandler(histoFiles,parallelread,*this, log);
+     379             :       std::vector<double> vmin,vmax;
+     380             :       std::vector<unsigned> vbin;
+     381           1 :       histoHandler.getMinMaxBin(tmphistovalues,comm,vmin,vmax,vbin,histoSigma);
+     382           1 :       log<<"  found boundaries from histofile: \n";
+     383           1 :       gmin.resize(vmin.size());
+     384           1 :       gmax.resize(vmax.size());
+     385           1 :       if(gbin.size()==0) {
+     386           0 :         gbin=vbin;
+     387             :       } else {
+     388           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     389             :       }
+     390           3 :       for(unsigned i=0; i<proj.size(); i++) {
+     391           2 :         Tools::convert(vmin[i],gmin[i]);
+     392           2 :         Tools::convert(vmax[i],gmax[i]);
+     393           2 :         log<<"  variable "<< proj[i] <<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     394             :       }
+     395             :     }
+     396           5 :     log<<"  done!\n";
+     397           5 :     log<<"   \n";
+     398             :   }
+     399             : 
+     400             : 
+     401           9 :   if( proj.size() != 0 || integratehisto==true  ) {
+     402           3 :     parse("KT",beta);
+     403           7 :     for(unsigned i=0; i<proj.size(); i++) log<<"  projection "<<i<<" : "<<proj[i]<<"\n";
+     404             :     // this should be only for projection or free energy from histograms
+     405           3 :     plumed_massert(beta>0.,"if you make a projection or a histogram correction then you need KT flag!");
+     406           3 :     beta=1./beta;
+     407           3 :     log<<"  beta is "<<beta<<"\n";
+     408             :   }
+     409             :   // is a cltool: then you start and then die
+     410           9 :   parseFlag("ISCLTOOL",iscltool);
+     411             :   //
+     412           9 :   parseFlag("NEGBIAS",negativebias);
+     413             :   //
+     414           9 :   parseFlag("PARALLELREAD",parallelread);
+     415             :   // stride
+     416           9 :   parse("INITSTRIDE",initstride);
+     417             :   // output suffix or names
+     418           9 :   if(initstride<0) {
+     419           8 :     log<<"  Doing only one integration: no stride \n";
+     420             :     outhills="fes.dat"; outhisto="histo.dat";
+     421             :   }
+     422             :   else {
+     423             :     outhills="fes_"; outhisto="histo_";
+     424           1 :     log<<"  Doing integration slices every "<<initstride<<" kernels\n";
+     425           1 :     parseFlag("NOHISTORY",nohistory);
+     426           1 :     if(nohistory)log<<"  nohistory: each stride block has no memory of the previous block\n";
+     427             :   }
+     428           9 :   parseFlag("MINTOZERO",minTOzero);
+     429           9 :   if(minTOzero)log<<"  mintozero: bias/histogram will be translated to have the minimum value equal to zero\n";
+     430             :   //what might it be this?
+     431             :   // here start
+     432             :   // want something right now?? do it and return
+     433             :   // your argument is a set of cvs
+     434             :   // then you need: a hills / a colvar-like file (to do a histogram)
+     435             :   // create a bias representation for this
+     436           9 :   if(iscltool) {
+     437             : 
+     438             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     439           9 :     if(integratehills) {
+     440          23 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     441             :         // allocate a new value from the old one: no deriv here
+     442             :         // if we are summing hills then all the arguments are needed
+     443          15 :         tmphillsvalues.push_back( getPntrToArgument(i) );
+     444             :       }
+     445             :     }
+     446           9 :     if(integratehisto) {
+     447           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     448           2 :         std::string ss = getPntrToArgument(i)->getName();
+     449           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     450           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     451             :         }
+     452             :       }
+     453             :     }
+     454             : 
+     455             :     // check if the files exists
+     456           9 :     if(integratehills) {
+     457           8 :       checkFilesAreExisting(hillsFiles);
+     458          16 :       biasrep=Tools::make_unique<BiasRepresentation>(tmphillsvalues,comm, gmin, gmax, gbin, doInt, lowI_, uppI_);
+     459           8 :       if(negativebias) {
+     460           1 :         biasrep->setRescaledToBias(true);
+     461           1 :         log<<"  required the -bias instead of the free energy \n";
+     462           1 :         if(initstride<0) {outhills="negativebias.dat";}
+     463             :         else {outhills="negativebias_";}
+     464             :       }
+     465             :     }
+     466             : 
+     467           9 :     parse("OUTHILLS",outhills);
+     468           9 :     parse("OUTHISTO",outhisto);
+     469           9 :     if(integratehills)log<<"  output file for fes/bias  is :  "<<outhills<<"\n";
+     470           9 :     if(integratehisto)log<<"  output file for histogram is :  "<<outhisto<<"\n";
+     471           9 :     checkRead();
+     472             : 
+     473           9 :     log<<"\n";
+     474           9 :     log<<"  Now calculating...\n";
+     475           9 :     log<<"\n";
+     476             : 
+     477             :     // here it defines the column to be histogrammed, tmpvalues should be only
+     478             :     // the list of the collective variable one want to consider
+     479           9 :     if(integratehisto) {
+     480           1 :       checkFilesAreExisting(histoFiles);
+     481           2 :       historep=Tools::make_unique<BiasRepresentation>(tmphistovalues,comm,gmin,gmax,gbin,histoSigma);
+     482             :     }
+     483             : 
+     484             :     // decide how to source hills ( serial/parallel )
+     485             :     // here below the input control
+     486             :     // say how many hills and it will read them from the
+     487             :     // bunch of files provided, will update the representation
+     488             :     // of hills (i.e. a list of hills and the associated grid)
+     489             : 
+     490             :     // decide how to source colvars ( serial parallel )
+     491           9 :     std::unique_ptr<FilesHandler> hillsHandler;
+     492           9 :     std::unique_ptr<FilesHandler> histoHandler;
+     493             : 
+     494          17 :     if(integratehills)  hillsHandler=Tools::make_unique<FilesHandler>(hillsFiles,parallelread,*this, log);
+     495          10 :     if(integratehisto)  histoHandler=Tools::make_unique<FilesHandler>(histoFiles,parallelread,*this, log);
+     496             : 
+     497             : // Stopwatch is logged when it goes out of scope
+     498           9 :     Stopwatch sw(log);
+     499             : 
+     500             : // Stopwatch is stopped when swh goes out of scope
+     501           9 :     auto swh=sw.startStop("0 Summing hills");
+     502             : 
+     503             :     // read a number of hills and put in the bias representation
+     504             :     int nfiles=0;
+     505           9 :     bool ibias=integratehills; bool ihisto=integratehisto;
+     506             :     while(true) {
+     507          10 :       if(  integratehills  && ibias  ) {
+     508           9 :         if(nohistory) {biasrep->clear(); log<<"  clearing history before reading a new block\n";};
+     509           9 :         log<<"  reading hills: \n";
+     510           9 :         ibias=hillsHandler->readBunch(biasrep.get(),initstride) ; log<<"\n";
+     511             :       }
+     512             : 
+     513          10 :       if(  integratehisto  && ihisto ) {
+     514           1 :         if(nohistory) {historep->clear(); log<<"  clearing history before reading a new block\n";};
+     515           1 :         log<<"  reading histogram: \n";
+     516           1 :         ihisto=histoHandler->readBunch(historep.get(),initstride) ;  log<<"\n";
+     517             :       }
+     518             : 
+     519             :       // dump: need to project?
+     520          10 :       if(proj.size()!=0) {
+     521             : 
+     522           4 :         if(integratehills) {
+     523             : 
+     524           3 :           log<<"  Bias: Projecting on subgrid... \n";
+     525           3 :           BiasWeight Bw(beta);
+     526           3 :           Grid biasGrid=*(biasrep->getGridPtr());
+     527           3 :           Grid smallGrid=biasGrid.project(proj,&Bw);
+     528           3 :           OFile gridfile; gridfile.link(*this);
+     529           3 :           std::ostringstream ostr; ostr<<nfiles;
+     530             :           std::string myout;
+     531           7 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     532           3 :           log<<"  Bias: Writing subgrid on file "<<myout<<" \n";
+     533           3 :           gridfile.open(myout);
+     534           3 :           if(minTOzero) smallGrid.setMinToZero();
+     535             :           smallGrid.setOutputFmt(fmt);
+     536           3 :           smallGrid.writeToFile(gridfile);
+     537           3 :           gridfile.close();
+     538           3 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     539           3 :         }
+     540             :         // this should be removed
+     541           4 :         if(integratehisto) {
+     542             : 
+     543           1 :           log<<"  Histo: Projecting on subgrid... \n";
+     544           1 :           Grid histoGrid=*(historep->getGridPtr());
+     545             : 
+     546           1 :           OFile gridfile; gridfile.link(*this);
+     547           1 :           std::ostringstream ostr; ostr<<nfiles;
+     548             :           std::string myout;
+     549           1 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     550           1 :           log<<"  Histo: Writing subgrid on file "<<myout<<" \n";
+     551           1 :           gridfile.open(myout);
+     552             : 
+     553           1 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     554           1 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     555           1 :           if(minTOzero) histoGrid.setMinToZero();
+     556             :           histoGrid.setOutputFmt(fmt);
+     557           1 :           histoGrid.writeToFile(gridfile);
+     558             : 
+     559           1 :           if(!ihisto)integratehisto=false;// once you get to the final bunch just give up
+     560           1 :         }
+     561             : 
+     562             :       } else {
+     563             : 
+     564           6 :         if(integratehills) {
+     565             : 
+     566           6 :           Grid biasGrid=*(biasrep->getGridPtr());
+     567           6 :           biasGrid.scaleAllValuesAndDerivatives(-1.);
+     568             : 
+     569           6 :           OFile gridfile; gridfile.link(*this);
+     570           6 :           std::ostringstream ostr; ostr<<nfiles;
+     571             :           std::string myout;
+     572           6 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     573           6 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     574           6 :           gridfile.open(myout);
+     575             : 
+     576           6 :           if(minTOzero) biasGrid.setMinToZero();
+     577             :           biasGrid.setOutputFmt(fmt);
+     578           6 :           biasGrid.writeToFile(gridfile);
+     579             :           // rescale back prior to accumulate
+     580           6 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     581           6 :         }
+     582           6 :         if(integratehisto) {
+     583             : 
+     584           0 :           Grid histoGrid=*(historep->getGridPtr());
+     585             :           // do this if you want a free energy from a grid, otherwise do not
+     586           0 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     587           0 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     588             : 
+     589           0 :           OFile gridfile; gridfile.link(*this);
+     590           0 :           std::ostringstream ostr; ostr<<nfiles;
+     591             :           std::string myout;
+     592           0 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     593           0 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     594           0 :           gridfile.open(myout);
+     595             : 
+     596             :           // also this is useful only for free energy
+     597           0 :           if(minTOzero) histoGrid.setMinToZero();
+     598             :           histoGrid.setOutputFmt(fmt);
+     599           0 :           histoGrid.writeToFile(gridfile);
+     600             : 
+     601           0 :           if(!ihisto)integratehisto=false; // once you get to the final bunch just give up
+     602           0 :         }
+     603             :       }
+     604          10 :       if ( !ibias && !ihisto) break; //when both are over then just quit
+     605             : 
+     606           1 :       nfiles++;
+     607           1 :     }
+     608             : 
+     609             :     return;
+     610           9 :   }
+     611             :   // just an initialization but you need to do something on the fly?: need to connect with a metad run and its grid representation
+     612             :   // your argument is a metad run
+     613             :   // if the grid does not exist crash and say that you need some data
+     614             :   // otherwise just link with it
+     615             : 
+     616           9 : }
+     617             : 
+     618           0 : void FuncSumHills::calculate() {
+     619             :   // this should be connected only with a grid representation to metadynamics
+     620             :   // at regular time just dump it
+     621           0 :   plumed_merror("You should have never got here: this stuff is not yet implemented!");
+     622             : }
+     623             : 
+     624           9 : bool FuncSumHills::checkFilesAreExisting(const std::vector<std::string> & hills ) {
+     625           9 :   plumed_massert(hills.size()!=0,"the number of  files provided should be at least one" );
+     626             :   auto ifile=Tools::make_unique<IFile>();
+     627           9 :   ifile->link(*this);
+     628          19 :   for(unsigned i=0; i< hills.size(); i++) {
+     629          10 :     plumed_massert(ifile->FileExist(hills[i]),"missing file "+hills[i]);
+     630             :   }
+     631           9 :   return true;
+     632             : 
+     633           9 : }
+     634             : 
+     635             : }
+     636             : 
+     637             : }
+     638             : 
+     639             : 
+
+
+
+ + + + +
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 000000000..cdd2e9a89 --- /dev/null +++ b/coverage/function/Function.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - function/Function.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8Function23addValueWithDerivativesEv1411
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE1511
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE2979
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3177
_ZN4PLMD8function8Function5applyEv268897
+
+
+ + + +
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 000000000..5b9a63609 --- /dev/null +++ b/coverage/function/Function.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - function/Function.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE2979
_ZN4PLMD8function8Function23addValueWithDerivativesEv1411
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3177
_ZN4PLMD8function8Function5applyEv268897
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE1511
+
+
+ + + +
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 000000000..d228a77db --- /dev/null +++ b/coverage/function/Function.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-10-17 16:45:00Functions: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        2979 : void Function::registerKeywords(Keywords& keys) {
+      30        2979 :   Action::registerKeywords(keys);
+      31        2979 :   ActionWithValue::registerKeywords(keys);
+      32        2979 :   ActionWithArguments::registerKeywords(keys);
+      33        5958 :   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        2979 : }
+      35             : 
+      36        1511 : Function::Function(const ActionOptions&ao):
+      37             :   Action(ao),
+      38             :   ActionWithValue(ao),
+      39        1511 :   ActionWithArguments(ao)
+      40             : {
+      41        1511 : }
+      42             : 
+      43        1411 : void Function::addValueWithDerivatives() {
+      44        1411 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      45        2822 :   ActionWithValue::addValueWithDerivatives();
+      46        1411 :   getPntrToValue()->resizeDerivatives(getNumberOfArguments());
+      47        1411 : }
+      48             : 
+      49        3177 : void Function::addComponentWithDerivatives( const std::string& name ) {
+      50        3177 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      51        3177 :   ActionWithValue::addComponentWithDerivatives(name);
+      52        3177 :   getPntrToComponent(name)->resizeDerivatives(getNumberOfArguments());
+      53        3177 : }
+      54             : 
+      55      268897 : void Function::apply()
+      56             : {
+      57      268897 :   if( !checkForForces() ) return;
+      58       62415 :   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 000000000..fb1212050 --- /dev/null +++ b/coverage/function/Function.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - function/Function.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8988.9 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionD2Ev1511
_ZN4PLMD8function8Function11getArgumentERKj24190
_ZN4PLMD8function8Function22getNumberOfDerivativesEv277163
+
+
+ + + +
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 000000000..b0960761b --- /dev/null +++ b/coverage/function/Function.h.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - function/Function.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8988.9 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function11getArgumentERKj24190
_ZN4PLMD8function8Function22getNumberOfDerivativesEv277163
_ZN4PLMD8function8FunctionD2Ev1511
+
+
+ + + +
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 000000000..d1264ccbf --- /dev/null +++ b/coverage/function/Function.h.gcov.html @@ -0,0 +1,159 @@ + + + + + + + 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-10-17 16:45:00Functions: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        1511 :   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      277163 : unsigned Function::getNumberOfDerivatives() {
+      67             :   unsigned narg=0;
+      68     4979619 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      69     4702456 :     if( getPntrToArgument(i)->getRank()==0 ) narg++;
+      70             :   }
+      71      277163 :   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/FunctionOfMatrix.h.func-sort-c.html b/coverage/function/FunctionOfMatrix.h.func-sort-c.html new file mode 100644 index 000000000..dd8df8359 --- /dev/null +++ b/coverage/function/FunctionOfMatrix.h.func-sort-c.html @@ -0,0 +1,504 @@ + + + + + + + LCOV - plumed test coverage - function/FunctionOfMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:20021692.6 %
Date:2024-10-17 16:45:00Functions:8510878.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE22getNumberOfDerivativesEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE22getNumberOfDerivativesEv0
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE18getNumberOfColumnsEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE26getValueShapeFromArgumentsEv1
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE26getValueShapeFromArgumentsEv1
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE22getNumberOfDerivativesEv2
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE26getValueShapeFromArgumentsEv2
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEC1ERKNS_13ActionOptionsE2
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE18getNumberOfColumnsEv2
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE7prepareEv5
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE7prepareEv5
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE5
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE26getValueShapeFromArgumentsEv6
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEEC1ERKNS_13ActionOptionsE6
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE26getValueShapeFromArgumentsEv6
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE6
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE22getNumberOfDerivativesEv8
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_10
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE7prepareEv10
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_12
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE7prepareEv12
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE7prepareEv13
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE17turnOnDerivativesEv14
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE22getNumberOfDerivativesEv14
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE18getNumberOfColumnsEv14
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_17
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE18getNumberOfColumnsEv20
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE26getValueShapeFromArgumentsEv26
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE17turnOnDerivativesEv30
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE22getNumberOfDerivativesEv30
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE26getValueShapeFromArgumentsEv41
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE26getValueShapeFromArgumentsEv42
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE42
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE17turnOnDerivativesEv44
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE51
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE7prepareEv114
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE7prepareEv165
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_170
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_188
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE7prepareEv189
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_195
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE22getNumberOfDerivativesEv233
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE26getValueShapeFromArgumentsEv370
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEEC1ERKNS_13ActionOptionsE370
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE17turnOnDerivativesEv398
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE22getNumberOfDerivativesEv398
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE16registerKeywordsERNS_8KeywordsE745
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE750
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE17turnOnDerivativesEv1429
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE7prepareEv1716
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_1923
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1995
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3403
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE4000
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8109
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE20398
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE26068
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE22getNumberOfDerivativesEv29726
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE30666
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE48510
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE48510
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE134163
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE18getNumberOfColumnsEv281808
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE503510
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE606751
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE943610
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE1742755
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE2486314
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE3980129
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE17568562
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfMatrix.h.func.html b/coverage/function/FunctionOfMatrix.h.func.html new file mode 100644 index 000000000..7024c6b96 --- /dev/null +++ b/coverage/function/FunctionOfMatrix.h.func.html @@ -0,0 +1,504 @@ + + + + + + + LCOV - plumed test coverage - function/FunctionOfMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:20021692.6 %
Date:2024-10-17 16:45:00Functions:8510878.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE17turnOnDerivativesEv44
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE22getNumberOfDerivativesEv233
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_195
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE26getValueShapeFromArgumentsEv41
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEE7prepareEv189
_ZN4PLMD8function16FunctionOfMatrixINS0_3SumEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE16registerKeywordsERNS_8KeywordsE745
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE17turnOnDerivativesEv398
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE22getNumberOfDerivativesEv398
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_1923
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE26getValueShapeFromArgumentsEv370
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEE7prepareEv1716
_ZN4PLMD8function16FunctionOfMatrixINS0_6CustomEEC1ERKNS_13ActionOptionsE370
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE22getNumberOfDerivativesEv2
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE26getValueShapeFromArgumentsEv1
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEE7prepareEv5
_ZN4PLMD8function16FunctionOfMatrixINS0_7BetweenEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE17turnOnDerivativesEv30
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE22getNumberOfDerivativesEv30
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_170
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE26getValueShapeFromArgumentsEv26
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEE7prepareEv165
_ZN4PLMD8function16FunctionOfMatrixINS0_7CombineEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE22getNumberOfDerivativesEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE26getValueShapeFromArgumentsEv1
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEE7prepareEv5
_ZN4PLMD8function16FunctionOfMatrixINS0_8LessThanEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE22getNumberOfDerivativesEv0
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_12
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE26getValueShapeFromArgumentsEv6
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE7prepareEv13
_ZN4PLMD8function16FunctionOfMatrixINS0_8MoreThanEEC1ERKNS_13ActionOptionsE6
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE17turnOnDerivativesEv1429
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE22getNumberOfDerivativesEv29726
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_188
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE26getValueShapeFromArgumentsEv42
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE7prepareEv114
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE42
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE22getNumberOfDerivativesEv8
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_10
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE26getValueShapeFromArgumentsEv2
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE7prepareEv10
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE17turnOnDerivativesEv14
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE22getNumberOfDerivativesEv14
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_17
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE26getValueShapeFromArgumentsEv6
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE7prepareEv12
_ZN4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE6
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE606751
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE51
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8109
_ZNK4PLMD8function16FunctionOfMatrixINS0_3SumEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE17568562
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3403
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE134163
_ZNK4PLMD8function16FunctionOfMatrixINS0_6CustomEE18getNumberOfColumnsEv281808
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE48510
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZNK4PLMD8function16FunctionOfMatrixINS0_7BetweenEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE3980129
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE5
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE20398
_ZNK4PLMD8function16FunctionOfMatrixINS0_7CombineEE18getNumberOfColumnsEv2
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE48510
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZNK4PLMD8function16FunctionOfMatrixINS0_8LessThanEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSD_RNS_10MultiValueE503510
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE750
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1995
_ZNK4PLMD8function16FunctionOfMatrixINS0_8MoreThanEE18getNumberOfColumnsEv14
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE1742755
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE30666
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE18getNumberOfColumnsEv0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE943610
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE4000
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE18getNumberOfColumnsEv20
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE2486314
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE26068
_ZNK4PLMD8function16FunctionOfMatrixINS_7symfunc7FccubicEE18getNumberOfColumnsEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfMatrix.h.gcov.html b/coverage/function/FunctionOfMatrix.h.gcov.html new file mode 100644 index 000000000..972f8c76b --- /dev/null +++ b/coverage/function/FunctionOfMatrix.h.gcov.html @@ -0,0 +1,517 @@ + + + + + + + LCOV - plumed test coverage - function/FunctionOfMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:20021692.6 %
Date:2024-10-17 16:45:00Functions: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_function_FunctionOfMatrix_h
+      23             : #define __PLUMED_function_FunctionOfMatrix_h
+      24             : 
+      25             : #include "core/ActionWithMatrix.h"
+      26             : #include "FunctionOfVector.h"
+      27             : #include "Sum.h"
+      28             : #include "tools/Matrix.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : template <class T>
+      34             : class FunctionOfMatrix : public ActionWithMatrix {
+      35             : private:
+      36             : /// Is this the first step of the calculation
+      37             :   bool firststep;
+      38             : /// The function that is being computed
+      39             :   T myfunc;
+      40             : /// The number of derivatives for this action
+      41             :   unsigned nderivatives;
+      42             : /// A vector that tells us if we have stored the input value
+      43             :   std::vector<bool> stored_arguments;
+      44             : /// Switch off updating the arguments for this action
+      45             :   std::vector<bool> update_arguments;
+      46             : /// The list of actiosn in this chain
+      47             :   std::vector<std::string> actionsLabelsInChain;
+      48             : /// Get the shape of the output matrix
+      49             :   std::vector<unsigned> getValueShapeFromArguments();
+      50             : public:
+      51             :   static void registerKeywords(Keywords&);
+      52             :   explicit FunctionOfMatrix(const ActionOptions&);
+      53             : /// Get the label to write in the graph
+      54           0 :   std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); }
+      55             : /// Make sure the derivatives are turned on
+      56             :   void turnOnDerivatives() override;
+      57             : /// Get the number of derivatives for this action
+      58             :   unsigned getNumberOfDerivatives() override ;
+      59             : /// Resize the matrices
+      60             :   void prepare() override ;
+      61             : /// This gets the number of columns
+      62             :   unsigned getNumberOfColumns() const override ;
+      63             : /// This checks for tasks in the parent class
+      64             : //  void buildTaskListFromArgumentRequests( const unsigned& ntasks, bool& reduce, std::set<AtomNumber>& otasks ) override ;
+      65             : /// This ensures that we create some bookeeping stuff during the first step
+      66             :   void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override ;
+      67             : /// This sets up for the task
+      68             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      69             : /// Calculate the full matrix
+      70             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override ;
+      71             : /// This updates the indices for the matrix
+      72             : //  void updateCentralMatrixIndex( const unsigned& ind, const std::vector<unsigned>& indices, MultiValue& myvals ) const override ;
+      73             :   void runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      74             : };
+      75             : 
+      76             : template <class T>
+      77        1013 : void FunctionOfMatrix<T>::registerKeywords(Keywords& keys ) {
+      78        2026 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG"); std::string name = keys.getDisplayName();
+      79        1013 :   std::size_t und=name.find("_MATRIX"); keys.setDisplayName( name.substr(0,und) );
+      80        2026 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      81        2026 :   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        1013 :   T tfunc; tfunc.registerKeywords( keys );
+      83        2026 :   if( keys.getDisplayName()=="SUM" ) {
+      84         168 :     keys.setValueDescription("the sum of all the elements in the input matrix");
+      85        1858 :   } else if( keys.getDisplayName()=="HIGHEST" ) {
+      86           0 :     keys.setValueDescription("the largest element of the input matrix");
+      87        1858 :   } else if( keys.getDisplayName()=="LOWEST" ) {
+      88           0 :     keys.setValueDescription("the smallest element in the input matrix");
+      89        1858 :   } else if( keys.outputComponentExists(".#!value") ) {
+      90        1672 :     keys.setValueDescription("the matrix obtained by doing an element-wise application of " + keys.getOutputComponentDescription(".#!value") + " to the input matrix");
+      91             :   }
+      92        1899 : }
+      93             : 
+      94             : template <class T>
+      95         495 : FunctionOfMatrix<T>::FunctionOfMatrix(const ActionOptions&ao):
+      96             :   Action(ao),
+      97             :   ActionWithMatrix(ao),
+      98         495 :   firststep(true)
+      99             : {
+     100         451 :   if( myfunc.getArgStart()>0 ) error("this has not beeen implemented -- if you are interested email gareth.tribello@gmail.com");
+     101             :   // Get the shape of the output
+     102         495 :   std::vector<unsigned> shape( getValueShapeFromArguments() );
+     103             :   // Check if the output matrix is symmetric
+     104         495 :   bool symmetric=true; unsigned argstart=myfunc.getArgStart();
+     105        1508 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     106        1013 :     if( getPntrToArgument(i)->getRank()==2 ) {
+     107         948 :       if( !getPntrToArgument(i)->isSymmetric() ) { symmetric=false;  }
+     108             :     }
+     109             :   }
+     110             :   // Read the input and do some checks
+     111         495 :   myfunc.read( this );
+     112             :   // Setup to do this in chain if possible
+     113         495 :   if( myfunc.doWithTasks() ) done_in_chain=true;
+     114             :   // Check we are not calculating a sum
+     115          41 :   if( myfunc.zeroRank() ) shape.resize(0);
+     116             :   // Get the names of the components
+     117         495 :   std::vector<std::string> components( keywords.getOutputComponents() );
+     118             :   // Create the values to hold the output
+     119          42 :   std::vector<std::string> str_ind( myfunc.getComponentsPerLabel() );
+     120        1034 :   for(unsigned i=0; i<components.size(); ++i) {
+     121          84 :     if( str_ind.size()>0 ) {
+     122         168 :       std::string compstr = components[i]; if( components[i]==".#!value" ) compstr = "";
+     123         760 :       for(unsigned j=0; j<str_ind.size(); ++j) {
+     124             :         if( myfunc.zeroRank() ) {
+     125             :           addComponentWithDerivatives( compstr + str_ind[j], shape );
+     126             :         } else {
+     127        1352 :           addComponent( compstr + str_ind[j], shape );
+     128         676 :           getPntrToComponent(i*str_ind.size()+j)->setSymmetric( symmetric );
+     129             :         }
+     130             :       }
+     131          41 :     } else if( components[i]==".#!value" && myfunc.zeroRank() ) {
+     132          41 :       addValueWithDerivatives( shape );
+     133         414 :     } else if( components[i]==".#!value" ) {
+     134         410 :       addValue( shape ); getPntrToComponent(0)->setSymmetric( symmetric );
+     135           4 :     } else if( components[i].find_first_of("_")!=std::string::npos ) {
+     136           0 :       if( getNumberOfArguments()-argstart==1 ) { addValue( shape ); getPntrToComponent(0)->setSymmetric( symmetric ); }
+     137             :       else {
+     138           0 :         for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     139           0 :           addComponent( getPntrToArgument(j)->getName() + components[i], shape );
+     140           0 :           getPntrToComponent(i*(getNumberOfArguments()-argstart)+j-argstart)->setSymmetric( symmetric );
+     141             :         }
+     142             :       }
+     143           4 :     } else { addComponent( components[i], shape ); getPntrToComponent(i)->setSymmetric( symmetric ); }
+     144             :   }
+     145             :   // Check if this can be sped up
+     146         370 :   if( myfunc.getDerivativeZeroIfValueIsZero() )  {
+     147         174 :     for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+     148             :   }
+     149             :   // Set the periodicities of the output components
+     150         495 :   myfunc.setPeriodicityForOutputs( this );
+     151             :   // 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
+     152             :   // In order to do this type of calculation.  There should be a neater fix than this but I can't see it.
+     153             :   bool foundneigh=false; const ActionWithMatrix* chainstart = NULL;
+     154        1503 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     155        1207 :     if( getPntrToArgument(i)->isConstant() && getNumberOfArguments()>1 ) continue ;
+     156         932 :     std::string argname=(getPntrToArgument(i)->getPntrToAction())->getName();
+     157         932 :     if( argname=="NEIGHBORS" ) { foundneigh=true; break; }
+     158         929 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     159         929 :     if( !av ) done_in_chain=false;
+     160         929 :     if( getPntrToArgument(i)->getRank()==0 ) {
+     161           0 :       function::FunctionOfVector<function::Sum>* as = dynamic_cast<function::FunctionOfVector<function::Sum>*>( getPntrToArgument(i)->getPntrToAction() );
+     162           0 :       if(as) done_in_chain=false;
+     163         929 :     } else if( getPntrToArgument(i)->ignoreStoredValue( getLabel() ) ) {
+     164             :       // 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
+     165             :       // of the two adjacency matrix are run over separately.  The value A_ij is thus not available when B_ij is calculated.
+     166         853 :       ActionWithMatrix* am = dynamic_cast<ActionWithMatrix*>( getPntrToArgument(i)->getPntrToAction() );
+     167         853 :       plumed_assert( am ); const ActionWithMatrix* thischain = am->getFirstMatrixInChain();
+     168         853 :       if( !thischain->isAdjacencyMatrix() && thischain->getName()!="VSTACK" ) continue;
+     169         657 :       if( !chainstart ) chainstart = thischain;
+     170         317 :       else if( thischain!=chainstart ) done_in_chain=false;
+     171             :     }
+     172             :   }
+     173             :   // If we are working with neighbors we trick PLUMED into storing ALL the components of the other arguments
+     174             :   // in this way we can ensure that the function of the neighbours matrix is in a chain starting from the
+     175             :   // Neighbours matrix action.
+     176             :   if( foundneigh ) {
+     177           9 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     178           6 :       ActionWithValue* av=getPntrToArgument(i)->getPntrToAction();
+     179           6 :       if( av->getName()!="NEIGHBORS" ) {
+     180           8 :         for(int i=0; i<av->getNumberOfComponents(); ++i) (av->copyOutput(i))->buildDataStore();
+     181             :       }
+     182             :     }
+     183             :   }
+     184             :   // Now setup the action in the chain if we can
+     185         495 :   nderivatives = buildArgumentStore(myfunc.getArgStart());
+     186         990 : }
+     187             : 
+     188             : template <class T>
+     189        1921 : void FunctionOfMatrix<T>::turnOnDerivatives() {
+     190        1921 :   if( !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+     191        1921 :   ActionWithValue::turnOnDerivatives(); myfunc.setup(this);
+     192        1921 : }
+     193             : 
+     194             : template <class T>
+     195       30411 : unsigned FunctionOfMatrix<T>::getNumberOfDerivatives() {
+     196       30411 :   return nderivatives;
+     197             : }
+     198             : 
+     199             : template <class T>
+     200        2229 : void FunctionOfMatrix<T>::prepare() {
+     201        2229 :   unsigned argstart = myfunc.getArgStart(); std::vector<unsigned> shape(2);
+     202        2229 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     203        2229 :     if( getPntrToArgument(i)->getRank()==2 ) {
+     204        2229 :       shape[0] = getPntrToArgument(i)->getShape()[0];
+     205        2229 :       shape[1] = getPntrToArgument(i)->getShape()[1];
+     206        2229 :       break;
+     207             :     }
+     208             :   }
+     209        6682 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     210        4453 :     Value* myval = getPntrToComponent(i);
+     211        4453 :     if( myval->getRank()==2 && (myval->getShape()[0]!=shape[0] || myval->getShape()[1]!=shape[1]) ) {
+     212          18 :       myval->setShape(shape); if( myval->valueIsStored() ) myval->reshapeMatrixStore( shape[1] );
+     213             :     }
+     214             :   }
+     215        2229 :   ActionWithVector::prepare();
+     216        2229 : }
+     217             : 
+     218             : template <class T>
+     219      281844 : unsigned FunctionOfMatrix<T>::getNumberOfColumns() const {
+     220      281844 :   if( getConstPntrToComponent(0)->getRank()==2 ) {
+     221             :     unsigned argstart=myfunc.getArgStart();
+     222      281844 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     223      281844 :       if( getPntrToArgument(i)->getRank()==2 ) {
+     224      281844 :         ActionWithMatrix* am=dynamic_cast<ActionWithMatrix*>( getPntrToArgument(i)->getPntrToAction() );
+     225      281844 :         if( am ) return am->getNumberOfColumns();
+     226        2238 :         return getPntrToArgument(i)->getShape()[1];
+     227             :       }
+     228             :     }
+     229             :   }
+     230           0 :   plumed_error(); return 0;
+     231             : }
+     232             : 
+     233             : template <class T>
+     234        4209 : void FunctionOfMatrix<T>::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     235       11667 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) plumed_assert( getPntrToArgument(i)->getRank()==2 );
+     236        4209 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(0)->getShape()[1];
+     237        4209 :   if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+     238      642613 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     239             :   myvals.setSplitIndex( size_v + 1 );
+     240        4209 : }
+     241             : 
+     242             : // template <class T>
+     243             : // void FunctionOfMatrix<T>::buildTaskListFromArgumentRequests( const unsigned& ntasks, bool& reduce, std::set<AtomNumber>& otasks ) {
+     244             : //   // Check if this is the first element in a chain
+     245             : //   if( actionInChain() ) return;
+     246             : //   // If it is computed outside a chain get the tassks the daughter chain needs
+     247             : //   propegateTaskListsForValue( 0, ntasks, reduce, otasks );
+     248             : // }
+     249             : 
+     250             : template <class T>
+     251        2525 : void FunctionOfMatrix<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     252        2525 :   if( firststep ) {
+     253         489 :     stored_arguments.resize( getNumberOfArguments() );
+     254         489 :     update_arguments.resize( getNumberOfArguments(), true );
+     255         489 :     std::string control = getFirstActionInChain()->getLabel();
+     256        1484 :     for(unsigned i=0; i<stored_arguments.size(); ++i) {
+     257         995 :       stored_arguments[i] = !getPntrToArgument(i)->ignoreStoredValue( control );
+     258         995 :       if( !stored_arguments[i] ) update_arguments[i] = true;
+     259         164 :       else update_arguments[i] = !argumentDependsOn( headstr, this, getPntrToArgument(i) );
+     260             :     }
+     261         489 :     firststep=false;
+     262             :   }
+     263        2525 :   ActionWithMatrix::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     264        2525 : }
+     265             : 
+     266             : template <class T>
+     267    27928651 : void FunctionOfMatrix<T>::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     268    27928651 :   unsigned argstart=myfunc.getArgStart(); std::vector<double> args( getNumberOfArguments() - argstart );
+     269    27928651 :   unsigned ind2 = index2;
+     270    27928651 :   if( getConstPntrToComponent(0)->getRank()==2 && index2>=getConstPntrToComponent(0)->getShape()[0] ) ind2 = index2 - getConstPntrToComponent(0)->getShape()[0];
+     271    24292268 :   else if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     272    27928651 :   if( actionInChain() ) {
+     273    85619946 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     274    58329699 :       if( getPntrToArgument(i)->getRank()==0 ) args[i-argstart] = getPntrToArgument(i)->get();
+     275    58193979 :       else if( !getPntrToArgument(i)->valueHasBeenSet() ) args[i-argstart] = myvals.get( getPntrToArgument(i)->getPositionInStream() );
+     276     1188593 :       else args[i-argstart] = getPntrToArgument(i)->get( getPntrToArgument(i)->getShape()[1]*index1 + ind2 );
+     277             :     }
+     278             :   } else {
+     279     1727072 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     280     1088668 :       if( getPntrToArgument(i)->getRank()==2 ) args[i-argstart]=getPntrToArgument(i)->get( getPntrToArgument(i)->getShape()[1]*index1 + ind2 );
+     281           0 :       else args[i-argstart] = getPntrToArgument(i)->get();
+     282             :     }
+     283             :   }
+     284             :   // Calculate the function and its derivatives
+     285    27928651 :   std::vector<double> vals( getNumberOfComponents() ); Matrix<double> derivatives( getNumberOfComponents(), getNumberOfArguments()-argstart );
+     286    27928651 :   myfunc.calc( this, args, vals, derivatives );
+     287             :   // And set the values
+     288    99634355 :   for(unsigned i=0; i<vals.size(); ++i) myvals.addValue( getConstPntrToComponent(i)->getPositionInStream(), vals[i] );
+     289             :   // Return if we are not computing derivatives
+     290    27928651 :   if( doNotCalculateDerivatives() ) return;
+     291             : 
+     292     5399619 :   if( actionInChain() ) {
+     293    33385311 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     294    27990552 :       unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     295   131996523 :       for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     296   104005971 :         if( getPntrToArgument(j)->getRank()==2 ) {
+     297   103890411 :           unsigned istrn = getPntrToArgument(j)->getPositionInStream();
+     298   103890411 :           if( stored_arguments[j] ) {
+     299      395048 :             unsigned task_index = getPntrToArgument(i)->getShape()[1]*index1 + ind2;
+     300      395048 :             myvals.clearDerivatives(istrn); myvals.addDerivative( istrn, task_index, 1.0 ); myvals.updateIndex( istrn, task_index );
+     301             :           }
+     302   470717695 :           for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     303   366827284 :             unsigned kind=myvals.getActiveIndex(istrn,k);
+     304   366827284 :             myvals.addDerivative( ostrn, arg_deriv_starts[j] + kind, derivatives(i,j)*myvals.getDerivative( istrn, kind ) );
+     305             :           }
+     306             :         }
+     307             :       }
+     308             :     }
+     309             :     // If we are computing a matrix we need to update the indices here so that derivatives are calcualted correctly in functions of these
+     310     5394759 :     if( getConstPntrToComponent(0)->getRank()==2 ) {
+     311    32784527 :       for(int i=0; i<getNumberOfComponents(); ++i) {
+     312    27690160 :         unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     313   131395739 :         for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     314   103705579 :           if( !update_arguments[j] || getPntrToArgument(j)->getRank()==0 ) continue ;
+     315             :           // Ensure we only store one lot of derivative indices
+     316             :           bool found=false;
+     317   105009550 :           for(unsigned k=0; k<j; ++k) {
+     318    76601003 :             if( arg_deriv_starts[k]==arg_deriv_starts[j] ) { found=true; break; }
+     319             :           }
+     320   103589995 :           if( found ) continue;
+     321             :           unsigned istrn = getPntrToArgument(j)->getPositionInStream();
+     322   138447375 :           for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     323   110038828 :             unsigned kind=myvals.getActiveIndex(istrn,k);
+     324   110038828 :             myvals.updateIndex( ostrn, arg_deriv_starts[j] + kind );
+     325             :           }
+     326             :         }
+     327             :       }
+     328             :     }
+     329             :   } else {
+     330        4860 :     unsigned base=0; ind2 = index2;
+     331        4860 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     332        4860 :       if( getPntrToArgument(j)->getRank()!=2 ) continue ;
+     333        4860 :       if( index2>=getPntrToArgument(j)->getShape()[0] ) ind2 = index2 - getPntrToArgument(j)->getShape()[0];
+     334             :       break;
+     335             :     }
+     336       13965 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     337        9105 :       if( getPntrToArgument(j)->getRank()==2 ) {
+     338       18210 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     339        9105 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     340        9105 :           unsigned myind = base + getPntrToArgument(j)->getShape()[1]*index1 + ind2;
+     341        9105 :           myvals.addDerivative( ostrn, myind, derivatives(i,j) );
+     342        9105 :           myvals.updateIndex( ostrn, myind );
+     343             :         }
+     344             :       } else {
+     345           0 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     346           0 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     347           0 :           myvals.addDerivative( ostrn, base, derivatives(i,j) );
+     348           0 :           myvals.updateIndex( ostrn, base );
+     349             :         }
+     350             :       }
+     351        9105 :       base += getPntrToArgument(j)->getNumberOfValues();
+     352             :     }
+     353             :   }
+     354             : }
+     355             : 
+     356             : template <class T>
+     357      226389 : void FunctionOfMatrix<T>::runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     358      226389 :   if( doNotCalculateDerivatives() ) return;
+     359             : 
+     360             :   unsigned argstart=myfunc.getArgStart();
+     361       71237 :   if( actionInChain() && getConstPntrToComponent(0)->getRank()==2 ) {
+     362             :     // This is triggered if we are outputting a matrix
+     363      624578 :     for(int vv=0; vv<getNumberOfComponents(); ++vv) {
+     364      558183 :       unsigned nmat = getConstPntrToComponent(vv)->getPositionInMatrixStash();
+     365             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntot_mat=0;
+     366      558183 :       if( mat_indices.size()<nderivatives ) mat_indices.resize( nderivatives );
+     367     2701544 :       for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     368     2143361 :         if( !update_arguments[i] || getPntrToArgument(i)->getRank()==0 ) continue ;
+     369             :         // Ensure we only store one lot of derivative indices
+     370             :         bool found=false;
+     371     2168017 :         for(unsigned j=0; j<i; ++j) {
+     372     1591516 :           if( arg_deriv_starts[j]==arg_deriv_starts[i] ) { found=true; break; }
+     373             :         }
+     374     2142277 :         if( found ) continue;
+     375             : 
+     376      576501 :         if( stored_arguments[i] ) {
+     377       15483 :           unsigned tbase = getPntrToArgument(i)->getShape()[1]*ind;
+     378      410507 :           for(unsigned k=1; k<indices.size(); ++k) {
+     379      395024 :             unsigned ind2 = indices[k] - getConstPntrToComponent(0)->getShape()[0];
+     380      395024 :             mat_indices[ntot_mat + k - 1] = arg_deriv_starts[i] + tbase + ind2;
+     381             :           }
+     382       15483 :           ntot_mat += indices.size()-1;
+     383             :         } else {
+     384             :           unsigned istrn = getPntrToArgument(i)->getPositionInMatrixStash();
+     385             :           std::vector<unsigned>& imat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     386    31848426 :           for(unsigned k=0; k<myvals.getNumberOfMatrixRowDerivatives( istrn ); ++k) mat_indices[ntot_mat + k] = arg_deriv_starts[i] + imat_indices[k];
+     387      561018 :           ntot_mat += myvals.getNumberOfMatrixRowDerivatives( istrn );
+     388             :         }
+     389             :       }
+     390             :       myvals.setNumberOfMatrixRowDerivatives( nmat, ntot_mat );
+     391             :     }
+     392        4842 :   } else if( actionInChain() ) {
+     393             :     // This is triggered if we are calculating a single scalar in the function
+     394        8822 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     395             :       bool found=false;
+     396        4411 :       for(unsigned j=0; j<i; ++j) {
+     397           0 :         if( arg_deriv_starts[j]==arg_deriv_starts[i] ) { found=true; break; }
+     398             :       }
+     399        4411 :       if( found ) continue;
+     400             :       unsigned istrn = getPntrToArgument(i)->getPositionInMatrixStash();
+     401             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     402      926766 :       for(unsigned k=0; k<myvals.getNumberOfMatrixRowDerivatives( istrn ); ++k) {
+     403     1844710 :         for(int j=0; j<getNumberOfComponents(); ++j) {
+     404      922355 :           unsigned ostrn = getConstPntrToComponent(j)->getPositionInStream();
+     405      922355 :           myvals.updateIndex( ostrn, arg_deriv_starts[i] + mat_indices[k] );
+     406             :         }
+     407             :       }
+     408             :     }
+     409         431 :   } else if( getConstPntrToComponent(0)->getRank()==2 ) {
+     410         760 :     for(int vv=0; vv<getNumberOfComponents(); ++vv) {
+     411         380 :       unsigned nmat = getConstPntrToComponent(vv)->getPositionInMatrixStash();
+     412             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntot_mat=0;
+     413         380 :       if( mat_indices.size()<nderivatives ) mat_indices.resize( nderivatives ); unsigned matderbase = 0;
+     414         986 :       for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     415         606 :         if( getPntrToArgument(i)->getRank()==0 ) continue ;
+     416         606 :         unsigned ss = getPntrToArgument(i)->getShape()[1]; unsigned tbase = matderbase + ss*myvals.getTaskIndex();
+     417        9558 :         for(unsigned k=0; k<ss; ++k) mat_indices[ntot_mat + k] = tbase + k;
+     418         606 :         ntot_mat += ss; matderbase += getPntrToArgument(i)->getNumberOfValues();
+     419             :       }
+     420             :       myvals.setNumberOfMatrixRowDerivatives( nmat, ntot_mat );
+     421             :     }
+     422             :   }
+     423             : }
+     424             : 
+     425             : template <class T>
+     426         495 : std::vector<unsigned> FunctionOfMatrix<T>::getValueShapeFromArguments() {
+     427         495 :   unsigned argstart=myfunc.getArgStart(); std::vector<unsigned> shape(2); shape[0]=shape[1]=0;
+     428        1508 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     429        1013 :     plumed_assert( getPntrToArgument(i)->getRank()==2 || getPntrToArgument(i)->getRank()==0 );
+     430        1013 :     if( getPntrToArgument(i)->getRank()==2 ) {
+     431         948 :       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");
+     432         948 :       else if( shape[0]==0 ) { shape[0]=getPntrToArgument(i)->getShape()[0]; shape[1]=getPntrToArgument(i)->getShape()[1]; }
+     433         948 :       plumed_assert( !getPntrToArgument(i)->hasDerivatives() );
+     434             :     }
+     435             :   }
+     436         495 :   myfunc.setPrefactor( this, 1.0 ); return shape;
+     437             : }
+     438             : 
+     439             : }
+     440             : }
+     441             : #endif
+
+
+
+ + + + +
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 000000000..7ef306de1 --- /dev/null +++ b/coverage/function/FunctionOfScalar.h.func-sort-c.html @@ -0,0 +1,392 @@ + + + + + + + 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:414395.3 %
Date:2024-10-17 16:45:00Functions:528065.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_3SumEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_6BesselEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_6CustomEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7CombineEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7HighestEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7MomentsEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_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_9PiecewiseEEC1ERKNS_13ActionOptionsE3
_ZNK4PLMD8function16FunctionOfScalarINS0_4SortEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE3
_ZNK4PLMD8function16FunctionOfScalarINS0_6CustomEE12writeInGraphB5cxx11Ev3
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE9calculateEv5
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE17turnOnDerivativesEv6
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE9calculateEv11
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED0Ev12
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED1Ev12
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEEC1ERKNS_13ActionOptionsE13
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED0Ev41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED1Ev41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED0Ev192
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED1Ev192
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEEC1ERKNS_13ActionOptionsE195
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE16registerKeywordsERNS_8KeywordsE389
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE17turnOnDerivativesEv613
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEEC1ERKNS_13ActionOptionsE1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED0Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED1Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE17turnOnDerivativesEv1527
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE9calculateEv1675
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE9calculateEv1676
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE16registerKeywordsERNS_8KeywordsE2348
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE9calculateEv31273
_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 000000000..68ec37a71 --- /dev/null +++ b/coverage/function/FunctionOfScalar.h.func.html @@ -0,0 +1,392 @@ + + + + + + + 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:414395.3 %
Date:2024-10-17 16:45:00Functions:528065.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_8KeywordsE28
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE9calculateEv11
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEEC1ERKNS_13ActionOptionsE13
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED0Ev12
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED1Ev12
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE9calculateEv0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEEC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEED0Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEED1Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE16registerKeywordsERNS_8KeywordsE2348
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE17turnOnDerivativesEv1527
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE9calculateEv56792
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEEC1ERKNS_13ActionOptionsE1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED0Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED1Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE16registerKeywordsERNS_8KeywordsE389
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE17turnOnDerivativesEv613
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE9calculateEv31273
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEEC1ERKNS_13ActionOptionsE195
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED0Ev192
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED1Ev192
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEED0Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEED1Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE9calculateEv5
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEED0Ev1
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEED1Ev1
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEED0Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEED1Ev2
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE17turnOnDerivativesEv6
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE9calculateEv1676
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED0Ev41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED1Ev41
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE9calculateEv1675
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEED0Ev1
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEED1Ev1
_ZNK4PLMD8function16FunctionOfScalarINS0_3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_3SumEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_4SortEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE3
_ZNK4PLMD8function16FunctionOfScalarINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_6BesselEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_6CustomEE12writeInGraphB5cxx11Ev3
_ZNK4PLMD8function16FunctionOfScalarINS0_6CustomEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7CombineEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7HighestEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7MomentsEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
+
+
+ + + +
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 000000000..bc9051ec0 --- /dev/null +++ b/coverage/function/FunctionOfScalar.h.gcov.html @@ -0,0 +1,195 @@ + + + + + + + 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:414395.3 %
Date:2024-10-17 16:45:00Functions:528065.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_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        2846 :   virtual ~FunctionOfScalar() {}
+      47             : /// Get the label to write in the graph
+      48           3 :   std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); }
+      49             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      50             :   void calculate() override;
+      51             :   static void registerKeywords(Keywords&);
+      52             :   void turnOnDerivatives() override;
+      53             : };
+      54             : 
+      55             : template <class T>
+      56        2878 : void FunctionOfScalar<T>::registerKeywords(Keywords& keys) {
+      57        5756 :   Function::registerKeywords(keys); keys.use("ARG"); std::string name = keys.getDisplayName();
+      58        2878 :   std::size_t und=name.find("_SCALAR"); keys.setDisplayName( name.substr(0,und) );
+      59        5756 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      60        2878 :   T tfunc; tfunc.registerKeywords( keys );
+      61        5758 :   if( keys.getDisplayName()=="SUM" ) keys.setValueDescription("the sum of all the input arguments");
+      62        5754 :   else if( keys.getDisplayName()=="MEAN" ) keys.setValueDescription("the mean of all the input arguments");
+      63        5703 : }
+      64             : 
+      65             : template <class T>
+      66        1428 : FunctionOfScalar<T>::FunctionOfScalar(const ActionOptions&ao):
+      67             :   Action(ao),
+      68             :   Function(ao),
+      69        1428 :   firststep(true)
+      70             : {
+      71        1428 :   myfunc.read( this );
+      72             :   // Get the names of the components
+      73        1423 :   std::vector<std::string> components( keywords.getOutputComponents() );
+      74             :   // Create the values to hold the output
+      75        1380 :   std::vector<std::string> str_ind( myfunc.getComponentsPerLabel() );
+      76        2846 :   for(unsigned i=0; i<components.size(); ++i) {
+      77          13 :     if( str_ind.size()>0 ) {
+      78          26 :       std::string compstr = components[i]; if( compstr==".#!value" ) compstr = "";
+      79          40 :       for(unsigned j=0; j<str_ind.size(); ++j) addComponentWithDerivatives( compstr + str_ind[j] );
+      80        1410 :     } else if( components[i]==".#!value" ) addValueWithDerivatives();
+      81           2 :     else if( components[i].find_first_of("_")!=std::string::npos ) {
+      82           2 :       if( getNumberOfArguments()==1 ) addValueWithDerivatives();
+      83           3 :       else { for(unsigned j=0; j<getNumberOfArguments(); ++j) addComponentWithDerivatives( getPntrToArgument(j)->getName() + components[i] ); }
+      84           0 :     } else addComponentWithDerivatives( components[i] );
+      85             :   }
+      86             :   // Set the periodicities of the output components
+      87        1423 :   myfunc.setPeriodicityForOutputs( this ); myfunc.setPrefactor( this, 1.0 );
+      88        1436 : }
+      89             : 
+      90             : template <class T>
+      91           3 : std::string FunctionOfScalar<T>::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+      92           3 :   if( getName().find("SORT")==std::string::npos ) return ActionWithValue::getOutputComponentDescription( cname, keys );
+      93           6 :   return "the " + cname + "th largest of the input scalars";
+      94             : }
+      95             : 
+      96             : template <class T>
+      97        2160 : void FunctionOfScalar<T>::turnOnDerivatives() {
+      98           0 :   if( !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+      99        2160 :   ActionWithValue::turnOnDerivatives();
+     100        2160 : }
+     101             : 
+     102             : template <class T>
+     103       91452 : void FunctionOfScalar<T>::calculate() {
+     104       91452 :   if( firststep ) { myfunc.setup( this ); firststep=false; } unsigned argstart = myfunc.getArgStart();
+     105      207653 :   std::vector<double> args( getNumberOfArguments() - argstart ); for(unsigned i=argstart; i<getNumberOfArguments(); ++i) args[i-argstart]=getPntrToArgument(i)->get();
+     106       91452 :   std::vector<double> vals( getNumberOfComponents() ); Matrix<double> derivatives( getNumberOfComponents(), args.size() );
+     107       91452 :   myfunc.calc( this, args, vals, derivatives );
+     108      182941 :   for(unsigned i=0; i<vals.size(); ++i) copyOutput(i)->set(vals[i]);
+     109       91452 :   if( doNotCalculateDerivatives() ) return;
+     110             : 
+     111      157772 :   for(unsigned i=0; i<vals.size(); ++i) {
+     112       78901 :     Value* val = getPntrToComponent(i);
+     113      174156 :     for(unsigned j=0; j<args.size(); ++j) setDerivative( val, j, derivatives(i,j) );
+     114             :   }
+     115             : }
+     116             : 
+     117             : }
+     118             : }
+     119             : #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 000000000..661574f54 --- /dev/null +++ b/coverage/function/FunctionOfVector.h.func-sort-c.html @@ -0,0 +1,756 @@ + + + + + + + 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:16016895.2 %
Date:2024-10-17 16:45:00Functions:14717186.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_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_3SumEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE21getNumberOfFinalTasksEv1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEED0Ev1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEED1Ev1
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE12writeInGraphB5cxx11Ev1
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS7_EE2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE22getNumberOfDerivativesEv2
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE12writeInGraphB5cxx11Ev2
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE12writeInGraphB5cxx11Ev2
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE21getNumberOfFinalTasksEv4
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEEC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED0Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED1Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE21getNumberOfFinalTasksEv4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEEC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEED0Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEED1Ev4
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE5
_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_7MomentsEE16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE16registerKeywordsERNS_8KeywordsE12
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE11performTaskERKjRNS_10MultiValueE14
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE17turnOnDerivativesEv16
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE22getNumberOfDerivativesEv16
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE17turnOnDerivativesEv28
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE7prepareEv34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE9calculateEv34
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE45
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE21getNumberOfFinalTasksEv48
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEEC1ERKNS_13ActionOptionsE48
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED0Ev48
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED1Ev48
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE21getNumberOfFinalTasksEv52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEEC1ERKNS_13ActionOptionsE52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEED0Ev52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEED1Ev52
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE21getNumberOfFinalTasksEv62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEEC1ERKNS_13ActionOptionsE62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEED0Ev62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEED1Ev62
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE21getNumberOfFinalTasksEv66
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEEC1ERKNS_13ActionOptionsE66
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED0Ev66
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED1Ev66
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS7_EE71
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE17turnOnDerivativesEv74
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE22getNumberOfDerivativesEv74
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE21getNumberOfFinalTasksEv84
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEEC1ERKNS_13ActionOptionsE84
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED0Ev84
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED1Ev84
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE16registerKeywordsERNS_8KeywordsE101
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE106
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_108
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE17turnOnDerivativesEv113
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE22getNumberOfDerivativesEv113
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE17turnOnDerivativesEv114
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE126
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE136
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE21getNumberOfFinalTasksEv143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEED0Ev143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEED1Ev143
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE16registerKeywordsERNS_8KeywordsE171
_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
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE288
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE17turnOnDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE22getNumberOfDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE344
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE9calculateEv482
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE7prepareEv483
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_512
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE9calculateEv517
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE7prepareEv521
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE626
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_650
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE11performTaskERKjRNS_10MultiValueE716
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE21getNumberOfFinalTasksEv777
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEEC1ERKNS_13ActionOptionsE777
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED0Ev777
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED1Ev777
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE17turnOnDerivativesEv813
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE21getNumberOfFinalTasksEv1016
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEEC1ERKNS_13ActionOptionsE1016
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED0Ev1016
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED1Ev1016
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE16registerKeywordsERNS_8KeywordsE1561
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_1675
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE7prepareEv1675
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE9calculateEv1675
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE16registerKeywordsERNS_8KeywordsE2043
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE17turnOnDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE22getNumberOfDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE17turnOnDerivativesEv2390
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE22getNumberOfDerivativesEv2390
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE2723
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_5290
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE22getNumberOfDerivativesEv5395
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE9calculateEv5398
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE7prepareEv5402
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE7874
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE11performTaskERKjRNS_10MultiValueE8375
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE9calculateEv22536
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE7prepareEv23125
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE11performTaskERKjRNS_10MultiValueE27589
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_32776
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE9calculateEv41307
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE7prepareEv41318
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE22getNumberOfDerivativesEv41984
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE7prepareEv49487
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE9calculateEv49487
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE11performTaskERKjRNS_10MultiValueE53152
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE9calculateEv63046
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE7prepareEv63065
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_78935
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_94404
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_103238
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE11performTaskERKjRNS_10MultiValueE139487
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE11performTaskERKjRNS_10MultiValueE357792
_ZNK4PLMD8function16FunctionOfVectorINS0_3SumEE11performTaskERKjRNS_10MultiValueE1270778
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE11performTaskERKjRNS_10MultiValueE1900096
_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 000000000..32e8bf6bd --- /dev/null +++ b/coverage/function/FunctionOfVector.h.func.html @@ -0,0 +1,756 @@ + + + + + + + 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:16016895.2 %
Date:2024-10-17 16:45:00Functions:14717186.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE16registerKeywordsERNS_8KeywordsE1561
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE17turnOnDerivativesEv813
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE2723
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE21getNumberOfFinalTasksEv777
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE22getNumberOfDerivativesEv41984
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_78935
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE7prepareEv41318
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE9calculateEv41307
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEEC1ERKNS_13ActionOptionsE777
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED0Ev777
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED1Ev777
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE17turnOnDerivativesEv28
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE1
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE21getNumberOfFinalTasksEv4
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE22getNumberOfDerivativesEv230
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_0
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE7prepareEv34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE9calculateEv34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEEC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED0Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED1Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE16registerKeywordsERNS_8KeywordsE16
_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_8KeywordsE2043
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE17turnOnDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE7874
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE21getNumberOfFinalTasksEv1016
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE22getNumberOfDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_103238
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE7prepareEv63065
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE9calculateEv63046
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEEC1ERKNS_13ActionOptionsE1016
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED0Ev1016
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED1Ev1016
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE106
_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_8KeywordsE171
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE17turnOnDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE626
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE21getNumberOfFinalTasksEv84
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE22getNumberOfDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_32776
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE7prepareEv23125
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE9calculateEv22536
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEEC1ERKNS_13ActionOptionsE84
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED0Ev84
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED1Ev84
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE16registerKeywordsERNS_8KeywordsE101
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE17turnOnDerivativesEv114
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE45
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE21getNumberOfFinalTasksEv48
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE22getNumberOfDerivativesEv5395
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_108
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_5290
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE7prepareEv5402
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE9calculateEv5398
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEEC1ERKNS_13ActionOptionsE48
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED0Ev48
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED1Ev48
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE10
_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_8KeywordsE136
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE17turnOnDerivativesEv113
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE344
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE21getNumberOfFinalTasksEv66
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE22getNumberOfDerivativesEv113
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_512
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE7prepareEv483
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE9calculateEv482
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEEC1ERKNS_13ActionOptionsE66
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED0Ev66
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED1Ev66
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE126
_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_8KeywordsE288
_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_8KeywordsE4
_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_10MultiValueE1270778
_ZNK4PLMD8function16FunctionOfVectorINS0_3SumEE12writeInGraphB5cxx11Ev7
_ZNK4PLMD8function16FunctionOfVectorINS0_3SumEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE5
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE11performTaskERKjRNS_10MultiValueE14
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE11performTaskERKjRNS_10MultiValueE1900096
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE12writeInGraphB5cxx11Ev2
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE11performTaskERKjRNS_10MultiValueE716
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE12writeInGraphB5cxx11Ev1
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE11performTaskERKjRNS_10MultiValueE357792
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE11performTaskERKjRNS_10MultiValueE27589
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE11performTaskERKjRNS_10MultiValueE139487
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE12writeInGraphB5cxx11Ev2
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE11performTaskERKjRNS_10MultiValueE53152
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE12writeInGraphB5cxx11Ev8
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE11performTaskERKjRNS_10MultiValueE2876173
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE11performTaskERKjRNS_10MultiValueE8375
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
+
+
+ + + +
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 000000000..516aa7982 --- /dev/null +++ b/coverage/function/FunctionOfVector.h.gcov.html @@ -0,0 +1,436 @@ + + + + + + + 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:16016895.2 %
Date:2024-10-17 16:45:00Functions:14717186.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_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        4660 :   ~FunctionOfVector() {}
+      54             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      55             : /// Get the size of the task list at the end of the run
+      56             :   unsigned getNumberOfFinalTasks();
+      57             : /// Check if derivatives are available
+      58             :   void turnOnDerivatives() override;
+      59             : /// Get the number of derivatives for this action
+      60             :   unsigned getNumberOfDerivatives() override ;
+      61             : /// Resize vectors that are the wrong size
+      62             :   void prepare() override ;
+      63             : /// Check if all he actions are required
+      64             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions );
+      65             : /// Get the label to write in the graph
+      66          20 :   std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); }
+      67             : /// This builds the task list for the action
+      68             :   void calculate() override;
+      69             : /// This ensures that we create some bookeeping stuff during the first step
+      70             :   void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override ;
+      71             : /// Calculate the function
+      72             :   void performTask( const unsigned& current, MultiValue& myvals ) const override ;
+      73             : };
+      74             : 
+      75             : template <class T>
+      76        4574 : void FunctionOfVector<T>::registerKeywords(Keywords& keys ) {
+      77        4574 :   Action::registerKeywords(keys); ActionWithValue::registerKeywords(keys); ActionWithArguments::registerKeywords(keys); keys.use("ARG");
+      78        4574 :   std::string name = keys.getDisplayName(); std::size_t und=name.find("_VECTOR"); keys.setDisplayName( name.substr(0,und) );
+      79        9148 :   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");
+      80        9148 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      81        4574 :   T tfunc; tfunc.registerKeywords( keys );
+      82        9148 :   if( keys.getDisplayName()=="SUM" ) {
+      83        2408 :     keys.setValueDescription("the sum of all the elements in the input vector");
+      84        6740 :   } else if( keys.getDisplayName()=="MEAN" ) {
+      85         714 :     keys.setValueDescription("the mean of all the elements in the input vector");
+      86        6026 :   } else if( keys.getDisplayName()=="HIGHEST" ) {
+      87          84 :     keys.setValueDescription("the largest element of the input vector");
+      88        5942 :   } else if( keys.getDisplayName()=="LOWEST" ) {
+      89         118 :     keys.setValueDescription("the smallest element in the input vector");
+      90        5824 :   } else if( keys.getDisplayName()=="SORT" ) {
+      91          24 :     keys.setValueDescription("a vector that has been sorted into ascending order");
+      92        5800 :   } else if( keys.outputComponentExists(".#!value") ) {
+      93        5780 :     keys.setValueDescription("the vector obtained by doing an element-wise application of " + keys.getOutputComponentDescription(".#!value") + " to the input vectors");
+      94             :   }
+      95        7080 : }
+      96             : 
+      97             : template <class T>
+      98        2264 : FunctionOfVector<T>::FunctionOfVector(const ActionOptions&ao):
+      99             :   Action(ao),
+     100             :   ActionWithVector(ao),
+     101        2264 :   doAtEnd(true),
+     102        2264 :   firststep(true),
+     103        2264 :   nderivatives(0)
+     104             : {
+     105             :   // Get the shape of the output
+     106        2264 :   std::vector<unsigned> shape(1); shape[0]=getNumberOfFinalTasks();
+     107             :   // Read the input and do some checks
+     108        2264 :   myfunc.read( this );
+     109             :   // Create the task list
+     110        2121 :   if( myfunc.doWithTasks() ) {
+     111        2224 :     doAtEnd=false; if( shape[0]>0 ) done_in_chain=true;
+     112          40 :   } else { plumed_assert( getNumberOfArguments()==1 ); done_in_chain=false; getPntrToArgument(0)->buildDataStore(); }
+     113             :   // Get the names of the components
+     114        2264 :   std::vector<std::string> components( keywords.getOutputComponents() );
+     115             :   // Create the values to hold the output
+     116          56 :   std::vector<std::string> str_ind( myfunc.getComponentsPerLabel() );
+     117        4528 :   for(unsigned i=0; i<components.size(); ++i) {
+     118           8 :     if( str_ind.size()>0 ) {
+     119          16 :       std::string strcompn = components[i]; if( components[i]==".#!value" ) strcompn = "";
+     120          34 :       for(unsigned j=0; j<str_ind.size(); ++j) {
+     121          52 :         if( myfunc.zeroRank() ) addComponentWithDerivatives( strcompn + str_ind[j] );
+     122           0 :         else addComponent( strcompn + str_ind[j], shape );
+     123             :       }
+     124        2256 :     } else if( components[i].find_first_of("_")!=std::string::npos ) {
+     125           0 :       if( getNumberOfArguments()==1 && myfunc.zeroRank() ) addValueWithDerivatives();
+     126           0 :       else if( getNumberOfArguments()==1 ) addValue( shape );
+     127             :       else {
+     128             :         unsigned argstart=myfunc.getArgStart();
+     129           0 :         for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     130           0 :           if( myfunc.zeroRank() ) addComponentWithDerivatives( getPntrToArgument(i)->getName() + components[i] );
+     131           0 :           else addComponent( getPntrToArgument(i)->getName() + components[i], shape );
+     132             :         }
+     133             :       }
+     134        1635 :     } else if( components[i]==".#!value" && myfunc.zeroRank() ) addValueWithDerivatives();
+     135        1446 :     else if( components[i]==".#!value" ) addValue(shape);
+     136           0 :     else if( myfunc.zeroRank() ) addComponentWithDerivatives( components[i] );
+     137           0 :     else addComponent( components[i], shape );
+     138             :   }
+     139             :   // Check if we can turn off the derivatives when they are zero
+     140        1016 :   if( myfunc.getDerivativeZeroIfValueIsZero() )  {
+     141         612 :     for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+     142             :   }
+     143             :   // Check if this is a timeseries
+     144             :   unsigned argstart=myfunc.getArgStart();
+     145             :   // for(unsigned i=argstart; i<getNumberOfArguments();++i) {
+     146             :   //   if( getPntrToArgument(i)->isTimeSeries() ) {
+     147             :   //       for(unsigned i=0; i<getNumberOfComponents(); ++i) getPntrToOutput(i)->makeHistoryDependent();
+     148             :   //       break;
+     149             :   //   }
+     150             :   // }
+     151             :   // Set the periodicities of the output components
+     152        2264 :   myfunc.setPeriodicityForOutputs( this );
+     153             :   // Check if we can put the function in a chain
+     154        6143 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     155             :     // CollectFrames* ab=dynamic_cast<CollectFrames*>( getPntrToArgument(i)->getPntrToAction() );
+     156             :     // if( ab && ab->hasClear() ) { doNotChain=true; getPntrToArgument(i)->buildDataStore( getLabel() ); }
+     157             :     // No chains if we are using a sum or a mean
+     158        3879 :     if( getPntrToArgument(i)->getRank()==0 ) {
+     159         246 :       FunctionOfVector<Sum>* as = dynamic_cast<FunctionOfVector<Sum>*>( getPntrToArgument(i)->getPntrToAction() );
+     160         246 :       if(as) done_in_chain=false;
+     161             :     } else {
+     162        3633 :       ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     163        3633 :       if( !av ) done_in_chain=false;
+     164             :     }
+     165             :   }
+     166             :   // Don't need to do the calculation in a chain if the input is constant
+     167             :   bool allconstant=true;
+     168        2595 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     169        2275 :     if( !getPntrToArgument(i)->isConstant() ) { allconstant=false; break; }
+     170             :   }
+     171        2264 :   if( allconstant ) done_in_chain=false;
+     172        2264 :   nderivatives = buildArgumentStore(myfunc.getArgStart());
+     173        4528 : }
+     174             : 
+     175             : template <class T>
+     176           5 : std::string FunctionOfVector<T>::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     177           5 :   if( getName().find("SORT")==std::string::npos ) return ActionWithValue::getOutputComponentDescription( cname, keys );
+     178           8 :   if( getNumberOfArguments()==1 ) return "the " + cname + "th largest element of the vector " + getPntrToArgument(0)->getName();
+     179           4 :   return "the " + cname + "th largest element in the input vectors";
+     180             : }
+     181             : 
+     182             : template <class T>
+     183        6140 : void FunctionOfVector<T>::turnOnDerivatives() {
+     184        6140 :   if( !getPntrToComponent(0)->isConstant() && !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+     185        6140 :   ActionWithValue::turnOnDerivatives(); myfunc.setup(this );
+     186        6140 : }
+     187             : 
+     188             : template <class T>
+     189       53011 : unsigned FunctionOfVector<T>::getNumberOfDerivatives() {
+     190       53011 :   return nderivatives;
+     191             : }
+     192             : 
+     193             : template <class T>
+     194      185527 : void FunctionOfVector<T>::prepare() {
+     195      185527 :   unsigned argstart = myfunc.getArgStart(); std::vector<unsigned> shape(1);
+     196      232505 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     197      232505 :     if( getPntrToArgument(i)->getRank()==1 ) {
+     198      185527 :       shape[0] = getPntrToArgument(i)->getShape()[0]; break;
+     199             :     }
+     200             :   }
+     201      371470 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     202      185943 :     Value* myval = getPntrToComponent(i);
+     203      185943 :     if( myval->getRank()==1 && myval->getShape()[0]!=shape[0] ) { myval->setShape(shape); }
+     204             :   }
+     205      185527 :   ActionWithVector::prepare();
+     206      185527 : }
+     207             : 
+     208             : template <class T>
+     209      312538 : void FunctionOfVector<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     210      312538 :   if( firststep ) {
+     211        2168 :     stored_arguments.resize( getNumberOfArguments() );
+     212        2168 :     std::string control = getFirstActionInChain()->getLabel();
+     213        5936 :     for(unsigned i=0; i<stored_arguments.size(); ++i) {
+     214        3768 :       if( getPntrToArgument(i)->isConstant() ) stored_arguments[i]=false;
+     215        3249 :       else stored_arguments[i] = !getPntrToArgument(i)->ignoreStoredValue( control );
+     216             :     }
+     217        2168 :     firststep=false;
+     218             :   }
+     219      312538 :   ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     220      312538 : }
+     221             : 
+     222             : template <class T>
+     223     6634172 : void FunctionOfVector<T>::performTask( const unsigned& current, MultiValue& myvals ) const {
+     224     6634172 :   unsigned argstart=myfunc.getArgStart(); std::vector<double> args( getNumberOfArguments()-argstart);
+     225     6634172 :   if( actionInChain() ) {
+     226     6832197 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     227     3923742 :       if(  getPntrToArgument(i)->getRank()==0 ) args[i-argstart] = getPntrToArgument(i)->get();
+     228     3905954 :       else if( !getPntrToArgument(i)->valueHasBeenSet() ) args[i-argstart] = myvals.get( getPntrToArgument(i)->getPositionInStream() );
+     229      154930 :       else args[i-argstart] = getPntrToArgument(i)->get( myvals.getTaskIndex() );
+     230             :     }
+     231             :   } else {
+     232    11032808 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     233     7307091 :       if( getPntrToArgument(i)->getRank()==1 ) args[i-argstart]=getPntrToArgument(i)->get(current);
+     234     3242545 :       else args[i-argstart] = getPntrToArgument(i)->get();
+     235             :     }
+     236             :   }
+     237             :   // Calculate the function and its derivatives
+     238     6634172 :   std::vector<double> vals( getNumberOfComponents() ); Matrix<double> derivatives( getNumberOfComponents(), args.size() );
+     239     6634172 :   myfunc.calc( this, args, vals, derivatives );
+     240             :   // And set the values
+     241    13268344 :   for(unsigned i=0; i<vals.size(); ++i) myvals.addValue( getConstPntrToComponent(i)->getPositionInStream(), vals[i] );
+     242             :   // Return if we are not computing derivatives
+     243     6634172 :   if( doNotCalculateDerivatives() ) return;
+     244             :   // And now compute the derivatives
+     245             :   // Second condition here is only not true if actionInChain()==True if
+     246             :   // input arguments the only non-constant objects in input are scalars.
+     247             :   // In that case we can use the non chain version to calculate the derivatives
+     248             :   // with respect to the scalar.
+     249     5721550 :   if( actionInChain() ) {
+     250     5183456 :     for(unsigned j=0; j<args.size(); ++j) {
+     251        8375 :       unsigned istrn = getPntrToArgument(argstart+j)->getPositionInStream();
+     252     2886517 :       if( stored_arguments[argstart+j] ) {
+     253          70 :         unsigned task_index = myvals.getTaskIndex(); if( getPntrToArgument(argstart+j)->getRank()==0 ) task_index=0;
+     254          70 :         myvals.addDerivative( istrn, task_index, 1.0 ); myvals.updateIndex( istrn, task_index );
+     255             :       }
+     256     2886517 :       unsigned arg_deriv_s = arg_deriv_starts[argstart+j];
+     257   114509648 :       for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     258   111623131 :         unsigned kind=myvals.getActiveIndex(istrn,k);
+     259   223246262 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     260   111623131 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     261   111623131 :           myvals.addDerivative( ostrn, arg_deriv_s + kind, derivatives(i,j)*myvals.getDerivative( istrn, kind ) );
+     262             :         }
+     263             :       }
+     264             :       // Ensure we only store one lot of derivative indices
+     265     2886517 :       bool found=false; ActionWithValue* aav=getPntrToArgument(argstart+j)->getPntrToAction();
+     266     2920439 :       for(unsigned k=0; k<j; ++k) {
+     267      589642 :         if( arg_deriv_starts[argstart+k]==arg_deriv_s ) {
+     268      555720 :           if( getPntrToArgument(argstart+k)->getPntrToAction()!=aav ) {
+     269      386484 :             ActionWithVector* av = dynamic_cast<ActionWithVector*>( getPntrToArgument(argstart+j)->getPntrToAction() );
+     270      386484 :             if( av ) {
+     271      772968 :               for(int i=0; i<getNumberOfComponents(); ++i) av->updateAdditionalIndices( getConstPntrToComponent(i)->getPositionInStream(), myvals );
+     272             :             }
+     273             :           }
+     274             :           found=true; break;
+     275             :         }
+     276             :       }
+     277      555720 :       if( found ) continue;
+     278    85327769 :       for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     279    82996972 :         unsigned kind=myvals.getActiveIndex(istrn,k);
+     280   165993944 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     281    82996972 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     282    82996972 :           myvals.updateIndex( ostrn, arg_deriv_s + kind );
+     283             :         }
+     284             :       }
+     285             :     }
+     286             :   } else {
+     287             :     unsigned base=0;
+     288    10141540 :     for(unsigned j=0; j<args.size(); ++j) {
+     289     6716929 :       if( getPntrToArgument(argstart+j)->getRank()==1 ) {
+     290     7241248 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     291     3620624 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     292     3620624 :           myvals.addDerivative( ostrn, base+current, derivatives(i,j) );
+     293     3620624 :           myvals.updateIndex( ostrn, base+current );
+     294             :         }
+     295             :       } else {
+     296     6192610 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     297     3096305 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     298     3096305 :           myvals.addDerivative( ostrn, base, derivatives(i,j) );
+     299     3096305 :           myvals.updateIndex( ostrn, base );
+     300             :         }
+     301             :       }
+     302     6716929 :       base += getPntrToArgument(argstart+j)->getNumberOfValues();
+     303             :     }
+     304             :   }
+     305             : }
+     306             : 
+     307             : template <class T>
+     308        2264 : unsigned FunctionOfVector<T>::getNumberOfFinalTasks() {
+     309             :   unsigned nelements=0, argstart=myfunc.getArgStart();
+     310        6143 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     311        3879 :     plumed_assert( getPntrToArgument(i)->getRank()<2 );
+     312        3879 :     if( getPntrToArgument(i)->getRank()==1 ) {
+     313        3633 :       if( nelements>0 ) {
+     314             :         // if( getPntrToArgument(i)->isTimeSeries() && getPntrToArgument(i)->getShape()[0]<nelements ) nelements=getPntrToArgument(i)->isTimeSeries();
+     315             :         // else
+     316        1369 :         if(getPntrToArgument(i)->getShape()[0]!=nelements ) error("all vectors input should have the same length");
+     317        2264 :       } else if( nelements==0 ) nelements=getPntrToArgument(i)->getShape()[0];
+     318        3633 :       plumed_assert( !getPntrToArgument(i)->hasDerivatives() );
+     319             :     }
+     320             :   }
+     321             :   // The prefactor for average and sum is set here so the number of input scalars is guaranteed to be correct
+     322         777 :   myfunc.setPrefactor( this, 1.0 );
+     323        2264 :   return nelements;
+     324             : }
+     325             : 
+     326             : template <class T>
+     327       12124 : void FunctionOfVector<T>::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     328       12124 :   if( task_reducing_actions.size()==0 ) return;
+     329        2221 :   if( !myfunc.allComponentsRequired( getArguments(), task_reducing_actions ) ) task_reducing_actions.push_back(this);
+     330             : }
+     331             : 
+     332             : template <class T>
+     333        5541 : void FunctionOfVector<T>::runSingleTaskCalculation( const Value* arg, ActionWithValue* action, T& f ) {
+     334             :   // This is used if we are doing sorting actions on a single vector
+     335        5541 :   unsigned nv = arg->getNumberOfValues(); std::vector<double> args( nv );
+     336     8198467 :   for(unsigned i=0; i<nv; ++i) args[i] = arg->get(i);
+     337        5541 :   std::vector<double> vals( action->getNumberOfComponents() ); Matrix<double> derivatives( action->getNumberOfComponents(), nv );
+     338        5541 :   ActionWithArguments* aa=dynamic_cast<ActionWithArguments*>(action); plumed_assert( aa ); f.calc( aa, args, vals, derivatives );
+     339       11498 :   for(unsigned i=0; i<vals.size(); ++i) action->copyOutput(i)->set( vals[i] );
+     340             :   // Return if we are not computing derivatives
+     341        5541 :   if( action->doNotCalculateDerivatives() ) return;
+     342             :   // Now set the derivatives
+     343      198059 :   for(unsigned j=0; j<nv; ++j) {
+     344      388720 :     for(unsigned i=0; i<vals.size(); ++i) action->copyOutput(i)->setDerivative( j, derivatives(i,j) );
+     345             :   }
+     346             : }
+     347             : 
+     348             : template <class T>
+     349      184898 : void FunctionOfVector<T>::calculate() {
+     350             :   // Everything is done elsewhere
+     351      184898 :   if( actionInChain() ) return;
+     352             :   // This is done if we are calculating a function of multiple cvs
+     353       80095 :   if( !doAtEnd ) runAllTasks();
+     354             :   // This is used if we are doing sorting actions on a single vector
+     355        5541 :   else if( !myfunc.doWithTasks() ) runSingleTaskCalculation( getPntrToArgument(0), this, myfunc );
+     356             : }
+     357             : 
+     358             : }
+     359             : }
+     360             : #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 000000000..0e070634b --- /dev/null +++ b/coverage/function/FunctionShortcut.h.func-sort-c.html @@ -0,0 +1,256 @@ + + + + + + + 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-10-17 16:45:00Functions: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_traitsIcESaIcEEE6
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE6
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE17
_ZN4PLMD8function16FunctionShortcutINS0_4SortEEC1ERKNS_13ActionOptionsE17
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE42
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE42
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE50
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEEC1ERKNS_13ActionOptionsE50
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE53
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEEC1ERKNS_13ActionOptionsE53
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE67
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEEC1ERKNS_13ActionOptionsE67
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE68
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEEC1ERKNS_13ActionOptionsE68
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE103
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE106
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE16registerKeywordsERNS_8KeywordsE107
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE128
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE134
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE184
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE184
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE305
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEEC1ERKNS_13ActionOptionsE305
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE365
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE16registerKeywordsERNS_8KeywordsE455
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE818
_ZN4PLMD8function16FunctionShortcutINS0_3SumEEC1ERKNS_13ActionOptionsE818
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE16registerKeywordsERNS_8KeywordsE1469
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2991
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEEC1ERKNS_13ActionOptionsE2991
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE16registerKeywordsERNS_8KeywordsE4757
+
+
+ + + +
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 000000000..b43231e3d --- /dev/null +++ b/coverage/function/FunctionShortcut.h.func.html @@ -0,0 +1,256 @@ + + + + + + + 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-10-17 16:45:00Functions:4646100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE818
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE16registerKeywordsERNS_8KeywordsE1469
_ZN4PLMD8function16FunctionShortcutINS0_3SumEEC1ERKNS_13ActionOptionsE818
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE17
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD8function16FunctionShortcutINS0_4SortEEC1ERKNS_13ActionOptionsE17
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2991
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE16registerKeywordsERNS_8KeywordsE4757
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEEC1ERKNS_13ActionOptionsE2991
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE53
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE103
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEEC1ERKNS_13ActionOptionsE53
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE305
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE16registerKeywordsERNS_8KeywordsE455
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEEC1ERKNS_13ActionOptionsE305
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE50
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE16registerKeywordsERNS_8KeywordsE107
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEEC1ERKNS_13ActionOptionsE50
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEEC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE67
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE134
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEEC1ERKNS_13ActionOptionsE67
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE68
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE106
_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_8KeywordsE365
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE184
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE42
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE128
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE42
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE6
_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 000000000..fc987284d --- /dev/null +++ b/coverage/function/FunctionShortcut.h.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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-10-17 16:45:00Functions: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        7699 : void FunctionShortcut<T>::registerKeywords(Keywords& keys ) {
+      48        7699 :   ActionShortcut::registerKeywords( keys );
+      49       15398 :   keys.add("numbered","ARG","the input to this function");
+      50       15398 :   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       33738 :   keys.addActionNameSuffix("_SCALAR"); keys.addActionNameSuffix("_VECTOR"); keys.addActionNameSuffix("_MATRIX"); keys.addActionNameSuffix("_GRID");
+      52        7699 :   T tfunc; tfunc.registerKeywords( keys );
+      53        7699 : }
+      54             : 
+      55             : template <class T>
+      56        4617 : FunctionShortcut<T>::FunctionShortcut(const ActionOptions&ao):
+      57             :   Action(ao),
+      58        4617 :   ActionShortcut(ao)
+      59             : {
+      60        9234 :   std::vector<std::string> args; parseVector("ARG",args);
+      61       12258 :   std::string allargs=args[0]; for(unsigned i=1; i<args.size(); ++i) allargs += "," + args[i];
+      62        4617 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals );
+      63        4622 :   if( vals.size()==0 ) error("found no input arguments to function");
+      64        4617 :   createAction( this, vals, allargs );
+      65        4630 : }
+      66             : 
+      67             : template <class T>
+      68        4619 : void FunctionShortcut<T>::createAction( ActionShortcut* action, const std::vector<Value*>& vals, const std::string& allargs ) {
+      69        4619 :   unsigned maxrank=vals[0]->getRank(); bool isgrid=false;
+      70       12327 :   for(unsigned i=0; i<vals.size(); ++i) {
+      71        7708 :     if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) isgrid=true;
+      72             :     if( vals[i]->getRank()>maxrank ) maxrank=vals[i]->getRank();
+      73             :   }
+      74        4619 :   if( isgrid ) {
+      75        1299 :     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        4186 :   } else if( maxrank==0 ) {
+      78        4309 :     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        2758 :   } else if( maxrank==1 ) {
+      81        6792 :     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         494 :   } else if( maxrank==2  ) {
+      84        1482 :     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        4614 : }
+      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 000000000..da6494dc7 --- /dev/null +++ b/coverage/function/FunctionTemplateBase.h.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + 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-10-17 16:45:00Functions: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_6
_ZNK4PLMD8function20FunctionTemplateBase12getGraphInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE23
_ZN4PLMD8function20FunctionTemplateBase5parseIiEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_44
_ZN4PLMD8function20FunctionTemplateBase11parseVectorIdEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISE_EE912
_ZN4PLMD8function20FunctionTemplateBase19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE1255
_ZN4PLMD8function20FunctionTemplateBase21allComponentsRequiredERKSt6vectorIPNS_5ValueESaIS4_EERKS2_IPNS_16ActionWithVectorESaISA_EE2221
_ZN4PLMD8function20FunctionTemplateBase5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RT_3079
_ZN4PLMD8function20FunctionTemplateBase24setPeriodicityForOutputsEPNS_15ActionWithValueE4454
_ZN4PLMD8function20FunctionTemplateBase11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RSt6vectorIT_SaISE_EE7192
_ZN4PLMD8function20FunctionTemplateBase5setupEPNS_15ActionWithValueE10647
+
+
+ + + +
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 000000000..40219695a --- /dev/null +++ b/coverage/function/FunctionTemplateBase.h.func.html @@ -0,0 +1,144 @@ + + + + + + + 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-10-17 16:45:00Functions:111861.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function20FunctionTemplateBase11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RSt6vectorIT_SaISE_EE7192
_ZN4PLMD8function20FunctionTemplateBase11parseVectorIdEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISE_EE912
_ZN4PLMD8function20FunctionTemplateBase11parseVectorIiEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISE_EE5
_ZN4PLMD8function20FunctionTemplateBase12setPrefactorEPNS_19ActionWithArgumentsEd0
_ZN4PLMD8function20FunctionTemplateBase19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE1255
_ZN4PLMD8function20FunctionTemplateBase21allComponentsRequiredERKSt6vectorIPNS_5ValueESaIS4_EERKS2_IPNS_16ActionWithVectorESaISA_EE2221
_ZN4PLMD8function20FunctionTemplateBase22derivativesImplementedEv0
_ZN4PLMD8function20FunctionTemplateBase24setPeriodicityForOutputsEPNS_15ActionWithValueE4454
_ZN4PLMD8function20FunctionTemplateBase5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RT_3079
_ZN4PLMD8function20FunctionTemplateBase5parseIdEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_6
_ZN4PLMD8function20FunctionTemplateBase5parseIiEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_44
_ZN4PLMD8function20FunctionTemplateBase5setupEPNS_15ActionWithValueE10647
_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 000000000..4d4c355c9 --- /dev/null +++ b/coverage/function/FunctionTemplateBase.h.gcov.html @@ -0,0 +1,211 @@ + + + + + + + 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-10-17 16:45:00Functions: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       10054 : 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        3129 : void FunctionTemplateBase::parse( Action* action, const std::string&key, T&t ) {
+      67        3129 :   action->parse(key,t);
+      68        3129 : }
+      69             : 
+      70             : template<class T>
+      71        8109 : void FunctionTemplateBase::parseVector( Action* action, const std::string&key,std::vector<T>&t) {
+      72        8109 :   action->parseVector(key,t);
+      73        8106 : }
+      74             : 
+      75             : inline
+      76             : void FunctionTemplateBase::parseFlag( Action* action, const std::string&key, bool&t ) {
+      77         390 :   action->parseFlag(key,t);
+      78         390 : }
+      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       10647 : void FunctionTemplateBase::setup( ActionWithValue* action ) {
+      87       10647 :   noderiv=action->doNotCalculateDerivatives();
+      88             :   // Check for grids in input
+      89       10647 :   ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( action ); plumed_assert( aarg );
+      90       32971 :   for(unsigned i=0; i<aarg->getNumberOfArguments(); ++i) {
+      91       23539 :     if( aarg->getPntrToArgument(i)->getRank()>0 && aarg->getPntrToArgument(i)->hasDerivatives() ) { noderiv=false; break; }
+      92             :   }
+      93       10647 : }
+      94             : 
+      95             : inline
+      96        4454 : void FunctionTemplateBase::setPeriodicityForOutputs( ActionWithValue* action ) {
+      97        4454 :   plumed_massert( action->getNumberOfComponents()==1,"you must defined a setPeriodicityForOutputs function in your function class");
+      98        8908 :   if( action->keywords.exists("PERIODIC") ) {
+      99        8402 :     std::vector<std::string> period; parseVector(action,"PERIODIC",period);
+     100        4201 :     if( period.size()==1 ) {
+     101        4197 :       if( period[0]!="NO") action->error("input to PERIODIC keyword does not make sense");
+     102        4197 :       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        4454 :   } else action->setNotPeriodic();
+     106             : }
+     107             : 
+     108             : inline
+     109        1255 : std::vector<Value*> FunctionTemplateBase::getArgumentsToCheck( const std::vector<Value*>& args ) {
+     110        1255 :   return args;
+     111             : }
+     112             : 
+     113             : inline
+     114        2221 : bool FunctionTemplateBase::allComponentsRequired( const std::vector<Value*>& args, const std::vector<ActionWithVector*>& actions ) {
+     115        2221 :   std::vector<Value*> checkArgs = getArgumentsToCheck( args );
+     116        3998 :   for(unsigned i=0; i<checkArgs.size(); ++i ) {
+     117        2260 :     ActionWithVector* av = dynamic_cast<ActionWithVector*>( checkArgs[i]->getPntrToAction() );
+     118        2260 :     if( !av ) return false;
+     119             :     bool found=false;
+     120       18121 :     for(unsigned j=0; j<actions.size(); ++j) {
+     121       17638 :       if( actions[j]==av ) { found=true; break; }
+     122             :     }
+     123        2260 :     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 000000000..4356d074d --- /dev/null +++ b/coverage/function/Highest.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:2121100.0 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function7Highest11doWithTasksEv0
_ZNK4PLMD8function7Highest8zeroRankEv0
_ZN4PLMD8function7Highest4readEPNS_19ActionWithArgumentsE50
_ZN4PLMD8function7Highest16registerKeywordsERNS_8KeywordsE216
_ZNK4PLMD8function7Highest4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE32889
+
+
+ + + +
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 000000000..da0830aef --- /dev/null +++ b/coverage/function/Highest.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:2121100.0 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Highest16registerKeywordsERNS_8KeywordsE216
_ZN4PLMD8function7Highest4readEPNS_19ActionWithArgumentsE50
_ZNK4PLMD8function7Highest11doWithTasksEv0
_ZNK4PLMD8function7Highest4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE32889
_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 000000000..e981e7a92 --- /dev/null +++ b/coverage/function/Highest.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + 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:2121100.0 %
Date:2024-10-17 16:45:00Functions: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 "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         316 : class Highest : public FunctionTemplateBase {
+      86             : private:
+      87             :   bool min, scalar_out;
+      88             : public:
+      89             :   void registerKeywords( Keywords& keys ) override ;
+      90             :   void read( ActionWithArguments* action ) override;
+      91          48 :   bool zeroRank() const override { return scalar_out; }
+      92        5338 :   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         216 : void Highest::registerKeywords( Keywords& keys ) {
+     107         520 :   if( keys.getDisplayName().find("LOWEST") ) keys.setValueDescription("the lowest of the input values");
+     108         256 :   else keys.setValueDescription("the highest of the input values");
+     109         216 : }
+     110             : 
+     111          50 : void Highest::read( ActionWithArguments* action ) {
+     112          50 :   min=action->getName().find("LOWEST")!=std::string::npos; if( !min ) plumed_assert( action->getName().find("HIGHEST")!=std::string::npos );
+     113         121 :   for(unsigned i=0; i<action->getNumberOfArguments(); ++i) {
+     114          71 :     if( action->getPntrToArgument(i)->isPeriodic() ) action->error("Cannot sort periodic values (check argument "+ action->getPntrToArgument(i)->getName() +")");
+     115             :   }
+     116          50 :   scalar_out = action->getNumberOfArguments()==1;
+     117          50 :   if( scalar_out && action->getPntrToArgument(0)->getRank()==0 ) action->error("sorting a single scalar is trivial");
+     118          50 : }
+     119             : 
+     120       32889 : void Highest::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     121       32889 :   if( min ) {
+     122       32755 :     vals[0] = *std::min_element(args.begin(), args.end());
+     123       32755 :     derivatives(0,std::min_element(args.begin(), args.end()) - args.begin()) = 1;
+     124             :   } else {
+     125         134 :     vals[0] = *std::max_element(args.begin(), args.end());
+     126         134 :     derivatives(0,std::max_element(args.begin(), args.end()) - args.begin()) = 1;
+     127             :   }
+     128       32889 : }
+     129             : 
+     130             : }
+     131             : }
+     132             : 
+     133             : 
+
+
+
+ + + + +
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 000000000..44e8c47f6 --- /dev/null +++ b/coverage/function/LessThan.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8LessThan4readEPNS_19ActionWithArgumentsE67
_ZN4PLMD8function8LessThan16registerKeywordsERNS_8KeywordsE274
_ZNK4PLMD8function8LessThan4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE187997
+
+
+ + + +
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 000000000..00b004245 --- /dev/null +++ b/coverage/function/LessThan.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8LessThan16registerKeywordsERNS_8KeywordsE274
_ZN4PLMD8function8LessThan4readEPNS_19ActionWithArgumentsE67
_ZNK4PLMD8function8LessThan4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE187997
+
+
+ + + +
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 000000000..d590bcc3c --- /dev/null +++ b/coverage/function/LessThan.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions: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 "FunctionOfMatrix.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : //+PLUMEDOC FUNCTION LESS_THAN
+      34             : /*
+      35             : Use a switching function to determine how many of the input variables are less than a certain cutoff.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC FUNCTION LESS_THAN_VECTOR
+      43             : /*
+      44             : Use a switching function to determine how many components of the vector are less than a certain cutoff.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : //+PLUMEDOC COLVAR LESS_THAN_MATRIX
+      52             : /*
+      53             : Transform all the elements of a matrix using a switching function that is one when the input value is smaller than a threshold
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : typedef FunctionShortcut<LessThan> LessThanShortcut;
+      61             : PLUMED_REGISTER_ACTION(LessThanShortcut,"LESS_THAN")
+      62             : typedef FunctionOfVector<LessThan> VectorLessThan;
+      63             : PLUMED_REGISTER_ACTION(VectorLessThan,"LESS_THAN_VECTOR")
+      64             : typedef FunctionOfMatrix<LessThan> MatrixLessThan;
+      65             : PLUMED_REGISTER_ACTION(MatrixLessThan,"LESS_THAN_MATRIX")
+      66             : 
+      67         274 : void LessThan::registerKeywords(Keywords& keys) {
+      68         548 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      69         548 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      70         548 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      71         548 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      72         548 :   keys.add("optional","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         548 :   keys.addFlag("SQUARED",false,"is the input quantity the square of the value that you would like to apply the switching function to");
+      76         274 :   keys.setValueDescription("a function that is one if the input is less than a threshold");
+      77         274 : }
+      78             : 
+      79          67 : void LessThan::read( ActionWithArguments* action ) {
+      80          67 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to less_than actions");
+      81          67 :   if( action->getPntrToArgument(0)->isPeriodic() ) action->error("cannot use this function on periodic functions");
+      82             : 
+      83             : 
+      84             :   std::string sw,errors;
+      85         134 :   action->parse("SWITCH",sw);
+      86          67 :   if(sw.length()>0) {
+      87          67 :     switchingFunction.set(sw,errors);
+      88          67 :     if( errors.length()!=0 ) action->error("problem reading SWITCH keyword : " + errors );
+      89             :   } else {
+      90           0 :     int nn=6; int mm=0; double d0=0.0; double r0=0.0; action->parse("R_0",r0);
+      91           0 :     if(r0<=0.0) action->error("R_0 should be explicitly specified and positive");
+      92           0 :     action->parse("D_0",d0); action->parse("NN",nn); action->parse("MM",mm);
+      93           0 :     switchingFunction.set(nn,mm,r0,d0);
+      94             :   }
+      95          67 :   action->log<<"  using switching function with cutoff "<<switchingFunction.description()<<"\n";
+      96          67 :   action->parseFlag("SQUARED",squared);
+      97          67 :   if( squared ) action->log<<"  input quantity is square of quantity that switching function acts upon\n";
+      98          67 : }
+      99             : 
+     100      187997 : void LessThan::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     101             :   plumed_dbg_assert( args.size()==1 );
+     102      187997 :   if( squared ) vals[0] = switchingFunction.calculateSqr( args[0], derivatives(0,0) );
+     103      187997 :   else vals[0] = switchingFunction.calculate( args[0], derivatives(0,0) );
+     104      187997 :   derivatives(0,0) = args[0]*derivatives(0,0);
+     105      187997 : }
+     106             : 
+     107             : }
+     108             : }
+     109             : 
+     110             : 
+
+
+
+ + + + +
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 000000000..8da3d12e8 --- /dev/null +++ b/coverage/function/LessThan.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e2257590f --- /dev/null +++ b/coverage/function/LessThan.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..552eedc50 --- /dev/null +++ b/coverage/function/LessThan.h.gcov.html @@ -0,0 +1,119 @@ + + + + + + + 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-10-17 16:45:00Functions: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         614 : 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 000000000..ff7e6b12b --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:313393.9 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8function13LocalEnsemble29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_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 000000000..0a6975df0 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:313393.9 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function13LocalEnsemble9calculateEv40
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8function13LocalEnsemble29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
+
+
+ + + +
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 000000000..bbca2e68c --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + 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:313393.9 %
Date:2024-10-17 16:45:00Functions: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 "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             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      86             : };
+      87             : 
+      88             : 
+      89             : PLUMED_REGISTER_ACTION(LocalEnsemble,"LOCALENSEMBLE")
+      90             : 
+      91           4 : void LocalEnsemble::registerKeywords(Keywords& keys) {
+      92           4 :   Function::registerKeywords(keys);
+      93           4 :   keys.use("ARG");
+      94           8 :   keys.add("compulsory","NUM","the number of local replicas");
+      95           4 :   useCustomisableComponents(keys);
+      96           4 : }
+      97             : 
+      98           2 : LocalEnsemble::LocalEnsemble(const ActionOptions&ao):
+      99             :   Action(ao),
+     100             :   Function(ao),
+     101           2 :   ens_dim(0)
+     102             : {
+     103           2 :   parse("NUM",ens_dim);
+     104           2 :   if(ens_dim==0) error("NUM should be greater or equal to 1");
+     105             : 
+     106             :   std::vector<Value*> arg;
+     107             :   int oldsize=-1;
+     108           8 :   for(unsigned i=1; i<=ens_dim; ++i ) {
+     109             :     std::vector<Value*> larg;
+     110          12 :     if(!parseArgumentList("ARG",i,larg)) break;
+     111          18 :     for(unsigned j=0; j<larg.size(); j++) arg.push_back(larg[j]);
+     112           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");
+     113           6 :     oldsize = larg.size();
+     114           6 :     if(!larg.empty()) {
+     115           6 :       log.printf("  with arguments %u: ", i);
+     116          18 :       for(unsigned j=0; j<larg.size(); j++) log.printf(" %s",larg[j]->getName().c_str());
+     117           6 :       log.printf("\n");
+     118             :     }
+     119             :   }
+     120           2 :   requestArguments(arg);
+     121           2 :   narg = arg.size()/ens_dim;
+     122             : 
+     123             :   // these are the averages
+     124           6 :   for(unsigned i=0; i<narg; i++) {
+     125           4 :     std::string s=getPntrToArgument(i)->getName();
+     126           4 :     addComponentWithDerivatives(s);
+     127           4 :     getPntrToComponent(i)->setNotPeriodic();
+     128             :   }
+     129             : 
+     130           2 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     131           2 : }
+     132             : 
+     133           0 : std::string LocalEnsemble::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     134           0 :   return "the average for argument named " + cname;
+     135             : }
+     136             : 
+     137          40 : void LocalEnsemble::calculate()
+     138             : {
+     139          40 :   const double fact = 1.0/static_cast<double>(ens_dim);
+     140          40 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     141             :   for(unsigned i=0; i<narg; ++i) {
+     142             :     double mean = 0.;
+     143             :     Value* v=getPntrToComponent(i);
+     144             :     for(unsigned j=0; j<ens_dim; ++j) {
+     145             :       const unsigned index = j*narg+i;
+     146             :       setDerivative(v, index, fact);
+     147             :       mean += fact*getArgument(index);
+     148             :     }
+     149             :     v->set(mean);
+     150             :   }
+     151          40 : }
+     152             : 
+     153             : }
+     154             : }
+     155             : 
+     156             : 
+
+
+
+ + + + +
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 000000000..72eb73e9d --- /dev/null +++ b/coverage/function/Moments.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function7Moments11doWithTasksEv0
_ZNK4PLMD8function7Moments8zeroRankEv0
_ZN4PLMD8function7Moments24setPeriodicityForOutputsEPNS_15ActionWithValueE5
_ZN4PLMD8function7Moments4readEPNS_19ActionWithArgumentsE5
_ZNK4PLMD8function7Moments21getComponentsPerLabelB5cxx11Ev5
_ZN4PLMD8function7Moments16registerKeywordsERNS_8KeywordsE27
_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 000000000..dea148493 --- /dev/null +++ b/coverage/function/Moments.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Moments16registerKeywordsERNS_8KeywordsE27
_ZN4PLMD8function7Moments24setPeriodicityForOutputsEPNS_15ActionWithValueE5
_ZN4PLMD8function7Moments4readEPNS_19ActionWithArgumentsE5
_ZNK4PLMD8function7Moments11doWithTasksEv0
_ZNK4PLMD8function7Moments21getComponentsPerLabelB5cxx11Ev5
_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 000000000..37ea1e0af --- /dev/null +++ b/coverage/function/Moments.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + 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-10-17 16:45:00Functions: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          56 : 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          27 : void Moments::registerKeywords(Keywords& keys) {
+      82          54 :   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          54 :   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          27 : }
+      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           5 : std::vector<std::string> Moments::getComponentsPerLabel() const {
+     118             :   std::vector<std::string> comp; std::string num;
+     119          13 :   for(unsigned i=0; i<powers.size(); ++i) {
+     120          16 :     Tools::convert(powers[i],num); comp.push_back( "-" + num );
+     121             :   }
+     122           5 :   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 000000000..405c1f48c --- /dev/null +++ b/coverage/function/MoreThan.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8MoreThan4readEPNS_19ActionWithArgumentsE68
_ZN4PLMD8function8MoreThan16registerKeywordsERNS_8KeywordsE246
_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 000000000..00a179f48 --- /dev/null +++ b/coverage/function/MoreThan.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8MoreThan16registerKeywordsERNS_8KeywordsE246
_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 000000000..03b275862 --- /dev/null +++ b/coverage/function/MoreThan.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + 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:252986.2 %
Date:2024-10-17 16:45:00Functions: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 "FunctionOfMatrix.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : //+PLUMEDOC FUNCTION MORE_THAN
+      34             : /*
+      35             : Use a switching function to determine how many of the input variables are more than a certain cutoff.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC FUNCTION MORE_THAN_VECTOR
+      43             : /*
+      44             : Use a switching function to determine how many of elements in the input vector are more than a certain cutoff.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : //+PLUMEDOC COLVAR MORE_THAN_MATRIX
+      52             : /*
+      53             : Transform all the elements of a matrix using a switching function that is one when the input value is larger than a threshold
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : typedef FunctionShortcut<MoreThan> MoreThanShortcut;
+      61             : PLUMED_REGISTER_ACTION(MoreThanShortcut,"MORE_THAN")
+      62             : typedef FunctionOfVector<MoreThan> VectorMoreThan;
+      63             : PLUMED_REGISTER_ACTION(VectorMoreThan,"MORE_THAN_VECTOR")
+      64             : typedef FunctionOfMatrix<MoreThan> MatrixMoreThan;
+      65             : PLUMED_REGISTER_ACTION(MatrixMoreThan,"MORE_THAN_MATRIX")
+      66             : 
+      67         246 : void MoreThan::registerKeywords(Keywords& keys) {
+      68         492 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      69         492 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      70         492 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      71         492 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      72         492 :   keys.add("optional","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         492 :   keys.addFlag("SQUARED",false,"is the input quantity the square of the value that you would like to apply the switching function to");
+      76         246 :   keys.setValueDescription("a function that is one if the if the input is more than a threshold");
+      77         246 : }
+      78             : 
+      79          68 : void MoreThan::read( ActionWithArguments* action ) {
+      80          68 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to more_than actions");
+      81          68 :   if( action->getPntrToArgument(0)->isPeriodic() ) action->error("cannot use this function on periodic functions");
+      82             : 
+      83             : 
+      84             :   std::string sw,errors;
+      85         136 :   action->parse("SWITCH",sw);
+      86          68 :   if(sw.length()>0) {
+      87          68 :     switchingFunction.set(sw,errors);
+      88          68 :     if( errors.length()!=0 ) action->error("problem reading SWITCH keyword : " + errors );
+      89             :   } else {
+      90           0 :     int nn=6; int mm=0; double d0=0.0; double r0=0.0; action->parse("R_0",r0);
+      91           0 :     if(r0<=0.0) action->error("R_0 should be explicitly specified and positive");
+      92           0 :     action->parse("D_0",d0); action->parse("NN",nn); action->parse("MM",mm);
+      93           0 :     switchingFunction.set(nn,mm,r0,d0);
+      94             :   }
+      95          68 :   action->log<<"  using switching function with cutoff "<<switchingFunction.description()<<"\n";
+      96          68 :   action->parseFlag("SQUARED",squared);
+      97          68 :   if( squared ) action->log<<"  input quantity is square of quantity that switching function acts upon\n";
+      98          68 : }
+      99             : 
+     100      556662 : void MoreThan::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     101             :   plumed_dbg_assert( args.size()==1 );
+     102      556662 :   if( squared ) vals[0] = 1.0 - switchingFunction.calculateSqr( args[0], derivatives(0,0) );
+     103       87550 :   else vals[0] = 1.0 - switchingFunction.calculate( args[0], derivatives(0,0) );
+     104      556662 :   derivatives(0,0) = -args[0]*derivatives(0,0);
+     105      556662 : }
+     106             : 
+     107             : }
+     108             : }
+     109             : 
+     110             : 
+
+
+
+ + + + +
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 000000000..5bb66a1cf --- /dev/null +++ b/coverage/function/MoreThan.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5c89d5324 --- /dev/null +++ b/coverage/function/MoreThan.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ed540be6a --- /dev/null +++ b/coverage/function/MoreThan.h.gcov.html @@ -0,0 +1,119 @@ + + + + + + + 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-10-17 16:45:00Functions: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         584 : 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 000000000..acce2d28d --- /dev/null +++ b/coverage/function/Piecewise.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9Piecewise24setPeriodicityForOutputsEPNS_15ActionWithValueE2
_ZN4PLMD8function9Piecewise4readEPNS_19ActionWithArgumentsE3
_ZNK4PLMD8function9Piecewise4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE10
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE12
+
+
+ + + +
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 000000000..c3c6feee9 --- /dev/null +++ b/coverage/function/Piecewise.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE12
_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 000000000..8da9ef591 --- /dev/null +++ b/coverage/function/Piecewise.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + 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-10-17 16:45:00Functions: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          28 : 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          12 : void Piecewise::registerKeywords(Keywords& keys) {
+      94          24 :   keys.add("numbered","POINT","This keyword is used to specify the various points in the function above.");
+      95          24 :   keys.reset_style("POINT","compulsory");
+      96          24 :   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          12 : }
+     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 000000000..4e5401873 --- /dev/null +++ b/coverage/function/Product.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1414100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7ProductC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7ProductC1ERKNS_13ActionOptionsE114
_ZN4PLMD8function7Product16registerKeywordsERNS_8KeywordsE129
+
+
+ + + +
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 000000000..3c6c77974 --- /dev/null +++ b/coverage/function/Product.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1414100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Product16registerKeywordsERNS_8KeywordsE129
_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 000000000..73a9aab06 --- /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:1414100.0 %
Date:2024-10-17 16:45:00Functions: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         129 : void Product::registerKeywords( Keywords& keys ) {
+      46         129 :   ActionShortcut::registerKeywords(keys);
+      47         258 :   keys.add("compulsory","ARG","The point that we are calculating the distance from");
+      48         129 :   keys.setValueDescription("the product of all the elements in the input vector");
+      49         387 :   keys.needsAction("CONCATENATE"); keys.needsAction("CUSTOM"); keys.needsAction("SUM");
+      50         129 : }
+      51             : 
+      52         114 : Product::Product( const ActionOptions& ao):
+      53             :   Action(ao),
+      54         114 :   ActionShortcut(ao)
+      55             : {
+      56         114 :   std::string arg; parse("ARG",arg);
+      57         228 :   readInputLine( getShortcutLabel() + "_vec: CONCATENATE ARG=" + arg );
+      58         228 :   readInputLine( getShortcutLabel() + "_logs: CUSTOM ARG=" + getShortcutLabel() + "_vec FUNC=log(x) PERIODIC=NO");
+      59         228 :   readInputLine( getShortcutLabel() + "_logsum: SUM ARG=" + getShortcutLabel() + "_logs PERIODIC=NO");
+      60         228 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_logsum FUNC=exp(x) PERIODIC=NO");
+      61         114 : }
+      62             : 
+      63             : }
+      64             : }
+
+
+
+ + + + +
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 000000000..4352a5a44 --- /dev/null +++ b/coverage/function/Sort.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - function/Sort.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sort.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function4Sort11doWithTasksEv0
_ZNK4PLMD8function4Sort8zeroRankEv0
_ZN4PLMD8function4Sort24setPeriodicityForOutputsEPNS_15ActionWithValueE16
_ZNK4PLMD8function4Sort21getComponentsPerLabelB5cxx11Ev16
_ZN4PLMD8function4Sort4readEPNS_19ActionWithArgumentsE17
_ZNK4PLMD8function4Sort4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE45
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE65
+
+
+ + + +
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 000000000..743ef2234 --- /dev/null +++ b/coverage/function/Sort.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - function/Sort.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sort.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD8function4Sort24setPeriodicityForOutputsEPNS_15ActionWithValueE16
_ZN4PLMD8function4Sort4readEPNS_19ActionWithArgumentsE17
_ZNK4PLMD8function4Sort11doWithTasksEv0
_ZNK4PLMD8function4Sort21getComponentsPerLabelB5cxx11Ev16
_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 000000000..55d65a37e --- /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:262892.9 %
Date:2024-10-17 16:45:00Functions: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          99 : 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          38 :   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          65 : void Sort::registerKeywords(Keywords& keys) {
+      96          65 :   keys.setValueDescription("sorted");
+      97          65 :   keys.setComponentsIntroduction("The names of the components in this action will be customized in accordance with the contents of the input file. "
+      98             :                                  "The largest value is called label.1th, the second largest label.2th, the third label.3th and so on");
+      99          65 : }
+     100             : 
+     101             : 
+     102          17 : void Sort::read( ActionWithArguments* action ) {
+     103          17 :   scalar_out = action->getNumberOfArguments()==1; nargs = action->getNumberOfArguments(); if( scalar_out ) nargs = action->getPntrToArgument(0)->getNumberOfValues();
+     104             : 
+     105          48 :   for(unsigned i=0; i<action->getNumberOfArguments(); ++i) {
+     106          33 :     if((action->getPntrToArgument(i))->isPeriodic()) action->error("Cannot sort periodic values (check argument "+ (action->getPntrToArgument(i))->getName() +")");
+     107             :   }
+     108          16 : }
+     109             : 
+     110          16 : std::vector<std::string> Sort::getComponentsPerLabel() const {
+     111             :   std::vector<std::string> comp; std::string num;
+     112          61 :   for(unsigned i=0; i<nargs; ++i) {
+     113          45 :     Tools::convert(i+1,num); comp.push_back( num );
+     114             :   }
+     115          16 :   return comp;
+     116           0 : }
+     117             : 
+     118          16 : void Sort::setPeriodicityForOutputs( ActionWithValue* action ) {
+     119          61 :   for(unsigned i=0; i<nargs; ++i) { std::string num; Tools::convert(i+1,num); action->componentIsNotPeriodic( num ); }
+     120          16 : }
+     121             : 
+     122          45 : void Sort::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     123          45 :   std::vector<std::pair<double,int> > data(args.size());
+     124         326 :   for(unsigned i=0; i<args.size(); ++i) {
+     125         281 :     data[i].first=args[i];
+     126             : // In this manner I remember from which argument the component depends:
+     127         281 :     data[i].second=i;
+     128             :   }
+     129             : // STL sort sorts based on first element (value) then second (index)
+     130          45 :   std::sort(data.begin(),data.end()); derivatives = 0;
+     131         326 :   for(int i=0; i<vals.size(); ++i) { vals[i] = data[i].first; derivatives(i, data[i].second ) = 1; }
+     132          45 : }
+     133             : 
+     134             : }
+     135             : }
+     136             : 
+     137             : 
+
+
+
+ + + + +
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 000000000..159aa2a6a --- /dev/null +++ b/coverage/function/Stats.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..9a0dcd5e5 --- /dev/null +++ b/coverage/function/Stats.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ebbc19251 --- /dev/null +++ b/coverage/function/Stats.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + LCOV - plumed test coverage - function/Stats.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Stats.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910396.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..93c63966f --- /dev/null +++ b/coverage/function/Sum.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function3Sum4readEPNS_19ActionWithArgumentsE908
_ZN4PLMD8function3Sum12setPrefactorEPNS_19ActionWithArgumentsEd998
_ZN4PLMD8function3Sum16registerKeywordsERNS_8KeywordsE3294
_ZNK4PLMD8function3Sum8zeroRankEv25622
_ZNK4PLMD8function3Sum4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE1901194
+
+
+ + + +
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 000000000..c9835ec5e --- /dev/null +++ b/coverage/function/Sum.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function3Sum12setPrefactorEPNS_19ActionWithArgumentsEd998
_ZN4PLMD8function3Sum16registerKeywordsERNS_8KeywordsE3294
_ZN4PLMD8function3Sum4readEPNS_19ActionWithArgumentsE908
_ZNK4PLMD8function3Sum4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE1901194
_ZNK4PLMD8function3Sum8zeroRankEv25622
+
+
+ + + +
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 000000000..a60376191 --- /dev/null +++ b/coverage/function/Sum.cpp.gcov.html @@ -0,0 +1,206 @@ + + + + + + + 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-10-17 16:45:00Functions: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 "FunctionOfMatrix.h"
+      27             : #include "core/ActionRegister.h"
+      28             : 
+      29             : //+PLUMEDOC COLVAR SUM
+      30             : /*
+      31             : Calculate the sum of the arguments
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : //+PLUMEDOC COLVAR SUM_VECTOR
+      39             : /*
+      40             : Calculate the sum of the elements in a vector
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : */
+      45             : //+ENDPLUMEDOC
+      46             : 
+      47             : //+PLUMEDOC COLVAR SUM_SCALAR
+      48             : /*
+      49             : Calculate the SUM of the set of input scalars
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : */
+      54             : //+ENDPLUMEDOC
+      55             : 
+      56             : //+PLUMEDOC COLVAR MEAN
+      57             : /*
+      58             : Calculate the arithmetic mean of the elements in a vector
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : //+PLUMEDOC COLVAR MEAN_SCALAR
+      66             : /*
+      67             : Calculate the arithmetic mean of the set of input scalars
+      68             : 
+      69             : \par Examples
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : //+PLUMEDOC COLVAR MEAN_VECTOR
+      75             : /*
+      76             : Calculate the arithmetic mean of the elements in a vector
+      77             : 
+      78             : \par Examples
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : //+PLUMEDOC COLVAR SUM_MATRIX
+      84             : /*
+      85             : Sum all the elements in a matrix
+      86             : 
+      87             : \par Examples
+      88             : 
+      89             : */
+      90             : //+ENDPLUMEDOC
+      91             : 
+      92             : 
+      93             : namespace PLMD {
+      94             : namespace function {
+      95             : 
+      96             : typedef FunctionShortcut<Sum> SumShortcut;
+      97             : PLUMED_REGISTER_ACTION(SumShortcut,"SUM")
+      98             : PLUMED_REGISTER_ACTION(SumShortcut,"MEAN")
+      99             : typedef FunctionOfScalar<Sum> ScalarSum;
+     100             : PLUMED_REGISTER_ACTION(ScalarSum,"SUM_SCALAR")
+     101             : PLUMED_REGISTER_ACTION(ScalarSum,"MEAN_SCALAR")
+     102             : typedef FunctionOfVector<Sum> VectorSum;
+     103             : PLUMED_REGISTER_ACTION(VectorSum,"SUM_VECTOR")
+     104             : PLUMED_REGISTER_ACTION(VectorSum,"MEAN_VECTOR")
+     105             : typedef FunctionOfMatrix<Sum> MatrixSum;
+     106             : PLUMED_REGISTER_ACTION(MatrixSum,"SUM_MATRIX")
+     107             : 
+     108        3294 : void Sum::registerKeywords( Keywords& keys ) {
+     109        6588 :   keys.use("PERIODIC"); keys.setValueDescription("the sum");
+     110        3294 : }
+     111             : 
+     112         908 : void Sum::read( ActionWithArguments* action ) {
+     113         908 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to sum actions");
+     114         908 : }
+     115             : 
+     116         998 : void Sum::setPrefactor( ActionWithArguments* action, const double pref ) {
+     117         998 :   if(action->getName().find("MEAN")!=std::string::npos) prefactor = pref / (action->getPntrToArgument(0))->getNumberOfValues();
+     118         821 :   else prefactor = pref;
+     119         998 : }
+     120             : 
+     121       25622 : bool Sum::zeroRank() const {
+     122       25622 :   return true;
+     123             : }
+     124             : 
+     125     1901194 : void Sum::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     126     1901194 :   vals[0]=prefactor*args[0]; derivatives(0,0)=prefactor;
+     127     1901194 : }
+     128             : 
+     129             : }
+     130             : }
+
+
+
+ + + + +
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 000000000..de191c16d --- /dev/null +++ b/coverage/function/Sum.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4082f5bc2 --- /dev/null +++ b/coverage/function/Sum.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d504eec5a --- /dev/null +++ b/coverage/function/Sum.h.gcov.html @@ -0,0 +1,119 @@ + + + + + + + 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-10-17 16:45:00Functions: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        5020 : 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 000000000..f8d06d7e2 --- /dev/null +++ b/coverage/function/index-sort-f.html @@ -0,0 +1,383 @@ + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:1535172688.9 %
Date:2024-10-17 16:45:00Functions:42452780.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Between.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
MoreThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
LocalEnsemble.cpp +
93.9%93.9%
+
93.9 %31 / 3360.0 %3 / 5
Ensemble.cpp +
60.6%60.6%
+
60.6 %80 / 13260.0 %3 / 5
Highest.cpp +
100.0%
+
100.0 %21 / 2160.0 %3 / 5
FunctionTemplateBase.h +
82.2%82.2%
+
82.2 %37 / 4561.1 %11 / 18
FunctionOfScalar.h +
95.3%95.3%
+
95.3 %41 / 4365.0 %52 / 80
Product.cpp +
100.0%
+
100.0 %14 / 1466.7 %2 / 3
Moments.cpp +
79.2%79.2%
+
79.2 %38 / 4871.4 %5 / 7
Sort.cpp +
92.9%92.9%
+
92.9 %26 / 2871.4 %5 / 7
Stats.cpp +
96.1%96.1%
+
96.1 %99 / 10375.0 %3 / 4
FunctionOfMatrix.h +
92.6%92.6%
+
92.6 %200 / 21678.7 %85 / 108
FuncPathMSD.cpp +
92.4%92.4%
+
92.4 %73 / 7980.0 %4 / 5
Function.cpp +
100.0%
+
100.0 %22 / 2283.3 %5 / 6
FuncPathGeneral.cpp +
77.3%77.3%
+
77.3 %99 / 12883.3 %5 / 6
Bessel.cpp +
94.4%94.4%
+
94.4 %34 / 3683.3 %5 / 6
FuncSumHills.cpp +
89.9%89.9%
+
89.9 %293 / 32683.3 %10 / 12
FunctionOfVector.h +
95.2%95.2%
+
95.2 %160 / 16886.0 %147 / 171
Combine.h +
100.0%
+
100.0 %1 / 1-0 / 0
Sum.h +
100.0%
+
100.0 %1 / 1-0 / 0
MoreThan.cpp +
86.2%86.2%
+
86.2 %25 / 29100.0 %3 / 3
LessThan.cpp +
86.2%86.2%
+
86.2 %25 / 29100.0 %3 / 3
Between.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
Combine.cpp +
100.0%
+
100.0 %34 / 34100.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 %65 / 65100.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 000000000..ef18b47c4 --- /dev/null +++ b/coverage/function/index-sort-l.html @@ -0,0 +1,383 @@ + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:1535172688.9 %
Date:2024-10-17 16:45:00Functions:42452780.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Between.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
MoreThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Ensemble.cpp +
60.6%60.6%
+
60.6 %80 / 13260.0 %3 / 5
FuncPathGeneral.cpp +
77.3%77.3%
+
77.3 %99 / 12883.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 +
86.2%86.2%
+
86.2 %25 / 29100.0 %3 / 3
LessThan.cpp +
86.2%86.2%
+
86.2 %25 / 29100.0 %3 / 3
Function.h +
88.9%88.9%
+
88.9 %8 / 9100.0 %3 / 3
FuncSumHills.cpp +
89.9%89.9%
+
89.9 %293 / 32683.3 %10 / 12
FuncPathMSD.cpp +
92.4%92.4%
+
92.4 %73 / 7980.0 %4 / 5
FunctionOfMatrix.h +
92.6%92.6%
+
92.6 %200 / 21678.7 %85 / 108
Sort.cpp +
92.9%92.9%
+
92.9 %26 / 2871.4 %5 / 7
LocalEnsemble.cpp +
93.9%93.9%
+
93.9 %31 / 3360.0 %3 / 5
Bessel.cpp +
94.4%94.4%
+
94.4 %34 / 3683.3 %5 / 6
FunctionOfVector.h +
95.2%95.2%
+
95.2 %160 / 16886.0 %147 / 171
FunctionOfScalar.h +
95.3%95.3%
+
95.3 %41 / 4365.0 %52 / 80
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 %14 / 1466.7 %2 / 3
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
Highest.cpp +
100.0%
+
100.0 %21 / 2160.0 %3 / 5
Function.cpp +
100.0%
+
100.0 %22 / 2283.3 %5 / 6
Between.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
Combine.cpp +
100.0%
+
100.0 %34 / 34100.0 %3 / 3
Piecewise.cpp +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
Custom.cpp +
100.0%
+
100.0 %65 / 65100.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 000000000..35e498349 --- /dev/null +++ b/coverage/function/index.html @@ -0,0 +1,383 @@ + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:1535172688.9 %
Date:2024-10-17 16:45:00Functions:42452780.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Bessel.cpp +
94.4%94.4%
+
94.4 %34 / 3683.3 %5 / 6
Between.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
Between.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Combine.cpp +
100.0%
+
100.0 %34 / 34100.0 %3 / 3
Combine.h +
100.0%
+
100.0 %1 / 1-0 / 0
Custom.cpp +
100.0%
+
100.0 %65 / 65100.0 %6 / 6
Ensemble.cpp +
60.6%60.6%
+
60.6 %80 / 13260.0 %3 / 5
FuncPathGeneral.cpp +
77.3%77.3%
+
77.3 %99 / 12883.3 %5 / 6
FuncPathMSD.cpp +
92.4%92.4%
+
92.4 %73 / 7980.0 %4 / 5
FuncSumHills.cpp +
89.9%89.9%
+
89.9 %293 / 32683.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
FunctionOfMatrix.h +
92.6%92.6%
+
92.6 %200 / 21678.7 %85 / 108
FunctionOfScalar.h +
95.3%95.3%
+
95.3 %41 / 4365.0 %52 / 80
FunctionOfVector.h +
95.2%95.2%
+
95.2 %160 / 16886.0 %147 / 171
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 +
100.0%
+
100.0 %21 / 2160.0 %3 / 5
LessThan.cpp +
86.2%86.2%
+
86.2 %25 / 29100.0 %3 / 3
LessThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
LocalEnsemble.cpp +
93.9%93.9%
+
93.9 %31 / 3360.0 %3 / 5
Moments.cpp +
79.2%79.2%
+
79.2 %38 / 4871.4 %5 / 7
MoreThan.cpp +
86.2%86.2%
+
86.2 %25 / 29100.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 %14 / 1466.7 %2 / 3
Sort.cpp +
92.9%92.9%
+
92.9 %26 / 2871.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 000000000..7ad6eb939 --- /dev/null +++ b/coverage/funnel/FPS.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7791e57fe --- /dev/null +++ b/coverage/funnel/FPS.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2817486a7 --- /dev/null +++ b/coverage/funnel/FPS.cpp.gcov.html @@ -0,0 +1,395 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..06477b140 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..245850b01 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2d99606b0 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.gcov.html @@ -0,0 +1,528 @@ + + + + + + + LCOV - plumed test coverage - funnel/Funnel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - Funnel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..0c5e2a1b7 --- /dev/null +++ b/coverage/funnel/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..a16adc2f6 --- /dev/null +++ b/coverage/funnel/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..778e79951 --- /dev/null +++ b/coverage/funnel/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..0fcdff13c --- /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/Accumulate.cpp.func-sort-c.html b/coverage/generic/Accumulate.cpp.func-sort-c.html new file mode 100644 index 000000000..89d21ea23 --- /dev/null +++ b/coverage/generic/Accumulate.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - generic/Accumulate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Accumulate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10AccumulateC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10Accumulate22getNumberOfDerivativesEv36
_ZN4PLMD7generic10AccumulateC1ERKNS_13ActionOptionsE63
_ZN4PLMD7generic10Accumulate23calculateConstantValuesERKb126
_ZN4PLMD7generic10Accumulate16registerKeywordsERNS_8KeywordsE127
_ZN4PLMD7generic10Accumulate6updateEv2324
_ZN4PLMD7generic10Accumulate5applyEv2328
_ZN4PLMD7generic10Accumulate9calculateEv2328
_ZN4PLMD7generic10Accumulate17calculateOnUpdateEv4778
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Accumulate.cpp.func.html b/coverage/generic/Accumulate.cpp.func.html new file mode 100644 index 000000000..a3ff9ef5f --- /dev/null +++ b/coverage/generic/Accumulate.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - generic/Accumulate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Accumulate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10Accumulate16registerKeywordsERNS_8KeywordsE127
_ZN4PLMD7generic10Accumulate17calculateOnUpdateEv4778
_ZN4PLMD7generic10Accumulate22getNumberOfDerivativesEv36
_ZN4PLMD7generic10Accumulate23calculateConstantValuesERKb126
_ZN4PLMD7generic10Accumulate5applyEv2328
_ZN4PLMD7generic10Accumulate6updateEv2324
_ZN4PLMD7generic10Accumulate9calculateEv2328
_ZN4PLMD7generic10AccumulateC1ERKNS_13ActionOptionsE63
_ZN4PLMD7generic10AccumulateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Accumulate.cpp.gcov.html b/coverage/generic/Accumulate.cpp.gcov.html new file mode 100644 index 000000000..6303bc866 --- /dev/null +++ b/coverage/generic/Accumulate.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + LCOV - plumed test coverage - generic/Accumulate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Accumulate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-10-17 16:45:00Functions: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             : 
+      29             : //+PLUMEDOC GRIDCALC ACCUMULATE
+      30             : /*
+      31             : Sum the elements of this value over the course of the trajectory
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace generic {
+      40             : 
+      41             : class Accumulate :
+      42             :   public ActionWithValue,
+      43             :   public ActionWithArguments,
+      44             :   public ActionPilot
+      45             : {
+      46             : private:
+      47             :   bool clearnextstep;
+      48             :   unsigned clearstride;
+      49             : public:
+      50             :   static void registerKeywords( Keywords& keys );
+      51             :   Accumulate( const ActionOptions& );
+      52             :   unsigned getNumberOfDerivatives();
+      53        4778 :   bool calculateOnUpdate() override { return false; }
+      54         126 :   bool calculateConstantValues( const bool& have_atoms ) override { return false; }
+      55        2328 :   void calculate() override {}
+      56        2328 :   void apply() override {}
+      57             :   void update() override ;
+      58             : };
+      59             : 
+      60             : PLUMED_REGISTER_ACTION(Accumulate,"ACCUMULATE")
+      61             : 
+      62         127 : void Accumulate::registerKeywords( Keywords& keys ) {
+      63         127 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      64         127 :   ActionWithArguments::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      65         381 :   keys.use("ARG"); keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL");
+      66         254 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged");
+      67         254 :   keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data.  The default value "
+      68             :            "of 0 implies that all the data will be used and that the grid will never be cleared");
+      69         127 :   keys.setValueDescription("a sum calculated from the time series of the input quantity");
+      70         127 : }
+      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/generic/Average.cpp.func-sort-c.html b/coverage/generic/Average.cpp.func-sort-c.html new file mode 100644 index 000000000..8571c914e --- /dev/null +++ b/coverage/generic/Average.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - generic/Average.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Average.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:363894.7 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7AverageC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic7AverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD7generic7Average16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Average.cpp.func.html b/coverage/generic/Average.cpp.func.html new file mode 100644 index 000000000..6bbec326c --- /dev/null +++ b/coverage/generic/Average.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - generic/Average.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Average.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:363894.7 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7Average16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7generic7AverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD7generic7AverageC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Average.cpp.gcov.html b/coverage/generic/Average.cpp.gcov.html new file mode 100644 index 000000000..d7ea43379 --- /dev/null +++ b/coverage/generic/Average.cpp.gcov.html @@ -0,0 +1,225 @@ + + + + + + + LCOV - plumed test coverage - generic/Average.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Average.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:363894.7 %
Date:2024-10-17 16:45:00Functions: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 generic {
+      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          12 :   keys.add("optional","NORMALIZATION","keyword for old version of the code that is there to maintain back compatibility only. Adding this keyword does nothing");
+     108           6 :   keys.setValueDescription("the value of the average");
+     109          24 :   keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("ONES"); keys.needsAction("ACCUMULATE");
+     110           6 : }
+     111             : 
+     112           4 : Average::Average( const ActionOptions& ao ):
+     113             :   Action(ao),
+     114           4 :   ActionShortcut(ao)
+     115             : {
+     116             : 
+     117          16 :   std::string lw; parse("LOGWEIGHTS",lw); std::string stride, clearstride; parse("STRIDE",stride); parse("CLEAR",clearstride);
+     118           4 :   if( lw.length()>0 ) {
+     119           2 :     readInputLine( getShortcutLabel() + "_wsum: COMBINE ARG=" + lw + " PERIODIC=NO");
+     120           2 :     readInputLine( getShortcutLabel() + "_weight: CUSTOM ARG=" + getShortcutLabel() + "_wsum FUNC=exp(x) PERIODIC=NO");
+     121           6 :   } else readInputLine( getShortcutLabel() + "_weight: ONES SIZE=1" );
+     122             : 
+     123           8 :   std::vector<std::string> arg; parseVector("ARG",arg);
+     124           4 :   if( arg.size()!=1 ) error("should only be one argument to this action");
+     125           4 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( arg, plumed.getActionSet(), this, vals );
+     126             : 
+     127           8 :   readInputLine( getShortcutLabel() + "_denom: ACCUMULATE ARG=" + getShortcutLabel() + "_weight STRIDE=" + stride + " CLEAR=" + clearstride );
+     128           4 :   if( vals[0]->isPeriodic() ) {
+     129           2 :     std::string lbound, ubound, pfactor; vals[0]->getDomain( lbound, ubound ); pfactor = "((" + ubound + "-" + lbound + ")/(pi+pi))";
+     130           2 :     readInputLine( getShortcutLabel() + "_sin: CUSTOM ARG=" + arg[0] + "," + getShortcutLabel() + "_weight FUNC=y*sin((x-" + lbound + ")/" + pfactor + ") PERIODIC=NO");
+     131           2 :     readInputLine( getShortcutLabel() + "_cos: CUSTOM ARG=" + arg[0] + "," + getShortcutLabel() + "_weight FUNC=y*cos((x-" + lbound + ")/" + pfactor + ") PERIODIC=NO");
+     132           2 :     readInputLine( getShortcutLabel() + "_sinsum: ACCUMULATE ARG=" + getShortcutLabel() + "_sin STRIDE=" + stride + " CLEAR=" + clearstride );
+     133           2 :     readInputLine( getShortcutLabel() + "_cossum: ACCUMULATE ARG=" + getShortcutLabel() + "_cos STRIDE=" + stride + " CLEAR=" + clearstride );
+     134           2 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_sinsum," + getShortcutLabel() + "_cossum," + getShortcutLabel() + "_denom FUNC=" + lbound + "+" + pfactor + "*atan2(x/z,y/z) PERIODIC=" + lbound +"," + ubound);
+     135             :   } else {
+     136           6 :     std::string normstr; parse("NORMALIZATION",normstr);
+     137           6 :     if( normstr=="true" || normstr=="false" ) warning("NORMALIZATION is deprecated. You are advised to take this out of input files in future and use the new syntax with ACCUMULATE for unormalized data rather than the shortcut AVERAGE");
+     138           3 :     else if( normstr.length()>0 ) error("NORMALIZATION=" + normstr + " is not valid PLUMED input.  If you want an unormalised 'average' use ACCUMULATE");
+     139           6 :     readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + arg[0] + "," + getShortcutLabel() + "_weight FUNC=x*y PERIODIC=NO");
+     140           3 :     if( normstr.length()==0 || normstr=="true" ) {
+     141           6 :       readInputLine( getShortcutLabel() + "_numer: ACCUMULATE ARG=" + getShortcutLabel() + "_prod STRIDE=" + stride + " CLEAR=" + clearstride  );
+     142           6 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     143           0 :     } else if( normstr=="false" ) readInputLine( getShortcutLabel() + ": ACCUMULATE ARG=" + getShortcutLabel() + "_prod STRIDE=" + stride + " CLEAR=" + clearstride  );
+     144           0 :     else plumed_error();
+     145             :   }
+     146           8 : }
+     147             : 
+     148             : }
+     149             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Collect.cpp.func-sort-c.html b/coverage/generic/Collect.cpp.func-sort-c.html new file mode 100644 index 000000000..e6e4e2c71 --- /dev/null +++ b/coverage/generic/Collect.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - generic/Collect.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Collect.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7Collect22getNumberOfDerivativesEv0
_ZN4PLMD7generic7CollectC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic7CollectC1ERKNS_13ActionOptionsE94
_ZN4PLMD7generic7Collect23calculateConstantValuesERKb182
_ZN4PLMD7generic7Collect16registerKeywordsERNS_8KeywordsE192
_ZN4PLMD7generic7Collect5applyEv17687
_ZN4PLMD7generic7Collect6updateEv17687
_ZN4PLMD7generic7Collect9calculateEv17687
_ZN4PLMD7generic7Collect17calculateOnUpdateEv35558
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Collect.cpp.func.html b/coverage/generic/Collect.cpp.func.html new file mode 100644 index 000000000..58fab34b3 --- /dev/null +++ b/coverage/generic/Collect.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - generic/Collect.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Collect.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9CommittorC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic9Committor16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic9Committor5applyEv30
_ZN4PLMD7generic9Committor9calculateEv30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Committor.cpp.func.html b/coverage/generic/Committor.cpp.func.html new file mode 100644 index 000000000..e67fe1bdc --- /dev/null +++ b/coverage/generic/Committor.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - generic/Committor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Committor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9Committor16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic9Committor5applyEv30
_ZN4PLMD7generic9Committor9calculateEv30
_ZN4PLMD7generic9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic9CommittorC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Committor.cpp.gcov.html b/coverage/generic/Committor.cpp.gcov.html new file mode 100644 index 000000000..61144b20c --- /dev/null +++ b/coverage/generic/Committor.cpp.gcov.html @@ -0,0 +1,267 @@ + + + + + + + LCOV - plumed test coverage - generic/Committor.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Committor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-10-17 16:45:00Functions: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 generic {
+      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/generic/Constant.cpp.func-sort-c.html b/coverage/generic/Constant.cpp.func-sort-c.html new file mode 100644 index 000000000..327f8ad9d --- /dev/null +++ b/coverage/generic/Constant.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:596492.2 %
Date:2024-10-17 16:45:00Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8Constant16clearDerivativesERKb0
_ZN4PLMD7generic8Constant5applyEv0
_ZN4PLMD7generic8Constant9calculateEv0
_ZN4PLMD7generic8ConstantC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8ConstantC1ERKNS_13ActionOptionsE851
_ZN4PLMD7generic8Constant16registerKeywordsERNS_8KeywordsE1508
_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 000000000..3b06847e8 --- /dev/null +++ b/coverage/generic/Constant.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:596492.2 %
Date:2024-10-17 16:45:00Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8Constant16clearDerivativesERKb0
_ZN4PLMD7generic8Constant16registerKeywordsERNS_8KeywordsE1508
_ZN4PLMD7generic8Constant22getNumberOfDerivativesEv6041
_ZN4PLMD7generic8Constant5applyEv0
_ZN4PLMD7generic8Constant9calculateEv0
_ZN4PLMD7generic8ConstantC1ERKNS_13ActionOptionsE851
_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 000000000..d232f1eb0 --- /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:596492.2 %
Date:2024-10-17 16:45:00Functions: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        1508 : void Constant::registerKeywords( Keywords& keys ) {
+      73        1508 :   Action::registerKeywords(keys); ActionWithValue::registerKeywords(keys); keys.remove("NUMERICAL_DERIVATIVES");
+      74        3016 :   keys.add("optional","FILE","an input file containing the matrix");
+      75        3016 :   keys.add("compulsory","NROWS","0","the number of rows in your input matrix");
+      76        3016 :   keys.add("compulsory","NCOLS","0","the number of columns in your matrix");
+      77        3016 :   keys.add("optional","VALUE","the single number that you would like to store");
+      78        3016 :   keys.add("optional","VALUES","the numbers that are in your constant value");
+      79        3016 :   keys.addFlag("SCALARS",false,"treat the input list of numbers as a set of scalars");
+      80        3016 :   keys.addFlag("NOLOG",false,"do not report all the read in scalars in the log");
+      81        3016 :   keys.addOutputComponent("v","SCALARS","the # value");
+      82        1508 :   keys.setValueDescription("the constant value that was read from the plumed input");
+      83        1508 : }
+      84             : 
+      85         851 : Constant::Constant(const ActionOptions&ao):
+      86             :   Action(ao),
+      87         851 :   ActionWithValue(ao)
+      88             : {
+      89         851 :   bool nolog=false; parseFlag("NOLOG",nolog);
+      90        1702 :   bool scalars=false; std::string fname, vname; parse("FILE",fname);
+      91             :   std::vector<unsigned> shape; std::vector<double> vals;
+      92         851 :   if( fname.length()>0 ) {
+      93           3 :     IFile mfile; mfile.open(fname);
+      94             :     // Read in first line
+      95             :     std::vector<std::string> words; unsigned nline=0;
+      96           6 :     while( nline==0 ) {
+      97           3 :       Tools::getParsedLine( mfile, words );
+      98           3 :       nline=words.size();
+      99             :     }
+     100             :     std::vector<std::vector<double> > dissimilarities;
+     101           3 :     if( nline==1 ) {
+     102           0 :       shape.resize(1);
+     103           0 :       error("invalid matrix in input file");
+     104             :     }
+     105           3 :     shape.resize(2); shape[1]=nline;
+     106           3 :     std::vector<double> tmpdis( shape[1] );
+     107          34 :     for(unsigned j=0; j<shape[1]; ++j) Tools::convert( words[j], tmpdis[j] );
+     108           3 :     dissimilarities.push_back( tmpdis );
+     109             : 
+     110          31 :     while( Tools::getParsedLine( mfile, words ) ) {
+     111          28 :       if( words.size()!=nline ) error("bad formatting in matrix file");
+     112         360 :       for(unsigned j=0; j<nline; ++j) Tools::convert( words[j], tmpdis[j] );
+     113          28 :       dissimilarities.push_back( tmpdis );
+     114             :     }
+     115           3 :     mfile.close(); shape[0] = dissimilarities.size(); vals.resize(shape[0]);
+     116           3 :     if( shape.size()==2 ) vals.resize( shape[0]*shape[1] );
+     117          34 :     for(unsigned i=0; i<shape[0]; ++i) {
+     118         394 :       for(unsigned j=0; j<nline; ++j) vals[i*nline+j] = dissimilarities[i][j];
+     119             :     }
+     120           3 :   } else {
+     121        1696 :     unsigned nr, nc; parse("NROWS",nr); parse("NCOLS",nc);
+     122         848 :     if( nr>0 && nc>0 ) {
+     123          73 :       shape.resize(2); shape[0]=nr; shape[1]=nc; vals.resize( nr*nc );
+     124          73 :       log.printf("  reading in %d by %d matrix \n", nr, nc );
+     125         775 :     } else if( nr>0 || nc>0 ) error("makes no sense to set only one of NROWS and NCOLS to a non-zero value");
+     126        2544 :     parseVector("VALUES",vals); parseFlag("SCALARS",scalars);
+     127         848 :     if( vals.size()==0 ) {
+     128         132 :       parseVector("VALUE",vals);
+     129          66 :       if( vals.size()!=1 ) error("VALUE keyword should take a single scalar");
+     130         782 :     } else if( vals.size()==1 ) scalars=false;
+     131             : 
+     132         848 :     log.printf("  read in %d values :", vals.size() );
+     133       26553 :     if( !nolog ) { for(unsigned i=0; i<vals.size(); ++i) log.printf(" %f", vals[i] ); }
+     134         848 :     log.printf("\n");
+     135         848 :     if( !scalars && shape.size()==0 && vals.size()>1 ) { shape.resize(1); shape[0] = vals.size(); }
+     136             :   }
+     137         851 :   if( !scalars ) {
+     138             :     // Now set the value
+     139         850 :     addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->setConstant();
+     140      147242 :     for(unsigned i=0; i<vals.size(); ++i) getPntrToComponent(0)->set( i, vals[i] );
+     141             :   } else {
+     142           3 :     for(unsigned i=0; i<vals.size(); i++) {
+     143           2 :       std::string num; Tools::convert(i,num);
+     144           4 :       addComponent("v-"+num); componentIsNotPeriodic("v-"+num);
+     145           2 :       Value* comp=getPntrToComponent("v-"+num);
+     146           2 :       comp->setConstant(); comp->set(vals[i]);
+     147             :     }
+     148             :   }
+     149         851 : }
+     150             : 
+     151             : }
+     152             : }
+     153             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/CreateMask.cpp.func-sort-c.html b/coverage/generic/CreateMask.cpp.func-sort-c.html new file mode 100644 index 000000000..6d0735298 --- /dev/null +++ b/coverage/generic/CreateMask.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - generic/CreateMask.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - CreateMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515494.4 %
Date:2024-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10CreateMask22getNumberOfDerivativesEv0
_ZN4PLMD7generic10CreateMaskC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10CreateMask5applyEv6
_ZN4PLMD7generic10CreateMaskC1ERKNS_13ActionOptionsE15
_ZN4PLMD7generic10CreateMask9calculateEv21
_ZN4PLMD7generic10CreateMask7prepareEv25
_ZN4PLMD7generic10CreateMask16registerKeywordsERNS_8KeywordsE28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/CreateMask.cpp.func.html b/coverage/generic/CreateMask.cpp.func.html new file mode 100644 index 000000000..51ce78f9a --- /dev/null +++ b/coverage/generic/CreateMask.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - generic/CreateMask.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - CreateMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515494.4 %
Date:2024-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10CreateMask16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD7generic10CreateMask22getNumberOfDerivativesEv0
_ZN4PLMD7generic10CreateMask5applyEv6
_ZN4PLMD7generic10CreateMask7prepareEv25
_ZN4PLMD7generic10CreateMask9calculateEv21
_ZN4PLMD7generic10CreateMaskC1ERKNS_13ActionOptionsE15
_ZN4PLMD7generic10CreateMaskC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/CreateMask.cpp.gcov.html b/coverage/generic/CreateMask.cpp.gcov.html new file mode 100644 index 000000000..0c65c904d --- /dev/null +++ b/coverage/generic/CreateMask.cpp.gcov.html @@ -0,0 +1,203 @@ + + + + + + + LCOV - plumed test coverage - generic/CreateMask.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - CreateMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515494.4 %
Date:2024-10-17 16:45:00Functions: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 generic {
+      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          28 : void CreateMask::registerKeywords( Keywords& keys ) {
+      58          28 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      59          28 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      60          56 :   keys.add("compulsory","TYPE","the way the zeros are supposed to be set");
+      61          56 :   keys.add("compulsory","NZEROS","the number of zeros that you want to put in the mask");
+      62          56 :   keys.add("optional","SEED","the seed to use for the random number generator");
+      63          28 :   keys.setValueDescription("a vector of zeros and ones that is used that can be used to mask some of the elements in a time series");
+      64          28 : }
+      65             : 
+      66             : 
+      67          15 : CreateMask::CreateMask( const ActionOptions& ao ) :
+      68             :   Action(ao),
+      69             :   ActionWithValue(ao),
+      70             :   ActionWithArguments(ao),
+      71          15 :   nzeros(0)
+      72             : {
+      73          15 :   if( getNumberOfArguments()!=1 ) error("should only be one argument to this action");
+      74          15 :   if( getPntrToArgument(0)->getRank()!=1 ) error("argument should be a vector");
+      75          39 :   std::string stype; parse("TYPE",stype); if( stype!="nomask" ) parse("NZEROS",nzeros);
+      76             : 
+      77          15 :   if( stype=="nomask" ) {
+      78           6 :     type=nomask; log.printf("  setting all points in output mask to zero \n");
+      79           9 :   } else if( stype=="stride" ) {
+      80           8 :     type=stride; log.printf("  setting every %d equally spaced points in output mask to zero \n", nzeros );
+      81           1 :   } else if( stype=="random" ) {
+      82           2 :     unsigned seed=230623; parse("SEED",seed); r.setSeed(-seed); getPntrToArgument(0)->buildDataStore();
+      83           1 :     type=random; log.printf("  choosing %d points to set to non-zero in mask in accordance with input weights \n", nzeros );
+      84           0 :   } else error( stype + " is not a valid way input for TYPE");
+      85          15 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0];
+      86          15 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      87          53 :   for(unsigned i=0; i<shape[0]; ++i) getPntrToComponent(0)->set( i, 1.0 );
+      88          15 : }
+      89             : 
+      90          25 : void CreateMask::prepare() {
+      91          25 :   Value* out=getPntrToComponent(0); Value* arg=getPntrToArgument(0);
+      92          25 :   if( out->getShape()[0]!=arg->getShape()[0] ) {
+      93          11 :     std::vector<unsigned> shape(1); shape[0] = arg->getShape()[0]; out->setShape( shape );
+      94             :   }
+      95          25 :   if( type!=nomask ) {
+      96         325 :     for(unsigned i=nzeros; i<out->getShape()[0]; ++i) out->set( i, 1 );
+      97             :   }
+      98          25 : }
+      99             : 
+     100          21 : void CreateMask::calculate() {
+     101          21 :   Value* out=getPntrToComponent(0); Value* arg=getPntrToArgument(0);
+     102          21 :   unsigned ns = arg->getShape()[0];
+     103        1171 :   for(unsigned i=0; i<ns; ++i) out->set( i, 1.0 );
+     104             : 
+     105          21 :   if( type==stride ) {
+     106          11 :     std::size_t ss = int( std::floor( ns / nzeros ) );
+     107         300 :     for(unsigned i=0; i<nzeros; ++i) out->set( i*ss, 0.0 );
+     108          10 :   } else if( type==random ) {
+     109          20 :     for(unsigned i=0; i<nzeros; ++i ) {
+     110             :       double totweights = 0;
+     111         112 :       for(unsigned j=0; j<ns; ++j) {
+     112          96 :         if( out->get(j)>0 ) totweights += arg->get(j);
+     113             :       }
+     114          16 :       double rr = r.U01()*totweights; double accum=0;
+     115          55 :       for(unsigned j=0; j<ns; ++j) {
+     116          55 :         if( out->get(j)>0 ) accum += arg->get(j);
+     117          55 :         if( accum<rr ) continue;
+     118          16 :         out->set( j, 0 ); break;
+     119             :       }
+     120             :     }
+     121           6 :   } else if( type==nomask ) {
+     122         555 :     for(unsigned i=0; i<ns; ++i) out->set( i, 0.0 );
+     123           0 :   } else error("invalid mask creation type");
+     124          21 : }
+     125             : 
+     126             : }
+     127             : }
+
+
+
+ + + + +
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 000000000..215db7c89 --- /dev/null +++ b/coverage/generic/Debug.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e902f3fba --- /dev/null +++ b/coverage/generic/Debug.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4ab1e47c9 --- /dev/null +++ b/coverage/generic/Debug.cpp.gcov.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - generic/Debug.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Debug.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..8679d4867 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtoms29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD2Ev0
_ZN4PLMD7generic9DumpAtoms15actionHasForcesEv194
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE220
_ZN4PLMD7generic9DumpAtomsD0Ev220
_ZN4PLMD7generic9DumpAtomsD1Ev220
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE222
_ZN4PLMD7generic9DumpAtoms6updateEv8998
_ZN4PLMD7generic9DumpAtoms12lockRequestsEv9093
_ZN4PLMD7generic9DumpAtoms14unlockRequestsEv9093
_ZN4PLMD7generic9DumpAtoms5applyEv9093
_ZN4PLMD7generic9DumpAtoms9calculateEv9093
+
+
+ + + +
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 000000000..14878ef01 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtoms12lockRequestsEv9093
_ZN4PLMD7generic9DumpAtoms14unlockRequestsEv9093
_ZN4PLMD7generic9DumpAtoms15actionHasForcesEv194
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE222
_ZN4PLMD7generic9DumpAtoms29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7generic9DumpAtoms5applyEv9093
_ZN4PLMD7generic9DumpAtoms6updateEv8998
_ZN4PLMD7generic9DumpAtoms9calculateEv9093
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE220
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD0Ev220
_ZN4PLMD7generic9DumpAtomsD1Ev220
_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 000000000..411414f79 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.gcov.html @@ -0,0 +1,438 @@ + + + + + + + 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-10-17 16:45:00Functions: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         194 :   bool actionHasForces() override { return false; }
+     142             :   void lockRequests() override;
+     143             :   void unlockRequests() override;
+     144        9093 :   void calculate() override {}
+     145        9093 :   void apply() override {}
+     146             :   void update() override ;
+     147             : };
+     148             : 
+     149             : PLUMED_REGISTER_ACTION(DumpAtoms,"DUMPATOMS")
+     150             : 
+     151         222 : void DumpAtoms::registerKeywords( Keywords& keys ) {
+     152         222 :   Action::registerKeywords( keys );
+     153         222 :   ActionPilot::registerKeywords( keys );
+     154         222 :   ActionAtomistic::registerKeywords( keys );
+     155         222 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+     156         444 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     157         444 :   keys.add("atoms", "ATOMS", "the atom indices whose positions you would like to print out");
+     158         444 :   keys.add("compulsory", "FILE", "file on which to output coordinates; extension is automatically detected");
+     159         444 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     160         444 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     161         444 :   keys.add("optional", "TYPE","file type, either xyz, gro, xtc, or trr, can override an automatically detected file extension");
+     162         444 :   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         444 :   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         222 :   keys.use("RESTART");
+     165         222 :   keys.use("UPDATE_FROM");
+     166         222 :   keys.use("UPDATE_UNTIL");
+     167         222 : }
+     168             : 
+     169         220 : DumpAtoms::DumpAtoms(const ActionOptions&ao):
+     170             :   Action(ao),
+     171             :   ActionAtomistic(ao),
+     172             :   ActionWithArguments(ao),
+     173             :   ActionPilot(ao),
+     174         220 :   iprecision(3)
+     175             : {
+     176             :   std::vector<AtomNumber> atoms;
+     177             :   std::string file;
+     178         440 :   parse("FILE",file);
+     179         220 :   if(file.length()==0) error("name out output file was not specified");
+     180         220 :   type=Tools::extension(file);
+     181         220 :   log<<"  file name "<<file<<"\n";
+     182         453 :   if(type=="gro" || type=="xyz" || type=="xtc" || type=="trr") {
+     183         197 :     log<<"  file extension indicates a "<<type<<" file\n";
+     184             :   } else {
+     185          23 :     log<<"  file extension not detected, assuming xyz\n";
+     186             :     type="xyz";
+     187             :   }
+     188             :   std::string ntype;
+     189         440 :   parse("TYPE",ntype);
+     190         220 :   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         440 :   parse("PRECISION",precision);
+     203         220 :   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         440 :   parseAtomList("ATOMS",atoms);
+     215             : 
+     216         440 :   std::string unitname; parse("UNITS",unitname);
+     217         220 :   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         528 :   } else if(type=="gro" || type=="xtc" || type=="trr") lenunit=getUnits().getLength();
+     224         147 :   else lenunit=1.0;
+     225             : 
+     226         220 :   of.link(*this);
+     227         220 :   of.open(file);
+     228             :   std::string path=of.getPath();
+     229         220 :   log<<"  Writing on file "<<path<<"\n";
+     230             :   std::string mode=of.getMode();
+     231         220 :   if(type=="xtc") {
+     232           6 :     of.close();
+     233           6 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     234         214 :   } else if(type=="trr") {
+     235           4 :     of.close();
+     236           4 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     237             :   }
+     238         220 :   log.printf("  printing the following atoms in %s :", unitname.c_str() );
+     239       30852 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     240         220 :   log.printf("\n");
+     241             : 
+     242         220 :   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         220 :   requestAtoms(atoms, false);
+     258         220 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     259         220 :   if( moldat ) {
+     260          56 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     261          56 :     names.resize(atoms.size());
+     262        5835 :     for(unsigned i=0; i<atoms.size(); i++) if(atoms[i].index()<moldat->getPDBsize()) names[i]=moldat->getAtomName(atoms[i]);
+     263          56 :     residueNumbers.resize(atoms.size());
+     264        5835 :     for(unsigned i=0; i<residueNumbers.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNumbers[i]=moldat->getResidueNumber(atoms[i]);
+     265          56 :     residueNames.resize(atoms.size());
+     266        5835 :     for(unsigned i=0; i<residueNames.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNames[i]=moldat->getResidueName(atoms[i]);
+     267             :   }
+     268         220 : }
+     269             : 
+     270           0 : void DumpAtoms::calculateNumericalDerivatives( ActionWithValue* a ) {
+     271           0 :   plumed_merror("this should never be called");
+     272             : }
+     273             : 
+     274        9093 : void DumpAtoms::lockRequests() {
+     275             :   ActionWithArguments::lockRequests();
+     276             :   ActionAtomistic::lockRequests();
+     277        9093 : }
+     278             : 
+     279        9093 : void DumpAtoms::unlockRequests() {
+     280             :   ActionWithArguments::unlockRequests();
+     281             :   ActionAtomistic::unlockRequests();
+     282        9093 : }
+     283             : 
+     284        8998 : void DumpAtoms::update() {
+     285        8998 :   if(type=="xyz") {
+     286        8412 :     unsigned nat=0; std::vector<double> args( getNumberOfArguments() );
+     287       73985 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i)  {
+     288       95475 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) args[j] = getPntrToArgument(j)->get(i);
+     289       65573 :       if( bounds.check( args ) ) nat++;
+     290             :     }
+     291        8412 :     of.printf("%d\n",nat);
+     292        8412 :     const Tensor & t(getPbc().getBox());
+     293        8412 :     if(getPbc().isOrthorombic()) {
+     294         612 :       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       73985 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     303       95475 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) args[j] = getPntrToArgument(j)->get(i);
+     304       65573 :       if( !bounds.check(args) ) continue;
+     305             :       const char* defname="X";
+     306             :       const char* name=defname;
+     307       61767 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     308      123534 :       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       87863 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) of.printf((" "+fmt_xyz).c_str(), getPntrToArgument(j)->get(i) );
+     310       61767 :       of.printf("\n");
+     311             :     }
+     312         586 :   } else if(type=="gro") {
+     313         466 :     const Tensor & t(getPbc().getBox());
+     314         466 :     of.printf("Made with PLUMED t=%f\n",getTime()/getUnits().getTime());
+     315         466 :     of.printf("%d\n",getNumberOfAtoms());
+     316       38404 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     317             :       const char* defname="X";
+     318             :       const char* name=defname;
+     319             :       unsigned residueNumber=0;
+     320       37938 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     321       37938 :       if(residueNumbers.size()>0) residueNumber=residueNumbers[i];
+     322       37938 :       std::string resname="";
+     323       37938 :       if(residueNames.size()>0) resname=residueNames[i];
+     324       75876 :       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       37938 :                 lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2));
+     327             :     }
+     328         932 :     of.printf((fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+"\n").c_str(),
+     329         466 :               lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2),
+     330         466 :               lenunit*t(0,1),lenunit*t(0,2),lenunit*t(1,0),
+     331         466 :               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        8998 : }
+     351             : 
+     352         440 : DumpAtoms::~DumpAtoms() {
+     353         220 :   if(type=="xtc") {
+     354           6 :     xdrfile_close(xd);
+     355         214 :   } else if(type=="trr") {
+     356           4 :     xdrfile_close(xd);
+     357             :   }
+     358        1100 : }
+     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 000000000..4f0bb1e75 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD2Ev0
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE253
_ZN4PLMD7generic15DumpDerivativesD0Ev253
_ZN4PLMD7generic15DumpDerivativesD1Ev253
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE255
_ZN4PLMD7generic15DumpDerivatives6updateEv9112
_ZN4PLMD7generic15DumpDerivatives5applyEv12297
_ZN4PLMD7generic15DumpDerivatives9calculateEv12339
+
+
+ + + +
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 000000000..fd3f559e8 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE255
_ZN4PLMD7generic15DumpDerivatives5applyEv12297
_ZN4PLMD7generic15DumpDerivatives6updateEv9112
_ZN4PLMD7generic15DumpDerivatives9calculateEv12339
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE253
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD0Ev253
_ZN4PLMD7generic15DumpDerivativesD1Ev253
_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 000000000..cea271ca7 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + 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-10-17 16:45:00Functions: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       12339 :   void calculate() override {}
+      64             :   explicit DumpDerivatives(const ActionOptions&);
+      65             :   static void registerKeywords(Keywords& keys);
+      66       12297 :   void apply() override {}
+      67             :   void update() override;
+      68             :   ~DumpDerivatives();
+      69             : };
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(DumpDerivatives,"DUMPDERIVATIVES")
+      72             : 
+      73         255 : void DumpDerivatives::registerKeywords(Keywords& keys) {
+      74         255 :   Action::registerKeywords(keys);
+      75         255 :   ActionPilot::registerKeywords(keys);
+      76         255 :   ActionWithArguments::registerKeywords(keys);
+      77         255 :   keys.use("ARG");
+      78         510 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      79         510 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      80         510 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      81         255 :   keys.use("RESTART");
+      82         255 :   keys.use("UPDATE_FROM");
+      83         255 :   keys.use("UPDATE_UNTIL");
+      84         255 : }
+      85             : 
+      86         253 : DumpDerivatives::DumpDerivatives(const ActionOptions&ao):
+      87             :   Action(ao),
+      88             :   ActionPilot(ao),
+      89             :   ActionWithArguments(ao),
+      90         253 :   fmt("%15.10f")
+      91             : {
+      92         506 :   parse("FILE",file);
+      93         253 :   if( file.length()==0 ) error("name of output file was not specified");
+      94         253 :   parse("FMT",fmt);
+      95         253 :   fmt=" "+fmt;
+      96         253 :   of.link(*this);
+      97         253 :   of.open(file);
+      98         253 :   log.printf("  on file %s\n",file.c_str());
+      99         253 :   log.printf("  with format %s\n",fmt.c_str());
+     100             :   unsigned nargs=getNumberOfArguments();
+     101         253 :   if( nargs==0 ) error("no arguments specified");
+     102         253 :   (getPntrToArgument(0)->getPntrToAction())->turnOnDerivatives();
+     103         253 :   if( getPntrToArgument(0)->getRank()>0 ) error("cannot dump derivatives of non-scalar objects");
+     104         253 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     105         253 :   if( npar==0 ) error("one or more arguments has no derivatives");
+     106         843 :   for(unsigned i=1; i<nargs; i++) {
+     107         590 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+     108         590 :     if( getPntrToArgument(i)->getRank()>0 ) error("cannot dump derivatives of non-scalar objects");
+     109         590 :     if( npar!=getPntrToArgument(i)->getNumberOfDerivatives() ) error("the number of derivatives must be the same in all values being dumped");
+     110             :   }
+     111         253 :   checkRead();
+     112         253 : }
+     113             : 
+     114             : 
+     115        9112 : void DumpDerivatives::update() {
+     116        9112 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     117      698622 :   for(unsigned ipar=0; ipar<npar; ipar++) {
+     118      689510 :     of.fmtField(" %f");
+     119      689510 :     of.printField("time",getTime());
+     120      689510 :     of.printField("parameter",(int)ipar);
+     121     3452310 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     122     2762800 :       of.fmtField(fmt);
+     123     2762800 :       of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getDerivative(ipar) );
+     124             :     }
+     125      689510 :     of.printField();
+     126             :   }
+     127        9112 : }
+     128             : 
+     129         506 : DumpDerivatives::~DumpDerivatives() {
+     130         506 : }
+     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 000000000..01b0014c6 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD2Ev0
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE29
_ZN4PLMD7generic10DumpForcesD0Ev29
_ZN4PLMD7generic10DumpForcesD1Ev29
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD7generic10DumpForces5applyEv406
_ZN4PLMD7generic10DumpForces6updateEv406
_ZN4PLMD7generic10DumpForces9calculateEv406
+
+
+ + + +
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 000000000..35a38c212 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD7generic10DumpForces5applyEv406
_ZN4PLMD7generic10DumpForces6updateEv406
_ZN4PLMD7generic10DumpForces9calculateEv406
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE29
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD0Ev29
_ZN4PLMD7generic10DumpForcesD1Ev29
_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 000000000..90db5a5fa --- /dev/null +++ b/coverage/generic/DumpForces.cpp.gcov.html @@ -0,0 +1,195 @@ + + + + + + + LCOV - plumed test coverage - generic/DumpForces.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpForces.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-10-17 16:45:00Functions: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         406 :   void calculate() override {}
+      62             :   explicit DumpForces(const ActionOptions&);
+      63             :   static void registerKeywords(Keywords& keys);
+      64         406 :   void apply() override {}
+      65             :   void update() override;
+      66             :   ~DumpForces();
+      67             : };
+      68             : 
+      69             : PLUMED_REGISTER_ACTION(DumpForces,"DUMPFORCES")
+      70             : 
+      71          31 : void DumpForces::registerKeywords(Keywords& keys) {
+      72          31 :   Action::registerKeywords(keys);
+      73          31 :   ActionPilot::registerKeywords(keys);
+      74          31 :   ActionWithArguments::registerKeywords(keys);
+      75          31 :   keys.use("ARG");
+      76          62 :   keys.add("compulsory","STRIDE","1","the frequency with which the forces should be output");
+      77          62 :   keys.add("compulsory","FILE","the name of the file on which to output the forces");
+      78          62 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      79          31 :   keys.use("RESTART");
+      80          31 :   keys.use("UPDATE_FROM");
+      81          31 :   keys.use("UPDATE_UNTIL");
+      82          31 : }
+      83             : 
+      84          29 : DumpForces::DumpForces(const ActionOptions&ao):
+      85             :   Action(ao),
+      86             :   ActionPilot(ao),
+      87             :   ActionWithArguments(ao),
+      88          29 :   fmt("%15.10f")
+      89             : {
+      90          58 :   parse("FILE",file);
+      91          29 :   if( file.length()==0 ) error("name of file was not specified");
+      92          29 :   parse("FMT",fmt);
+      93          29 :   fmt=" "+fmt;
+      94          29 :   of.link(*this);
+      95          29 :   of.open(file);
+      96          29 :   log.printf("  on file %s\n",file.c_str());
+      97          29 :   log.printf("  with format %s\n",fmt.c_str());
+      98          29 :   if( getNumberOfArguments()==0 ) error("no arguments have been specified");
+      99          29 :   checkRead();
+     100          29 : }
+     101             : 
+     102             : 
+     103         406 : void DumpForces::update() {
+     104         406 :   of.fmtField(" %f");
+     105         406 :   of.printField("time",getTime());
+     106        5052 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     107        4646 :     of.fmtField(fmt);
+     108        4646 :     of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getForce());
+     109             :   }
+     110         406 :   of.printField();
+     111         406 : }
+     112             : 
+     113          58 : DumpForces::~DumpForces() {
+     114          58 : }
+     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 000000000..428001212 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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:616396.8 %
Date:2024-10-17 16:45:00Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14DumpMassCharge15actionHasForcesEv0
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD2Ev0
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE14
_ZN4PLMD7generic14DumpMassChargeD0Ev14
_ZN4PLMD7generic14DumpMassChargeD1Ev14
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7generic14DumpMassCharge5applyEv94
_ZN4PLMD7generic14DumpMassCharge6updateEv94
_ZN4PLMD7generic14DumpMassCharge7prepareEv94
_ZN4PLMD7generic14DumpMassCharge9calculateEv94
+
+
+ + + +
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 000000000..e947b2df2 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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:616396.8 %
Date:2024-10-17 16:45:00Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14DumpMassCharge15actionHasForcesEv0
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7generic14DumpMassCharge5applyEv94
_ZN4PLMD7generic14DumpMassCharge6updateEv94
_ZN4PLMD7generic14DumpMassCharge7prepareEv94
_ZN4PLMD7generic14DumpMassCharge9calculateEv94
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE14
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD0Ev14
_ZN4PLMD7generic14DumpMassChargeD1Ev14
_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 000000000..4456edc05 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.gcov.html @@ -0,0 +1,262 @@ + + + + + + + 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:616396.8 %
Date:2024-10-17 16:45:00Functions: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          94 :   void calculate() override {}
+      92          94 :   void apply() override {}
+      93             :   void update() override;
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(DumpMassCharge,"DUMPMASSCHARGE")
+      97             : 
+      98          16 : void DumpMassCharge::registerKeywords( Keywords& keys ) {
+      99          16 :   Action::registerKeywords( keys );
+     100          16 :   ActionPilot::registerKeywords( keys );
+     101          16 :   ActionAtomistic::registerKeywords( keys );
+     102          32 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     103          32 :   keys.add("atoms", "ATOMS", "the atom indices whose charges and masses you would like to print out");
+     104          32 :   keys.add("compulsory", "FILE", "file on which to output charges and masses.");
+     105          32 :   keys.addFlag("ONLY_MASSES",false,"Only output masses to file");
+     106          32 :   keys.addFlag("ONLY_CHARGES",false,"Only output charges to file");
+     107          16 : }
+     108             : 
+     109          14 : DumpMassCharge::DumpMassCharge(const ActionOptions&ao):
+     110             :   Action(ao),
+     111             :   ActionAtomistic(ao),
+     112             :   ActionPilot(ao),
+     113          14 :   first(true),
+     114          14 :   second(true),
+     115          14 :   print_masses(true),
+     116          14 :   print_charges(true)
+     117             : {
+     118             :   std::vector<AtomNumber> atoms;
+     119          28 :   parse("FILE",file);
+     120          14 :   if(file.length()==0) error("name of output file was not specified");
+     121          14 :   log.printf("  output written to file %s\n",file.c_str());
+     122             : 
+     123          28 :   parseAtomList("ATOMS",atoms);
+     124             : 
+     125          14 :   if(atoms.size()==0) {
+     126          10 :     std::vector<std::string> strvec(1); strvec[0]="@mdatoms"; interpretAtomList( strvec,atoms );
+     127          10 :   }
+     128             : 
+     129          14 :   bool only_masses = false;
+     130          14 :   parseFlag("ONLY_MASSES",only_masses);
+     131          14 :   if(only_masses) {
+     132           1 :     print_charges = false;
+     133           1 :     log.printf("  only masses will be written to file\n");
+     134             :   }
+     135             : 
+     136          14 :   bool only_charges = false;
+     137          14 :   parseFlag("ONLY_CHARGES",only_charges);
+     138          14 :   if(only_charges) {
+     139           1 :     print_masses = false;
+     140           1 :     log.printf("  only charges will be written to file\n");
+     141             :   }
+     142             : 
+     143             : 
+     144          14 :   checkRead();
+     145             : 
+     146          14 :   log.printf("  printing the following atoms:" );
+     147        1224 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     148          14 :   log.printf("\n");
+     149          14 :   requestAtoms(atoms);
+     150             : 
+     151          14 :   if(only_masses && only_charges) {
+     152           0 :     plumed_merror("using both ONLY_MASSES and ONLY_CHARGES doesn't make sense");
+     153             :   }
+     154             : 
+     155          14 : }
+     156             : 
+     157          94 : void DumpMassCharge::prepare() {
+     158          94 :   if(!first && second) {
+     159          14 :     requestAtoms(std::vector<AtomNumber>());
+     160          14 :     second=false;
+     161             :   }
+     162          94 : }
+     163             : 
+     164          94 : void DumpMassCharge::update() {
+     165          94 :   if(!first) return;
+     166          14 :   first=false;
+     167             : 
+     168          14 :   OFile of;
+     169          14 :   of.link(*this);
+     170          14 :   of.open(file);
+     171             : 
+     172        1224 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     173        1210 :     int ii=getAbsoluteIndex(i).index();
+     174        1210 :     of.printField("index",ii);
+     175        2312 :     if(print_masses) {of.printField("mass",getMass(i));}
+     176        2312 :     if(print_charges) {of.printField("charge",getCharge(i));}
+     177        1210 :     of.printField();
+     178             :   }
+     179          14 : }
+     180             : 
+     181          28 : DumpMassCharge::~DumpMassCharge() {
+     182          28 : }
+     183             : 
+     184             : 
+     185             : }
+     186             : }
+
+
+
+ + + + +
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 000000000..e75a23824 --- /dev/null +++ b/coverage/generic/DumpPDB.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:104104100.0 %
Date:2024-10-17 16:45:00Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7DumpPDBC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic7DumpPDB5applyEv7
_ZN4PLMD7generic7DumpPDB9calculateEv7
_ZN4PLMD7generic7DumpPDBC1ERKNS_13ActionOptionsE15
_ZN4PLMD7generic7DumpPDB6updateEv19
_ZN4PLMD7generic7DumpPDB16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD7generic7DumpPDB13buildArgnamesEv23
_ZNK4PLMD7generic7DumpPDB9printAtomERNS_5OFileERKjS5_RKNS_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 000000000..5668d2364 --- /dev/null +++ b/coverage/generic/DumpPDB.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:104104100.0 %
Date:2024-10-17 16:45:00Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7DumpPDB13buildArgnamesEv23
_ZN4PLMD7generic7DumpPDB16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD7generic7DumpPDB5applyEv7
_ZN4PLMD7generic7DumpPDB6updateEv19
_ZN4PLMD7generic7DumpPDB9calculateEv7
_ZN4PLMD7generic7DumpPDBC1ERKNS_13ActionOptionsE15
_ZN4PLMD7generic7DumpPDBC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic7DumpPDB9printAtomERNS_5OFileERKjS5_RKNS_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 000000000..b2f27f8c0 --- /dev/null +++ b/coverage/generic/DumpPDB.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + 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:104104100.0 %
Date:2024-10-17 16:45:00Functions: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/ActionAtomistic.h"
+      25             : #include "core/ActionPilot.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "tools/OFile.h"
+      29             : #include "tools/h36.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace generic {
+      33             : 
+      34             : //+PLUMEDOC PRINTANALYSIS DUMPPDB
+      35             : /*
+      36             : Output PDB file.
+      37             : 
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class DumpPDB :
+      45             :   public ActionWithArguments,
+      46             :   public ActionPilot
+      47             : {
+      48             :   std::string fmt;
+      49             :   std::string file;
+      50             :   std::string description;
+      51             :   std::vector<unsigned> pdb_resid_indices;
+      52             :   std::vector<double> beta, occupancy;
+      53             :   std::vector<std::string> argnames;
+      54             :   std::vector<AtomNumber> pdb_atom_indices;
+      55             :   void buildArgnames();
+      56             :   void printAtom( OFile& opdbf, const unsigned& anum, const unsigned& rnum, const Vector& pos, const double& m, const double& q ) const ;
+      57             : public:
+      58             :   static void registerKeywords( Keywords& keys );
+      59             :   explicit DumpPDB(const ActionOptions&);
+      60           7 :   void calculate() override {}
+      61           7 :   void apply() override {}
+      62             :   void update() override ;
+      63             : };
+      64             : 
+      65             : PLUMED_REGISTER_ACTION(DumpPDB,"DUMPPDB")
+      66             : 
+      67          21 : void DumpPDB::registerKeywords( Keywords& keys ) {
+      68          21 :   Action::registerKeywords( keys );
+      69          21 :   ActionPilot::registerKeywords( keys );
+      70          21 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      71          42 :   keys.add("optional","ATOMS","value containing positions of atoms that should be output");
+      72          42 :   keys.add("compulsory","STRIDE","0","the frequency with which the atoms should be output");
+      73          42 :   keys.add("compulsory","FILE","the name of the file on which to output these quantities");
+      74          42 :   keys.add("compulsory","FMT","%f","the format that should be used to output real numbers");
+      75          42 :   keys.add("compulsory","OCCUPANCY","1.0","vector of values to output in the occupancy column of the pdb file");
+      76          42 :   keys.add("compulsory","BETA","1.0","vector of values to output in the beta column of the pdb file");
+      77          42 :   keys.add("optional","DESCRIPTION","the title to use for your PDB output");
+      78          42 :   keys.add("optional","ATOM_INDICES","the indices of the atoms in your PDB output");
+      79          42 :   keys.add("optional","RESIDUE_INDICES","the indices of the residues in your PDB output");
+      80          42 :   keys.add("optional","ARG_NAMES","the names of the arguments that are being output");
+      81          21 : }
+      82             : 
+      83          15 : DumpPDB::DumpPDB(const ActionOptions&ao):
+      84             :   Action(ao),
+      85             :   ActionWithArguments(ao),
+      86          15 :   ActionPilot(ao)
+      87             : {
+      88          30 :   parse("FILE",file);
+      89          15 :   if(file.length()==0) error("name out output file was not specified");
+      90          30 :   std::vector<std::string> atoms; parseVector("ATOMS",atoms);
+      91          15 :   if( atoms.size()>0 ) {
+      92           8 :     std::vector<Value*> atom_args; interpretArgumentList( atoms, plumed.getActionSet(), this, atom_args );
+      93           8 :     if( atom_args.size()!=1 ) error("only one action should appear in input to atom args");
+      94           8 :     std::vector<Value*> args( getArguments() ); args.push_back( atom_args[0] ); requestArguments( args );
+      95          16 :     std::vector<std::string> indices; parseVector("ATOM_INDICES",indices); std::vector<Value*> xvals,yvals,zvals,masv,chargev;
+      96           8 :     ActionAtomistic::getAtomValuesFromPlumedObject(plumed,xvals,yvals,zvals,masv,chargev);
+      97           8 :     ActionAtomistic::interpretAtomList( indices, xvals, this, pdb_atom_indices );
+      98           8 :     log.printf("  printing atoms : ");
+      99         153 :     for(unsigned i=0; i<indices.size(); ++i) log.printf("%d ", pdb_atom_indices[i].serial() );
+     100           8 :     log.printf("\n");
+     101           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");
+     102           8 :     beta.resize( atom_args[0]->getShape()[1]/3 ); occupancy.resize( atom_args[0]->getShape()[1]/3 );
+     103          16 :     parseVector("OCCUPANCY", occupancy ); parseVector("BETA", beta );
+     104          16 :     parseVector("RESIDUE_INDICES",pdb_resid_indices);
+     105           8 :     if( pdb_resid_indices.size()==0 ) {
+     106           6 :       pdb_resid_indices.resize( pdb_atom_indices.size() );
+     107         125 :       for(unsigned i=0; i<pdb_resid_indices.size(); ++i) pdb_resid_indices[i] = pdb_atom_indices[i].serial();
+     108           2 :     } else if( pdb_resid_indices.size()!=pdb_atom_indices.size() ) error("mismatch between number of atom indices provided and number of residue indices provided");
+     109           8 :   }
+     110          15 :   log.printf("  printing configurations to PDB file to file named %s \n", file.c_str() );
+     111          30 :   parseVector("ARG_NAMES",argnames); if( argnames.size()==0 ) buildArgnames();
+     112          30 :   parse("FMT",fmt); fmt=" "+fmt;
+     113          15 :   if( getStride()==0 ) { setStride(0); log.printf("  printing pdb at end of calculation \n"); }
+     114             : 
+     115          30 :   parse("DESCRIPTION",description);
+     116          15 :   if( getPntrToArgument(0)->getRank()==0 || getPntrToArgument(0)->hasDerivatives() ) error("argument for printing of PDB should be vector or matrix");
+     117          15 :   unsigned nv=getPntrToArgument(0)->getShape()[0];
+     118          44 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     119          29 :     if( getPntrToArgument(i)->getRank()==0 || getPntrToArgument(i)->hasDerivatives() ) error("argument for printing of PDB should be vector or matrix");
+     120          29 :     if( getPntrToArgument(i)->getShape()[0]!=nv ) error("for printing to pdb files all arguments must have same number of values");
+     121             :   }
+     122          15 : }
+     123             : 
+     124        2143 : void DumpPDB::printAtom( OFile& opdbf, const unsigned& anum, const unsigned& rnum, const Vector& pos, const double& m, const double& q ) const {
+     125        2143 :   if( rnum>999 ) plumed_merror("atom number too large to be used as residue number");
+     126        2143 :   std::array<char,6> at; const char* msg = h36::hy36encode(5,anum,&at[0]);
+     127        2143 :   plumed_assert(msg==nullptr) << msg; at[5]=0; double lunits = plumed.getUnits().getLength()/0.1;
+     128        2143 :   opdbf.printf("ATOM  %s  X   RES  %4u    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     129        2143 :                &at[0], rnum, lunits*pos[0], lunits*pos[1], lunits*pos[2], m, q );
+     130        2143 : }
+     131             : 
+     132          23 : void DumpPDB::buildArgnames() {
+     133          23 :   unsigned nargs = getNumberOfArguments(); if( pdb_atom_indices.size()>0 ) nargs = nargs - 1;
+     134             :   if( nargs<0 ) return;
+     135             : 
+     136          23 :   argnames.resize(0); unsigned nvals = getPntrToArgument(0)->getShape()[0];
+     137             :   if( getPntrToArgument(0)->getRank()==2 ) nvals = getPntrToArgument(0)->getShape()[0];
+     138          48 :   for(unsigned i=0; i<nargs; ++i) {
+     139          25 :     if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all arguments should have same number of values");
+     140          25 :     if( getPntrToArgument(i)->getRank()==1 ) {
+     141          17 :       argnames.push_back( getPntrToArgument(i)->getName() );
+     142           8 :     } else if( getPntrToArgument(i)->getRank()==2 ) {
+     143           8 :       (getPntrToArgument(i)->getPntrToAction())->getMatrixColumnTitles( argnames );
+     144             :     }
+     145          25 :     getPntrToArgument(i)->buildDataStore();
+     146             :   }
+     147             : }
+     148             : 
+     149          19 : void DumpPDB::update() {
+     150          19 :   OFile opdbf; opdbf.link(*this);
+     151          19 :   opdbf.setBackupString("analysis");
+     152          19 :   opdbf.open( file );
+     153          19 :   std::size_t psign=fmt.find("%"); plumed_assert( psign!=std::string::npos );
+     154          38 :   std::string descr2="%s=%-" + fmt.substr(psign+1) + " ";
+     155             : 
+     156          19 :   unsigned totargs = 0; unsigned nvals = getPntrToArgument(0)->getShape()[0];
+     157          56 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     158          37 :     if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all arguments should have same number of values");
+     159          37 :     if( getPntrToArgument(i)->getRank()==1 ) totargs += 1;
+     160          18 :     else if( getPntrToArgument(i)->getRank()==2 ) totargs += getPntrToArgument(i)->getShape()[1];
+     161             :   }
+     162          19 :   if( totargs!=argnames.size() ) buildArgnames();
+     163             : 
+     164          19 :   if( description.length()>0 ) opdbf.printf("# %s AT STEP %lld TIME %f \n", description.c_str(), getStep(), getTime() );
+     165          19 :   unsigned nargs = getNumberOfArguments(), atomarg=0;
+     166          19 :   if( pdb_atom_indices.size()>0 ) {
+     167           9 :     if( nargs>1 ) { atomarg = nargs - 1; nargs = nargs-1; }
+     168             :     else nargs = 0;
+     169             :   }
+     170         448 :   for(unsigned i=0; i<nvals; ++i) {
+     171             :     unsigned n=0;
+     172        1269 :     for(unsigned j=0; j<nargs; j++) {
+     173         840 :       Value* thisarg=getPntrToArgument(j); opdbf.printf("REMARK ");
+     174         840 :       if( thisarg->getRank()==1 ) {
+     175         405 :         opdbf.printf( descr2.c_str(), argnames[n].c_str(), thisarg->get(i) ); n++;
+     176         435 :       } else if( thisarg->getRank()==2 ) {
+     177         435 :         unsigned ncols = thisarg->getShape()[1];
+     178        1297 :         for(unsigned k=0; k<ncols; ++k) { opdbf.printf( descr2.c_str(), argnames[n].c_str(), thisarg->get(i*ncols+k) ); n++; }
+     179             :       }
+     180         840 :       opdbf.printf("\n");
+     181             :     }
+     182         429 :     if( pdb_atom_indices.size()>0 ) {
+     183         138 :       unsigned npos = pdb_atom_indices.size(); Vector pos;
+     184        2281 :       for(unsigned k=0; k<npos; ++k) {
+     185        2143 :         pos[0]=getPntrToArgument(atomarg)->get(npos*(3*i+0) + k);
+     186        2143 :         pos[1]=getPntrToArgument(atomarg)->get(npos*(3*i+1) + k);
+     187        2143 :         pos[2]=getPntrToArgument(atomarg)->get(npos*(3*i+2) + k);
+     188        2143 :         printAtom( opdbf, pdb_atom_indices[k].serial(), pdb_resid_indices[k], pos, occupancy[k], beta[k] );
+     189             :       }
+     190             :     }
+     191         429 :     opdbf.printf("END\n");
+     192             :   }
+     193          19 :   opdbf.close();
+     194          19 : }
+     195             : 
+     196             : }
+     197             : }
+
+
+
+ + + + +
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 000000000..32ea12cc7 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d8d35fe2b --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..81e896040 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + LCOV - plumed test coverage - generic/DumpProjections.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..bc4e3a8a8 --- /dev/null +++ b/coverage/generic/DumpVector.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpVectorC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpVector5applyEv16
_ZN4PLMD7generic10DumpVector9calculateEv16
_ZN4PLMD7generic10DumpVectorC1ERKNS_13ActionOptionsE36
_ZN4PLMD7generic10DumpVectorD0Ev36
_ZN4PLMD7generic10DumpVectorD1Ev36
_ZN4PLMD7generic10DumpVector13buildArgnamesEv40
_ZN4PLMD7generic10DumpVector16registerKeywordsERNS_8KeywordsE44
_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 000000000..a69b7df62 --- /dev/null +++ b/coverage/generic/DumpVector.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpVector13buildArgnamesEv40
_ZN4PLMD7generic10DumpVector16registerKeywordsERNS_8KeywordsE44
_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 000000000..aafee378e --- /dev/null +++ b/coverage/generic/DumpVector.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + 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-10-17 16:45:00Functions: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          44 : void DumpVector::registerKeywords( Keywords& keys ) {
+      62          44 :   Action::registerKeywords( keys );
+      63          44 :   ActionPilot::registerKeywords( keys );
+      64          44 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      65          88 :   keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file.");
+      66          88 :   keys.add("compulsory","FILE","density","the file on which to write the vetors");
+      67          88 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      68          88 :   keys.addFlag("PRINT_ONE_FILE",false,"output vectors one after the other in a single file");
+      69          44 : }
+      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          97 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      91          57 :     if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all arguments should have same number of values");
+      92          57 :     if( getPntrToArgument(i)->getRank()==1 ) {
+      93          24 :       argnames.push_back( getPntrToArgument(i)->getName() );
+      94          33 :     } else if( getPntrToArgument(i)->getRank()==2 ) {
+      95          33 :       (getPntrToArgument(i)->getPntrToAction())->getMatrixColumnTitles( argnames );
+      96             :     }
+      97          57 :     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         116 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     109          70 :     if( getPntrToArgument(i)->getRank()==1 ) totargs += 1;
+     110          39 :     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       13163 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     121        7981 :       if( getPntrToArgument(j)->getRank()==1 ) {
+     122        4989 :         ofile.fmtField(fmt); ofile.printField(argnames[n],getPntrToArgument(j)->get(i) ); n++;
+     123        2992 :       } else if( getPntrToArgument(j)->getRank()==2 ) {
+     124        2992 :         unsigned ncols = getPntrToArgument(j)->getShape()[1];
+     125       13725 :         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 000000000..b8d85c888 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3a7ec95c3 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c9b31ae47 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html @@ -0,0 +1,447 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..277af81ff --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..aab56bfcd --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6bb3822bb --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage - generic/EndPlumed.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EndPlumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3ccdb1bac --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..61229c351 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fd6a387bb --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.gcov.html @@ -0,0 +1,460 @@ + + + + + + + LCOV - plumed test coverage - generic/FitToTemplate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - FitToTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410797.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..13d7d5ebb --- /dev/null +++ b/coverage/generic/Flush.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0d00fdc13 --- /dev/null +++ b/coverage/generic/Flush.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..df157512d --- /dev/null +++ b/coverage/generic/Flush.cpp.gcov.html @@ -0,0 +1,167 @@ + + + + + + + LCOV - plumed test coverage - generic/Flush.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Flush.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-10-17 16:45:00Functions: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/GatherReplicas.cpp.func-sort-c.html b/coverage/generic/GatherReplicas.cpp.func-sort-c.html new file mode 100644 index 000000000..a7b35ca80 --- /dev/null +++ b/coverage/generic/GatherReplicas.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - generic/GatherReplicas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - GatherReplicas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344085.0 %
Date:2024-10-17 16:45:00Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14GatherReplicas22getNumberOfDerivativesEv0
_ZN4PLMD7generic14GatherReplicasC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14GatherReplicasC1ERKNS_13ActionOptionsE13
_ZN4PLMD7generic14GatherReplicas16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD7generic14GatherReplicas5applyEv4224
_ZN4PLMD7generic14GatherReplicas9calculateEv4224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/GatherReplicas.cpp.func.html b/coverage/generic/GatherReplicas.cpp.func.html new file mode 100644 index 000000000..59ab97423 --- /dev/null +++ b/coverage/generic/GatherReplicas.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - generic/GatherReplicas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - GatherReplicas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344085.0 %
Date:2024-10-17 16:45:00Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14GatherReplicas16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD7generic14GatherReplicas22getNumberOfDerivativesEv0
_ZN4PLMD7generic14GatherReplicas5applyEv4224
_ZN4PLMD7generic14GatherReplicas9calculateEv4224
_ZN4PLMD7generic14GatherReplicasC1ERKNS_13ActionOptionsE13
_ZN4PLMD7generic14GatherReplicasC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/GatherReplicas.cpp.gcov.html b/coverage/generic/GatherReplicas.cpp.gcov.html new file mode 100644 index 000000000..c747d1968 --- /dev/null +++ b/coverage/generic/GatherReplicas.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + LCOV - plumed test coverage - generic/GatherReplicas.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - GatherReplicas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344085.0 %
Date:2024-10-17 16:45:00Functions: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 generic {
+      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          29 : void GatherReplicas::registerKeywords( Keywords& keys ) {
+      56          29 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys );
+      57          87 :   keys.remove("ARG"); keys.add("compulsory","ARG","the argument from the various replicas that you would like to gather");
+      58          58 :   keys.addOutputComponent("rep","default","the input arguments for each of the replicas");
+      59          29 : }
+      60             : 
+      61          13 : GatherReplicas::GatherReplicas( const ActionOptions& ao ):
+      62             :   Action(ao),
+      63             :   ActionWithValue(ao),
+      64          13 :   ActionWithArguments(ao)
+      65             : {
+      66          13 :   if( getNumberOfArguments()!=1 ) error("you can only gather one argument at a time with GatherReplicas");
+      67             : 
+      68          13 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      69          13 :   std::string min, max; nreplicas=multi_sim_comm.Get_size(); bool periodic=false;
+      70          13 :   if( getPntrToArgument(0)->isPeriodic() ) { periodic=true; getPntrToArgument(0)->getDomain( min, max ); }
+      71             : 
+      72          86 :   for(unsigned i=0; i<nreplicas; ++i) {
+      73          73 :     std::string num; Tools::convert( i+1, num);
+      74         146 :     if( getPntrToArgument(0)->hasDerivatives() ) addComponentWithDerivatives( "rep-" + num, shape );
+      75           0 :     else addComponent( "rep-" + num, shape );
+      76          73 :     if( periodic ) componentIsPeriodic( "rep-" + num, min, max );
+      77         146 :     else componentIsNotPeriodic( "rep-" + num );
+      78             :   }
+      79          13 : }
+      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/generic/Include.cpp.func-sort-c.html b/coverage/generic/Include.cpp.func-sort-c.html new file mode 100644 index 000000000..f40c3a07f --- /dev/null +++ b/coverage/generic/Include.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0ea33be94 --- /dev/null +++ b/coverage/generic/Include.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4f5afa0f9 --- /dev/null +++ b/coverage/generic/Include.cpp.gcov.html @@ -0,0 +1,255 @@ + + + + + + + LCOV - plumed test coverage - generic/Include.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Include.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101283.3 %
Date:2024-10-17 16:45:00Functions: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/MassChargeInput.cpp.func-sort-c.html b/coverage/generic/MassChargeInput.cpp.func-sort-c.html new file mode 100644 index 000000000..1f550d3da --- /dev/null +++ b/coverage/generic/MassChargeInput.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - generic/MassChargeInput.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - MassChargeInput.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404197.6 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15MassChargeInputC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15MassChargeInputC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic15MassChargeInput16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/MassChargeInput.cpp.func.html b/coverage/generic/MassChargeInput.cpp.func.html new file mode 100644 index 000000000..55835b1c9 --- /dev/null +++ b/coverage/generic/MassChargeInput.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - generic/MassChargeInput.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - MassChargeInput.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404197.6 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15MassChargeInput16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7generic15MassChargeInputC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic15MassChargeInputC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/MassChargeInput.cpp.gcov.html b/coverage/generic/MassChargeInput.cpp.gcov.html new file mode 100644 index 000000000..8e772daa5 --- /dev/null +++ b/coverage/generic/MassChargeInput.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + LCOV - plumed test coverage - generic/MassChargeInput.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - MassChargeInput.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404197.6 %
Date:2024-10-17 16:45:00Functions: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/ActionToPutData.h"
+      25             : #include "core/ActionAnyorder.h"
+      26             : #include "core/ActionSetup.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : #include "tools/IFile.h"
+      30             : #include "tools/PDB.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace generic {
+      34             : 
+      35             : //+PLUMEDOC COLVAR READMASSCHARGE
+      36             : /*
+      37             : Set the masses and charges from an input PDB file.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class MassChargeInput : public ActionShortcut {
+      45             : public:
+      46             :   static void registerKeywords(Keywords& keys);
+      47             :   explicit MassChargeInput(const ActionOptions&);
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(MassChargeInput,"READMASSCHARGE")
+      51             : 
+      52           4 : void MassChargeInput::registerKeywords(Keywords& keys) {
+      53           4 :   ActionShortcut::registerKeywords( keys );
+      54           8 :   keys.add("optional","FILE","input file that contains the masses and charges that should be used");
+      55           8 :   keys.add("compulsory","PDBFILE","a pdb file that contains the masses and charges of the atoms in the beta and occupancy columns");
+      56           8 :   keys.addOutputComponent("mass","default","the masses of the atoms in the system");
+      57           8 :   keys.addOutputComponent("charges","default","the masses of the atoms in the system");
+      58           4 :   keys.needsAction("CONSTANT");
+      59           4 : }
+      60             : 
+      61           2 : MassChargeInput::MassChargeInput(const ActionOptions& ao):
+      62             :   Action(ao),
+      63           2 :   ActionShortcut(ao)
+      64             : {
+      65           2 :   const ActionSet& actionset(plumed.getActionSet());
+      66          18 :   for(const auto & p : actionset) {
+      67             :     // check that all the preceding actions are ActionSetup
+      68          16 :     if( !dynamic_cast<ActionSetup*>(p.get()) && !dynamic_cast<ActionForInterface*>(p.get()) && !dynamic_cast<ActionAnyorder*>(p.get()) ) {
+      69           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.");
+      70          16 :     } else if( (p.get())->getName()=="READMASSCHARGE" ) error("should only be one READMASSCHARGE action in the input file");
+      71             :   }
+      72             :   // Check for correct number of atoms
+      73           2 :   unsigned natoms=0; std::vector<ActionToPutData*> inputs=plumed.getActionSet().select<ActionToPutData*>();
+      74          16 :   for(const auto & pp : inputs ) {
+      75          28 :     if( pp->getRole()=="x" ) natoms = (pp->copyOutput(0))->getShape()[0];
+      76             :   }
+      77           4 :   std::string input; parse("FILE",input); std::vector<double> masses( natoms ), charges( natoms );
+      78           2 :   if( input.length()>0 ) {
+      79           1 :     log.printf("   reading masses and charges from file named %s \n", input.c_str() );
+      80           1 :     IFile ifile; ifile.open( input ); int index; double mass; double charge;
+      81         218 :     while(ifile.scanField("index",index).scanField("mass",mass).scanField("charge",charge).scanField()) {
+      82         108 :       if( index>=natoms ) error("indices of atoms in input file are too large");
+      83         108 :       masses[index]=mass; charges[index]=charge;
+      84             :     }
+      85           1 :     ifile.close();
+      86           1 :   } else {
+      87           2 :     std::string pdbinpt; parse("PDBFILE",pdbinpt); PDB pdb;
+      88           1 :     log.printf("  reading masses and charges from pdb file named %s \n", pdbinpt.c_str() );
+      89           1 :     if( !pdb.read(pdbinpt, false, 1.0 ) ) error("error reading pdb file containing masses and charges");
+      90           1 :     if( natoms!=pdb.size() ) error("mismatch between number of atoms passed from MD code and number of atoms in PDB file");
+      91           1 :     masses = pdb.getOccupancy(); charges = pdb.getBeta();
+      92           1 :   }
+      93             : 
+      94             :   // Now get masses and charges
+      95             :   std::string nnn, qstr, mstr;
+      96           2 :   Tools::convert( masses[0], mstr );
+      97           2 :   Tools::convert( charges[0], qstr );
+      98         216 :   for(unsigned i=1; i<natoms; ++i) {
+      99         428 :     Tools::convert( masses[i], nnn ); mstr += "," + nnn;
+     100         428 :     Tools::convert( charges[i], nnn ); qstr += "," + nnn;
+     101             :   }
+     102             :   // And create constant actions to hold masses and charges
+     103           4 :   readInputLine( getShortcutLabel() + "_mass: CONSTANT VALUES=" + mstr );
+     104           4 :   readInputLine( getShortcutLabel() + "_charges: CONSTANT VALUES=" + qstr );
+     105           2 : }
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
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 000000000..9c53102a0 --- /dev/null +++ b/coverage/generic/Ones.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1212100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4OnesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4OnesC1ERKNS_13ActionOptionsE255
_ZN4PLMD7generic4Ones16registerKeywordsERNS_8KeywordsE451
+
+
+ + + +
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 000000000..491675851 --- /dev/null +++ b/coverage/generic/Ones.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1212100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Ones16registerKeywordsERNS_8KeywordsE451
_ZN4PLMD7generic4OnesC1ERKNS_13ActionOptionsE255
_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 000000000..4fad57ddc --- /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:1212100.0 %
Date:2024-10-17 16:45:00Functions: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         451 : void Ones::registerKeywords(Keywords& keys) {
+      46         451 :   ActionShortcut::registerKeywords( keys );
+      47         902 :   keys.add("compulsory","SIZE","the number of ones that you would like to create");
+      48         451 :   keys.setValueDescription("a vector of ones with the required number of elements");
+      49         451 :   keys.needsAction("CONSTANT");
+      50         451 : }
+      51             : 
+      52         255 : Ones::Ones(const ActionOptions& ao):
+      53             :   Action(ao),
+      54         255 :   ActionShortcut(ao)
+      55             : {
+      56         510 :   unsigned size; parse("SIZE",size); if( size<1 ) error("size should be greater than 0");
+      57      120919 :   std::string ones="1"; for(unsigned i=1; i<size; ++i) ones +=",1";
+      58         510 :   readInputLine( getShortcutLabel() + ": CONSTANT NOLOG VALUES=" + ones );
+      59         255 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
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 000000000..3f4abc078 --- /dev/null +++ b/coverage/generic/PDB2Constant.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:555698.2 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12PDB2ConstantC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12PDB2ConstantC1ERKNS_13ActionOptionsE115
_ZN4PLMD7generic12PDB2Constant16registerKeywordsERNS_8KeywordsE168
+
+
+ + + +
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 000000000..b1f0d4b56 --- /dev/null +++ b/coverage/generic/PDB2Constant.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:555698.2 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12PDB2Constant16registerKeywordsERNS_8KeywordsE168
_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 000000000..15c6908bb --- /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:555698.2 %
Date:2024-10-17 16:45:00Functions: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         168 : void PDB2Constant::registerKeywords(Keywords& keys) {
+      49         168 :   ActionShortcut::registerKeywords( keys );
+      50         336 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure");
+      51         336 :   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         336 :   keys.addFlag("NOARGS",false,"the arguments that are being read from the PDB file are not in the plumed input");
+      53         336 :   keys.add("optional","ARG","read this single argument from the input rather than the atomic structure");
+      54         168 :   keys.setValueDescription("a value that is constructed from the information in the PDB file");
+      55         168 :   keys.needsAction("CONSTANT");
+      56         168 : }
+      57             : 
+      58         115 : PDB2Constant::PDB2Constant(const ActionOptions& ao):
+      59             :   Action(ao),
+      60         115 :   ActionShortcut(ao)
+      61             : {
+      62         115 :   std::string input; parse("REFERENCE",input);
+      63         230 :   unsigned frame; parse("NUMBER",frame); bool noargs=false;
+      64         230 :   std::vector<std::string> argn; parseVector("ARG",argn); std::vector<Value*> theargs;
+      65         115 :   if( argn.size()>0 ) {
+      66          75 :     parseFlag("NOARGS",noargs);
+      67          75 :     if( !noargs ) ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, theargs );
+      68           2 :     else if( argn.size()>1 ) error("can only read one argument at a time from input pdb file");
+      69           2 :     else log.printf("  reading argument %s from file \n", argn[0].c_str() );
+      70             :   }
+      71         115 :   if( theargs.size()>1 ) error("can only read one argument at a time from input pdb file");
+      72             : 
+      73         115 :   FILE* fp=std::fopen(input.c_str(),"r"); bool do_read=true; std::vector<double> vals;
+      74         115 :   if(!fp) plumed_merror("could not open reference file " + input); unsigned natoms=0, nframes=0;
+      75             : 
+      76        2235 :   while ( do_read ) {
+      77        2235 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength());
+      78        2235 :     if( !do_read && nframes>0 ) break ;
+      79             : 
+      80        2120 :     if( natoms==0 ) natoms = mypdb.getPositions().size();
+      81         742 :     else if( mypdb.getPositions().size()!=natoms ) plumed_merror("mismatch between sizes of reference configurations");
+      82             : 
+      83        2120 :     if( nframes+1==frame || frame==0 ) {
+      84        1642 :       std::vector<double> align( mypdb.getOccupancy() );
+      85       10326 :       double asum=0; for(unsigned i=0; i<align.size(); ++i) asum += align[i];
+      86        1642 :       if( asum>epsilon ) {
+      87        9358 :         double iasum = 1 / asum; for(unsigned i=0; i<align.size(); ++i) align[i] *= iasum;
+      88         968 :       } else if( mypdb.size()>0 ) {
+      89           0 :         double iasum = 1 / mypdb.size(); for(unsigned i=0; i<align.size(); ++i) align[i] = iasum;
+      90             :       }
+      91       10326 :       Vector center; center.zero(); for(unsigned i=0; i<mypdb.getPositions().size(); ++i) center += align[i]*mypdb.getPositions()[i];
+      92             : 
+      93        1642 :       if( theargs.size()==0 && argn.size()==0 ) {
+      94        1688 :         for(unsigned j=0; j<3; ++j) {
+      95       17490 :           for(unsigned i=0; i<mypdb.getPositions().size(); ++i) vals.push_back( mypdb.getPositions()[i][j] - center[j] );
+      96             :         }
+      97        1220 :       } else if( noargs ) {
+      98          20 :         std::vector<double> argvals( 1 );
+      99          20 :         if( !mypdb.getArgumentValue(argn[0], argvals ) ) error("argument " + argn[0] + " was not set in pdb input");
+     100          20 :         vals.push_back( argvals[0] );
+     101             :       } else {
+     102        1200 :         std::vector<double> argvals( theargs[0]->getNumberOfValues() );
+     103        1200 :         if( !mypdb.getArgumentValue(theargs[0]->getName(), argvals ) ) error("argument " + theargs[0]->getName() + " was not set in pdb input");
+     104        2402 :         for(unsigned i=0; i<argvals.size(); ++i) vals.push_back( argvals[i] );
+     105             :       }
+     106             :     }
+     107        2120 :     nframes++;
+     108        2235 :   }
+     109         115 :   if( frame>0 ) nframes=1;
+     110         115 :   std::fclose(fp); std::string rnum; plumed_assert( vals.size()>0 );
+     111         115 :   Tools::convert( vals[0], rnum ); std::string valstr = " VALUES=" + rnum;
+     112       17446 :   for(unsigned i=1; i<vals.size(); ++i) { Tools::convert( vals[i], rnum ); valstr += "," + rnum; }
+     113         115 :   if( vals.size()>nframes ) {
+     114          41 :     std::string nc, nr; Tools::convert( nframes, nr ); Tools::convert( vals.size()/nframes, nc );
+     115          82 :     readInputLine( getShortcutLabel() + ": CONSTANT NROWS=" + nr + " NCOLS=" + nc + valstr );
+     116         148 :   } else readInputLine( getShortcutLabel() + ": CONSTANT" + valstr );
+     117         230 : }
+     118             : 
+     119             : }
+     120             : }
+
+
+
+ + + + +
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 000000000..2ae340acd --- /dev/null +++ b/coverage/generic/Plumed.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7d35c0368 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..81ad10e6c --- /dev/null +++ b/coverage/generic/Plumed.cpp.gcov.html @@ -0,0 +1,493 @@ + + + + + + + LCOV - plumed test coverage - generic/Plumed.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Plumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16617893.3 %
Date:2024-10-17 16:45:00Functions: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], {3,3});
+     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(), {masses.size(),3});
+     373         134 :   if(root) p.cmd("setForces",forces.data(),forces.size());
+     374         134 :   if(root) p.cmd("setVirial",&virial[0][0], {3,3});
+     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 000000000..6bf18cd32 --- /dev/null +++ b/coverage/generic/Print.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD2Ev0
_ZNK4PLMD7generic5Print12writeInGraphB5cxx11Ev8
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE1121
_ZN4PLMD7generic5PrintD0Ev1121
_ZN4PLMD7generic5PrintD1Ev1121
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE1123
_ZN4PLMD7generic5Print6updateEv218386
_ZN4PLMD7generic5Print5applyEv225558
_ZN4PLMD7generic5Print9calculateEv225680
_ZN4PLMD7generic5Print7prepareEv225824
+
+
+ + + +
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 000000000..65d05d46f --- /dev/null +++ b/coverage/generic/Print.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE1123
_ZN4PLMD7generic5Print5applyEv225558
_ZN4PLMD7generic5Print6updateEv218386
_ZN4PLMD7generic5Print7prepareEv225824
_ZN4PLMD7generic5Print9calculateEv225680
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE1121
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD0Ev1121
_ZN4PLMD7generic5PrintD1Ev1121
_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 000000000..f15ab735c --- /dev/null +++ b/coverage/generic/Print.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + 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-10-17 16:45:00Functions: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      225680 :   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      225558 :   void apply() override {}
+      92             :   void update() override;
+      93             :   ~Print();
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(Print,"PRINT")
+      97             : 
+      98        1123 : void Print::registerKeywords(Keywords& keys) {
+      99        1123 :   Action::registerKeywords(keys);
+     100        1123 :   ActionPilot::registerKeywords(keys);
+     101        1123 :   ActionWithArguments::registerKeywords(keys);
+     102        1123 :   keys.use("ARG");
+     103        2246 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     104        2246 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+     105        2246 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     106        2246 :   keys.add("hidden","_ROTATE","some funky thing implemented by GBussi");
+     107        1123 :   keys.use("RESTART");
+     108        1123 :   keys.use("UPDATE_FROM");
+     109        1123 :   keys.use("UPDATE_UNTIL");
+     110        1123 : }
+     111             : 
+     112        1121 : Print::Print(const ActionOptions&ao):
+     113             :   Action(ao),
+     114             :   ActionPilot(ao),
+     115             :   ActionWithArguments(ao),
+     116        1121 :   fmt("%f"),
+     117        2242 :   rotate(0)
+     118             : {
+     119        1121 :   ofile.link(*this);
+     120        2242 :   parse("FILE",file);
+     121        1121 :   if(file.length()>0) {
+     122        1121 :     ofile.open(file);
+     123        1121 :     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        1121 :   parse("FMT",fmt);
+     129        1121 :   fmt=" "+fmt;
+     130        1121 :   log.printf("  with format %s\n",fmt.c_str());
+     131        7394 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     132        6273 :     ofile.setupPrintValue( getPntrToArgument(i) );
+     133        6273 :     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        1121 :   parse("_ROTATE",rotate);
+     140        1121 :   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        1121 :   checkRead();
+     149        1121 : }
+     150             : 
+     151           8 : std::string Print::writeInGraph() const {
+     152          16 :   return getName() + "\n" + "FILE=" + file;
+     153             : }
+     154             : 
+     155      225824 : void Print::prepare() {
+     156             : /////////////////////////////////////////
+     157             : // these are crazy things just for debug:
+     158             : // they allow to change regularly the
+     159             : // printed argument
+     160      225824 :   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      225824 : }
+     171             : 
+     172      218386 : void Print::update() {
+     173      218386 :   ofile.fmtField(" %f");
+     174      218386 :   ofile.printField("time",getTime());
+     175      766428 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     176      548042 :     ofile.fmtField(fmt); getPntrToArgument(i)->print( ofile );
+     177             :   }
+     178      218386 :   ofile.printField();
+     179      218386 : }
+     180             : 
+     181        2242 : Print::~Print() {
+     182        2242 : }
+     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 000000000..37c1e2839 --- /dev/null +++ b/coverage/generic/PrintNDX.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions: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_8KeywordsE8
+
+
+ + + +
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 000000000..c34b282da --- /dev/null +++ b/coverage/generic/PrintNDX.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8PrintNDX12lockRequestsEv4
_ZN4PLMD7generic8PrintNDX14unlockRequestsEv4
_ZN4PLMD7generic8PrintNDX15actionHasForcesEv0
_ZN4PLMD7generic8PrintNDX16registerKeywordsERNS_8KeywordsE8
_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 000000000..4df96de5e --- /dev/null +++ b/coverage/generic/PrintNDX.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + 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-10-17 16:45:00Functions: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           8 : void PrintNDX::registerKeywords(Keywords& keys) {
+      65           8 :   Action::registerKeywords(keys);
+      66           8 :   ActionPilot::registerKeywords(keys);
+      67           8 :   ActionAtomistic::registerKeywords( keys );
+      68           8 :   ActionWithArguments::registerKeywords(keys);
+      69           8 :   keys.use("ARG");
+      70          16 :   keys.add("atoms","ATOMS","the list of atoms that have the corresponding arguments");
+      71          16 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+      72          16 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+      73          16 :   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          16 :   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           8 :   keys.use("RESTART");
+      76           8 :   keys.use("UPDATE_FROM");
+      77           8 :   keys.use("UPDATE_UNTIL");
+      78           8 : }
+      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 000000000..6084ab2ae --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..48bedd095 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7349b020b --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + LCOV - plumed test coverage - generic/RandomExchanges.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - RandomExchanges.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41330.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..e70cecdb0 --- /dev/null +++ b/coverage/generic/Read.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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:9810494.2 %
Date:2024-10-17 16:45:00Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic4Read29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE4
_ZN4PLMD7generic4Read17turnOnDerivativesEv26
_ZN4PLMD7generic4Read7getFileEv47
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev50
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE91
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE95
_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 000000000..fdaaaf32d --- /dev/null +++ b/coverage/generic/Read.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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:9810494.2 %
Date:2024-10-17 16:45:00Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE95
_ZN4PLMD7generic4Read17turnOnDerivativesEv26
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Read5applyEv921429
_ZN4PLMD7generic4Read6updateEv921429
_ZN4PLMD7generic4Read7getFileEv47
_ZN4PLMD7generic4Read7prepareEv921429
_ZN4PLMD7generic4Read9calculateEv921429
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE91
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev50
_ZNK4PLMD7generic4Read29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE4
+
+
+ + + +
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 000000000..47b89513d --- /dev/null +++ b/coverage/generic/Read.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + 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:9810494.2 %
Date:2024-10-17 16:45:00Functions: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/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             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      98             :   void prepare() override;
+      99      921429 :   void apply() override {}
+     100             :   void calculate() override;
+     101             :   void update() override;
+     102             :   std::string getFilename() const;
+     103             :   IFile* getFile();
+     104             :   unsigned getNumberOfDerivatives() override;
+     105             :   void turnOnDerivatives() override;
+     106             : };
+     107             : 
+     108             : PLUMED_REGISTER_ACTION(Read,"READ")
+     109             : 
+     110          95 : void Read::registerKeywords(Keywords& keys) {
+     111          95 :   Action::registerKeywords(keys);
+     112          95 :   ActionPilot::registerKeywords(keys);
+     113          95 :   ActionWithValue::registerKeywords(keys);
+     114         190 :   keys.add("compulsory","STRIDE","1","the frequency with which the file should be read.");
+     115         190 :   keys.add("compulsory","EVERY","1","only read every nth line of the colvar file. This should be used if the colvar was written more frequently than the trajectory.");
+     116         190 :   keys.add("compulsory","VALUES","the values to read from the file");
+     117         190 :   keys.add("compulsory","FILE","the name of the file from which to read these quantities");
+     118         190 :   keys.addFlag("IGNORE_TIME",false,"ignore the time in the colvar file. When this flag is not present read will be quite strict "
+     119             :                "about the start time of the simulation and the stride between frames");
+     120         190 :   keys.addFlag("IGNORE_FORCES",false,"use this flag if the forces added by any bias can be safely ignored.  As an example forces can be "
+     121             :                "safely ignored if you are doing post processing that does not involve outputting forces");
+     122          95 :   keys.remove("NUMERICAL_DERIVATIVES");
+     123          95 :   keys.use("UPDATE_FROM");
+     124          95 :   keys.use("UPDATE_UNTIL");
+     125          95 :   ActionWithValue::useCustomisableComponents(keys);
+     126          95 : }
+     127             : 
+     128          91 : Read::Read(const ActionOptions&ao):
+     129             :   Action(ao),
+     130             :   ActionPilot(ao),
+     131             :   ActionWithValue(ao),
+     132          91 :   ignore_time(false),
+     133          91 :   ignore_forces(false),
+     134          91 :   nlinesPerStep(1)
+     135             : {
+     136             :   // Read the file name from the input line
+     137          91 :   parse("FILE",filename);
+     138             :   // Check if time is to be ignored
+     139          91 :   parseFlag("IGNORE_TIME",ignore_time);
+     140             :   // Check if forces are to be ignored
+     141          91 :   parseFlag("IGNORE_FORCES",ignore_forces);
+     142             :   // Open the file if it is not already opened
+     143          91 :   cloned_file=false;
+     144          91 :   std::vector<Read*> other_reads=plumed.getActionSet().select<Read*>();
+     145         141 :   for(unsigned i=0; i<other_reads.size(); ++i) {
+     146          50 :     if( other_reads[i]->getFilename()==filename ) {
+     147          47 :       ifile=other_reads[i]->getFile();
+     148          47 :       cloned_file=true;
+     149             :     }
+     150             :   }
+     151          91 :   if( !cloned_file ) {
+     152          63 :     ifile_ptr=Tools::make_unique<IFile>();
+     153          63 :     ifile=ifile_ptr.get();
+     154          63 :     if( !ifile->FileExist(filename) ) error("could not find file named " + filename);
+     155          63 :     ifile->link(*this);
+     156          63 :     ifile->open(filename);
+     157          63 :     ifile->allowIgnoredFields();
+     158             :   }
+     159          91 :   parse("EVERY",nlinesPerStep);
+     160          91 :   if(nlinesPerStep>1) log.printf("  only reading every %uth line of file %s\n",nlinesPerStep,filename.c_str() );
+     161          89 :   else log.printf("  reading data from file %s\n",filename.c_str() );
+     162             :   // Find out what we are reading
+     163          91 :   std::vector<std::string> valread; parseVector("VALUES",valread);
+     164             : 
+     165          91 :   if(nlinesPerStep>1 && cloned_file) error("Opening a file multiple times and using EVERY is not allowed");
+     166             : 
+     167             :   std::size_t dot=valread[0].find_first_of('.');
+     168          91 :   if( valread[0].find(".")!=std::string::npos ) {
+     169          11 :     std::string label=valread[0].substr(0,dot);
+     170          11 :     std::string name=valread[0].substr(dot+1);
+     171          11 :     if( name=="*" ) {
+     172           2 :       if( valread.size()>1 ) error("all values must be from the same Action when using READ");
+     173             :       std::vector<std::string> fieldnames;
+     174           2 :       ifile->scanFieldList( fieldnames );
+     175          16 :       for(unsigned i=0; i<fieldnames.size(); ++i) {
+     176          14 :         if( fieldnames[i].substr(0,dot)==label ) {
+     177          12 :           readvals.emplace_back(Tools::make_unique<Value>(this, fieldnames[i], false) ); addComponentWithDerivatives( fieldnames[i].substr(dot+1) );
+     178          12 :           if( ifile->FieldExist("min_" + fieldnames[i]) ) componentIsPeriodic( fieldnames[i].substr(dot+1), "-pi","pi" );
+     179          12 :           else componentIsNotPeriodic( fieldnames[i].substr(dot+1) );
+     180             :         }
+     181             :       }
+     182           2 :     } else {
+     183           9 :       readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addComponentWithDerivatives( name );
+     184          18 :       if( ifile->FieldExist("min_" + valread[0]) ) componentIsPeriodic( valread[0].substr(dot+1), "-pi", "pi" );
+     185          18 :       else componentIsNotPeriodic( valread[0].substr(dot+1) );
+     186          12 :       for(unsigned i=1; i<valread.size(); ++i) {
+     187           6 :         if( valread[i].substr(0,dot)!=label ) error("all values must be from the same Action when using READ");;
+     188           6 :         readvals.emplace_back(Tools::make_unique<Value>(this, valread[i], false) ); addComponentWithDerivatives( valread[i].substr(dot+1) );
+     189           6 :         if( ifile->FieldExist("min_" + valread[i]) ) componentIsPeriodic( valread[i].substr(dot+1), "-pi", "pi" );
+     190           6 :         else componentIsNotPeriodic( valread[i].substr(dot+1) );
+     191             :       }
+     192             :     }
+     193             :   } else {
+     194          80 :     if( valread.size()!=1 ) error("all values must be from the same Action when using READ");
+     195          80 :     readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addValueWithDerivatives();
+     196         169 :     if( ifile->FieldExist("min_" + valread[0]) ) setPeriodic( "-pi", "pi" );
+     197          71 :     else setNotPeriodic();
+     198          80 :     log.printf("  reading value %s and storing as %s\n",valread[0].c_str(),getLabel().c_str() );
+     199             :   }
+     200          91 :   checkRead();
+     201         182 : }
+     202             : 
+     203           4 : std::string Read::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     204           4 :   plumed_assert( !exists( getLabel() ) );
+     205           7 :   for(unsigned i=0; i<readvals.size(); ++i) {
+     206          11 :     if( readvals[i]->getName().find( cname )!=std::string::npos ) return "values from the column labelled " + readvals[i]->getName() + " in the file named " + filename;
+     207             :   }
+     208           0 :   plumed_error(); return "";
+     209             : }
+     210             : 
+     211          50 : std::string Read::getFilename() const {
+     212          50 :   return filename;
+     213             : }
+     214             : 
+     215          47 : IFile* Read::getFile() {
+     216          47 :   return ifile;
+     217             : }
+     218             : 
+     219           0 : unsigned Read::getNumberOfDerivatives() {
+     220           0 :   return 0;
+     221             : }
+     222             : 
+     223          26 : void Read::turnOnDerivatives() {
+     224          26 :   if( !ignore_forces ) error("cannot calculate derivatives for colvars that are read in from a file.  If you are postprocessing and "
+     225             :                                "these forces do not matter add the flag IGNORE_FORCES to all READ actions");
+     226          26 : }
+     227             : 
+     228      921429 : void Read::prepare() {
+     229      921429 :   if( !cloned_file ) {
+     230             :     double du_time;
+     231      403414 :     if( !ifile->scanField("time",du_time) ) {
+     232           0 :       error("Reached end of file " + filename + " before end of trajectory");
+     233      201707 :     } else if( std::abs( du_time-getTime() )>getTimeStep() && !ignore_time ) {
+     234           0 :       std::string str_dutime,str_ptime; Tools::convert(du_time,str_dutime); Tools::convert(getTime(),str_ptime);
+     235           0 :       error("mismatched times in colvar files : colvar time=" + str_dutime + " plumed time=" + str_ptime + ". Add IGNORE_TIME to ignore error.");
+     236             :     }
+     237             :   }
+     238      921429 : }
+     239             : 
+     240      921429 : void Read::calculate() {
+     241             :   std::string smin, smax;
+     242     2019293 :   for(unsigned i=0; i<readvals.size(); ++i) {
+     243             : // .get  returns the raw pointer
+     244             : // ->get calls the Value::get() method
+     245     1097864 :     ifile->scanField( readvals[i].get() );
+     246     1097864 :     getPntrToComponent(i)->set( readvals[i]->get() );
+     247     1097864 :     if( readvals[i]->isPeriodic() ) {
+     248        3309 :       readvals[i]->getDomain( smin, smax );
+     249        3309 :       getPntrToComponent(i)->setDomain( smin, smax );
+     250             :     }
+     251             :   }
+     252      921429 : }
+     253             : 
+     254      921429 : void Read::update() {
+     255      921429 :   if( !cloned_file ) {
+     256      403965 :     for(unsigned i=0; i<nlinesPerStep; ++i) {
+     257      202258 :       ifile->scanField(); double du_time;
+     258      404516 :       if( !ifile->scanField("time",du_time) && !plumed.inputsAreActive() ) plumed.stop();
+     259             :     }
+     260             :   }
+     261      921429 : }
+     262             : 
+     263             : }
+     264             : }
+
+
+
+ + + + +
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 000000000..74f936dd2 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..66ef150b4 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..11e5c8479 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.gcov.html @@ -0,0 +1,283 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..bfb478bab --- /dev/null +++ b/coverage/generic/Time.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - generic/Time.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51533.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..fdd2b6bb1 --- /dev/null +++ b/coverage/generic/Time.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - generic/Time.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51533.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..36d086950 --- /dev/null +++ b/coverage/generic/Time.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage - generic/Time.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51533.3 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the time since the start of the trajectory");
+      60           2 : }
+      61             : 
+      62           0 : Time::Time(const ActionOptions&ao):
+      63           0 :   Action(ao),ActionWithValue(ao)
+      64             : {
+      65           0 :   addValueWithDerivatives(); setNotPeriodic();
+      66             :   // resize derivative by hand to a nonzero value
+      67           0 :   getPntrToValue()->resizeDerivatives(1);
+      68           0 : }
+      69             : 
+      70           0 : void Time::calculate() {
+      71           0 :   setValue           (getTime());
+      72           0 : }
+      73             : 
+      74             : }
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+      79             : 
+      80             : }
+
+
+
+ + + + +
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 000000000..f97e0b346 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..76c99973b --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3c2c25ccc --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + LCOV - plumed test coverage - generic/UpdateIf.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - UpdateIf.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4bac1e51b --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE58
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE80
_ZN4PLMD7generic14WholeMolecules15actionHasForcesEv841
_ZN4PLMD7generic14WholeMolecules5applyEv9888
_ZN4PLMD7generic14WholeMolecules9calculateEv9888
+
+
+ + + +
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 000000000..bdd0b0eb0 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14WholeMolecules15actionHasForcesEv841
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE80
_ZN4PLMD7generic14WholeMolecules5applyEv9888
_ZN4PLMD7generic14WholeMolecules9calculateEv9888
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE58
_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 000000000..9bc783e64 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + LCOV - plumed test coverage - generic/WholeMolecules.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WholeMolecules.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778788.5 %
Date:2024-10-17 16:45:00Functions: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        9888 :   void apply() override {}
+     116             : };
+     117             : 
+     118             : PLUMED_REGISTER_ACTION(WholeMolecules,"WHOLEMOLECULES")
+     119             : 
+     120          80 : void WholeMolecules::registerKeywords( Keywords& keys ) {
+     121          80 :   Action::registerKeywords( keys );
+     122          80 :   ActionPilot::registerKeywords( keys );
+     123          80 :   ActionAtomistic::registerKeywords( keys );
+     124         160 :   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         160 :   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         160 :   keys.reset_style("ENTITY","atoms");
+     127         160 :   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         160 :   keys.add("optional","MOLTYPE","the type of molecule that is under study.  This is used to define the backbone atoms");
+     132         160 :   keys.addFlag("EMST", false, "Define atoms sequence in entities using an Euclidean minimum spanning tree");
+     133         160 :   keys.addFlag("ADDREFERENCE", false, "Define the reference position of the first atom of each entity using a PDB file");
+     134          80 : }
+     135             : 
+     136          58 : WholeMolecules::WholeMolecules(const ActionOptions&ao):
+     137             :   Action(ao),
+     138             :   ActionPilot(ao),
+     139             :   ActionAtomistic(ao),
+     140          58 :   doemst(false), addref(false)
+     141             : {
+     142             :   std::vector<std::vector<AtomNumber> > groups;
+     143             :   std::vector<std::vector<AtomNumber> > roots;
+     144             :   // parse optional flags
+     145          58 :   parseFlag("EMST", doemst);
+     146         116 :   parseFlag("ADDREFERENCE", addref);
+     147             : 
+     148             :   // create groups from ENTITY
+     149         409 :   for(int i=0;; i++) {
+     150             :     std::vector<AtomNumber> group;
+     151         934 :     parseAtomList("ENTITY",i,group);
+     152         467 :     if( group.empty() ) break;
+     153         409 :     groups.push_back(group);
+     154         409 :   }
+     155             : 
+     156             :   // Read residues to align from MOLINFO
+     157         116 :   std::vector<std::string> resstrings; parseVector("RESIDUES",resstrings);
+     158          58 :   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          58 :   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          58 :   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         463 :     for(unsigned i=0; i<groups.size(); ++i) {
+     191             :       std::vector<AtomNumber> root;
+     192        9863 :       for(unsigned j=0; j<groups[i].size()-1; ++j) root.push_back(groups[i][j]);
+     193             :       // store root atoms
+     194         407 :       roots.push_back(root);
+     195             :     }
+     196             :   }
+     197             : 
+     198             :   // adding reference if needed
+     199          58 :   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         467 :   for(unsigned i=0; i<groups.size(); ++i) {
+     210         409 :     log.printf("  atoms in entity %d : ",i);
+     211       10517 :     for(unsigned j=0; j<groups[i].size(); ++j) log.printf("%d ",groups[i][j].serial() );
+     212         409 :     log.printf("\n");
+     213         409 :     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         467 :   for(unsigned i=0; i<groups.size(); ++i) {
+     219         409 :     merge.insert(merge.end(),groups[i].begin(),groups[i].end());
+     220             :   }
+     221             : 
+     222             :   // Convert groups to p_groups
+     223          58 :   p_groups.resize( groups.size() );
+     224         467 :   for(unsigned i=0; i<groups.size(); ++i) {
+     225         409 :     p_groups[i].resize( groups[i].size() );
+     226       10517 :     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          58 :   p_roots.resize( roots.size() );
+     230         467 :   for(unsigned i=0; i<roots.size(); ++i) {
+     231         409 :     p_roots[i].resize( roots[i].size() );
+     232       10108 :     for(unsigned j=0; j<roots[i].size(); ++j) p_roots[i][j] = getValueIndices( roots[i][j] );
+     233             :   }
+     234             : 
+     235             : 
+     236          58 :   checkRead();
+     237          58 :   Tools::removeDuplicates(merge);
+     238          58 :   requestAtoms(merge);
+     239             :   doNotRetrieve();
+     240             :   doNotForce();
+     241          58 : }
+     242             : 
+     243        9888 : void WholeMolecules::calculate() {
+     244       20480 :   for(unsigned i=0; i<p_groups.size(); ++i) {
+     245       10592 :     Vector first = getGlobalPosition(p_groups[i][0]);
+     246       10592 :     if(addref) {
+     247          12 :       first = refs[i]+pbcDistance(refs[i],first);
+     248          12 :       setGlobalPosition( p_groups[i][0], first );
+     249             :     }
+     250       10592 :     if(!doemst) {
+     251      391950 :       for(unsigned j=1; j<p_groups[i].size(); ++j) {
+     252      381362 :         Vector second=getGlobalPosition(p_groups[i][j]);
+     253      381362 :         first = first+pbcDistance(first,second);
+     254      381362 :         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        9888 : }
+     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 000000000..bff4ff04c --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7376ebd8a --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4a8af1440 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.gcov.html @@ -0,0 +1,333 @@ + + + + + + + LCOV - plumed test coverage - generic/WrapAround.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WrapAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:575996.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..1eb8c309a --- /dev/null +++ b/coverage/generic/index-sort-f.html @@ -0,0 +1,413 @@ + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1899199595.2 %
Date:2024-10-17 16:45:00Functions:18024473.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Time.cpp +
33.3%33.3%
+
33.3 %5 / 1516.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.2%92.2%
+
92.2 %59 / 6442.9 %3 / 7
EndPlumed.cpp +
80.0%80.0%
+
80.0 %8 / 1050.0 %2 / 4
PDB2Constant.cpp +
98.2%98.2%
+
98.2 %55 / 5666.7 %2 / 3
Average.cpp +
94.7%94.7%
+
94.7 %36 / 3866.7 %2 / 3
Ones.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
MassChargeInput.cpp +
97.6%97.6%
+
97.6 %40 / 4166.7 %2 / 3
GatherReplicas.cpp +
85.0%85.0%
+
85.0 %34 / 4066.7 %4 / 6
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
CreateMask.cpp +
94.4%94.4%
+
94.4 %51 / 5471.4 %5 / 7
DumpMassCharge.cpp +
96.8%96.8%
+
96.8 %61 / 6372.7 %8 / 11
DumpAtoms.cpp +
97.3%97.3%
+
97.3 %142 / 14676.9 %10 / 13
DumpDerivatives.cpp +
100.0%
+
100.0 %48 / 4877.8 %7 / 9
Collect.cpp +
96.4%96.4%
+
96.4 %54 / 5677.8 %7 / 9
EffectiveEnergyDrift.cpp +
97.4%97.4%
+
97.4 %147 / 15177.8 %7 / 9
DumpForces.cpp +
100.0%
+
100.0 %37 / 3777.8 %7 / 9
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
Debug.cpp +
100.0%
+
100.0 %56 / 5680.0 %4 / 5
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
DumpProjections.cpp +
100.0%
+
100.0 %38 / 3880.0 %8 / 10
UpdateIf.cpp +
100.0%
+
100.0 %42 / 4280.0 %8 / 10
Print.cpp +
96.7%96.7%
+
96.7 %58 / 6081.8 %9 / 11
WholeMolecules.cpp +
88.5%88.5%
+
88.5 %77 / 8783.3 %5 / 6
Read.cpp +
94.2%94.2%
+
94.2 %98 / 10483.3 %10 / 12
Plumed.cpp +
93.3%93.3%
+
93.3 %166 / 17883.3 %10 / 12
DumpPDB.cpp +
100.0%
+
100.0 %104 / 10487.5 %7 / 8
DumpVector.cpp +
100.0%
+
100.0 %54 / 5488.9 %8 / 9
Accumulate.cpp +
95.1%95.1%
+
95.1 %39 / 4188.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 000000000..fa06434d5 --- /dev/null +++ b/coverage/generic/index-sort-l.html @@ -0,0 +1,413 @@ + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1899199595.2 %
Date:2024-10-17 16:45:00Functions:18024473.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
RandomExchanges.cpp +
30.8%30.8%
+
30.8 %4 / 1325.0 %1 / 4
Time.cpp +
33.3%33.3%
+
33.3 %5 / 1516.7 %1 / 6
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
GatherReplicas.cpp +
85.0%85.0%
+
85.0 %34 / 4066.7 %4 / 6
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.2%92.2%
+
92.2 %59 / 6442.9 %3 / 7
Plumed.cpp +
93.3%93.3%
+
93.3 %166 / 17883.3 %10 / 12
Read.cpp +
94.2%94.2%
+
94.2 %98 / 10483.3 %10 / 12
CreateMask.cpp +
94.4%94.4%
+
94.4 %51 / 5471.4 %5 / 7
Average.cpp +
94.7%94.7%
+
94.7 %36 / 3866.7 %2 / 3
Accumulate.cpp +
95.1%95.1%
+
95.1 %39 / 4188.9 %8 / 9
Collect.cpp +
96.4%96.4%
+
96.4 %54 / 5677.8 %7 / 9
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.8%96.8%
+
96.8 %61 / 6372.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
MassChargeInput.cpp +
97.6%97.6%
+
97.6 %40 / 4166.7 %2 / 3
PDB2Constant.cpp +
98.2%98.2%
+
98.2 %55 / 5666.7 %2 / 3
Ones.cpp +
100.0%
+
100.0 %12 / 1266.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
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
DumpPDB.cpp +
100.0%
+
100.0 %104 / 10487.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 000000000..282aa1b64 --- /dev/null +++ b/coverage/generic/index.html @@ -0,0 +1,413 @@ + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1899199595.2 %
Date:2024-10-17 16:45:00Functions:18024473.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Accumulate.cpp +
95.1%95.1%
+
95.1 %39 / 4188.9 %8 / 9
Average.cpp +
94.7%94.7%
+
94.7 %36 / 3866.7 %2 / 3
Collect.cpp +
96.4%96.4%
+
96.4 %54 / 5677.8 %7 / 9
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
Constant.cpp +
92.2%92.2%
+
92.2 %59 / 6442.9 %3 / 7
CreateMask.cpp +
94.4%94.4%
+
94.4 %51 / 5471.4 %5 / 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.8%96.8%
+
96.8 %61 / 6372.7 %8 / 11
DumpPDB.cpp +
100.0%
+
100.0 %104 / 10487.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
GatherReplicas.cpp +
85.0%85.0%
+
85.0 %34 / 4066.7 %4 / 6
Include.cpp +
83.3%83.3%
+
83.3 %10 / 1240.0 %2 / 5
MassChargeInput.cpp +
97.6%97.6%
+
97.6 %40 / 4166.7 %2 / 3
Ones.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
PDB2Constant.cpp +
98.2%98.2%
+
98.2 %55 / 5666.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.2%94.2%
+
94.2 %98 / 10483.3 %10 / 12
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
Time.cpp +
33.3%33.3%
+
33.3 %5 / 1516.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 000000000..7b3346079 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE772
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE1525
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv10835
_ZN4PLMD9gridtools14ActionWithGrid22getInputActionWithGridEPNS_6ActionE16527
+
+
+ + + +
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 000000000..5931dbc12 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE1525
_ZN4PLMD9gridtools14ActionWithGrid22getInputActionWithGridEPNS_6ActionE16527
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv10835
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE772
+
+
+ + + +
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 000000000..073992533 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.gcov.html @@ -0,0 +1,131 @@ + + + + + + + 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-10-17 16:45:00Functions: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       16527 : ActionWithGrid* ActionWithGrid::getInputActionWithGrid( Action* action ) {
+      28       16527 :   ActionWithGrid* ag = dynamic_cast<ActionWithGrid*>( action );
+      29       17385 :   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       16527 :   plumed_assert( ag ); return ag;
+      34             : }
+      35             : 
+      36        1525 : void ActionWithGrid::registerKeywords( Keywords& keys ) {
+      37        1525 :   ActionWithVector::registerKeywords( keys );
+      38        1525 : }
+      39             : 
+      40         772 : ActionWithGrid::ActionWithGrid(const ActionOptions&ao):
+      41             :   Action(ao),
+      42             :   ActionWithVector(ao),
+      43         772 :   firststep(true)
+      44             : {
+      45         772 : }
+      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 000000000..46d5f505d --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..02a824604 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..07665801f --- /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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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          17 :   keys.setValueDescription("the free energy surface");
+      76          34 :   keys.needsAction("FIND_GRID_MINIMUM"); keys.needsAction("CUSTOM");
+      77          17 : }
+      78             : 
+      79          15 : ConvertToFES::ConvertToFES(const ActionOptions&ao):
+      80             :   Action(ao),
+      81          15 :   ActionShortcut(ao)
+      82             : {
+      83          15 :   bool minzero=false; parseFlag("MINTOZERO",minzero);
+      84          15 :   double simtemp=getkBT(); if( simtemp==0 ) error("TEMP not set - use keyword TEMP");
+      85             : 
+      86          30 :   std::vector<std::string> argv; parseVector("GRID",argv);
+      87          30 :   if( argv.size()==0 ) parseVector("ARG",argv);
+      88          15 :   if( argv.size()!=1 ) error("should only have one argument");
+      89             : 
+      90          15 :   std::string str_temp; Tools::convert( simtemp, str_temp ); std::string flab=""; if( minzero ) flab="_unz";
+      91          30 :   readInputLine( getShortcutLabel() + flab + ": CUSTOM ARG=" + argv[0] + " FUNC=-" + str_temp + "*log(x) PERIODIC=NO");
+      92          15 :   if( minzero ) {
+      93           4 :     readInputLine( getShortcutLabel() + "_min: FIND_GRID_MINIMUM ARG=" + getShortcutLabel() + "_unz" );
+      94           4 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_unz," + getShortcutLabel() + "_min.optval FUNC=x-y PERIODIC=NO");
+      95             :   }
+      96          15 : }
+      97             : 
+      98             : }
+      99             : }
+
+
+
+ + + + +
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 000000000..ed887e0f1 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..80d90016d --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..df86a5491 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.gcov.html @@ -0,0 +1,425 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f8ee817df --- /dev/null +++ b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a9e86e946 --- /dev/null +++ b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1dbc40f6b --- /dev/null +++ b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f944dd20c --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:9010288.2 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20EvaluateGridFunction4readEPNS_19ActionWithArgumentsE88
_ZN4PLMD9gridtools20EvaluateGridFunction5setupEPNS_15ActionWithValueE170
_ZN4PLMD9gridtools20EvaluateGridFunction16registerKeywordsERNS_8KeywordsE184
_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 000000000..88e9dcb19 --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:9010288.2 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20EvaluateGridFunction16registerKeywordsERNS_8KeywordsE184
_ZN4PLMD9gridtools20EvaluateGridFunction4readEPNS_19ActionWithArgumentsE88
_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 000000000..c739f02d0 --- /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:9010288.2 %
Date:2024-10-17 16:45:00Functions: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         184 : void EvaluateGridFunction::registerKeywords( Keywords& keys ) {
+      31         368 :   keys.add("compulsory","INTERPOLATION_TYPE","spline","the method to use for interpolation.  Can be spline, linear, ceiling or floor.");
+      32         368 :   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         184 :   keys.setValueDescription("interpolation of the input grid to get the value of the function at the input arguments");
+      34         184 : }
+      35             : 
+      36         242 : std::vector<bool> EvaluateGridFunction::getPbc() const {
+      37         242 :   std::vector<bool> ipbc( gridobject.getDimension() );
+      38         484 :   for(unsigned i=0; i<ipbc.size(); ++i) ipbc[i] = gridobject.isPeriodic(i);
+      39         242 :   return ipbc;
+      40             : }
+      41             : 
+      42          88 : void EvaluateGridFunction::read( ActionWithArguments* action ) {
+      43          88 :   if( action->getPntrToArgument(0)->getRank()==0 || !action->getPntrToArgument(0)->hasDerivatives() ) action->error("should have one grid as input to this action");
+      44             :   // Get the input grid
+      45          88 :   ActionWithGrid* ag = ActionWithGrid::getInputActionWithGrid( (action->getPntrToArgument(0))->getPntrToAction() );
+      46         176 :   if( ag->getGridCoordinatesObject().getGridType()!="flat" ) action->error("cannot interpolate on fibonacci sphere");
+      47          88 :   std::vector<bool> ipbc( ag->getGridCoordinatesObject().getDimension() );
+      48         184 :   for(unsigned i=0; i<ipbc.size(); ++i) ipbc[i] = ag->getGridCoordinatesObject().isPeriodic(i);
+      49         176 :   gridobject.setup( "flat", ipbc, 0, 0.0 );
+      50             :   // Now use this information to create a gridobject
+      51             :   std::vector<std::string> argn;
+      52          88 :   parseFlag(action,"ZERO_OUTSIDE_GRID_RANGE",set_zero_outside_range);
+      53          88 :   if( set_zero_outside_range ) action->log.printf("  function is zero outside grid range \n");
+      54             :   // Get the type of interpolation that we are doing
+      55         176 :   std::string itype; parse(action,"INTERPOLATION_TYPE",itype);
+      56          88 :   if( itype=="spline" ) {
+      57           8 :     interpolation_type=spline;
+      58           8 :     spline_interpolator=Tools::make_unique<Interpolator>( action->getPntrToArgument(0), gridobject );
+      59          80 :   } else if( itype=="linear" ) {
+      60          65 :     interpolation_type=linear;
+      61          15 :   } else if( itype=="floor" ) {
+      62           0 :     interpolation_type=floor;
+      63          15 :   } else if( itype=="ceiling" ) {
+      64          15 :     interpolation_type=ceiling;
+      65           0 :   } else action->error("type " + itype + " of interpolation is not defined");
+      66          88 :   action->log.printf("  generating off grid points using %s interpolation \n", itype.c_str() );
+      67         176 : }
+      68             : 
+      69         170 : void EvaluateGridFunction::setup( ActionWithValue* action ) {
+      70         170 :   FunctionTemplateBase::setup( action );
+      71         170 :   ActionWithArguments* aarg = dynamic_cast<ActionWithArguments*>( action );
+      72         170 :   ActionWithGrid* ag = ActionWithGrid::getInputActionWithGrid( (aarg->getPntrToArgument(0))->getPntrToAction() );
+      73         170 :   const GridCoordinatesObject & ingrid = ag->getGridCoordinatesObject(); std::vector<double> sp( ingrid.getGridSpacing() );
+      74         170 :   gridobject.setBounds( ingrid.getMin(), ingrid.getMax(), ingrid.getNbin(false), sp );
+      75         170 : }
+      76             : 
+      77       39145 : void EvaluateGridFunction::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+      78       39145 :   if( set_zero_outside_range && !gridobject.inbounds( args ) ) { vals[0]=0.0; return; }
+      79             :   unsigned dimension = gridobject.getDimension(); plumed_dbg_assert( args.size()==dimension && vals.size()==1 );
+      80       39145 :   if( interpolation_type==spline ) {
+      81       23729 :     std::vector<double> der( dimension );
+      82       23729 :     vals[0] =  spline_interpolator->splineInterpolation( args, der );
+      83       74416 :     for(unsigned j=0; j<dimension; ++j) derivatives(0,j) = der[j];
+      84       15416 :   } else if( interpolation_type==linear ) {
+      85        6600 :     Value* values=action->getPntrToArgument(0); std::vector<double> xfloor(dimension);
+      86        6600 :     std::vector<unsigned> indices(dimension), nindices(dimension), ind(dimension);
+      87        6600 :     gridobject.getIndices( args, indices ); unsigned nn=gridobject.getIndex(args);
+      88        6600 :     gridobject.getGridPointCoordinates( nn, nindices, xfloor );
+      89        6600 :     double y1 = values->get(nn); vals[0] = y1;
+      90       13200 :     for(unsigned i=0; i<args.size(); ++i) {
+      91        6600 :       int x0=1; if(nindices[i]==indices[i]) x0=0;
+      92        6600 :       double ddx=gridobject.getGridSpacing()[i];
+      93        6600 :       double X = fabs((args[i]-xfloor[i])/ddx-(double)x0);
+      94       13200 :       for(unsigned j=0; j<args.size(); ++j) ind[j] = indices[j];
+      95        6600 :       if( gridobject.isPeriodic(i) && (ind[i]+1)==gridobject.getNbin(false)[i] ) ind[i]=0;
+      96        6600 :       else ind[i] = ind[i] + 1;
+      97        6600 :       vals[0] += ( values->get( gridobject.getIndex(ind) ) - y1 )*X;
+      98        6600 :       derivatives(0,i) = ( values->get( gridobject.getIndex(ind) ) - y1 ) / ddx;
+      99             :     }
+     100        8816 :   } else if( interpolation_type==floor ) {
+     101           0 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     102           0 :     gridobject.getIndices( args, indices ); unsigned nn = gridobject.getIndex(indices);
+     103             :     plumed_dbg_assert( nn<values->getNumberOfValues() );
+     104           0 :     vals[0] = values->get( nn );
+     105           0 :     for(unsigned j=0; j<dimension; ++j) derivatives(0,j) = values->getGridDerivative( nn, j );
+     106        8816 :   } else if( interpolation_type==ceiling ) {
+     107        8816 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     108        8816 :     gridobject.getIndices( args, indices );
+     109       17632 :     for(unsigned i=0; i<indices.size(); ++i) {
+     110       17632 :       if( gridobject.isPeriodic(i) && (indices[i]+1)==gridobject.getNbin(false)[i] ) indices[i]=0;
+     111        6612 :       else indices[i] = indices[i] + 1;
+     112             :     }
+     113        8816 :     unsigned nn = gridobject.getIndex(indices); vals[0] = values->get( nn );
+     114       17632 :     for(unsigned j=0; j<dimension; ++j) derivatives(0,j) = values->getGridDerivative( nn, j );
+     115           0 :   } else plumed_error();
+     116             : }
+     117             : 
+     118        1956 : void EvaluateGridFunction::applyForce( const ActionWithArguments* action, const std::vector<double>& args, const double& force, std::vector<double>& forcesToApply ) const {
+     119             :   unsigned dimension = gridobject.getDimension();
+     120        1956 :   if( interpolation_type==spline ) {
+     121           0 :     action->error("can't apply forces on values interpolated using splines");
+     122        1956 :   } else if( interpolation_type==linear ) {
+     123         100 :     Value* values=action->getPntrToArgument(0); std::vector<double> xfloor(dimension);
+     124         100 :     std::vector<unsigned> indices(dimension), nindices(dimension), ind(dimension);
+     125         100 :     gridobject.getIndices( args, indices ); unsigned nn=gridobject.getIndex(args);
+     126         100 :     gridobject.getGridPointCoordinates( nn, nindices, xfloor );
+     127         200 :     for(unsigned i=0; i<args.size(); ++i) {
+     128         100 :       int x0=1; if(nindices[i]==indices[i]) x0=0;
+     129         100 :       double ddx=gridobject.getGridSpacing()[i];
+     130         100 :       double X = fabs((args[i]-xfloor[i])/ddx-(double)x0);
+     131         200 :       for(unsigned j=0; j<args.size(); ++j) ind[j] = indices[j];
+     132         100 :       if( gridobject.isPeriodic(i) && (ind[i]+1)==gridobject.getNbin(false)[i] ) ind[i]=0;
+     133         100 :       else ind[i] = ind[i] + 1;
+     134         100 :       forcesToApply[nn] += force*(1-X); forcesToApply[gridobject.getIndex(ind)] += X*force;
+     135             :     }
+     136        1856 :   } else if( interpolation_type==floor ) {
+     137           0 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     138           0 :     gridobject.getIndices( args, indices ); unsigned nn = gridobject.getIndex(indices);
+     139           0 :     forcesToApply[nn] += force;
+     140        1856 :   } else if( interpolation_type==ceiling ) {
+     141        1856 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     142        1856 :     gridobject.getIndices( args, indices );
+     143        3712 :     for(unsigned i=0; i<indices.size(); ++i) {
+     144        3712 :       if( gridobject.isPeriodic(i) && (indices[i]+1)==gridobject.getNbin(false)[i] ) indices[i]=0;
+     145        1392 :       else indices[i] = indices[i] + 1;
+     146             :     }
+     147        1856 :     unsigned nn = gridobject.getIndex(indices); forcesToApply[nn] += force;
+     148           0 :   } else plumed_error();
+     149        1956 : }
+     150             : 
+     151             : }
+     152             : }
+
+
+
+ + + + +
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 000000000..9550ec69f --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1897b800d --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..81b4a3bab --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.h.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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-10-17 16:45:00Functions: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         272 : 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 000000000..30ec37abe --- /dev/null +++ b/coverage/gridtools/FindGridOptimum.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15FindGridOptimum16setupOnFirstStepEb0
_ZN4PLMD9gridtools15FindGridOptimum22getNumberOfDerivativesEv0
_ZN4PLMD9gridtools15FindGridOptimumC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15FindGridOptimum11performTaskERKjRNS_10MultiValueE0
_ZN4PLMD9gridtools15FindGridOptimum9calculateEv2
_ZN4PLMD9gridtools15FindGridOptimumC1ERKNS_13ActionOptionsE2
_ZNK4PLMD9gridtools15FindGridOptimum22getGridCoordinateNamesB5cxx11Ev2
_ZN4PLMD9gridtools15FindGridOptimum16registerKeywordsERNS_8KeywordsE8
_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 000000000..ceea15a4e --- /dev/null +++ b/coverage/gridtools/FindGridOptimum.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15FindGridOptimum16registerKeywordsERNS_8KeywordsE8
_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 000000000..1060d8881 --- /dev/null +++ b/coverage/gridtools/FindGridOptimum.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + 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-10-17 16:45:00Functions: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           8 : void FindGridOptimum::registerKeywords( Keywords& keys ) {
+      70           8 :   ActionWithGrid::registerKeywords( keys ); keys.use("ARG");
+      71          16 :   keys.addFlag("NOINTERPOL",false,"do not interpolate the function when finding the optimum");
+      72          16 :   keys.add("compulsory","CGTOL","1E-4","the tolerance for the conjugate gradient optimization");
+      73          16 :   keys.addOutputComponent("optval","default","the value of the function at the optimum");
+      74          16 :   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           8 : }
+      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 000000000..54a217eaa --- /dev/null +++ b/coverage/gridtools/FunctionOfGrid.h.func-sort-c.html @@ -0,0 +1,152 @@ + + + + + + + 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:10110398.1 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE176
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE16setupOnFirstStepEb180
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE22getGridCoordinateNamesB5cxx11Ev198
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEEC1ERKNS_13ActionOptionsE433
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE24getGridCoordinatesObjectEv512
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE22getNumberOfDerivativesEv514
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16setupOnFirstStepEb865
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16registerKeywordsERNS_8KeywordsE871
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE22getNumberOfDerivativesEv1300
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE5applyEv2100
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE5applyEv3967
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE24getGridCoordinatesObjectEv14948
_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 000000000..f72ebb51f --- /dev/null +++ b/coverage/gridtools/FunctionOfGrid.h.func.html @@ -0,0 +1,152 @@ + + + + + + + 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:10110398.1 %
Date:2024-10-17 16:45:00Functions:162080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE16registerKeywordsERNS_8KeywordsE176
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE16setupOnFirstStepEb180
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE22getNumberOfDerivativesEv514
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE5applyEv2100
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEEC1ERKNS_13ActionOptionsE90
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16registerKeywordsERNS_8KeywordsE871
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16setupOnFirstStepEb865
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE22getNumberOfDerivativesEv1300
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE5applyEv3967
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEEC1ERKNS_13ActionOptionsE433
_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_8function6CustomEE22getGridCoordinateNamesB5cxx11Ev198
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE24getGridCoordinatesObjectEv14948
+
+
+ + + +
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 000000000..121c934c3 --- /dev/null +++ b/coverage/gridtools/FunctionOfGrid.h.gcov.html @@ -0,0 +1,309 @@ + + + + + + + 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:10110398.1 %
Date:2024-10-17 16:45:00Functions: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        1047 : void FunctionOfGrid<T>::registerKeywords(Keywords& keys ) {
+      61        2094 :   ActionWithGrid::registerKeywords(keys); keys.use("ARG"); std::string name = keys.getDisplayName();
+      62        1047 :   std::size_t und=name.find("_GRID"); keys.setDisplayName( name.substr(0,und) );
+      63        2094 :   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");
+      64        1047 :   T tfunc; tfunc.registerKeywords( keys ); if( typeid(tfunc)==typeid(function::Custom()) ) keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      65        2094 :   if( keys.getDisplayName()=="INTEGRATE") {
+      66         294 :     keys.setValueDescription("the numerical integral of the input function over its whole domain");
+      67        1800 :   } else if( keys.outputComponentExists(".#!value") ) {
+      68        1800 :     keys.setValueDescription("the grid obtained by doing an element-wise application of " + keys.getOutputComponentDescription(".#!value") + " to the input grid");
+      69             :   }
+      70        1918 : }
+      71             : 
+      72             : template <class T>
+      73         523 : FunctionOfGrid<T>::FunctionOfGrid(const ActionOptions&ao):
+      74             :   Action(ao),
+      75         523 :   ActionWithGrid(ao)
+      76             : {
+      77         523 :   if( getNumberOfArguments()==0 ) error("found no arguments");
+      78             :   // This will require a fix
+      79         523 :   if( getPntrToArgument(0)->getRank()==0 || !getPntrToArgument(0)->hasDerivatives() ) error("first input to this action must be a grid");
+      80             :   // Get the shape of the input grid
+      81         523 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      82         937 :   for(unsigned i=1; i<getNumberOfArguments(); ++i ) {
+      83         414 :     if( getPntrToArgument(i)->getRank()==0 ) continue;
+      84         292 :     std::vector<unsigned> s( getPntrToArgument(i)->getShape() );
+      85         292 :     if( s.size()!=shape.size() ) error("mismatch between dimensionalities of input grids");
+      86             :   }
+      87             :   // Read the input and do some checks
+      88         523 :   myfunc.read( this );
+      89             :   // Check we are not calculating an integral
+      90         523 :   if( myfunc.zeroRank() ) { shape.resize(0); }
+      91             :   // Check that derivatives are available
+      92          90 :   if( !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+      93             :   // Get the names of the components
+      94         523 :   std::vector<std::string> components( keywords.getOutputComponents() );
+      95             :   // Create the values to hold the output
+      96        1046 :   if( components.size()!=1 || components[0]!=".#!value" ) error("functions of grid should only output one grid");
+      97         523 :   addValueWithDerivatives( shape );
+      98             :   // Set the periodicities of the output components
+      99         523 :   myfunc.setPeriodicityForOutputs( this );
+     100             :   // Check if we can turn off the derivatives when they are zero
+     101         433 :   if( myfunc.getDerivativeZeroIfValueIsZero() )  {
+     102         492 :     for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+     103             :   }
+     104         523 :   setupOnFirstStep( false );
+     105        1046 : }
+     106             : 
+     107             : template <class T>
+     108        1045 : void FunctionOfGrid<T>::setupOnFirstStep( const bool incalc ) {
+     109             :   double volume = 1.0;
+     110        1045 :   const GridCoordinatesObject& mygrid = getGridCoordinatesObject();
+     111        1045 :   unsigned npoints = getPntrToArgument(0)->getNumberOfValues();
+     112        2090 :   if( mygrid.getGridType()=="flat" ) {
+     113         999 :     std::vector<unsigned> shape( getGridCoordinatesObject().getNbin(true) );
+     114        1794 :     for(unsigned i=1; i<getNumberOfArguments(); ++i ) {
+     115         795 :       if( getPntrToArgument(i)->getRank()==0 ) continue;
+     116         573 :       std::vector<unsigned> s( getPntrToArgument(i)->getShape() );
+     117        1160 :       for(unsigned j=0; j<shape.size(); ++j) {
+     118         587 :         if( shape[j]!=s[j] ) error("mismatch between sizes of input grids");
+     119             :       }
+     120             :     }
+     121        1998 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     122         999 :       if( getPntrToComponent(i)->getRank()>0 ) getPntrToComponent(i)->setShape(shape);
+     123             :     }
+     124         999 :     std::vector<double> vv( getGridCoordinatesObject().getGridSpacing() );
+     125        1081 :     volume=vv[0]; for(unsigned i=1; i<vv.size(); ++i) volume *=vv[i];
+     126          14 :   } else volume=4*pi / static_cast<double>( npoints );
+     127             :   // This resizes the scalars
+     128        2090 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     129        1045 :     if( getPntrToComponent(i)->getRank()==0 ) getPntrToComponent(i)->resizeDerivatives( npoints );
+     130             :   }
+     131        1045 :   if( getName()=="SUM_GRID" ) volume = 1.0;
+     132             :   // This sets the prefactor to the volume which converts integrals to sums
+     133        1045 :   myfunc.setup( this ); myfunc.setPrefactor( this, volume );
+     134        1045 : }
+     135             : 
+     136             : template <class T>
+     137       15460 : const GridCoordinatesObject& FunctionOfGrid<T>::getGridCoordinatesObject() const {
+     138       15460 :   ActionWithGrid* ag=ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     139       15460 :   plumed_assert( ag ); return ag->getGridCoordinatesObject();
+     140             : }
+     141             : 
+     142             : template <class T>
+     143         198 : std::vector<std::string> FunctionOfGrid<T>::getGridCoordinateNames() const {
+     144         198 :   ActionWithGrid* ag=ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     145         198 :   plumed_assert( ag ); return ag->getGridCoordinateNames();
+     146             : }
+     147             : 
+     148             : template <class T>
+     149        1814 : unsigned FunctionOfGrid<T>::getNumberOfDerivatives() {
+     150         514 :   if( myfunc.zeroRank() ) return getPntrToArgument(0)->getNumberOfValues();
+     151        1300 :   unsigned nder = getGridCoordinatesObject().getDimension();
+     152        1300 :   return getGridCoordinatesObject().getDimension() + getNumberOfArguments() - myfunc.getArgStart();
+     153             : }
+     154             : 
+     155             : template <class T>
+     156      974814 : void FunctionOfGrid<T>::performTask( const unsigned& current, MultiValue& myvals ) const {
+     157      974814 :   unsigned argstart=myfunc.getArgStart(); std::vector<double> args( getNumberOfArguments() - argstart );
+     158     2629182 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     159     1654368 :     if( getPntrToArgument(i)->getRank()==0 ) args[i-argstart]=getPntrToArgument(i)->get();
+     160     1110136 :     else args[i-argstart] = getPntrToArgument(i)->get(current);
+     161             :   }
+     162             :   // Calculate the function and its derivatives
+     163      974814 :   std::vector<double> vals(1); Matrix<double> derivatives( 1, getNumberOfArguments()-argstart );
+     164      974814 :   myfunc.calc( this, args, vals, derivatives ); unsigned np = myvals.getTaskIndex();
+     165             :   // And set the values and derivatives
+     166      974814 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+     167      974814 :   myvals.addValue( ostrn, vals[0] );
+     168       23665 :   if( !myfunc.zeroRank() ) {
+     169             :     // Add the derivatives for a grid
+     170     2581852 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     171             :       // We store all the derivatives of all the input values - i.e. the grid points these are used in apply
+     172     1630703 :       myvals.addDerivative( ostrn, getConstPntrToComponent(0)->getRank()+j-argstart, derivatives(0,j-argstart) );
+     173             :       // And now we calculate the derivatives of the value that is stored on the grid correctly so that we can interpolate functions
+     174     1630703 :       if( getPntrToArgument(j)->getRank()!=0 ) {
+     175     3413677 :         for(unsigned k=0; k<getPntrToArgument(j)->getRank(); ++k) myvals.addDerivative( ostrn, k, derivatives(0,j-argstart)*getPntrToArgument(j)->getGridDerivative( np, k ) );
+     176             :       }
+     177             :     }
+     178      951149 :     unsigned nderivatives = getConstPntrToComponent(0)->getNumberOfGridDerivatives();
+     179     4575808 :     for(unsigned j=0; j<nderivatives; ++j) myvals.updateIndex( ostrn, j );
+     180       23665 :   } else if( !doNotCalculateDerivatives() ) {
+     181             :     // These are the derivatives of the integral
+     182        8161 :     myvals.addDerivative( ostrn, current, derivatives(0,0) ); myvals.updateIndex( ostrn, current );
+     183             :   }
+     184      974814 : }
+     185             : 
+     186             : template <class T>
+     187      951149 : void FunctionOfGrid<T>::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     188             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     189      951149 :   if( getConstPntrToComponent(0)->getRank()>0 && getConstPntrToComponent(0)->hasDerivatives() ) {
+     190             :     plumed_dbg_assert( getNumberOfComponents()==1 && valindex==0 );
+     191      951149 :     unsigned nder = getConstPntrToComponent(0)->getNumberOfGridDerivatives();
+     192      951149 :     unsigned ostr = getConstPntrToComponent(0)->getPositionInStream();
+     193      951149 :     unsigned kp = bufstart + code*(1+nder); buffer[kp] += myvals.get( ostr );
+     194     4575808 :     for(unsigned i=0; i<nder; ++i) buffer[kp + 1 + i] += myvals.getDerivative( ostr, i );
+     195           0 :   } else ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer );
+     196      951149 : }
+     197             : 
+     198             : template <class T>
+     199        6067 : void FunctionOfGrid<T>::apply() {
+     200        6561 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return;
+     201             : 
+     202             :   // This applies forces for the integral
+     203         494 :   if( myfunc.zeroRank() ) { ActionWithVector::apply(); return; }
+     204             : 
+     205             :   // Work out how to deal with arguments
+     206             :   unsigned nscalars=0, argstart=myfunc.getArgStart();
+     207        1870 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     208        1245 :     if( getPntrToArgument(i)->getRank()==0 ) { nscalars++; }
+     209             :   }
+     210             : 
+     211         625 :   std::vector<double> totv(nscalars,0); Value* outval=getPntrToComponent(0);
+     212        7575 :   for(unsigned i=0; i<outval->getNumberOfValues(); ++i) {
+     213             :     nscalars=0;
+     214       19845 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     215       12895 :       double fforce = outval->getForce(i);
+     216       12895 :       if( getPntrToArgument(j)->getRank()==0 ) {
+     217        3205 :         totv[nscalars] += fforce*outval->getGridDerivative( i, outval->getRank()+j ); nscalars++;
+     218             :       } else {
+     219        9690 :         double vval = outval->getGridDerivative( i, outval->getRank()+j  );
+     220        9690 :         getPntrToArgument(j)->addForce( i, fforce*vval );
+     221             :       }
+     222             :     }
+     223             :   }
+     224             :   nscalars=0;
+     225        1870 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     226        1245 :     if( getPntrToArgument(i)->getRank()==0 ) { getPntrToArgument(i)->addForce( 0, totv[nscalars] ); nscalars++; }
+     227             :   }
+     228             : 
+     229             : }
+     230             : 
+     231             : }
+     232             : }
+     233             : #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 000000000..814043d23 --- /dev/null +++ b/coverage/gridtools/Gradient.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:4848100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..ca40ad78d --- /dev/null +++ b/coverage/gridtools/Gradient.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:4848100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..0f0abd5e7 --- /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:4848100.0 %
Date:2024-10-17 16:45:00Functions: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           9 :   keys.setValueDescription("the desired gradient");
+      54          27 :   keys.needsAction("DISTANCES"); keys.needsAction("KDE"); keys.needsAction("INTERPOLATE_GRID");
+      55          27 :   keys.needsAction("CUSTOM"); keys.needsAction("SUM_GRID"); keys.needsAction("COMBINE");
+      56           9 : }
+      57             : 
+      58           7 : Gradient::Gradient(const ActionOptions&ao):
+      59             :   Action(ao),
+      60           7 :   ActionShortcut(ao)
+      61             : {
+      62          14 :   std::string atom_str; parse("ATOMS",atom_str);
+      63          14 :   std::string dir; parse("DIR",dir);
+      64          14 :   std::string origin_str; parse("ORIGIN",origin_str);
+      65          14 :   std::string nbin_str; parse("NBINS",nbin_str);
+      66          14 :   std::string band_str; parse("SIGMA",band_str);
+      67           7 :   std::string kernel_str; parse("KERNEL",kernel_str);
+      68             :   // First get positions of all atoms relative to origin
+      69          14 :   readInputLine( getShortcutLabel() + "_dist: DISTANCES ORIGIN=" + origin_str + " ATOMS=" + atom_str + " COMPONENTS");
+      70             :   // Now constrcut the histograms
+      71          22 :   if( dir=="x" || dir=="xy" || dir=="xz" || dir=="xyz" ) {
+      72           8 :     readInputLine( getShortcutLabel() + "_xhisto: KDE ARG=" + getShortcutLabel() + "_dist.x GRID_BIN=" + nbin_str + " KERNEL=" + kernel_str + " BANDWIDTH=" + band_str );
+      73           8 :     std::string thislab = getShortcutLabel() + "_xgrad"; if( dir=="x" ) thislab = getShortcutLabel();
+      74           8 :     readInputLine( thislab + "_shift: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_xhisto INTERPOLATION_TYPE=ceiling MIDPOINTS");
+      75           8 :     readInputLine( thislab + "_x2: CUSTOM ARG=" + getShortcutLabel() + "_xhisto," + thislab + "_shift FUNC=(x-y)*(x-y) PERIODIC=NO");
+      76           8 :     readInputLine( thislab + ": SUM_GRID ARG=" + thislab + "_x2 PERIODIC=NO");
+      77             :   }
+      78          22 :   if( dir=="y" || dir=="xy" || dir=="yz" || dir=="xyz" ) {
+      79           8 :     readInputLine( getShortcutLabel() + "_yhisto: KDE ARG=" + getShortcutLabel() + "_dist.y GRID_BIN=" + nbin_str + " KERNEL=" + kernel_str + " BANDWIDTH=" + band_str );
+      80           8 :     std::string thislab = getShortcutLabel() + "_ygrad"; if( dir=="y" ) thislab = getShortcutLabel();
+      81           8 :     readInputLine( thislab + "_shift: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_yhisto INTERPOLATION_TYPE=ceiling MIDPOINTS");
+      82           8 :     readInputLine( thislab + "_x2: CUSTOM ARG=" + getShortcutLabel() + "_yhisto," + thislab + "_shift FUNC=(x-y)*(x-y) PERIODIC=NO");
+      83           8 :     readInputLine( thislab + ": SUM_GRID ARG=" + thislab + "_x2 PERIODIC=NO");
+      84             :   }
+      85          22 :   if( dir=="z" || dir=="yz" || dir=="xz" || dir=="xyz" ) {
+      86           8 :     readInputLine( getShortcutLabel() + "_zhisto: KDE ARG=" + getShortcutLabel() + "_dist.z GRID_BIN=" + nbin_str + " KERNEL=" + kernel_str + " BANDWIDTH=" + band_str );
+      87           8 :     std::string thislab = getShortcutLabel() + "_zgrad"; if( dir=="z" ) thislab = getShortcutLabel();
+      88           8 :     readInputLine( thislab + "_shift: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_zhisto INTERPOLATION_TYPE=ceiling MIDPOINTS");
+      89           8 :     readInputLine( thislab + "_x2: CUSTOM ARG=" + getShortcutLabel() + "_zhisto," + thislab + "_shift FUNC=(x-y)*(x-y) PERIODIC=NO");
+      90           8 :     readInputLine( thislab + ": SUM_GRID ARG=" + thislab + "_x2 PERIODIC=NO");
+      91             :   }
+      92           7 :   if( dir=="xy" ) {
+      93           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_xgrad," + getShortcutLabel() + "_ygrad PERIODIC=NO");
+      94           6 :   } else if( dir=="xz" ) {
+      95           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_xgrad," + getShortcutLabel() + "_zgrad PERIODIC=NO");
+      96           5 :   } else if( dir=="yz" ) {
+      97           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_ygrad," + getShortcutLabel() + "_zgrad PERIODIC=NO");
+      98           4 :   } else if( dir=="xyz" ) {
+      99           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_xgrad," + getShortcutLabel() + "_ygrad," + getShortcutLabel() + "_zgrad PERIODIC=NO");
+     100             :   }
+     101           7 : }
+     102             : 
+     103             : 
+     104             : 
+     105             : }
+     106             : }
+
+
+
+ + + + +
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 000000000..82af7eede --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.cpp.func-sort-c.html @@ -0,0 +1,152 @@ + + + + + + + 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-10-17 16:45:00Functions:192095.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools21GridCoordinatesObject20putCoordinateAtValueERKjRKdRSt6vectorIdSaIdEE0
_ZN4PLMD9gridtools21GridCoordinatesObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIbSaIbEERKjRKd335
_ZN4PLMD9gridtools21GridCoordinatesObject9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERS2_IdSaIdEE618
_ZNK4PLMD9gridtools21GridCoordinatesObject17getFibonacciIndexERKSt6vectorIdSaIdEE16510
_ZNK4PLMD9gridtools21GridCoordinatesObject8inboundsERKSt6vectorIdSaIdEE197426
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIdSaIdEERKS2_IjSaIjEERjRS8_231602
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIjSaIjEES6_RjRS4_245010
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMaxB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMinB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject7getNbinERKb483329
_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 000000000..3083c4017 --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.cpp.func.html @@ -0,0 +1,152 @@ + + + + + + + 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-10-17 16:45:00Functions:192095.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools21GridCoordinatesObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIbSaIbEERKjRKd335
_ZN4PLMD9gridtools21GridCoordinatesObject9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERS2_IdSaIdEE618
_ZNK4PLMD9gridtools21GridCoordinatesObject10getIndicesERKSt6vectorIdSaIdEERS2_IjSaIjEE1175406
_ZNK4PLMD9gridtools21GridCoordinatesObject10getIndicesERKjRSt6vectorIjSaIjEE42760057
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIdSaIdEERKS2_IjSaIjEERjRS8_231602
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIjSaIjEES6_RjRS4_245010
_ZNK4PLMD9gridtools21GridCoordinatesObject17getFibonacciIndexERKSt6vectorIdSaIdEE16510
_ZNK4PLMD9gridtools21GridCoordinatesObject18getSplineNeighborsERKjRjRSt6vectorIjSaIjEE544167
_ZNK4PLMD9gridtools21GridCoordinatesObject20putCoordinateAtValueERKjRKdRSt6vectorIdSaIdEE0
_ZNK4PLMD9gridtools21GridCoordinatesObject21convertIndexToIndicesERKjRKSt6vectorIjSaIjEERS6_94917677
_ZNK4PLMD9gridtools21GridCoordinatesObject22getFlatGridCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE39980732
_ZNK4PLMD9gridtools21GridCoordinatesObject23getFibonacciCoordinatesERKjRSt6vectorIdSaIdEE4974037
_ZNK4PLMD9gridtools21GridCoordinatesObject23getGridPointCoordinatesERKjRSt6vectorIdSaIdEE40720264
_ZNK4PLMD9gridtools21GridCoordinatesObject23getGridPointCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE41484313
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMaxB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMinB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject7getNbinERKb483329
_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 000000000..4a5f46b2c --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.cpp.gcov.html @@ -0,0 +1,413 @@ + + + + + + + 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-10-17 16:45:00Functions: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         335 : void GridCoordinatesObject::setup( const std::string& geom, const std::vector<bool>& ipbc,
+      30             :                                    const unsigned& np, const double& fib_cutoff ) {
+      31         335 :   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         335 :   if( gtype==flat ) {
+      36         678 :     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         335 : }
+      80             : 
+      81         618 : 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         618 :   plumed_assert( gtype==flat && (spacing.size()==dimension || binsin.size()==dimension) );
+      85         618 :   str_min.resize( dimension ); str_max.resize( dimension ); nbin.resize( dimension );
+      86         618 :   min.resize( dimension ); max.resize( dimension ); dx.resize( dimension ); stride.resize( dimension );
+      87             : 
+      88        1164 :   npoints=1; bounds_set=(smin[0]!="auto" && smax[0]!="auto");
+      89         618 :   if( bounds_set ) {
+      90         596 :     for(unsigned i=1; i<dimension; ++i) {
+      91         100 :       if( smin[i]=="auto" || smax[i]=="auto" ) { bounds_set=false; break; }
+      92             :     }
+      93             :   }
+      94        1302 :   for(unsigned i=0; i<dimension; ++i) {
+      95         684 :     str_min[i]=smin[i]; str_max[i]=smax[i];
+      96         684 :     if( bounds_set ) {
+      97         596 :       Tools::convert( str_min[i], min[i] );
+      98         596 :       Tools::convert( str_max[i], max[i] );
+      99             :     }
+     100         684 :     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         394 :     } else if( binsin.size()==dimension ) {
+     108         394 :       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         684 :     if( !pbc[i] ) { max[i] +=dx[i]; nbin[i]+=1; }
+     113         684 :     stride[i]=npoints;
+     114         684 :     npoints*=nbin[i];
+     115             :   }
+     116         618 :   if( spacing.size()!=dimension && bounds_set ) {
+     117         616 :     spacing.resize(dimension); for(unsigned i=0; i<dimension; ++i) spacing[i]=dx[i];
+     118             :   }
+     119         618 : }
+     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      483329 : std::vector<unsigned> GridCoordinatesObject::getNbin( const bool& shape ) const {
+     275             :   plumed_dbg_assert( gtype==flat && nbin.size()==dimension );
+     276      483329 :   std::vector<unsigned> ngrid( dimension );
+     277     1591468 :   for(unsigned i=0; i<dimension; ++i) {
+     278     1108139 :     if( !pbc[i] && !shape ) ngrid[i]=nbin[i] - 1;
+     279      534057 :     else ngrid[i]=nbin[i];
+     280             :   }
+     281      483329 :   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 000000000..9dd80ee66 --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools21GridCoordinatesObject11getGridTypeB5cxx11Ev214508
_ZNK4PLMD9gridtools21GridCoordinatesObject14getGridSpacingEv5000599
+
+
+ + + +
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 000000000..ce8f6248f --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools21GridCoordinatesObject11getGridTypeB5cxx11Ev214508
_ZNK4PLMD9gridtools21GridCoordinatesObject14getGridSpacingEv5000599
+
+
+ + + +
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 000000000..4cfbacb9e --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.h.gcov.html @@ -0,0 +1,243 @@ + + + + + + + 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-10-17 16:45:00Functions: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     5000599 : const std::vector<double>& GridCoordinatesObject::getGridSpacing() const {
+     126     5000599 :   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     2506946 :   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      214508 : std::string GridCoordinatesObject::getGridType() const {
+     160      214508 :   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 000000000..400494eb4 --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e4c88f397 --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1c9a71d89 --- /dev/null +++ b/coverage/gridtools/GridSearch.h.gcov.html @@ -0,0 +1,193 @@ + + + + + + + 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-10-17 16:45:00Functions: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/Histogram.cpp.func-sort-c.html b/coverage/gridtools/Histogram.cpp.func-sort-c.html new file mode 100644 index 000000000..4f4241d8d --- /dev/null +++ b/coverage/gridtools/Histogram.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - gridtools/Histogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools9HistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools9HistogramC1ERKNS_13ActionOptionsE22
_ZN4PLMD9gridtools9Histogram16registerKeywordsERNS_8KeywordsE29
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Histogram.cpp.func.html b/coverage/gridtools/Histogram.cpp.func.html new file mode 100644 index 000000000..5f7511ade --- /dev/null +++ b/coverage/gridtools/Histogram.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - gridtools/Histogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools9Histogram16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD9gridtools9HistogramC1ERKNS_13ActionOptionsE22
_ZN4PLMD9gridtools9HistogramC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Histogram.cpp.gcov.html b/coverage/gridtools/Histogram.cpp.gcov.html new file mode 100644 index 000000000..8f3cb8ce8 --- /dev/null +++ b/coverage/gridtools/Histogram.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + LCOV - plumed test coverage - gridtools/Histogram.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-10-17 16:45:00Functions: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 gridtools {
+     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          29 :   keys.setValueDescription("the estimate of the histogram as a function of the argument that was obtained");
+     220          87 :   keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("ONES");
+     221          58 :   keys.needsAction("KDE"); keys.needsAction("ACCUMULATE");
+     222          29 : }
+     223             : 
+     224          22 : Histogram::Histogram( const ActionOptions& ao ):
+     225             :   Action(ao),
+     226          22 :   ActionShortcut(ao)
+     227             : {
+     228          44 :   std::string normflag; parse("NORMALIZATION",normflag);
+     229          88 :   std::string lw; parse("LOGWEIGHTS",lw); std::string stride, clearstride; parse("STRIDE",stride); parse("CLEAR",clearstride);
+     230          28 :   if( lw.length()>0 && normflag!="ndata" ) {
+     231          12 :     readInputLine( getShortcutLabel() + "_wsum: COMBINE ARG=" + lw + " PERIODIC=NO");
+     232          12 :     readInputLine( getShortcutLabel() + "_weight: CUSTOM ARG=" + getShortcutLabel() + "_wsum FUNC=exp(x) PERIODIC=NO");
+     233          32 :   } else readInputLine( getShortcutLabel() + "_weight: ONES SIZE=1" );
+     234             : 
+     235          44 :   std::vector<std::string> arglist; parseVector("ARG",arglist); if( arglist.size()==0 ) parseVector("DATA",arglist);
+     236          22 :   if( arglist.size()==0 ) error("arguments have not been specified use ARG");
+     237          22 :   std::vector<Value*> theargs; ActionWithArguments::interpretArgumentList( arglist, plumed.getActionSet(), this, theargs );
+     238          22 :   plumed_assert( theargs.size()>0 ); std::string argstr=theargs[0]->getName();
+     239          33 :   for(unsigned i=1; i<theargs.size(); ++i) argstr += "," + theargs[i]->getName();
+     240          22 :   std::string strnum; Tools::convert( theargs[0]->getNumberOfValues(), strnum );
+     241          22 :   if( theargs[0]->getNumberOfValues()==1 ) {
+     242             :     // Create the KDE object
+     243          38 :     readInputLine( getShortcutLabel() + "_kde: KDE ARG=" + argstr + " " + convertInputLineToString() );
+     244             :   } else {
+     245             :     // Create the KDE object
+     246           6 :     readInputLine( getShortcutLabel() + "_kde_u: KDE ARG=" + argstr + " " + convertInputLineToString() );
+     247             :     // Normalise the KDE object
+     248           6 :     readInputLine( getShortcutLabel() + "_kde: CUSTOM ARG=" + getShortcutLabel() + "_kde_u PERIODIC=NO FUNC=x/" + strnum );
+     249             :   }
+     250             :   // Now get the quantity to accumulate
+     251          44 :   readInputLine( getShortcutLabel() + "_kdep: CUSTOM ARG=" + getShortcutLabel() + "_kde," + getShortcutLabel() + "_weight FUNC=x*y PERIODIC=NO");
+     252             :   // And accumulate the average
+     253          22 :   if( normflag=="false" ) {
+     254          14 :     readInputLine( getShortcutLabel() + ": ACCUMULATE ARG=" + getShortcutLabel() + "_kdep STRIDE=" + stride + " CLEAR=" + clearstride + " " + getUpdateLimits() );
+     255             :   } else {
+     256          30 :     readInputLine( getShortcutLabel() + "_u: ACCUMULATE ARG=" + getShortcutLabel() + "_kdep STRIDE=" + stride + " CLEAR=" + clearstride + " " + getUpdateLimits() );
+     257          30 :     readInputLine( getShortcutLabel() + "_nsum: ACCUMULATE ARG=" + getShortcutLabel() + "_weight STRIDE=" + stride + " CLEAR=" + clearstride + " " + getUpdateLimits() );
+     258             :     // And divide by the total weight
+     259          30 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_u," + getShortcutLabel() + "_nsum FUNC=x/y PERIODIC=NO");
+     260             :   }
+     261          44 : }
+     262             : 
+     263             : }
+     264             : }
+
+
+
+ + + + +
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 000000000..fc1b46ed0 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15InterpolateGrid22getGridCoordinateNamesB5cxx11Ev2
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE82
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE161
_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 000000000..c349fd068 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE161
_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 000000000..34790b2a0 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.gcov.html @@ -0,0 +1,258 @@ + + + + + + + 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-10-17 16:45:00Functions: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         161 : void InterpolateGrid::registerKeywords( Keywords& keys ) {
+      77         161 :   ActionWithGrid::registerKeywords( keys );
+      78         322 :   keys.add("optional","GRID_BIN","the number of bins for the grid"); keys.use("ARG");
+      79         322 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+      80         322 :   keys.addFlag("MIDPOINTS",false,"interpolate the values of the function at the midpoints of the grid coordinates of the input grid");
+      81         161 :   EvaluateGridFunction ii; ii.registerKeywords( keys );
+      82         161 : }
+      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 000000000..e38deb857 --- /dev/null +++ b/coverage/gridtools/Interpolator.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..027ec6a5a --- /dev/null +++ b/coverage/gridtools/Interpolator.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..92b73f387 --- /dev/null +++ b/coverage/gridtools/Interpolator.cpp.gcov.html @@ -0,0 +1,151 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e26e1b05a --- /dev/null +++ b/coverage/gridtools/Interpolator.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..601a6c606 --- /dev/null +++ b/coverage/gridtools/Interpolator.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..05ec46881 --- /dev/null +++ b/coverage/gridtools/Interpolator.h.gcov.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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          11 :   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 000000000..698996e4f --- /dev/null +++ b/coverage/gridtools/KDE.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + 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:29434086.5 %
Date:2024-10-17 16:45:00Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3KDEC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools3KDE22getGridCoordinateNamesB5cxx11Ev125
_ZN4PLMD9gridtools3KDE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE149
_ZN4PLMD9gridtools3KDEC1ERKNS_13ActionOptionsE149
_ZN4PLMD9gridtools3KDE20setupNeighborsVectorEv237
_ZN4PLMD9gridtools3KDE16registerKeywordsERNS_8KeywordsE274
_ZN4PLMD9gridtools3KDE16setupOnFirstStepEb295
_ZNK4PLMD9gridtools3KDE25updateForceTasksFromValueEPKNS_5ValueERSt6vectorIjSaIjEE610
_ZN4PLMD9gridtools3KDE22getNumberOfDerivativesEv1065
_ZN4PLMD9gridtools3KDE16getNumberOfTasksERj2651
_ZNK4PLMD9gridtools3KDE24getGridCoordinatesObjectEv6222
_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 000000000..8e00d2089 --- /dev/null +++ b/coverage/gridtools/KDE.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + 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:29434086.5 %
Date:2024-10-17 16:45:00Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3KDE16getNumberOfTasksERj2651
_ZN4PLMD9gridtools3KDE16registerKeywordsERNS_8KeywordsE274
_ZN4PLMD9gridtools3KDE16setupOnFirstStepEb295
_ZN4PLMD9gridtools3KDE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE149
_ZN4PLMD9gridtools3KDE20setupNeighborsVectorEv237
_ZN4PLMD9gridtools3KDE22getNumberOfDerivativesEv1065
_ZN4PLMD9gridtools3KDEC1ERKNS_13ActionOptionsE149
_ZN4PLMD9gridtools3KDEC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools3KDE11performTaskERKjRNS_10MultiValueE309567
_ZNK4PLMD9gridtools3KDE14evaluateKernelERKSt6vectorIdSaIdEES6_RKdRS4_38119671
_ZNK4PLMD9gridtools3KDE15checkTaskStatusERKjRi1500435
_ZNK4PLMD9gridtools3KDE17evaluateBeadValueERSt6vectorINS_13HistogramBeadESaIS3_EERKS2_IdSaIdEESA_RKdRS8_533600
_ZNK4PLMD9gridtools3KDE17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE251539
_ZNK4PLMD9gridtools3KDE19setupHistogramBeadsERSt6vectorINS_13HistogramBeadESaIS3_EE133400
_ZNK4PLMD9gridtools3KDE22getGridCoordinateNamesB5cxx11Ev125
_ZNK4PLMD9gridtools3KDE24getGridCoordinatesObjectEv6222
_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 000000000..7bfd86cab --- /dev/null +++ b/coverage/gridtools/KDE.cpp.gcov.html @@ -0,0 +1,654 @@ + + + + + + + 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:29434086.5 %
Date:2024-10-17 16:45:00Functions: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             : #include "tools/Matrix.h"
+      30             : 
+      31             : //+PLUMEDOC ANALYSIS KDE
+      32             : /*
+      33             : Create a histogram from the input scalar/vector/matrix using KDE
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : //+PLUMEDOC ANALYSIS SPHERICAL_KDE
+      42             : /*
+      43             : Create a histogram from the input scalar/vector/matrix using SPHERICAL_KDE
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : namespace PLMD {
+      52             : namespace gridtools {
+      53             : 
+      54             : class KDE : public ActionWithGrid {
+      55             : private:
+      56             :   double hh;
+      57             :   bool hasheight;
+      58             :   bool ignore_out_of_bounds, fixed_width;
+      59             :   double dp2cutoff;
+      60             :   std::string kerneltype;
+      61             :   GridCoordinatesObject gridobject;
+      62             :   std::vector<std::string> gmin, gmax;
+      63             :   std::vector<double> center;
+      64             :   std::vector<double> gspacing;
+      65             :   unsigned num_neigh, bwargno;
+      66             :   std::vector<Value> grid_diff_value;
+      67             :   std::vector<unsigned> nbin, nneigh, neighbors;
+      68             :   unsigned numberOfKernels, nbins;
+      69             :   SwitchingFunction switchingFunction;
+      70             :   double von_misses_concentration, von_misses_norm;
+      71             :   void setupNeighborsVector();
+      72             :   void retrieveArgumentsAndHeight( const MultiValue& myvals, std::vector<double>& args, double& height ) const ;
+      73             :   double evaluateKernel( const std::vector<double>& gpoint, const std::vector<double>& args, const double& height, std::vector<double>& der ) const ;
+      74             :   void setupHistogramBeads( std::vector<HistogramBead>& bead ) const ;
+      75             :   double evaluateBeadValue( std::vector<HistogramBead>& bead, const std::vector<double>& gpoint, const std::vector<double>& args, const double& height, std::vector<double>& der ) const ;
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit KDE(const ActionOptions&ao);
+      79             :   std::vector<std::string> getGridCoordinateNames() const override ;
+      80             :   const GridCoordinatesObject& getGridCoordinatesObject() const override ;
+      81             :   unsigned getNumberOfDerivatives() override;
+      82             :   void setupOnFirstStep( const bool incalc ) override ;
+      83             :   void getNumberOfTasks( unsigned& ntasks ) override ;
+      84             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) override ;
+      85             :   int checkTaskStatus( const unsigned& taskno, int& flag ) const override ;
+      86             :   void performTask( const unsigned& current, MultiValue& myvals ) const override ;
+      87             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+      88             :                           const unsigned& bufstart, std::vector<double>& buffer ) const override ;
+      89             :   void updateForceTasksFromValue( const Value* myval, std::vector<unsigned>& force_tasks ) const override ;
+      90             :   void gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const override ;
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(KDE,"KDE")
+      94             : PLUMED_REGISTER_ACTION(KDE,"SPHERICAL_KDE")
+      95             : 
+      96         274 : void KDE::registerKeywords( Keywords& keys ) {
+      97         274 :   ActionWithGrid::registerKeywords( keys ); keys.use("ARG");
+      98         548 :   keys.add("optional","HEIGHTS","this keyword takes the label of an action that calculates a vector of values.  The elements of this vector "
+      99             :            "are used as weights for the Gaussians.");
+     100         548 :   keys.add("optional","VOLUMES","this keyword take the label of an action that calculates a vector of values.  The elements of this vector "
+     101             :            "divided by the volume of the Gaussian are used as weights for the Gaussians");
+     102             :   // Keywords for KDE
+     103         548 :   keys.add("compulsory","GRID_MIN","auto","the lower bounds for the grid");
+     104         548 :   keys.add("compulsory","GRID_MAX","auto","the upper bounds for the grid");
+     105         548 :   keys.add("optional","BANDWIDTH","the bandwidths for kernel density esimtation");
+     106         548 :   keys.add("compulsory","METRIC","the inverse covariance to use for the kernels that are added to the grid");
+     107         548 :   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");
+     108         548 :   keys.add("compulsory","KERNEL","GAUSSIAN","the kernel function you are using.  More details on  the kernels available "
+     109             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+     110         548 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     111         548 :   keys.addFlag("IGNORE_IF_OUT_OF_RANGE",false,"if a kernel is outside of the range of the grid it is safe to ignore");
+     112         548 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     113             :   // Keywords for spherical KDE
+     114         548 :   keys.add("compulsory","CONCENTRATION","the concentration parameter for Von Mises-Fisher distributions (only required for SPHERICAL_KDE)");
+     115         274 :   keys.setValueDescription("a function on a grid that was obtained by doing a Kernel Density Estimation using the input arguments");
+     116         274 : }
+     117             : 
+     118         149 : KDE::KDE(const ActionOptions&ao):
+     119             :   Action(ao),
+     120             :   ActionWithGrid(ao),
+     121         149 :   hasheight(false),
+     122         149 :   fixed_width(false)
+     123             : {
+     124         149 :   std::vector<unsigned> shape( getNumberOfArguments() ); center.resize( getNumberOfArguments() );
+     125         149 :   numberOfKernels=getPntrToArgument(0)->getNumberOfValues();
+     126         199 :   for(unsigned i=1; i<shape.size(); ++i) {
+     127          50 :     if( numberOfKernels!=getPntrToArgument(i)->getNumberOfValues() ) error("mismatch between numbers of values in input arguments");
+     128             :   }
+     129             : 
+     130         298 :   bool weights_are_volumes=true; std::vector<std::string> weight_str; parseVector("VOLUMES",weight_str);
+     131         149 :   if( weight_str.size()==0 ) {
+     132         146 :     parseVector("HEIGHTS",weight_str);
+     133          73 :     if( weight_str.size()>0 ) weights_are_volumes=false;
+     134             :   }
+     135         149 :   hasheight=(weight_str.size()==1);
+     136         149 :   if( weight_str.size()>1 ) error("only one scalar/vector/matrix should be input to HEIGHTS");
+     137             : 
+     138         149 :   if( getName()=="KDE" ) {
+     139         278 :     parse("KERNEL",kerneltype);
+     140         139 :     if( kerneltype!="DISCRETE" ) {
+     141         254 :       std::string bandwidth; std::vector<std::string> bwidths; parseVector("BANDWIDTH",bwidths);
+     142         127 :       if( bwidths.size()>0 ) {
+     143         127 :         std::string band="VALUES=" + bwidths[0];
+     144         284 :         for(unsigned i=0; i<bwidths.size(); ++i) {
+     145         187 :           if( i>0 ) band += "," + bwidths[i];
+     146             :         }
+     147         254 :         plumed.readInputLine( getLabel() + "_sigma: CONSTANT " + band );
+     148         254 :         plumed.readInputLine( getLabel() + "_cov: CUSTOM ARG=" + getLabel() + "_sigma FUNC=x*x PERIODIC=NO" );
+     149         254 :         plumed.readInputLine( getLabel() + "_icov: CUSTOM ARG=" + getLabel() + "_cov FUNC=1/x PERIODIC=NO" );
+     150         254 :         bandwidth = getLabel() + "_icov";
+     151             : 
+     152         254 :         if( (kerneltype=="gaussian" || kerneltype=="GAUSSIAN") && weights_are_volumes ) {
+     153         105 :           std::string pstr; Tools::convert( sqrt(pow(2*pi,bwidths.size())), pstr );
+     154         210 :           plumed.readInputLine( getLabel() + "_bwprod: PRODUCT ARG=" + getLabel() + "_cov");
+     155         210 :           plumed.readInputLine( getLabel() + "_vol: CUSTOM ARG=" + getLabel() + "_bwprod FUNC=(sqrt(x)*" + pstr + ") PERIODIC=NO");
+     156         181 :           if( hasheight ) plumed.readInputLine( getLabel() + "_height: CUSTOM ARG=" + weight_str[0] + "," + getLabel() + "_vol FUNC=x/y PERIODIC=NO");
+     157          58 :           else plumed.readInputLine( getLabel() + "_height: CUSTOM ARG=" + getLabel() + "_vol FUNC=1/x PERIODIC=NO");
+     158         210 :           hasheight=true; weight_str.resize(1); weight_str[0] = getLabel() + "_height";
+     159             :         }
+     160           0 :       } else parse("METRIC",bandwidth);
+     161         127 :       weight_str.push_back( bandwidth );
+     162         127 :     }
+     163             :   }
+     164         149 :   if( weight_str.size()>0 ) {
+     165         145 :     std::vector<Value*> weight_args; ActionWithArguments::interpretArgumentList( weight_str, plumed.getActionSet(), this, weight_args );
+     166         145 :     std::vector<Value*> args( getArguments() ); args.push_back( weight_args[0] );
+     167         145 :     if( hasheight && weight_args[0]->getNumberOfValues()>1 && numberOfKernels!=weight_args[0]->getNumberOfValues() ) error("mismatch between numbers of values in input arguments and HEIGHTS");
+     168             : 
+     169         145 :     if( weight_str.size()==2 ) {
+     170         112 :       log.printf("  quantities used for weights are : %s \n", weight_str[0].c_str() );
+     171         112 :       args.push_back( weight_args[1] );
+     172         112 :       if( weight_args[1]->getRank()==1 && weight_args[1]->getNumberOfValues()!=shape.size() ) error("size of bandwidth vector is incorrect");
+     173         112 :       if( weight_args[1]->getRank()>2 ) error("bandwidths cannot have rank greater than 2");
+     174         112 :       bwargno=args.size()-1; log.printf("  bandwidths are taken from : %s \n", weight_str[1].c_str() );
+     175          33 :     } else if( !hasheight ) {
+     176          15 :       if( weight_args[0]->getRank()==1 && weight_args[0]->getNumberOfValues()!=shape.size() ) error("size of bandwidth vector is incorrect");
+     177          15 :       if( weight_args[0]->getRank()>2 ) error("bandwidths cannot have rank greater than 2");
+     178          15 :       bwargno=args.size()-1; log.printf("  bandwidths are taken from : %s \n", weight_str[0].c_str() );
+     179          18 :     } else if ( weight_str.size()==1 ) {
+     180          18 :       log.printf("  quantities used for weights are : %s \n", weight_str[0].c_str() );
+     181           0 :     } else error("only one scalar/vector/matrix should be input to HEIGHTS");
+     182         145 :     requestArguments( args );
+     183             :   }
+     184             : 
+     185         149 :   if( getName()=="KDE" ) {
+     186         139 :     bool hasauto=false; gmin.resize( shape.size() ); gmax.resize( shape.size() );
+     187         278 :     parseVector("GRID_MIN",gmin); parseVector("GRID_MAX",gmax);
+     188         308 :     for(unsigned i=0; i<gmin.size(); ++i) {
+     189         169 :       if( gmin[i]=="auto" ) {
+     190          52 :         log.printf("  for %dth coordinate min and max are set from cell directions \n", (i+1) );
+     191             :         hasauto=true;  // We need to do a preparation step to set the grid from the box size
+     192          52 :         if( gmax[i]!="auto" ) error("if gmin is set from box vectors gmax must also be set in the same way");
+     193          52 :         if( getPntrToArgument(i)->isPeriodic() ) {
+     194           0 :           if( gmin[i]=="auto" ) getPntrToArgument(i)->getDomain( gmin[i], gmax[i] );
+     195             :           else {
+     196           0 :             std::string str_min, str_max; getPntrToArgument(i)->getDomain( str_min, str_max );
+     197           0 :             if( str_min!=gmin[i] || str_max!=gmax[i] ) error("all periodic arguments should have the same domain");
+     198             :           }
+     199          52 :         } else if( getPntrToArgument(i)->getName().find(".")!=std::string::npos ) {
+     200          52 :           std::size_t dot = getPntrToArgument(i)->getName().find_first_of(".");
+     201          52 :           std::string name = getPntrToArgument(i)->getName().substr(dot+1);
+     202          90 :           if( name!="x" && name!="y" && name!="z" ) {
+     203           0 :             error("cannot set GRID_MIN and GRID_MAX automatically if input argument is not component of distance");
+     204             :           }
+     205             :         } else {
+     206           0 :           error("cannot set GRID_MIN and GRID_MAX automatically if input argument is not component of distance");
+     207             :         }
+     208             :       } else {
+     209         117 :         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() );
+     210             :       }
+     211             :     }
+     212         139 :     if( hasauto && gmin.size()>3 ) error("can only set GRID_MIN and GRID_MAX automatically if components of distance are used in input");
+     213             : 
+     214         417 :     parseVector("GRID_BIN",nbin); parseVector("GRID_SPACING",gspacing); parse("CUTOFF",dp2cutoff);
+     215         260 :     if( kerneltype.find("bin")==std::string::npos && kerneltype!="DISCRETE" ) {
+     216         218 :       std::string errors; switchingFunction.set( kerneltype + " R_0=1.0 NOSTRETCH", errors );
+     217         109 :       if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     218             :     }
+     219             : 
+     220         139 :     if( nbin.size()!=shape.size() && gspacing.size()!=shape.size() ) error("GRID_BIN or GRID_SPACING must be set");
+     221             :     // Create a value
+     222         139 :     std::vector<bool> ipbc( shape.size() );
+     223         308 :     for(unsigned i=0; i<shape.size(); ++i) {
+     224         324 :       if( getPntrToArgument( i )->isPeriodic() || gmin[i]=="auto" ) ipbc[i]=true;
+     225             :       else ipbc[i]=false;
+     226             :     }
+     227         278 :     gridobject.setup( "flat", ipbc, 0, 0.0 );
+     228             :   } else {
+     229          10 :     if( shape.size()!=3 ) error("should have three coordinates in input to this action");
+     230             : 
+     231          20 :     parse("GRID_BIN",nbins); log.printf("  setting number of bins to %d \n", nbins );
+     232          10 :     parse("CONCENTRATION",von_misses_concentration); fixed_width=true;
+     233          10 :     von_misses_norm = von_misses_concentration / ( 4*pi*sinh( von_misses_concentration ) );
+     234          10 :     log.printf("  setting concentration parameter to %f \n", von_misses_concentration );
+     235             : 
+     236             :     // Create a value
+     237          10 :     std::vector<bool> ipbc( shape.size(), false );
+     238          10 :     double fib_cutoff = std::log( epsilon / von_misses_norm ) / von_misses_concentration;
+     239          20 :     gridobject.setup( "fibonacci", ipbc, nbins, fib_cutoff ); checkRead();
+     240             : 
+     241             :     // Setup the grid
+     242          10 :     shape[0]=nbins; shape[1]=shape[2]=1;
+     243             :   }
+     244         149 :   parseFlag("IGNORE_IF_OUT_OF_RANGE",ignore_out_of_bounds);
+     245         149 :   if( ignore_out_of_bounds ) log.printf("  ignoring kernels that are outside of grid \n");
+     246         149 :   addValueWithDerivatives( shape ); setNotPeriodic();
+     247         149 :   getPntrToComponent(0)->setDerivativeIsZeroWhenValueIsZero();
+     248             :   // Make sure we store all the arguments
+     249         605 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) getPntrToArgument(i)->buildDataStore();
+     250             :   // Check for task reduction
+     251         149 :   updateTaskListReductionStatus(); setupOnFirstStep( false );
+     252         298 : }
+     253             : 
+     254         295 : void KDE::setupOnFirstStep( const bool incalc ) {
+     255         295 :   if( getName()=="SPHERICAL_KDE" ) return ;
+     256             : 
+     257         606 :   for(unsigned i=0; i<getNumberOfDerivatives(); ++i) {
+     258         331 :     if( gmin[i]=="auto" && incalc ) {
+     259             :       double lcoord, ucoord;
+     260          92 :       PbcAction* bv = plumed.getActionSet().selectWithLabel<PbcAction*>("Box"); Tensor box( bv->getPbc().getBox() );
+     261          46 :       std::size_t dot = getPntrToArgument(i)->getName().find_first_of(".");
+     262          46 :       std::string name = getPntrToArgument(i)->getName().substr(dot+1);
+     263          46 :       if( name=="x" ) { lcoord=-0.5*box(0,0); ucoord=0.5*box(0,0); }
+     264          22 :       else if( name=="y" ) { lcoord=-0.5*box(1,1); ucoord=0.5*box(1,1); }
+     265          10 :       else if( name=="z" ) { lcoord=-0.5*box(2,2); ucoord=0.5*box(2,2); }
+     266           0 :       else plumed_error();
+     267             :       // And convert to strings for bin and bmax
+     268          46 :       Tools::convert( lcoord, gmin[i] ); Tools::convert( ucoord, gmax[i] );
+     269             :     }
+     270         331 :     if( incalc ) {
+     271         324 :       grid_diff_value.push_back( Value() );
+     272         162 :       if( gridobject.isPeriodic(i) ) grid_diff_value[i].setDomain( gmin[i], gmax[i] );
+     273         103 :       else grid_diff_value[i].setNotPeriodic();
+     274             :     }
+     275             :   }
+     276             :   // And setup the grid object
+     277         275 :   gridobject.setBounds( gmin, gmax, nbin, gspacing );
+     278         275 :   std::vector<unsigned> shape( gridobject.getNbin(true) );
+     279         275 :   getPntrToComponent(0)->setShape( shape );
+     280         867 :   bool hasauto=false; for(unsigned i=0; i<gmin.size(); ++i) { if(gmin[i]=="auto" || gmax[i]=="auto" ) { hasauto=true; break; } }
+     281             :   // And setup the neighbors
+     282         275 :   if( !hasauto && kerneltype!="DISCRETE" && getPntrToArgument(bwargno)->isConstant() ) {
+     283         214 :     fixed_width=true; setupNeighborsVector();
+     284             :   }
+     285             : }
+     286             : 
+     287         237 : void KDE::setupNeighborsVector() {
+     288         237 :   if( kerneltype!="DISCRETE" ) {
+     289         214 :     std::vector<double> support(gmin.size(),0); nneigh.resize( gmin.size() );
+     290         214 :     if( kerneltype.find("bin")!=std::string::npos ) {
+     291          18 :       std::size_t dd = kerneltype.find("-bin");
+     292          18 :       HistogramBead bead; bead.setKernelType( kerneltype.substr(0,dd) );
+     293          18 :       Value* bw_arg=getPntrToArgument(bwargno);
+     294          18 :       if( bw_arg->getRank()<2 ) {
+     295          36 :         for(unsigned i=0; i<support.size(); ++i) {
+     296          18 :           bead.set( 0, gridobject.getGridSpacing()[i], 1./sqrt(bw_arg->get(i)) );
+     297          18 :           support[i] = bead.getCutoff(); nneigh[i] = static_cast<unsigned>( ceil( support[i]/gridobject.getGridSpacing()[i] ));
+     298             :         }
+     299           0 :       } else plumed_error();
+     300             :     } else {
+     301         196 :       Value* bw_arg=getPntrToArgument(bwargno);
+     302         196 :       if( bw_arg->getRank()<2 ) {
+     303         432 :         for(unsigned i=0; i<support.size(); ++i) {
+     304         236 :           support[i] = sqrt(2.0*dp2cutoff)*(1.0/sqrt(bw_arg->get(i)));
+     305         236 :           nneigh[i] = static_cast<unsigned>( ceil( support[i] / gridobject.getGridSpacing()[i] ) );
+     306             :         }
+     307           0 :       } else if( bw_arg->getRank()==2 ) {
+     308           0 :         Matrix<double> metric(support.size(),support.size()); unsigned k=0;
+     309           0 :         for(unsigned i=0; i<support.size(); ++i) {
+     310           0 :           for(unsigned j=0; j<support.size(); ++j) { metric(i,j)=bw_arg->get(k); k++; }
+     311             :         }
+     312           0 :         Matrix<double> myautovec(support.size(),support.size()); std::vector<double> myautoval(support.size());
+     313           0 :         diagMat(metric,myautoval,myautovec); double maxautoval=1/myautoval[0]; unsigned ind_maxautoval=0;
+     314           0 :         for(unsigned i=1; i<support.size(); i++) {
+     315           0 :           double neweig=1/myautoval[i]; if(neweig>maxautoval) { maxautoval=neweig; ind_maxautoval=i; }
+     316             :         }
+     317           0 :         for(unsigned i=0; i<support.size(); i++) {
+     318           0 :           support[i] = sqrt(2.0*dp2cutoff)*fabs(sqrt(maxautoval)*myautovec(i,ind_maxautoval));
+     319           0 :           nneigh[i] = static_cast<unsigned>( ceil( support[i] / gridobject.getGridSpacing()[i] ) );
+     320             :         }
+     321           0 :       } else plumed_error();
+     322             :     }
+     323         468 :     for(unsigned i=0; i<gridobject.getDimension(); ++i) {
+     324         254 :       double fmax, fmin; Tools::convert( gridobject.getMin()[i], fmin ); Tools::convert( gridobject.getMax()[i], fmax );
+     325         254 :       if( gridobject.isPeriodic(i) && 2*support[i]>(fmax-fmin) ) error("bandwidth is too large for periodic grid");
+     326             :     }
+     327             :   }
+     328         237 : }
+     329             : 
+     330        1065 : unsigned KDE::getNumberOfDerivatives() {
+     331        1065 :   return gridobject.getDimension();
+     332             : }
+     333             : 
+     334         125 : std::vector<std::string> KDE::getGridCoordinateNames() const {
+     335         125 :   std::vector<std::string> names( gridobject.getDimension() );
+     336         301 :   for(unsigned i=0; i<names.size(); ++i) names[i] = getPntrToArgument(i)->getName();
+     337         125 :   return names;
+     338           0 : }
+     339             : 
+     340        6222 : const GridCoordinatesObject& KDE::getGridCoordinatesObject() const {
+     341        6222 :   return gridobject;
+     342             : }
+     343             : 
+     344         149 : void KDE::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     345         149 :   if( numberOfKernels==1 || (hasheight && getPntrToArgument(gridobject.getDimension())->getRank()>0) ) task_reducing_actions.push_back(this);
+     346         149 : }
+     347             : 
+     348        2651 : void KDE::getNumberOfTasks( unsigned& ntasks ) {
+     349        2651 :   if( !fixed_width ) setupNeighborsVector();
+     350        2651 :   ntasks = numberOfKernels = getPntrToArgument(0)->getNumberOfValues();
+     351        2651 :   if( numberOfKernels>1 ) return;
+     352             : 
+     353         132 :   hh = 1.0; if( hasheight ) hh = getPntrToArgument(gridobject.getDimension())->get();
+     354         309 :   for(unsigned i=0; i<center.size(); ++i) center[i]=getPntrToArgument(i)->get();
+     355         132 :   if( !ignore_out_of_bounds && !gridobject.inbounds( center ) ) {
+     356             :     //if( fabs(height)>epsilon ) warning("bounds are possibly set too small as hills with substantial heights are being ignored");
+     357             :     return;
+     358             :   }
+     359         132 :   if( kerneltype=="DISCRETE" ) {
+     360          12 :     num_neigh=1; neighbors.resize(1);
+     361          24 :     for(unsigned i=0; i<center.size(); ++i) center[i] += 0.5*gridobject.getGridSpacing()[i];
+     362          12 :     neighbors[0]=gridobject.getIndex( center );
+     363         120 :   } else gridobject.getNeighbors( center, nneigh, num_neigh, neighbors );
+     364         132 :   ntasks = getPntrToComponent(0)->getNumberOfValues();
+     365         132 :   return;
+     366             : }
+     367             : 
+     368     1500435 : int KDE::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+     369     1500435 :   if( numberOfKernels>1 ) {
+     370     1400374 :     if( hasheight && getPntrToArgument(gridobject.getDimension())->getRank()>0
+     371     2823898 :         && fabs(getPntrToArgument(gridobject.getDimension())->get(taskno))<epsilon ) return 0;
+     372      185408 :     return 1;
+     373             :   }
+     374    19394629 :   for(unsigned i=0; i<num_neigh; ++i) {
+     375    19339045 :     if( taskno==neighbors[i] ) return 1;
+     376             :   }
+     377             :   return 0;
+     378             : }
+     379             : 
+     380      309567 : void KDE::performTask( const unsigned& current, MultiValue& myvals ) const {
+     381      309567 :   if( numberOfKernels==1 ) {
+     382       21277 :     double newval; std::vector<double> args( gridobject.getDimension() ), der( gridobject.getDimension() );
+     383       21277 :     unsigned valout = getConstPntrToComponent(0)->getPositionInStream();
+     384       21277 :     gridobject.getGridPointCoordinates( current, args );
+     385       21277 :     if( getName()=="KDE" ) {
+     386       21277 :       if( kerneltype=="DISCRETE" ) {
+     387             :         newval = 1.0;
+     388       21265 :       } else if( kerneltype.find("bin")!=std::string::npos ) {
+     389           0 :         double val=hh; std::size_t dd = kerneltype.find("-bin");
+     390           0 :         HistogramBead bead; bead.setKernelType( kerneltype.substr(0,dd) ); Value* bw_arg=getPntrToArgument(bwargno);
+     391           0 :         for(unsigned j=0; j<args.size(); ++j) {
+     392           0 :           if( gridobject.isPeriodic(j) ) {
+     393           0 :             double lcoord,  ucoord; Tools::convert( gmin[j], lcoord );
+     394           0 :             Tools::convert( gmax[j], ucoord ); bead.isPeriodic( lcoord, ucoord );
+     395             :           } else bead.isNotPeriodic();
+     396           0 :           if( bw_arg->getRank()<2 ) bead.set( args[j], args[j]+gridobject.getGridSpacing()[j], 1/sqrt(bw_arg->get(j)) );
+     397           0 :           else if( bw_arg->getRank()==2 ) plumed_error();
+     398           0 :           double contr = bead.calculateWithCutoff( args[j], der[j] );
+     399           0 :           val = val*contr; der[j] = der[j] / contr;
+     400             :         }
+     401           0 :         for(unsigned j=0; j<args.size(); ++j) der[j] *= val; newval=val;
+     402             :       } else {
+     403       21265 :         newval = evaluateKernel( args, center, hh, der );
+     404             :       }
+     405             :     } else {
+     406           0 :       double dot=0; for(unsigned i=0; i<der.size(); ++i) { dot += args[i]*center[i]; }
+     407           0 :       newval = hh*von_misses_norm*exp( von_misses_concentration*dot );
+     408           0 :       for(unsigned i=0; i<der.size(); ++i) der[i] = von_misses_concentration*newval*args[i];
+     409             :     }
+     410       21277 :     myvals.setValue( valout, newval );
+     411       78047 :     for(unsigned i=0; i<der.size(); ++i) { myvals.addDerivative( valout, i, der[i] ); myvals.updateIndex( valout, i ); }
+     412             :   }
+     413      309567 : }
+     414             : 
+     415      288290 : void KDE::retrieveArgumentsAndHeight( const MultiValue& myvals, std::vector<double>& args, double& height ) const {
+     416      712540 :   height=1.0; for(unsigned i=0; i<args.size(); ++i) args[i]=getPntrToArgument(i)->get( myvals.getTaskIndex() );
+     417      288290 :   if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) height = getPntrToArgument( args.size() )->get();
+     418      272358 :   else if( hasheight ) height = getPntrToArgument( args.size() )->get( myvals.getTaskIndex() );
+     419      288290 : }
+     420             : 
+     421    38119671 : double KDE::evaluateKernel( const std::vector<double>& gpoint, const std::vector<double>& args, const double& height, std::vector<double>& der ) const {
+     422    38119671 :   double r2=0, hval = height; Value* bw_arg=getPntrToArgument(bwargno);
+     423    38119671 :   if( bw_arg->getRank()<2 ) {
+     424   151428182 :     for(unsigned j=0; j<der.size(); ++j) {
+     425   113308511 :       double tmp = -grid_diff_value[j].difference( gpoint[j], args[j] );
+     426   113308511 :       der[j] = tmp*bw_arg->get(j); r2 += tmp*der[j];
+     427             :     }
+     428           0 :   } else if( bw_arg->getRank()==2 ) {
+     429           0 :     for(unsigned j=0; j<der.size(); ++j) {
+     430           0 :       der[j]=0; double dp_j, dp_k; dp_j = -grid_diff_value[j].difference( gpoint[j], args[j] );
+     431           0 :       for(unsigned k=0; k<der.size(); ++k ) {
+     432           0 :         if(j==k) dp_k = dp_j;
+     433           0 :         else dp_k = -grid_diff_value[k].difference( gpoint[k], args[k] );
+     434           0 :         der[j] += bw_arg->get(j*der.size()+k)*dp_k; r2 += dp_j*dp_k*bw_arg->get(j*der.size()+k);
+     435             :       }
+     436             :     }
+     437           0 :   } else plumed_error();
+     438    38119671 :   double dval, val=hval*switchingFunction.calculateSqr( r2, dval );
+     439   151428182 :   dval *= hval; for(unsigned j=0; j<der.size(); ++j) der[j] *= dval;
+     440    38119671 :   return val;
+     441             : }
+     442             : 
+     443      133400 : void KDE::setupHistogramBeads( std::vector<HistogramBead>& bead ) const {
+     444      133400 :   std::size_t dd = kerneltype.find("-bin");
+     445      133400 :   std::string ktype=kerneltype.substr(0,dd);
+     446      266800 :   for(unsigned j=0; j<bead.size(); ++j) {
+     447      133400 :     bead[j].setKernelType( ktype );
+     448      133400 :     if( gridobject.isPeriodic(j) ) {
+     449      133400 :       double lcoord,  ucoord; Tools::convert( gmin[j], lcoord );
+     450      133400 :       Tools::convert( gmax[j], ucoord ); bead[j].isPeriodic( lcoord, ucoord );
+     451             :     } else bead[j].isNotPeriodic();
+     452             :   }
+     453      133400 : }
+     454             : 
+     455      533600 : double KDE::evaluateBeadValue( std::vector<HistogramBead>& bead, const std::vector<double>& gpoint, const std::vector<double>& args,
+     456             :                                const double& height, std::vector<double>& der ) const {
+     457      533600 :   double val=height; std::vector<double> contr( args.size() ); Value* bw_arg=getPntrToArgument(bwargno);
+     458      533600 :   if( bw_arg->getRank()<2 ) {
+     459     1067200 :     for(unsigned j=0; j<args.size(); ++j) {
+     460      533600 :       bead[j].set( gpoint[j], gpoint[j]+gridobject.getGridSpacing()[j], 1/sqrt(bw_arg->get(j)) );
+     461      533600 :       contr[j] = bead[j].calculateWithCutoff( args[j], der[j] );
+     462      533600 :       val = val*contr[j];
+     463             :     }
+     464           0 :   } else plumed_error();
+     465     1067200 :   for(unsigned j=0; j<args.size(); ++j) {
+     466      533600 :     if( fabs(contr[j])>epsilon ) der[j] *= val / contr[j];
+     467             :   }
+     468      533600 :   return val;
+     469             : }
+     470             : 
+     471      251539 : void KDE::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     472             :                              const unsigned& bufstart, std::vector<double>& buffer ) const {
+     473             :   plumed_dbg_assert( valindex==0 );
+     474      251539 :   if( numberOfKernels==1 ) {
+     475       21277 :     unsigned istart = bufstart + (1+gridobject.getDimension())*code;
+     476       21277 :     unsigned valout = getConstPntrToComponent(0)->getPositionInStream(); buffer[istart] += myvals.get( valout );
+     477       78047 :     for(unsigned i=0; i<gridobject.getDimension(); ++i) buffer[istart+1+i] += myvals.getDerivative( valout, i );
+     478       46591 :     return;
+     479             :   }
+     480      230262 :   std::vector<double> args( gridobject.getDimension() ); double height; retrieveArgumentsAndHeight( myvals, args, height );
+     481      230262 :   if( !ignore_out_of_bounds && !gridobject.inbounds( args ) ) {
+     482             :     // if( fabs(height)>epsilon ) warning("bounds are possibly set too small as hills with substantial heights are being ignored");
+     483             :     return ;
+     484             :   }
+     485             :   // Add the kernel to the grid
+     486             :   unsigned num_neigh; std::vector<unsigned> neighbors;
+     487      204948 :   if( kerneltype!="DISCRETE" ) gridobject.getNeighbors( args, nneigh, num_neigh, neighbors );
+     488      204948 :   std::vector<double> der( args.size() ), gpoint( args.size() );
+     489      204948 :   if( fabs(height)>epsilon ) {
+     490      204948 :     if( getName()=="KDE" ) {
+     491      197340 :       if( kerneltype=="DISCRETE" ) {
+     492       31494 :         std::vector<double> newargs( args.size() );
+     493       62988 :         for(unsigned i=0; i<args.size(); ++i) newargs[i] = args[i] + 0.5*gridobject.getGridSpacing()[i];
+     494       31494 :         plumed_assert( bufstart + gridobject.getIndex( newargs )*(1+args.size())<buffer.size() );
+     495       31494 :         buffer[ bufstart + gridobject.getIndex( newargs )*(1+args.size()) ] += height;
+     496      165846 :       } else if( kerneltype.find("bin")!=std::string::npos ) {
+     497      104400 :         std::vector<HistogramBead> bead( args.size() ); setupHistogramBeads( bead );
+     498      522000 :         for(unsigned i=0; i<num_neigh; ++i) {
+     499      417600 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     500      417600 :           double val = evaluateBeadValue( bead, gpoint, args, height, der );
+     501      417600 :           buffer[ bufstart + neighbors[i]*(1+der.size()) ] += val;
+     502      835200 :           for(unsigned j=0; j<der.size(); ++j) buffer[ bufstart + neighbors[i]*(1+der.size()) + 1 + j ] += val*der[j];
+     503             :         }
+     504             :       } else {
+     505    37979124 :         for(unsigned i=0; i<num_neigh; ++i) {
+     506    37917678 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     507    37917678 :           buffer[ bufstart + neighbors[i]*(1+der.size()) ] += evaluateKernel( gpoint, args, height, der );
+     508   150985777 :           for(unsigned j=0; j<der.size(); ++j) buffer[ bufstart + neighbors[i]*(1+der.size()) + 1 + j ] += der[j];
+     509             :         }
+     510             :       }
+     511             :     } else {
+     512      828405 :       for(unsigned i=0; i<num_neigh; ++i) {
+     513      820797 :         gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     514     3283188 :         double dot=0; for(unsigned j=0; j<gpoint.size(); ++j) dot += args[j]*gpoint[j];
+     515      820797 :         double newval = height*von_misses_norm*exp( von_misses_concentration*dot );
+     516      820797 :         buffer[ bufstart + neighbors[i]*(1+gpoint.size()) ] += newval;
+     517     3283188 :         for(unsigned j=0; j<gpoint.size(); ++j) buffer[ bufstart + neighbors[i]*(1+gpoint.size()) + 1 + j ] += von_misses_concentration*newval*gpoint[j];
+     518             :       }
+     519             :     }
+     520             :   }
+     521             : }
+     522             : 
+     523         610 : void KDE::updateForceTasksFromValue( const Value* myval, std::vector<unsigned>& force_tasks ) const {
+     524         610 :   if( !myval->forcesWereAdded() ) return ;
+     525         610 :   if( numberOfKernels==1 ) plumed_error();
+     526             : 
+     527         610 :   int flag=1;
+     528      290135 :   for(unsigned i=0; i<numberOfKernels; ++i) {
+     529      289525 :     if( checkTaskStatus( i, flag ) ) force_tasks.push_back(i);
+     530             :   }
+     531             : }
+     532             : 
+     533       58028 : void KDE::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     534       58028 :   if( numberOfKernels==1 ) {
+     535           0 :     plumed_error();
+     536             :     return;
+     537             :   }
+     538       58028 :   double height; std::vector<double> args( gridobject.getDimension() );
+     539       58028 :   retrieveArgumentsAndHeight( myvals, args, height );
+     540             :   unsigned num_neigh; std::vector<unsigned> neighbors;
+     541       58028 :   gridobject.getNeighbors( args, nneigh, num_neigh, neighbors );
+     542       58028 :   std::vector<double> der( args.size() ), gpoint( args.size() );
+     543      129700 :   unsigned hforce_start = 0; for(unsigned j=0; j<der.size(); ++j) hforce_start += getPntrToArgument(j)->getNumberOfStoredValues();
+     544       58028 :   if( fabs(height)>epsilon ) {
+     545       58028 :     if( getName()=="KDE" ) {
+     546       51226 :       if( kerneltype.find("bin")!=std::string::npos ) {
+     547       29000 :         std::vector<HistogramBead> bead( args.size() ); setupHistogramBeads( bead );
+     548      145000 :         for(unsigned i=0; i<num_neigh; ++i) {
+     549      116000 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     550      116000 :           double val = evaluateBeadValue( bead, gpoint, args, height, der ); double fforce = getConstPntrToComponent(0)->getForce( neighbors[i] );
+     551      116000 :           if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) forces[ hforce_start ] += val*fforce / height;
+     552      116000 :           else if( hasheight ) forces[ hforce_start + getPntrToArgument(args.size())->getIndexInStore(itask) ] += val*fforce / height;
+     553      232000 :           unsigned n=0; for(unsigned j=0; j<der.size(); ++j) { forces[n + getPntrToArgument(j)->getIndexInStore(itask)] += der[j]*fforce; n += getPntrToArgument(j)->getNumberOfStoredValues(); }
+     554             :         }
+     555             :       } else {
+     556      202954 :         for(unsigned i=0; i<num_neigh; ++i) {
+     557      180728 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     558      180728 :           double val = evaluateKernel( gpoint, args, height, der ), fforce = getConstPntrToComponent(0)->getForce( neighbors[i] );
+     559      180728 :           if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) forces[ hforce_start ] += val*fforce / height;
+     560      179910 :           else if( hasheight ) forces[ hforce_start + getPntrToArgument(args.size())->getIndexInStore(itask) ] += val*fforce / height;
+     561      364382 :           unsigned n=0; for(unsigned j=0; j<der.size(); ++j) { forces[n + getPntrToArgument(j)->getIndexInStore(itask)] += -der[j]*fforce; n += getPntrToArgument(j)->getNumberOfStoredValues(); }
+     562             :         }
+     563             :       }
+     564             :     } else {
+     565      687002 :       for(unsigned i=0; i<num_neigh; ++i) {
+     566      680200 :         gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     567     2720800 :         double dot=0; for(unsigned j=0; j<gpoint.size(); ++j) dot += args[j]*gpoint[j];
+     568      680200 :         double fforce = myval->getForce( neighbors[i] ); double newval = height*von_misses_norm*exp( von_misses_concentration*dot );
+     569      680200 :         if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) forces[ hforce_start ] += newval*fforce / height;
+     570      680200 :         else if( hasheight ) forces[ hforce_start + getPntrToArgument(args.size())->getIndexInStore(itask) ] += newval*fforce / height;
+     571     2720800 :         unsigned n=0; for(unsigned j=0; j<gpoint.size(); ++j) { forces[n + getPntrToArgument(j)->getIndexInStore(itask)] += von_misses_concentration*newval*gpoint[j]*fforce; n += getPntrToArgument(j)->getNumberOfStoredValues(); }
+     572             :       }
+     573             :     }
+     574             :   }
+     575             : }
+     576             : 
+     577             : }
+     578             : }
+
+
+
+ + + + +
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 000000000..2ba952dfd --- /dev/null +++ b/coverage/gridtools/KLEntropy.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1616100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3ce8e46f9 --- /dev/null +++ b/coverage/gridtools/KLEntropy.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1616100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..7f294e102 --- /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:1616100.0 %
Date:2024-10-17 16:45:00Functions: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           7 :   keys.setValueDescription("the value of the KL-Entropy");
+      52          21 :   keys.needsAction("REFERENCE_GRID"); keys.needsAction("CUSTOM"); keys.needsAction("INTEGRATE_GRID");
+      53           7 : }
+      54             : 
+      55           5 : KLEntropy::KLEntropy( const ActionOptions& ao):
+      56             :   Action(ao),
+      57           5 :   ActionShortcut(ao)
+      58             : {
+      59             :   // Reference grid object
+      60          15 :   std::string ref_str, val_str, input_g; parse("VALUE",val_str); parse("REFERENCE",ref_str); parse("ARG",input_g);
+      61          10 :   readInputLine( getShortcutLabel() + "_ref: REFERENCE_GRID VALUE=" + val_str + " FILE=" + ref_str );
+      62             :   // Compute KL divergence
+      63           5 :   if( input_g=="") plumed_merror("could not find ARG keyword in input to KL_ENTROPY");
+      64          10 :   readInputLine( getShortcutLabel()  + "_kl: CUSTOM ARG=" + input_g + "," + getShortcutLabel() + "_ref FUNC=y*log(y/(0.5*(x+y))) PERIODIC=NO");
+      65             :   // Compute integral
+      66          10 :   readInputLine( getShortcutLabel() + ": INTEGRATE_GRID ARG=" + getShortcutLabel() + "_kl PERIODIC=NO");
+      67           5 : }
+      68             : 
+      69             : }
+      70             : }
+
+
+
+ + + + +
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 000000000..5cbb9cdbb --- /dev/null +++ b/coverage/gridtools/MultiColvarDensity.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:445284.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..1cb92ac33 --- /dev/null +++ b/coverage/gridtools/MultiColvarDensity.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:445284.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..7f60b6c63 --- /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:445284.6 %
Date:2024-10-17 16:45:00Functions: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          10 :   keys.setValueDescription("the average value of the order parameters at each point on the grid");
+     102          30 :   keys.needsAction("DISTANCES"); keys.needsAction("KDE"); keys.needsAction("ACCUMULATE");
+     103          30 :   keys.needsAction("CUSTOM"); keys.needsAction("ONES"); keys.needsAction("CUSTOM");
+     104          10 : }
+     105             : 
+     106           8 : MultiColvarDensity::MultiColvarDensity(const ActionOptions&ao):
+     107             :   Action(ao),
+     108           8 :   ActionShortcut(ao)
+     109             : {
+     110             :   // Read in the position of the origin
+     111          16 :   std::string origin_str; parse("ORIGIN",origin_str);
+     112             :   // Read in the quantity we are calculating the density for
+     113          24 :   std::string atoms_str, data_str; parse("ATOMS",atoms_str); parse("DATA",data_str);
+     114           8 :   if( atoms_str.length()==0 && data_str.length()==0 ) error("quantity to calculate the density for was not specified used DATA/ATOMS");
+     115             :   // Get the information on the direction for the density
+     116          24 :   std::string dir, direction_string; parse("DIR",dir); std::string nbins=""; parse("NBINS",nbins); if(nbins.length()>0) nbins=" GRID_BIN=" + nbins;
+     117          16 :   if( dir=="x" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x " + nbins;
+     118           0 :   else if( dir=="y" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.y " + nbins;
+     119           0 :   else if( dir=="z" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.z " + nbins;
+     120           0 :   else if( dir=="xy" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x," + getShortcutLabel() + "_dist.y " + nbins;
+     121           0 :   else if( dir=="xz" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x," + getShortcutLabel() + "_dist.z " + nbins;
+     122           0 :   else if( dir=="yz" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.y," + getShortcutLabel() + "_dist.z " + nbins;
+     123           0 :   else if( dir=="xyz" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x," + getShortcutLabel() + "_dist.y," + getShortcutLabel() + "_dist.z " + nbins;
+     124           0 :   else error( dir + " is invalid dir specification use x/y/z/xy/xz/yz/xyz");
+     125             : 
+     126             :   // Parse the keymap for this averaging stuff
+     127          24 :   std::string stride, clear; parse("STRIDE",stride); parse("CLEAR",clear); bool unorm; parseFlag("UNORMALIZED",unorm);
+     128          14 :   if( !unorm ) { std::string normstr; parse("NORMALIZATION",normstr); if( normstr=="false" ) unorm=true; }
+     129             :   // Create distance action
+     130          16 :   bool hasheights; std::string dist_words = getShortcutLabel() + "_dist: DISTANCES COMPONENTS ORIGIN=" + origin_str;
+     131          11 :   if( atoms_str.length()>0 ) { hasheights=false; dist_words += " ATOMS=" + atoms_str; }
+     132          10 :   else { hasheights=true; dist_words += " ATOMS=" + data_str; }
+     133             :   // plumed_massert( keys.count("ORIGIN"), "you must specify the position of the origin" );
+     134           8 :   readInputLine( dist_words );
+     135             : 
+     136           8 :   std::string inputLine = convertInputLineToString();
+     137             :   // Make the kde object for the numerator if needed
+     138           8 :   if( hasheights ) {
+     139          10 :     readInputLine( getShortcutLabel() + "_inumer: KDE VOLUMES=" + data_str + " " + direction_string + " " + inputLine );
+     140           7 :     if( unorm ) { readInputLine( getShortcutLabel() + ": ACCUMULATE ARG=" + getShortcutLabel() + "_inumer STRIDE=" + stride + " CLEAR=" + clear ); return; }
+     141           6 :     else readInputLine( getShortcutLabel() + "_numer: ACCUMULATE ARG=" + getShortcutLabel() + "_inumer STRIDE=" + stride + " CLEAR=" + clear );
+     142             :   }
+     143             :   // Make the kde object
+     144          12 :   readInputLine( getShortcutLabel() + "_kde: KDE " + inputLine  + " " + direction_string );
+     145             :   // Make the division object if it is required
+     146           6 :   if( hasheights && !unorm ) {
+     147           6 :     readInputLine( getShortcutLabel() + "_denom: ACCUMULATE ARG=" + getShortcutLabel() + "_kde STRIDE=" + stride + " CLEAR=" + clear );
+     148           6 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     149           3 :   } else if( !hasheights ) {
+     150           3 :     readInputLine( getShortcutLabel() + "_weight: ONES SIZE=1" );
+     151           6 :     readInputLine( getShortcutLabel() + "_numer: ACCUMULATE ARG=" + getShortcutLabel() + "_kde STRIDE=" + stride + " CLEAR=" + clear );
+     152           6 :     readInputLine( getShortcutLabel() + "_denom: ACCUMULATE ARG=" + getShortcutLabel() + "_weight STRIDE=" + stride + " CLEAR=" + clear );
+     153           6 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     154             :   }
+     155           0 : }
+     156             : 
+     157             : }
+     158             : }
+
+
+
+ + + + +
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 000000000..3230fa7bd --- /dev/null +++ b/coverage/gridtools/PairEntropies.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3010d173a --- /dev/null +++ b/coverage/gridtools/PairEntropies.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3ca7fb9f2 --- /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:2626100.0 %
Date:2024-10-17 16:45:00Functions: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           3 :   keys.setValueDescription("the a vector containing the KL-entropy that is computed from the radial distribution function around each of the atoms in the input");
+      50           6 :   keys.needsAction("PAIRENTROPY"); keys.needsAction("INTERPOLATE_GRID");
+      51           6 :   keys.needsAction("INTEGRATE_GRID"); keys.needsAction("CUSTOM");
+      52           3 :   keys.needsAction("CONCATENATE");
+      53           3 : }
+      54             : 
+      55           1 : PairEntropies::PairEntropies(const ActionOptions&ao):
+      56             :   Action(ao),
+      57           1 :   ActionShortcut(ao)
+      58             : {
+      59             :   // Read in the atoms involved
+      60           2 :   std::string atoms_str; parse("ATOMS",atoms_str);
+      61             :   // Create the x2 value
+      62           3 :   std::string maxr, nbins, dens; parse("MAXR",maxr); parse("GRID_BIN",nbins); parse("DENSITY",dens);
+      63           2 :   std::string grid_setup = "GRID_MIN=0 GRID_MAX=" + maxr + " GRID_BIN=" + nbins;
+      64           1 :   RDF::createX2ReferenceObject( getShortcutLabel(), grid_setup, dens.length()==0, this );
+      65             :   // Create the number of input atoms
+      66           2 :   std::string pair_str = "GRID_BIN=" + nbins + " MAXR=" + maxr + " " + convertInputLineToString();
+      67           1 :   std::vector<std::string> awords=Tools::getWords(atoms_str,"\t\n ,"); Tools::interpretRanges( awords );
+      68             :   // Now create all the pairentropy objects
+      69          65 :   for(unsigned i=0; i<awords.size(); ++i) {
+      70          64 :     std::string ilab, jlab, atoms_str2; Tools::convert( awords[i], ilab );
+      71        4160 :     for(unsigned j=0; j<awords.size(); ++j) {
+      72        4096 :       if( awords[i]==awords[j] ) continue; Tools::convert( awords[j], jlab );
+      73        8000 :       if( atoms_str2.length()==0 ) atoms_str2 = jlab; else atoms_str2 += "," + jlab;
+      74             :     }
+      75         128 :     readInputLine( getShortcutLabel() + ilab + ": PAIRENTROPY GROUPA=" + ilab + " GROUPB=" + atoms_str2 + " " + pair_str + " REFERENCE=" + getShortcutLabel() );
+      76             :   }
+      77             :   // And compose a vector containing the values of all the pair entropies
+      78           1 :   std::string num, argstr = "ARG=" + getShortcutLabel() + "1";
+      79          64 :   for(unsigned i=1; i<awords.size(); ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + num; }
+      80           2 :   readInputLine( getShortcutLabel() + ": CONCATENATE " + argstr );
+      81           2 : }
+      82             : 
+      83             : }
+      84             : }
+
+
+
+ + + + +
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 000000000..ca53f8f38 --- /dev/null +++ b/coverage/gridtools/PairEntropy.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:3232100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11PairEntropyC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools11PairEntropyC1ERKNS_13ActionOptionsE65
_ZN4PLMD9gridtools11PairEntropy16registerKeywordsERNS_8KeywordsE131
+
+
+ + + +
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 000000000..1525d115d --- /dev/null +++ b/coverage/gridtools/PairEntropy.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:3232100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11PairEntropy16registerKeywordsERNS_8KeywordsE131
_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 000000000..c43e24592 --- /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:3232100.0 %
Date:2024-10-17 16:45:00Functions: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         131 : void PairEntropy::registerKeywords( Keywords& keys ) {
+      47         131 :   RDF::registerKeywords( keys ); keys.needsAction("RDF");
+      48         131 :   keys.setValueDescription("the KL-entropy that is computed from the radial distribution function");
+      49         262 :   keys.needsAction("INTERPOLATE_GRID"); keys.needsAction("INTEGRATE_GRID");
+      50         131 : }
+      51             : 
+      52          65 : PairEntropy::PairEntropy(const ActionOptions&ao):
+      53             :   Action(ao),
+      54          65 :   ActionShortcut(ao)
+      55             : {
+      56         130 :   std::string ref_str, ref_name; parse("REFERENCE",ref_name);
+      57         130 :   if( ref_name.length()>0 ) ref_str = "REFERENCE=" + ref_name; else ref_name = getShortcutLabel() + "_rdf";
+      58             :   // Read in the atoms and get the number of atoms that we are using
+      59         130 :   std::string atom_str, group_str, natoms; parse("GROUP",group_str);
+      60          65 :   if( group_str.length()>0 ) {
+      61           1 :     atom_str="GROUP=" + group_str;
+      62           1 :     std::vector<std::string> awords=Tools::getWords(group_str,"\t\n ,");
+      63           1 :     Tools::interpretRanges( awords ); Tools::convert( awords.size(), natoms );
+      64           1 :   } else {
+      65             :     std::string groupa_str, groupb_str;
+      66         128 :     parse("GROUPA",groupa_str); parse("GROUPB",groupb_str);
+      67         128 :     atom_str="GROUPA=" + groupa_str + " GROUPB=" + groupb_str;
+      68          64 :     std::vector<std::string> awords=Tools::getWords(groupb_str,"\t\n ,");
+      69          64 :     Tools::interpretRanges( awords ); Tools::convert( awords.size()+1, natoms );
+      70          64 :   }
+      71             :   // Read in all other keywords and create the RDF object
+      72         390 :   std::string maxr, nbins, dens, bw, cutoff; parse("MAXR",maxr); parse("GRID_BIN",nbins); parse("DENSITY",dens); parse("BANDWIDTH",bw); parse("CUTOFF",cutoff);
+      73          65 :   std::string dens_str; if( dens.length()>0 ) dens_str = " DENSITY=" + dens;
+      74         130 :   readInputLine( getShortcutLabel() + "_rdf: RDF " + atom_str + " CUTOFF=" + cutoff + " GRID_BIN=" + nbins + " MAXR=" + maxr + dens_str + " BANDWIDTH=" + bw + " " + ref_str);
+      75             :   // 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)
+      76         130 :   readInputLine( getShortcutLabel() + "_conv_t1: CUSTOM ARG=" + getShortcutLabel() + "_rdf," + ref_name + "_x2 FUNC=x*y*log(x) PERIODIC=NO");
+      77         130 :   readInputLine( getShortcutLabel() + "_conv_t2: CUSTOM ARG=" + getShortcutLabel() + "_rdf," + ref_name + "_x2 FUNC=(1-x)*y PERIODIC=NO");
+      78         130 :   readInputLine( getShortcutLabel() + "_conv: CUSTOM ARG=" + getShortcutLabel() + "_conv_t1," + getShortcutLabel() + "_conv_t2 FUNC=x+y PERIODIC=NO");
+      79             :   // Now integrate using trapezium rule
+      80         130 :   readInputLine( getShortcutLabel() + "_midp: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_conv INTERPOLATION_TYPE=linear MIDPOINTS"); // First interpolate onto midpoints
+      81         130 :   readInputLine( getShortcutLabel() + "_int: INTEGRATE_GRID ARG=" + getShortcutLabel() + "_midp PERIODIC=NO"); // And then integrate
+      82             :   // And multiply by final normalizing constant
+      83             :   std::string norm_str;
+      84          65 :   if( dens.length()>0 ) norm_str = " FUNC=-2*pi*x*" + dens;
+      85         130 :   else norm_str = "," + ref_name + "_vol FUNC=-(2*pi*x/y)*" + natoms;
+      86         130 :   readInputLine( getShortcutLabel() + ": CUSTOM PERIODIC=NO ARG=" + getShortcutLabel() + "_int" + norm_str );
+      87          65 : }
+      88             : 
+      89             : }
+      90             : }
+
+
+
+ + + + +
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 000000000..1651062c1 --- /dev/null +++ b/coverage/gridtools/RDF.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:646697.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3RDFC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools3RDF23createX2ReferenceObjectERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKbPNS_14ActionShortcutE3
_ZN4PLMD9gridtools3RDFC1ERKNS_13ActionOptionsE66
_ZN4PLMD9gridtools3RDF16registerKeywordsERNS_8KeywordsE267
+
+
+ + + +
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 000000000..0256b3d71 --- /dev/null +++ b/coverage/gridtools/RDF.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:646697.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3RDF16registerKeywordsERNS_8KeywordsE267
_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 000000000..c452d4db4 --- /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:646697.0 %
Date:2024-10-17 16:45:00Functions: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         267 : void RDF::registerKeywords( Keywords& keys ) {
+      47         267 :   ActionShortcut::registerKeywords( keys );
+      48         534 :   keys.add("atoms","GROUP","");
+      49         534 :   keys.add("atoms-2","GROUPA","");
+      50         534 :   keys.add("atoms-2","GROUPB","");
+      51         534 :   keys.add("compulsory","GRID_BIN","the number of bins to use when computing the RDF");
+      52         534 :   keys.add("compulsory","KERNEL","GAUSSIAN","the type of kernel to use for computing the histograms for the RDF");
+      53         534 :   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         534 :   keys.add("compulsory","MAXR","the maximum distance to use for the rdf");
+      55         534 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density esimtation");
+      56         534 :   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         534 :   keys.add("compulsory","STRIDE","1","the frequency with which to compute the rdf and accumulate averages");
+      58         534 :   keys.add("optional","DENSITY","the reference density to use when normalizing the RDF");
+      59         534 :   keys.add("hidden","REFERENCE","this is the label of the reference objects");
+      60         267 :   keys.setValueDescription("the radial distribution function");
+      61         801 :   keys.needsAction("REFERENCE_GRID"); keys.needsAction("VOLUME"); keys.needsAction("DISTANCE_MATRIX");
+      62         801 :   keys.needsAction("CUSTOM"); keys.needsAction("KDE"); keys.needsAction("ACCUMULATE");
+      63         267 :   keys.needsAction("CONSTANT");
+      64         267 : }
+      65             : 
+      66          66 : RDF::RDF(const ActionOptions&ao):
+      67             :   Action(ao),
+      68          66 :   ActionShortcut(ao)
+      69             : {
+      70             :   // Read in grid extent and number of bins
+      71         198 :   std::string maxr, nbins, dens; parse("MAXR",maxr); parse("GRID_BIN",nbins); parse("DENSITY",dens);
+      72         132 :   std::string grid_setup = "GRID_MIN=0 GRID_MAX=" + maxr + " GRID_BIN=" + nbins;
+      73             :   // Create grid with normalizing function on it
+      74         132 :   std::string refstr; parse("REFERENCE",refstr);
+      75          66 :   if( refstr.length()==0 ) {
+      76           2 :     createX2ReferenceObject( getShortcutLabel(), grid_setup, dens.length()==0, this ); refstr = getShortcutLabel();
+      77             :   }
+      78             :   // Read input to histogram
+      79         132 :   std::string cutoff, kernel, bandwidth, kernel_data; parse("KERNEL",kernel);
+      80          66 :   if( kernel=="DISCRETE" ) {
+      81             :     cutoff = maxr; kernel_data="KERNEL=DISCRETE";
+      82           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");
+      83             :   } else {
+      84         260 :     parse("BANDWIDTH",bandwidth); double rcut; parse("CUTOFF",rcut); kernel_data="KERNEL=" + kernel + " IGNORE_IF_OUT_OF_RANGE BANDWIDTH=" + bandwidth;
+      85          65 :     double bw; Tools::convert( bandwidth, bw ); double fcut; Tools::convert( maxr, fcut ); Tools::convert( fcut + sqrt(2.0*rcut)*bw, cutoff );
+      86             :   }
+      87             : 
+      88             :   // Create contact matrix
+      89         132 :   std::string natoms, str_norm_atoms, atom_str, group_str, groupa_str, groupb_str; parse("GROUP",group_str);
+      90          66 :   if( group_str.length()>0 ) {
+      91           4 :     atom_str="GROUP=" + group_str; std::vector<std::string> awords=Tools::getWords(group_str,"\t\n ,");
+      92           2 :     Tools::interpretRanges( awords ); Tools::convert( awords.size(), natoms ); str_norm_atoms = natoms;
+      93           2 :   } else {
+      94         128 :     parse("GROUPA",groupa_str); parse("GROUPB",groupb_str);
+      95          64 :     std::vector<std::string> awords=Tools::getWords(groupb_str,"\t\n ,");
+      96          64 :     Tools::interpretRanges( awords ); Tools::convert( awords.size(), natoms );
+      97         128 :     atom_str="GROUPA=" + groupa_str + " GROUPB=" + groupb_str;
+      98          64 :     std::vector<std::string> bwords=Tools::getWords(groupa_str,"\t\n ,"); Tools::interpretRanges( bwords );
+      99          64 :     Tools::convert( bwords.size()+1, str_norm_atoms );
+     100          64 :   }
+     101             :   // Retrieve the number of atoms
+     102         132 :   readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX CUTOFF=" + cutoff + " " + atom_str);
+     103             : 
+     104             :   // Calculate weights of distances
+     105         132 :   readInputLine( getShortcutLabel() + "_wmat: CUSTOM ARG=" + getShortcutLabel() + "_mat FUNC=step(" + cutoff + "-x) PERIODIC=NO");
+     106             :   // Now create a histogram from the contact matrix
+     107         132 :   unsigned clear, stride; parse("CLEAR",clear); parse("STRIDE",stride);
+     108          66 :   if( clear==1 ) {
+     109         130 :     readInputLine( getShortcutLabel() + "_kde: KDE ARG=" + getShortcutLabel() + "_mat VOLUMES=" + getShortcutLabel() + "_wmat " + grid_setup + " " + kernel_data);
+     110             :   } else {
+     111           1 :     std::string stridestr, clearstr; Tools::convert( stride, stridestr ); Tools::convert( clear, clearstr );
+     112           2 :     readInputLine( getShortcutLabel() + "_okde: KDE ARG=" + getShortcutLabel() + "_mat HEIGHTS=" + getShortcutLabel() + "_wmat " + grid_setup + " " + kernel_data);
+     113           2 :     readInputLine( getShortcutLabel() + "_kde: ACCUMULATE ARG=" + getShortcutLabel() + "_okde STRIDE=" + stridestr + " CLEAR=" + clearstr );
+     114           1 :     readInputLine( getShortcutLabel() + "_one: CONSTANT VALUE=1");
+     115           2 :     readInputLine( getShortcutLabel() + "_norm: ACCUMULATE ARG=" + getShortcutLabel() + "_one STRIDE=" + stridestr + " CLEAR=" + clearstr );
+     116             :   }
+     117             :   // Transform the histogram by normalizing factor for rdf
+     118         132 :   readInputLine( getShortcutLabel() + "_vrdf: CUSTOM ARG=" + getShortcutLabel() + "_kde," + refstr + "_x2 FUNC=x/(4*pi*y) PERIODIC=NO");
+     119             :   // And normalize by density and number of atoms (separated from above to avoid nans)
+     120         132 :   std::string func_str = "PERIODIC=NO ARG=" + getShortcutLabel() + "_vrdf";
+     121          66 :   if( dens.length()>0 ) {
+     122           0 :     if( clear==1 ) func_str += " FUNC=x/(" + dens + "*" + str_norm_atoms + ")";
+     123           0 :     else func_str += "," + getShortcutLabel() + "_norm FUNC=x/(y*" + dens + "*" + str_norm_atoms + ")";
+     124             :   } else {
+     125         131 :     if( clear==1 ) func_str += "," + refstr + "_vol FUNC=x*y/(" + natoms + "*" + str_norm_atoms + ")";
+     126           2 :     else func_str += "," + refstr + "_vol," + getShortcutLabel() + "_norm FUNC=x*y/(z*" + natoms + "*" + str_norm_atoms + ")";
+     127             :   }
+     128         132 :   readInputLine( getShortcutLabel() + ": CUSTOM " + func_str);
+     129          66 : }
+     130             : 
+     131             : }
+     132             : }
+
+
+
+ + + + +
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 000000000..5ebae1ca8 --- /dev/null +++ b/coverage/gridtools/ReadGridInSetup.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:12214981.9 %
Date:2024-10-17 16:45:00Functions: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_8KeywordsE21
_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 000000000..84c28a0f8 --- /dev/null +++ b/coverage/gridtools/ReadGridInSetup.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:12214981.9 %
Date:2024-10-17 16:45:00Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15ReadGridInSetup16registerKeywordsERNS_8KeywordsE21
_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 000000000..9666779e2 --- /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:12214981.9 %
Date:2024-10-17 16:45:00Functions: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          21 : void ReadGridInSetup::registerKeywords( Keywords& keys ) {
+      75          21 :   ActionWithGrid::registerKeywords(keys); keys.remove("SERIAL");
+      76          42 :   keys.add("optional","FUNC","the function to compute on the grid");
+      77          42 :   keys.add("compulsory","GRID_MIN","auto","the lower bounds for the grid");
+      78          42 :   keys.add("compulsory","GRID_MAX","auto","the upper bounds for the grid");
+      79          42 :   keys.add("compulsory","PERIODIC","are the grid directions periodic");
+      80          42 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+      81          42 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+      82          42 :   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          42 :   keys.add("compulsory","FILE","the name of the file that contains the reference data");
+      84          42 :   keys.add("compulsory","VALUE","the name of the value that should be read from the grid");
+      85          21 :   keys.setValueDescription("the constant function on the grid that was specified in input");
+      86          21 : }
+      87             : 
+      88          11 : ReadGridInSetup::ReadGridInSetup(const ActionOptions&ao):
+      89             :   Action(ao),
+      90          11 :   ActionWithGrid(ao)
+      91             : {
+      92          22 :   std::string func; parse("FUNC",func);
+      93          11 :   if( func.length()>0 ) {
+      94             :     // Read in stuff for grid
+      95          10 :     std::vector<std::string> gmin; parseVector("GRID_MIN",gmin);
+      96          10 :     std::vector<std::string> gmax(gmin.size()); parseVector("GRID_MAX",gmax);
+      97          10 :     std::vector<unsigned> gbin(gmin.size()); parseVector("GRID_BIN",gbin);
+      98          10 :     std::vector<std::string> pbc(gmin.size()); parseVector("PERIODIC",pbc);
+      99           5 :     std::vector<bool> ipbc( pbc.size() );
+     100          10 :     for(unsigned i=0; i<ipbc.size(); ++i) {
+     101           5 :       if( pbc[i]=="YES" ) ipbc[i]=true;
+     102           5 :       else if( pbc[i]=="NO" ) ipbc[i]=false;
+     103           0 :       else error( pbc[i] + " is not a valid instruction to the PERIODIC keyword");
+     104             :     }
+     105             : 
+     106             :     // Read in the variables
+     107          10 :     parseVector("VAR",dernames);
+     108           5 :     if(dernames.size()==0) {
+     109           3 :       dernames.resize(gmin.size());
+     110           3 :       if(gmin.size()>3)
+     111           0 :         error("Using more than 3 arguments you should explicitly write their names with VAR");
+     112           3 :       if(dernames.size()>0) dernames[0]="x";
+     113           3 :       if(dernames.size()>1) dernames[1]="y";
+     114           3 :       if(dernames.size()>2) dernames[2]="z";
+     115             :     }
+     116           5 :     if(dernames.size()!=gmin.size()) error("Size of VAR array should be the same as number of grid dimensions");
+     117             : 
+     118             :     // Create the grid and the value of the grid
+     119           5 :     createGridAndValue( "flat", ipbc, 0, gmin, gmax, gbin );
+     120             : 
+     121             :     // Read in stuff for function
+     122           5 :     log.printf("  evaluating function : %s\n",func.c_str());
+     123           5 :     log.printf("  with variables :");
+     124          10 :     for(unsigned i=0; i<dernames.size(); i++) log.printf(" %s",dernames[i].c_str());
+     125           5 :     log.printf("\n");
+     126           5 :     log.printf("  on %d", gbin[0]);
+     127           5 :     for(unsigned i=1; i<gbin.size(); ++i) log.printf(" by %d \n", gbin[i]);
+     128           5 :     log.printf(" grid of points between (%s", gmin[0].c_str() );
+     129           5 :     for(unsigned i=1; i<gmin.size(); ++i) log.printf(", %s", gmin[i].c_str() );
+     130           5 :     log.printf(") and (%s", gmax[0].c_str() );
+     131           5 :     for(unsigned i=1; i<gmax.size(); ++i) log.printf(", %s", gmax[i].c_str() );
+     132           5 :     log.printf(")\n");
+     133             : 
+     134           5 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(leptonConstants);
+     135           5 :     log<<"  function as parsed by lepton: "<<pe<<"\n";
+     136           5 :     lepton::CompiledExpression expression=pe.createCompiledExpression();
+     137          10 :     for(auto &p: expression.getVariables()) {
+     138           5 :       if(std::find(dernames.begin(),dernames.end(),p)==dernames.end()) {
+     139           0 :         error("variable " + p + " is not defined");
+     140             :       }
+     141             :     }
+     142           5 :     log<<"  derivatives as computed by lepton:\n";
+     143           5 :     std::vector<lepton::CompiledExpression> expression_deriv( dernames.size() );
+     144          10 :     for(unsigned i=0; i<dernames.size(); i++) {
+     145          10 :       lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(dernames[i]).optimize(leptonConstants);
+     146           5 :       log<<"    "<<pe<<"\n";
+     147           5 :       expression_deriv[i]=pe.createCompiledExpression();
+     148             :     }
+     149             :     // And finally calculate all the grid points
+     150           5 :     std::vector<double> dder( dernames.size() ), xx( dernames.size() ); Value* valout=getPntrToComponent(0);
+     151         115 :     for(unsigned index=0; index<valout->getNumberOfValues(); ++index) {
+     152         110 :       gridobject.getGridPointCoordinates( index, xx );
+     153         220 :       for(unsigned j=0; j<xx.size(); ++j) {
+     154             :         try {
+     155         110 :           expression.getVariableReference(dernames[j])=xx[j];
+     156           0 :         } catch(PLMD::lepton::Exception& exc) {
+     157             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     158             : // e.g. func=0*x
+     159           0 :         }
+     160             :       }
+     161         110 :       valout->set( index, expression.evaluate() );
+     162         220 :       for(unsigned k=0; k<xx.size(); ++k) {
+     163         220 :         for(unsigned j=0; j<xx.size(); ++j) {
+     164             :           try {
+     165         110 :             expression_deriv[k].getVariableReference(dernames[j])=xx[j];
+     166           0 :           } catch(PLMD::lepton::Exception& exc) {
+     167             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     168             : // e.g. func=0*x
+     169           0 :           }
+     170             :         }
+     171         110 :         valout->addGridDerivatives( index, k, expression_deriv[k].evaluate() );
+     172             :       }
+     173             :     }
+     174          15 :   } else {
+     175          12 :     std::string valuestr; parse("VALUE",valuestr);
+     176          12 :     std::string tstyle, filen; parse("FILE",filen);
+     177           6 :     if( filen.length()>0 ) {
+     178           6 :       std::size_t dot=filen.find_first_of(".");
+     179          12 :       if( dot!=std::string::npos ) tstyle=filen.substr(dot+1);
+     180           6 :       if( tstyle!="grid" ) error("can only read in grids using read value in setup");
+     181           6 :       log.printf("  reading function %s on grid from file %s \n", valuestr.c_str(), filen.c_str() );
+     182             :     }
+     183           6 :     IFile ifile; ifile.open(filen);
+     184           6 :     if( !ifile.FieldExist( valuestr ) ) error("could not find grid value in input file");
+     185           6 :     std::vector<std::string> fieldnames; ifile.scanFieldList( fieldnames );
+     186             : 
+     187             :     // Retrieve the names of the variables the grid is computed over
+     188             :     bool flatgrid=false;
+     189          54 :     for(unsigned i=0; i<fieldnames.size(); ++i) {
+     190          48 :       if( fieldnames[i].find("min_")!=std::string::npos ) flatgrid=true;
+     191          96 :       std::size_t dot = fieldnames[i].find_first_of("d" + valuestr + "_" );
+     192         114 :       if( fieldnames[i].find("d" + valuestr + "_")!=std::string::npos ) dernames.push_back( fieldnames[i].substr(dot+2+valuestr.length()) );
+     193             :     }
+     194           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 + "_");
+     195             :     // Now get all the header data for the grid
+     196           6 :     std::vector<std::string> gmin( dernames.size() ), gmax( dernames.size() ); std::string pstring;
+     197           6 :     int gbin1; std::vector<unsigned> gbin( dernames.size() ); std::vector<bool> ipbc( dernames.size() );
+     198           6 :     if( !flatgrid ) {
+     199          12 :       ifile.scanField( "nbins", gbin1); gbin[0]=gbin1;
+     200          12 :       createGridAndValue( "fibonacci", ipbc, gbin[0], gmin, gmax, gbin );
+     201             :     } else {
+     202           0 :       for(unsigned i=0; i<dernames.size(); ++i) {
+     203           0 :         ifile.scanField( "min_" + dernames[i], gmin[i]);
+     204           0 :         ifile.scanField( "max_" + dernames[i], gmax[i]);
+     205           0 :         ifile.scanField( "periodic_" + dernames[i], pstring );
+     206           0 :         ifile.scanField( "nbins_" + dernames[i], gbin1); gbin[i]=gbin1;
+     207           0 :         if( pstring=="true" ) {
+     208           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]);
+     209             :           ipbc[i]=true;
+     210           0 :         } else if( pstring=="false" ) {
+     211           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]);
+     212             :           ipbc[i]=false;
+     213           0 :         } else error("do not understand periodidicy of " + dernames[i] );
+     214             : 
+     215           0 :         bool hasder=ifile.FieldExist( "d" + valuestr + "_" + dernames[i] );
+     216           0 :         if( !hasder ) plumed_merror("missing derivatives from grid file");
+     217             :       }
+     218           0 :       createGridAndValue( "flat", ipbc, 0, gmin, gmax, gbin );
+     219             :     }
+     220             :     // And finally read all the grid points
+     221           6 :     Value* valout=getPntrToComponent(0);
+     222           6 :     std::vector<double> dder( dernames.size() ), xx( dernames.size() );
+     223        2106 :     for(unsigned i=0; i<valout->getNumberOfValues(); ++i) {
+     224        2100 :       double x, val; ifile.scanField( valuestr, val );
+     225        8400 :       for(unsigned j=0; j<dernames.size(); ++j) {
+     226        6300 :         ifile.scanField(dernames[j],x);
+     227        6300 :         if( !flatgrid ) {
+     228       12600 :           ifile.scanField("nbins", gbin1);
+     229             :         } else {
+     230           0 :           xx[j]=x+gridobject.getGridSpacing()[j]/2.0;
+     231           0 :           ifile.scanField( "min_" + dernames[j], gmin[j]);
+     232           0 :           ifile.scanField( "max_" + dernames[j], gmax[j]);
+     233           0 :           ifile.scanField( "nbins_" + dernames[j], gbin1);
+     234           0 :           ifile.scanField( "periodic_" + dernames[j], pstring );
+     235             :         }
+     236             :       }
+     237        8400 :       for(unsigned j=0; j<dernames.size(); ++j) ifile.scanField( "d" + valuestr + "_" + dernames[j], dder[j] );
+     238             : 
+     239        2100 :       unsigned index=gridobject.getIndex(xx); if( !flatgrid ) index=i;
+     240        2100 :       valout->set( index, val );
+     241        8400 :       for(unsigned j=0; j<dernames.size(); ++j) valout->addGridDerivatives( index, j, dder[j] );
+     242        2100 :       ifile.scanField();
+     243             :     }
+     244           6 :     ifile.close();
+     245           6 :   }
+     246          11 : }
+     247             : 
+     248          11 : void ReadGridInSetup::createGridAndValue( const std::string& gtype, const std::vector<bool>& ipbc, const unsigned& nfermi,
+     249             :     const std::vector<std::string>& gmin, const std::vector<std::string>& gmax,
+     250             :     const std::vector<unsigned>& gbin ) {
+     251          11 :   gridobject.setup( gtype, ipbc, nfermi, 0.0 ); std::vector<double> gspacing;
+     252          11 :   if( gtype=="flat" ) {
+     253           5 :     gridobject.setBounds( gmin, gmax, gbin, gspacing );
+     254             :     // Now create the value
+     255           5 :     std::vector<unsigned> shape( gridobject.getNbin(true) );
+     256           5 :     ActionWithValue::addValueWithDerivatives( shape ); setNotPeriodic();
+     257             :   } else {
+     258           6 :     std::vector<unsigned> shape( 3 ); shape[0]=gbin[0]; shape[1]=shape[2]=1;
+     259           6 :     ActionWithValue::addValueWithDerivatives( shape ); setNotPeriodic();
+     260             :   }
+     261          22 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     262          11 :     getPntrToComponent(i)->setConstant();
+     263          11 :     getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+     264             :   }
+     265             :   // This ensures we set the flag to never active the action.  We can say we have atoms here as we don't need them
+     266             :   // to calculate the CV
+     267          11 :   setupConstantValues( true );
+     268          11 : }
+     269             : 
+     270          34 : unsigned ReadGridInSetup::getNumberOfDerivatives() {
+     271          34 :   return dernames.size();
+     272             : }
+     273             : 
+     274           3 : std::vector<std::string> ReadGridInSetup::getGridCoordinateNames() const {
+     275           3 :   return dernames;
+     276             : }
+     277             : 
+     278          12 : const GridCoordinatesObject& ReadGridInSetup::getGridCoordinatesObject() const {
+     279          12 :   return gridobject;
+     280             : }
+     281             : 
+     282             : }
+     283             : }
+     284             : 
+
+
+
+ + + + +
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 000000000..bd31b6431 --- /dev/null +++ b/coverage/gridtools/index-sort-f.html @@ -0,0 +1,313 @@ + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1447158391.4 %
Date:2024-10-17 16:45:00Functions:11614281.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
KLEntropy.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
EvaluateFunctionOnGrid.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
Gradient.cpp +
100.0%
+
100.0 %48 / 4866.7 %2 / 3
Histogram.cpp +
100.0%
+
100.0 %43 / 4366.7 %2 / 3
PairEntropy.cpp +
100.0%
+
100.0 %32 / 3266.7 %2 / 3
PairEntropies.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
ConvertToFES.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
MultiColvarDensity.cpp +
84.6%84.6%
+
84.6 %44 / 5266.7 %2 / 3
ReadGridInSetup.cpp +
81.9%81.9%
+
81.9 %122 / 14966.7 %6 / 9
RDF.cpp +
97.0%97.0%
+
97.0 %64 / 6675.0 %3 / 4
ActionWithGrid.cpp +
100.0%
+
100.0 %17 / 1780.0 %4 / 5
FunctionOfGrid.h +
98.1%98.1%
+
98.1 %101 / 10380.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.5%86.5%
+
86.5 %294 / 34094.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.2%88.2%
+
88.2 %90 / 102100.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 000000000..cb2686a0a --- /dev/null +++ b/coverage/gridtools/index-sort-l.html @@ -0,0 +1,313 @@ + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1447158391.4 %
Date:2024-10-17 16:45:00Functions:11614281.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.9%81.9%
+
81.9 %122 / 14966.7 %6 / 9
FindGridOptimum.cpp +
83.6%83.6%
+
83.6 %46 / 5560.0 %6 / 10
MultiColvarDensity.cpp +
84.6%84.6%
+
84.6 %44 / 5266.7 %2 / 3
EvaluateGridFunction.h +
85.7%85.7%
+
85.7 %6 / 70.0 %0 / 1
KDE.cpp +
86.5%86.5%
+
86.5 %294 / 34094.7 %18 / 19
EvaluateGridFunction.cpp +
88.2%88.2%
+
88.2 %90 / 102100.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 +
97.0%97.0%
+
97.0 %64 / 6675.0 %3 / 4
FunctionOfGrid.h +
98.1%98.1%
+
98.1 %101 / 10380.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 %16 / 1666.7 %2 / 3
ActionWithGrid.cpp +
100.0%
+
100.0 %17 / 1780.0 %4 / 5
ConvertToFES.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
EvaluateFunctionOnGrid.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
PairEntropies.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
PairEntropy.cpp +
100.0%
+
100.0 %32 / 3266.7 %2 / 3
Interpolator.cpp +
100.0%
+
100.0 %33 / 33100.0 %1 / 1
Histogram.cpp +
100.0%
+
100.0 %43 / 4366.7 %2 / 3
Gradient.cpp +
100.0%
+
100.0 %48 / 4866.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 000000000..cc1e92b38 --- /dev/null +++ b/coverage/gridtools/index.html @@ -0,0 +1,313 @@ + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1447158391.4 %
Date:2024-10-17 16:45:00Functions:11614281.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 %22 / 2266.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.2%88.2%
+
88.2 %90 / 102100.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 +
98.1%98.1%
+
98.1 %101 / 10380.0 %16 / 20
Gradient.cpp +
100.0%
+
100.0 %48 / 4866.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
Histogram.cpp +
100.0%
+
100.0 %43 / 4366.7 %2 / 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.5%86.5%
+
86.5 %294 / 34094.7 %18 / 19
KLEntropy.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
MultiColvarDensity.cpp +
84.6%84.6%
+
84.6 %44 / 5266.7 %2 / 3
PairEntropies.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
PairEntropy.cpp +
100.0%
+
100.0 %32 / 3266.7 %2 / 3
RDF.cpp +
97.0%97.0%
+
97.0 %64 / 6675.0 %3 / 4
ReadGridInSetup.cpp +
81.9%81.9%
+
81.9 %122 / 14966.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 000000000..9d3821c43 --- /dev/null +++ b/coverage/index-sort-f.html @@ -0,0 +1,583 @@ + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:532216342983.9 %
Date:2024-10-17 16:45:00Functions:5842744678.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
metatensor +
4.6%4.6%
+
4.6 %16 / 3452.9 %1 / 34
config +
45.9%45.9%
+
45.9 %67 / 14646.2 %24 / 52
wrapper +
48.4%48.4%
+
48.4 %267 / 55251.0 %147 / 288
wham +
97.1%97.1%
+
97.1 %102 / 10558.3 %7 / 12
piv +
71.8%71.8%
+
71.8 %428 / 59660.0 %3 / 5
landmarks +
97.3%97.3%
+
97.3 %182 / 18761.1 %11 / 18
multicolvar +
85.4%85.4%
+
85.4 %510 / 59763.3 %31 / 49
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
sprint +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
fourier +
87.0%87.0%
+
87.0 %87 / 10066.7 %6 / 9
isdb +
74.9%74.9%
+
74.9 %9086 / 1213069.4 %163 / 235
pamm +
92.3%92.3%
+
92.3 %144 / 15670.0 %7 / 10
clusters +
98.3%98.3%
+
98.3 %232 / 23672.1 %31 / 43
small_vector +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
volumes +
62.9%62.9%
+
62.9 %480 / 76372.3 %47 / 65
tools +
80.6%80.6%
+
80.6 %5734 / 711173.5 %1154 / 1571
generic +
95.2%95.2%
+
95.2 %1899 / 199573.8 %180 / 244
envsim +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
s2cm +
91.6%91.6%
+
91.6 %152 / 16675.0 %6 / 8
membranefusion +
88.2%88.2%
+
88.2 %456 / 51775.0 %9 / 12
vatom +
94.8%94.8%
+
94.8 %366 / 38676.2 %16 / 21
matrixtools +
90.1%90.1%
+
90.1 %457 / 50777.0 %57 / 74
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
adjmat +
96.5%96.5%
+
96.5 %695 / 72077.8 %49 / 63
contour +
93.6%93.6%
+
93.6 %421 / 45077.8 %49 / 63
crystdistrib +
92.0%92.0%
+
92.0 %518 / 56378.1 %25 / 32
refdist +
91.5%91.5%
+
91.5 %314 / 34378.6 %22 / 28
colvar +
91.7%91.7%
+
91.7 %2722 / 296878.5 %216 / 275
dimred +
98.1%98.1%
+
98.1 %505 / 51578.9 %30 / 38
bias +
91.5%91.5%
+
91.5 %2446 / 267279.5 %97 / 122
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
secondarystructure +
97.1%97.1%
+
97.1 %472 / 48680.0 %16 / 20
maze +
85.1%85.1%
+
85.1 %653 / 76780.2 %65 / 81
function +
88.9%88.9%
+
88.9 %1535 / 172680.5 %424 / 527
cltools +
72.0%72.0%
+
72.0 %1697 / 235680.5 %128 / 159
sasa +
82.0%82.0%
+
82.0 %999 / 121880.8 %21 / 26
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
symfunc +
91.2%91.2%
+
91.2 %786 / 86281.0 %51 / 63
gridtools +
91.4%91.4%
+
91.4 %1447 / 158381.7 %116 / 142
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
mapping +
96.7%96.7%
+
96.7 %792 / 81983.9 %47 / 56
sizeshape +
96.7%96.7%
+
96.7 %295 / 30584.2 %16 / 19
eds +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
valtools +
94.7%94.7%
+
94.7 %304 / 32185.3 %29 / 34
opes +
96.1%96.1%
+
96.1 %2142 / 223091.5 %108 / 118
logmfd +
87.8%87.8%
+
87.8 %325 / 37092.3 %12 / 13
core +
89.7%89.7%
+
89.7 %4775 / 532693.3 %1791 / 1920
drr +
94.5%94.5%
+
94.5 %1200 / 127094.7 %89 / 94
main +
83.3%83.3%
+
83.3 %15 / 18100.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 000000000..76c87b982 --- /dev/null +++ b/coverage/index-sort-l.html @@ -0,0 +1,583 @@ + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:532216342983.9 %
Date:2024-10-17 16:45:00Functions:5842744678.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
metatensor +
4.6%4.6%
+
4.6 %16 / 3452.9 %1 / 34
config +
45.9%45.9%
+
45.9 %67 / 14646.2 %24 / 52
wrapper +
48.4%48.4%
+
48.4 %267 / 55251.0 %147 / 288
volumes +
62.9%62.9%
+
62.9 %480 / 76372.3 %47 / 65
piv +
71.8%71.8%
+
71.8 %428 / 59660.0 %3 / 5
cltools +
72.0%72.0%
+
72.0 %1697 / 235680.5 %128 / 159
isdb +
74.9%74.9%
+
74.9 %9086 / 1213069.4 %163 / 235
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
tools +
80.6%80.6%
+
80.6 %5734 / 711173.5 %1154 / 1571
sasa +
82.0%82.0%
+
82.0 %999 / 121880.8 %21 / 26
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
main +
83.3%83.3%
+
83.3 %15 / 18100.0 %1 / 1
maze +
85.1%85.1%
+
85.1 %653 / 76780.2 %65 / 81
multicolvar +
85.4%85.4%
+
85.4 %510 / 59763.3 %31 / 49
small_vector +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
fourier +
87.0%87.0%
+
87.0 %87 / 10066.7 %6 / 9
logmfd +
87.8%87.8%
+
87.8 %325 / 37092.3 %12 / 13
membranefusion +
88.2%88.2%
+
88.2 %456 / 51775.0 %9 / 12
function +
88.9%88.9%
+
88.9 %1535 / 172680.5 %424 / 527
core +
89.7%89.7%
+
89.7 %4775 / 532693.3 %1791 / 1920
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
matrixtools +
90.1%90.1%
+
90.1 %457 / 50777.0 %57 / 74
symfunc +
91.2%91.2%
+
91.2 %786 / 86281.0 %51 / 63
gridtools +
91.4%91.4%
+
91.4 %1447 / 158381.7 %116 / 142
s2cm +
91.6%91.6%
+
91.6 %152 / 16675.0 %6 / 8
refdist +
91.5%91.5%
+
91.5 %314 / 34378.6 %22 / 28
bias +
91.5%91.5%
+
91.5 %2446 / 267279.5 %97 / 122
colvar +
91.7%91.7%
+
91.7 %2722 / 296878.5 %216 / 275
crystdistrib +
92.0%92.0%
+
92.0 %518 / 56378.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
contour +
93.6%93.6%
+
93.6 %421 / 45077.8 %49 / 63
drr +
94.5%94.5%
+
94.5 %1200 / 127094.7 %89 / 94
valtools +
94.7%94.7%
+
94.7 %304 / 32185.3 %29 / 34
envsim +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
vatom +
94.8%94.8%
+
94.8 %366 / 38676.2 %16 / 21
generic +
95.2%95.2%
+
95.2 %1899 / 199573.8 %180 / 244
opes +
96.1%96.1%
+
96.1 %2142 / 223091.5 %108 / 118
adjmat +
96.5%96.5%
+
96.5 %695 / 72077.8 %49 / 63
sizeshape +
96.7%96.7%
+
96.7 %295 / 30584.2 %16 / 19
mapping +
96.7%96.7%
+
96.7 %792 / 81983.9 %47 / 56
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
wham +
97.1%97.1%
+
97.1 %102 / 10558.3 %7 / 12
secondarystructure +
97.1%97.1%
+
97.1 %472 / 48680.0 %16 / 20
landmarks +
97.3%97.3%
+
97.3 %182 / 18761.1 %11 / 18
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.1%98.1%
+
98.1 %505 / 51578.9 %30 / 38
clusters +
98.3%98.3%
+
98.3 %232 / 23672.1 %31 / 43
sprint +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 000000000..14f0a72e7 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,583 @@ + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:532216342983.9 %
Date:2024-10-17 16:45:00Functions:5842744678.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
adjmat +
96.5%96.5%
+
96.5 %695 / 72077.8 %49 / 63
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
bias +
91.5%91.5%
+
91.5 %2446 / 267279.5 %97 / 122
cltools +
72.0%72.0%
+
72.0 %1697 / 235680.5 %128 / 159
clusters +
98.3%98.3%
+
98.3 %232 / 23672.1 %31 / 43
colvar +
91.7%91.7%
+
91.7 %2722 / 296878.5 %216 / 275
config +
45.9%45.9%
+
45.9 %67 / 14646.2 %24 / 52
contour +
93.6%93.6%
+
93.6 %421 / 45077.8 %49 / 63
core +
89.7%89.7%
+
89.7 %4775 / 532693.3 %1791 / 1920
crystdistrib +
92.0%92.0%
+
92.0 %518 / 56378.1 %25 / 32
dimred +
98.1%98.1%
+
98.1 %505 / 51578.9 %30 / 38
drr +
94.5%94.5%
+
94.5 %1200 / 127094.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 +
87.0%87.0%
+
87.0 %87 / 10066.7 %6 / 9
function +
88.9%88.9%
+
88.9 %1535 / 172680.5 %424 / 527
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
generic +
95.2%95.2%
+
95.2 %1899 / 199573.8 %180 / 244
gridtools +
91.4%91.4%
+
91.4 %1447 / 158381.7 %116 / 142
isdb +
74.9%74.9%
+
74.9 %9086 / 1213069.4 %163 / 235
landmarks +
97.3%97.3%
+
97.3 %182 / 18761.1 %11 / 18
logmfd +
87.8%87.8%
+
87.8 %325 / 37092.3 %12 / 13
main +
83.3%83.3%
+
83.3 %15 / 18100.0 %1 / 1
mapping +
96.7%96.7%
+
96.7 %792 / 81983.9 %47 / 56
matrixtools +
90.1%90.1%
+
90.1 %457 / 50777.0 %57 / 74
maze +
85.1%85.1%
+
85.1 %653 / 76780.2 %65 / 81
membranefusion +
88.2%88.2%
+
88.2 %456 / 51775.0 %9 / 12
metatensor +
4.6%4.6%
+
4.6 %16 / 3452.9 %1 / 34
multicolvar +
85.4%85.4%
+
85.4 %510 / 59763.3 %31 / 49
opes +
96.1%96.1%
+
96.1 %2142 / 223091.5 %108 / 118
pamm +
92.3%92.3%
+
92.3 %144 / 15670.0 %7 / 10
piv +
71.8%71.8%
+
71.8 %428 / 59660.0 %3 / 5
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
refdist +
91.5%91.5%
+
91.5 %314 / 34378.6 %22 / 28
s2cm +
91.6%91.6%
+
91.6 %152 / 16675.0 %6 / 8
sasa +
82.0%82.0%
+
82.0 %999 / 121880.8 %21 / 26
secondarystructure +
97.1%97.1%
+
97.1 %472 / 48680.0 %16 / 20
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
sizeshape +
96.7%96.7%
+
96.7 %295 / 30584.2 %16 / 19
small_vector +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
sprint +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
symfunc +
91.2%91.2%
+
91.2 %786 / 86281.0 %51 / 63
tools +
80.6%80.6%
+
80.6 %5734 / 711173.5 %1154 / 1571
valtools +
94.7%94.7%
+
94.7 %304 / 32185.3 %29 / 34
vatom +
94.8%94.8%
+
94.8 %366 / 38676.2 %16 / 21
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
volumes +
62.9%62.9%
+
62.9 %480 / 76372.3 %47 / 65
wham +
97.1%97.1%
+
97.1 %102 / 10558.3 %7 / 12
wrapper +
48.4%48.4%
+
48.4 %267 / 55251.0 %147 / 288
+
+
+ + + + +
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 000000000..31c09202d --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func-sort-c.html @@ -0,0 +1,164 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8940977d6 --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func.html @@ -0,0 +1,164 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a07f75fcf --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.gcov.html @@ -0,0 +1,1920 @@ + + + + + + + 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-10-17 16:45:00Functions: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 :   MetainferenceBase::registerKeywords( keys );
+     503          40 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     504          40 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     505          40 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein.");
+     506          40 :   keys.add("compulsory","DATADIR","data/","The folder with the experimental chemical shifts.");
+     507          40 :   keys.add("compulsory","TEMPLATE","template.pdb","A PDB file of the protein system.");
+     508          40 :   keys.add("compulsory","NEIGH_FREQ","20","Period in step for neighbor list update.");
+     509          40 :   keys.addFlag("CAMSHIFT",false,"Set to TRUE if you to calculate a single CamShift score.");
+     510          40 :   keys.addFlag("NOEXP",false,"Set to TRUE if you don't want to have fixed components with the experimental values.");
+     511          40 :   keys.addOutputComponent("ha","default","the calculated Ha hydrogen chemical shifts");
+     512          40 :   keys.addOutputComponent("hn","default","the calculated H hydrogen chemical shifts");
+     513          40 :   keys.addOutputComponent("nh","default","the calculated N nitrogen chemical shifts");
+     514          40 :   keys.addOutputComponent("ca","default","the calculated Ca carbon chemical shifts");
+     515          40 :   keys.addOutputComponent("cb","default","the calculated Cb carbon chemical shifts");
+     516          40 :   keys.addOutputComponent("co","default","the calculated C' carbon chemical shifts");
+     517          40 :   keys.addOutputComponent("expha","default","the experimental Ha hydrogen chemical shifts");
+     518          40 :   keys.addOutputComponent("exphn","default","the experimental H hydrogen chemical shifts");
+     519          40 :   keys.addOutputComponent("expnh","default","the experimental N nitrogen chemical shifts");
+     520          40 :   keys.addOutputComponent("expca","default","the experimental Ca carbon chemical shifts");
+     521          40 :   keys.addOutputComponent("expcb","default","the experimental Cb carbon chemical shifts");
+     522          40 :   keys.addOutputComponent("expco","default","the experimental C' carbon chemical shifts");
+     523          20 :   keys.setValueDescription("the backbone 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 000000000..78dcd94bd --- /dev/null +++ b/coverage/isdb/Caliber.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b6fb2ef80 --- /dev/null +++ b/coverage/isdb/Caliber.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..eefe0daee --- /dev/null +++ b/coverage/isdb/Caliber.cpp.gcov.html @@ -0,0 +1,423 @@ + + + + + + + LCOV - plumed test coverage - isdb/Caliber.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Caliber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11614778.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..b121060a5 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func-sort-c.html @@ -0,0 +1,228 @@ + + + + + + + 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:58877875.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..964dd5602 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func.html @@ -0,0 +1,228 @@ + + + + + + + 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:58877875.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..d9df6ad35 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.gcov.html @@ -0,0 +1,1822 @@ + + + + + + + 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:58877875.6 %
Date:2024-10-17 16:45:00Functions: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          44 :   keys.addOutputComponent("scoreb","default","Bayesian score");
+     424          44 :   keys.addOutputComponent("acc",   "NOISETYPE","MC acceptance for uncertainty");
+     425          44 :   keys.addOutputComponent("scale", "REGRESSION","scale factor");
+     426          44 :   keys.addOutputComponent("accscale", "REGRESSION","MC acceptance for scale regression");
+     427          44 :   keys.addOutputComponent("enescale", "REGRESSION","MC energy for scale regression");
+     428          44 :   keys.addOutputComponent("anneal","ANNEAL","annealing factor");
+     429          44 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     430          44 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     431          44 :   keys.addOutputComponent("sigma",      "NOISETYPE",     "uncertainty in the forward models and experiment");
+     432          44 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     433          22 : }
+     434             : 
+     435          20 : EMMI::EMMI(const ActionOptions&ao):
+     436             :   Action(ao),
+     437             :   ActionAtomistic(ao),
+     438             :   ActionWithArguments(ao),
+     439             :   ActionWithValue(ao),
+     440          20 :   inv_sqrt2_(0.707106781186548),
+     441          20 :   sqrt2_pi_(0.797884560802865),
+     442          20 :   first_time_(true), no_aver_(false), pbc_(true),
+     443          20 :   MCstride_(1), MCaccept_(0.), MCtrials_(0.),
+     444          40 :   statusstride_(0), first_status_(true),
+     445          20 :   nregres_(0), scale_(1.),
+     446          20 :   dpcutoff_(15.0), nexp_(1000000), nanneal_(0),
+     447          40 :   kanneal_(0.), anneal_(1.), prior_(1.), ovstride_(0),
+     448          20 :   do_reweight_(false), first_time_w_(true), decay_w_(1.)
+     449             : {
+     450             :   // periodic boundary conditions
+     451          20 :   bool nopbc=!pbc_;
+     452          20 :   parseFlag("NOPBC",nopbc);
+     453          20 :   pbc_=!nopbc;
+     454             : 
+     455             :   // list of atoms
+     456             :   std::vector<AtomNumber> atoms;
+     457          40 :   parseAtomList("ATOMS", atoms);
+     458             : 
+     459             :   // file with data GMM
+     460             :   std::string GMM_file;
+     461          40 :   parse("GMM_FILE", GMM_file);
+     462             : 
+     463             :   // type of data noise
+     464             :   std::string noise;
+     465          40 :   parse("NOISETYPE",noise);
+     466          20 :   if      (noise=="GAUSS")   noise_ = 0;
+     467          12 :   else if(noise=="OUTLIERS") noise_ = 1;
+     468           6 :   else if(noise=="MARGINAL") noise_ = 2;
+     469           0 :   else error("Unknown noise type!");
+     470             : 
+     471             :   // minimum value for error
+     472             :   double sigma_min;
+     473          20 :   parse("SIGMA_MIN", sigma_min);
+     474          20 :   if(sigma_min<0) error("SIGMA_MIN should be greater or equal to zero");
+     475             : 
+     476             :   // the following parameters must be specified with noise type 0 and 1
+     477             :   double sigma_ini, dsigma;
+     478          20 :   if(noise_!=2) {
+     479             :     // initial value of the uncertainty
+     480          14 :     parse("SIGMA0", sigma_ini);
+     481          14 :     if(sigma_ini<=0) error("you must specify a positive SIGMA0");
+     482             :     // MC parameters
+     483          14 :     parse("DSIGMA", dsigma);
+     484          14 :     if(dsigma<0) error("you must specify a positive DSIGMA");
+     485          14 :     parse("MC_STRIDE", MCstride_);
+     486          14 :     if(dsigma>0 && MCstride_<=0) error("you must specify a positive MC_STRIDE");
+     487             :     // status file parameters
+     488          14 :     parse("WRITE_STRIDE", statusstride_);
+     489          14 :     if(statusstride_==0) error("you must specify a positive WRITE_STRIDE");
+     490          28 :     parse("STATUS_FILE",  statusfilename_);
+     491          28 :     if(statusfilename_=="") statusfilename_ = "MISTATUS"+getLabel();
+     492           0 :     else                    statusfilename_ = statusfilename_+getLabel();
+     493             :   }
+     494             : 
+     495             :   // error file
+     496             :   std::string errfile;
+     497          40 :   parse("ERR_FILE", errfile);
+     498             : 
+     499             :   // file with experimental overlaps
+     500             :   std::string ovfile;
+     501          20 :   parse("OV_FILE", ovfile);
+     502             : 
+     503             :   // integral of the experimetal density
+     504          20 :   double norm_d = 0.0;
+     505          20 :   parse("NORM_DENSITY", norm_d);
+     506             : 
+     507             :   // temperature
+     508          20 :   kbt_ = getkBT();
+     509             : 
+     510             :   // exponent of uncertainty prior
+     511          20 :   parse("PRIOR",prior_);
+     512             : 
+     513             :   // simulated annealing stuff
+     514          20 :   parse("ANNEAL", nanneal_);
+     515          20 :   parse("ANNEAL_FACT", kanneal_);
+     516          20 :   if(nanneal_>0 && kanneal_<=1.0) error("with ANNEAL, ANNEAL_FACT must be greater than 1");
+     517             : 
+     518             :   // regression stride
+     519          20 :   parse("REGRESSION",nregres_);
+     520             :   // other regression parameters
+     521          20 :   if(nregres_>0) {
+     522           0 :     parse("REG_SCALE_MIN",scale_min_);
+     523           0 :     parse("REG_SCALE_MAX",scale_max_);
+     524           0 :     parse("REG_DSCALE",dscale_);
+     525             :     // checks
+     526           0 :     if(scale_max_<=scale_min_) error("with REGRESSION, REG_SCALE_MAX must be greater than REG_SCALE_MIN");
+     527           0 :     if(dscale_<=0.) error("with REGRESSION, REG_DSCALE must be positive");
+     528             :   }
+     529             : 
+     530             :   // scale factor
+     531          20 :   parse("SCALE", scale_);
+     532             : 
+     533             :   // read map resolution
+     534             :   double reso;
+     535          20 :   parse("RESOLUTION", reso);
+     536          20 :   if(reso<=0.) error("RESOLUTION should be strictly positive");
+     537             : 
+     538             :   // neighbor list stuff
+     539          20 :   parse("NL_CUTOFF",nl_cutoff_);
+     540          20 :   if(nl_cutoff_<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     541          20 :   parse("NL_STRIDE",nl_stride_);
+     542          20 :   if(nl_stride_==0) error("NL_STRIDE should be explicitly specified and positive");
+     543             : 
+     544             :   // averaging or not
+     545          20 :   parseFlag("NO_AVER",no_aver_);
+     546             : 
+     547             :   // write overlap file
+     548          20 :   parse("WRITE_OV_STRIDE", ovstride_);
+     549          20 :   parse("WRITE_OV", ovfilename_);
+     550          20 :   if(ovstride_>0 && ovfilename_=="") error("With WRITE_OV_STRIDE you must specify WRITE_OV");
+     551             : 
+     552             :   // set parallel stuff
+     553          20 :   size_=comm.Get_size();
+     554          20 :   rank_=comm.Get_rank();
+     555             : 
+     556             :   // get number of replicas
+     557          20 :   if(rank_==0) {
+     558          14 :     if(no_aver_) {
+     559          12 :       nrep_ = 1;
+     560             :     } else {
+     561           2 :       nrep_ = multi_sim_comm.Get_size();
+     562             :     }
+     563          14 :     replica_ = multi_sim_comm.Get_rank();
+     564             :   } else {
+     565           6 :     nrep_ = 0;
+     566           6 :     replica_ = 0;
+     567             :   }
+     568          20 :   comm.Sum(&nrep_,1);
+     569          20 :   comm.Sum(&replica_,1);
+     570             : 
+     571             :   // Reweighting flag
+     572          20 :   parseFlag("REWEIGHT", do_reweight_);
+     573          20 :   if(do_reweight_&&getNumberOfArguments()!=1) error("To REWEIGHT one must provide one single bias as an argument");
+     574          20 :   if(do_reweight_&&no_aver_) error("REWEIGHT cannot be used with NO_AVER");
+     575          20 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     576          20 :   if(!getRestart()) average_weights_.resize(nrep_, 1./static_cast<double>(nrep_));
+     577           0 :   else average_weights_.resize(nrep_, 0.);
+     578             : 
+     579          20 :   unsigned averaging=0;
+     580          20 :   parse("AVERAGING", averaging);
+     581          20 :   if(averaging>0) {
+     582           2 :     decay_w_ = 1./static_cast<double> (averaging);
+     583             :   }
+     584             : 
+     585          20 :   checkRead();
+     586             : 
+     587          20 :   log.printf("  atoms involved : ");
+     588       10876 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     589          20 :   log.printf("\n");
+     590          20 :   log.printf("  GMM data file : %s\n", GMM_file.c_str());
+     591          20 :   if(no_aver_) log.printf("  without ensemble averaging\n");
+     592          20 :   log.printf("  type of data noise : %s\n", noise.c_str());
+     593          20 :   log.printf("  neighbor list cutoff : %lf\n", nl_cutoff_);
+     594          20 :   log.printf("  neighbor list stride : %u\n",  nl_stride_);
+     595          20 :   log.printf("  minimum uncertainty : %f\n",sigma_min);
+     596          20 :   log.printf("  scale factor : %lf\n",scale_);
+     597          20 :   if(nregres_>0) {
+     598           0 :     log.printf("  regression stride : %u\n", nregres_);
+     599           0 :     log.printf("  regression minimum scale : %lf\n", scale_min_);
+     600           0 :     log.printf("  regression maximum scale : %lf\n", scale_max_);
+     601           0 :     log.printf("  regression maximum scale MC move : %lf\n", dscale_);
+     602             :   }
+     603          20 :   if(noise_!=2) {
+     604          14 :     log.printf("  initial value of the uncertainty : %f\n",sigma_ini);
+     605          14 :     log.printf("  max MC move in uncertainty : %f\n",dsigma);
+     606          14 :     log.printf("  MC stride : %u\n", MCstride_);
+     607          14 :     log.printf("  reading/writing to status file : %s\n",statusfilename_.c_str());
+     608          14 :     log.printf("  with stride : %u\n",statusstride_);
+     609             :   }
+     610          20 :   if(errfile.size()>0) log.printf("  reading experimental errors from file : %s\n", errfile.c_str());
+     611          20 :   if(ovfile.size()>0)  log.printf("  reading experimental overlaps from file : %s\n", ovfile.c_str());
+     612          20 :   log.printf("  temperature of the system in energy unit : %f\n",kbt_);
+     613          20 :   log.printf("  prior exponent : %f\n",prior_);
+     614          20 :   log.printf("  number of replicas for averaging: %u\n",nrep_);
+     615          20 :   log.printf("  id of the replica : %u\n",replica_);
+     616          20 :   if(nanneal_>0) {
+     617           0 :     log.printf("  length of annealing cycle : %u\n",nanneal_);
+     618           0 :     log.printf("  annealing factor : %f\n",kanneal_);
+     619             :   }
+     620          20 :   if(ovstride_>0) {
+     621           0 :     log.printf("  stride for writing model overlaps : %u\n",ovstride_);
+     622           0 :     log.printf("  file for writing model overlaps : %s\n", ovfilename_.c_str());
+     623             :   }
+     624             : 
+     625             :   // set constant quantity before calculating stuff
+     626          20 :   cfact_ = 1.0/pow( 2.0*pi, 1.5 );
+     627             : 
+     628             :   // calculate model GMM constant parameters
+     629          20 :   std::vector<double> GMM_m_w = get_GMM_m(atoms);
+     630             : 
+     631             :   // read data GMM parameters
+     632          20 :   get_GMM_d(GMM_file);
+     633          20 :   log.printf("  number of GMM components : %u\n", static_cast<unsigned>(GMM_d_m_.size()));
+     634             : 
+     635             :   // normalize atom weight map
+     636          40 :   if(norm_d <= 0.0) norm_d = accumulate(GMM_d_w_.begin(), GMM_d_w_.end(), 0.0);
+     637             :   double norm_m = accumulate(GMM_m_w.begin(),  GMM_m_w.end(),  0.0);
+     638             :   // renormalization
+     639         100 :   for(unsigned i=0; i<GMM_m_w_.size(); ++i) GMM_m_w_[i] *= norm_d / norm_m;
+     640             : 
+     641             :   // read experimental errors
+     642             :   std::vector<double> exp_err;
+     643          20 :   if(errfile.size()>0) exp_err = read_exp_errors(errfile);
+     644             : 
+     645             :   // get self overlaps between data GMM components
+     646          20 :   if(ovfile.size()>0) {
+     647           0 :     ovdd_ = read_exp_overlaps(ovfile);
+     648             :   } else {
+     649        1982 :     for(unsigned i=0; i<GMM_d_m_.size(); ++i) {
+     650        1962 :       double ov = get_self_overlap(i);
+     651        1962 :       ovdd_.push_back(ov);
+     652             :     }
+     653             :   }
+     654             : 
+     655          20 :   log.printf("  number of GMM groups : %u\n", static_cast<unsigned>(GMM_d_grps_.size()));
+     656             :   // cycle on GMM groups
+     657          40 :   for(unsigned Gid=0; Gid<GMM_d_grps_.size(); ++Gid) {
+     658          20 :     log.printf("    group %d\n", Gid);
+     659             :     // calculate median overlap and experimental error
+     660             :     std::vector<double> ovdd;
+     661             :     std::vector<double> err;
+     662             :     // cycle on the group members
+     663        1982 :     for(unsigned i=0; i<GMM_d_grps_[Gid].size(); ++i) {
+     664             :       // GMM id
+     665        1962 :       int GMMid = GMM_d_grps_[Gid][i];
+     666             :       // add to experimental error
+     667        1962 :       if(errfile.size()>0) err.push_back(exp_err[GMMid]);
+     668        1962 :       else                 err.push_back(0.);
+     669             :       // add to GMM overlap
+     670        1962 :       ovdd.push_back(ovdd_[GMMid]);
+     671             :     }
+     672             :     // calculate median quantities
+     673          20 :     double ovdd_m = get_median(ovdd);
+     674          20 :     double err_m  = get_median(err);
+     675             :     // print out statistics
+     676          20 :     log.printf("     # of members : %zu\n", GMM_d_grps_[Gid].size());
+     677          20 :     log.printf("     median overlap : %lf\n", ovdd_m);
+     678          20 :     log.printf("     median error : %lf\n", err_m);
+     679             :     // add minimum value of sigma for this group of GMMs
+     680          20 :     sigma_min_.push_back(std::sqrt(err_m*err_m+sigma_min*ovdd_m*sigma_min*ovdd_m));
+     681             :     // these are only needed with Gaussian and Outliers noise models
+     682          20 :     if(noise_!=2) {
+     683             :       // set dsigma
+     684          14 :       dsigma_.push_back(dsigma * ovdd_m);
+     685             :       // set sigma max
+     686          14 :       sigma_max_.push_back(10.0*ovdd_m + sigma_min_[Gid] + dsigma_[Gid]);
+     687             :       // initialize sigma
+     688          28 :       sigma_.push_back(std::max(sigma_min_[Gid],std::min(sigma_ini*ovdd_m,sigma_max_[Gid])));
+     689             :     }
+     690             :   }
+     691             : 
+     692             :   // read status file if restarting
+     693          20 :   if(getRestart() && noise_!=2) read_status();
+     694             : 
+     695             :   // calculate auxiliary stuff
+     696          20 :   calculate_useful_stuff(reso);
+     697             : 
+     698             :   // prepare data and derivative std::vectors
+     699          20 :   ovmd_.resize(ovdd_.size());
+     700          20 :   ovmd_ave_.resize(ovdd_.size());
+     701          20 :   atom_der_.resize(GMM_m_type_.size());
+     702          20 :   GMMid_der_.resize(ovdd_.size());
+     703             : 
+     704             :   // clear things that are no longer needed
+     705             :   GMM_d_cov_.clear();
+     706             : 
+     707             :   // add components
+     708          40 :   addComponentWithDerivatives("scoreb"); componentIsNotPeriodic("scoreb");
+     709             : 
+     710          48 :   if(noise_!=2) {addComponent("acc"); componentIsNotPeriodic("acc");}
+     711             : 
+     712          20 :   if(nregres_>0) {
+     713           0 :     addComponent("scale");     componentIsNotPeriodic("scale");
+     714           0 :     addComponent("accscale");  componentIsNotPeriodic("accscale");
+     715           0 :     addComponent("enescale");  componentIsNotPeriodic("enescale");
+     716             :   }
+     717             : 
+     718          20 :   if(nanneal_>0) {addComponent("anneal"); componentIsNotPeriodic("anneal");}
+     719             : 
+     720          20 :   if(do_reweight_) {
+     721           4 :     addComponent("biasDer");
+     722           4 :     componentIsNotPeriodic("biasDer");
+     723           4 :     addComponent("weight");
+     724           4 :     componentIsNotPeriodic("weight");
+     725             :   }
+     726             : 
+     727          40 :   addComponent("neff");
+     728          20 :   componentIsNotPeriodic("neff");
+     729             : 
+     730          34 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+     731          14 :     std::string num; Tools::convert(i, num);
+     732          28 :     addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     733          28 :     getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     734             :   }
+     735             : 
+     736             :   // initialize random seed
+     737             :   unsigned iseed;
+     738          20 :   if(rank_==0) iseed = time(NULL)+replica_;
+     739           6 :   else iseed = 0;
+     740          20 :   comm.Sum(&iseed, 1);
+     741          20 :   random_.setSeed(-iseed);
+     742             : 
+     743             :   // request the atoms
+     744          20 :   requestAtoms(atoms);
+     745          20 :   setDerivatives();
+     746             : 
+     747             :   // print bibliography
+     748          40 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     749          40 :   log<<plumed.cite("Hanot, Bonomi, Greenberg, Sali, Nilges, Vendruscolo, Pellarin, bioRxiv doi: 10.1101/113951 (2017)");
+     750          40 :   log<<plumed.cite("Bonomi, Pellarin, Vendruscolo, Biophys. J. 114, 1604 (2018)");
+     751          22 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     752          22 :   if(!no_aver_ && nrep_>1)log<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     753          20 :   log<<"\n";
+     754          20 : }
+     755             : 
+     756           0 : void EMMI::write_model_overlap(long long int step)
+     757             : {
+     758           0 :   OFile ovfile;
+     759           0 :   ovfile.link(*this);
+     760           0 :   std::string num; Tools::convert(step,num);
+     761           0 :   std::string name = ovfilename_+"-"+num;
+     762           0 :   ovfile.open(name);
+     763             :   ovfile.setHeavyFlush();
+     764           0 :   ovfile.fmtField("%10.7e ");
+     765             : // write overlaps
+     766           0 :   for(int i=0; i<ovmd_.size(); ++i) {
+     767           0 :     ovfile.printField("Model", ovmd_[i]);
+     768           0 :     ovfile.printField("ModelScaled", scale_ * ovmd_[i]);
+     769           0 :     ovfile.printField("Data", ovdd_[i]);
+     770           0 :     ovfile.printField();
+     771             :   }
+     772           0 :   ovfile.close();
+     773           0 : }
+     774             : 
+     775          40 : double EMMI::get_median(std::vector<double> &v)
+     776             : {
+     777             : // dimension of std::vector
+     778          40 :   unsigned size = v.size();
+     779             : // in case of only one entry
+     780          40 :   if (size==1) {
+     781           0 :     return v[0];
+     782             :   } else {
+     783             :     // reorder std::vector
+     784          40 :     sort(v.begin(), v.end());
+     785             :     // odd or even?
+     786          40 :     if (size%2==0) {
+     787           4 :       return (v[size/2-1]+v[size/2])/2.0;
+     788             :     } else {
+     789          36 :       return v[size/2];
+     790             :     }
+     791             :   }
+     792             : }
+     793             : 
+     794           0 : void EMMI::read_status()
+     795             : {
+     796             :   double MDtime;
+     797             : // open file
+     798             :   auto ifile = Tools::make_unique<IFile>();
+     799           0 :   ifile->link(*this);
+     800           0 :   if(ifile->FileExist(statusfilename_)) {
+     801           0 :     ifile->open(statusfilename_);
+     802           0 :     while(ifile->scanField("MD_time", MDtime)) {
+     803           0 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     804             :         // convert i to std::string
+     805           0 :         std::string num; Tools::convert(i,num);
+     806             :         // read entries
+     807           0 :         ifile->scanField("s"+num, sigma_[i]);
+     808             :       }
+     809             :       // new line
+     810           0 :       ifile->scanField();
+     811             :     }
+     812           0 :     ifile->close();
+     813             :   } else {
+     814           0 :     error("Cannot find status file "+statusfilename_+"\n");
+     815             :   }
+     816           0 : }
+     817             : 
+     818       10904 : void EMMI::print_status(long long int step)
+     819             : {
+     820             : // if first time open the file
+     821       10904 :   if(first_status_) {
+     822          14 :     first_status_ = false;
+     823          14 :     statusfile_.link(*this);
+     824          14 :     statusfile_.open(statusfilename_);
+     825             :     statusfile_.setHeavyFlush();
+     826          28 :     statusfile_.fmtField("%6.3e ");
+     827             :   }
+     828             : // write fields
+     829       10904 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     830       10904 :   statusfile_.printField("MD_time", MDtime);
+     831       21808 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+     832             :     // convert i to std::string
+     833       10904 :     std::string num; Tools::convert(i,num);
+     834             :     // print entry
+     835       21808 :     statusfile_.printField("s"+num, sigma_[i]);
+     836             :   }
+     837       10904 :   statusfile_.printField();
+     838       10904 : }
+     839             : 
+     840           0 : bool EMMI::doAccept(double oldE, double newE, double kbt) {
+     841             :   bool accept = false;
+     842             :   // calculate delta energy
+     843           0 :   double delta = ( newE - oldE ) / kbt;
+     844             :   // if delta is negative always accept move
+     845           0 :   if( delta < 0.0 ) {
+     846             :     accept = true;
+     847             :   } else {
+     848             :     // otherwise extract random number
+     849           0 :     double s = random_.RandU01();
+     850           0 :     if( s < std::exp(-delta) ) { accept = true; }
+     851             :   }
+     852           0 :   return accept;
+     853             : }
+     854             : 
+     855           0 : void EMMI::doMonteCarlo()
+     856             : {
+     857             :   // extract random GMM group
+     858           0 :   unsigned nGMM = static_cast<unsigned>(std::floor(random_.RandU01()*static_cast<double>(GMM_d_grps_.size())));
+     859           0 :   if(nGMM==GMM_d_grps_.size()) nGMM -= 1;
+     860             : 
+     861             :   // generate random move
+     862           0 :   double shift = dsigma_[nGMM] * ( 2.0 * random_.RandU01() - 1.0 );
+     863             :   // new sigma
+     864           0 :   double new_s = sigma_[nGMM] + shift;
+     865             :   // check boundaries
+     866           0 :   if(new_s > sigma_max_[nGMM]) {new_s = 2.0 * sigma_max_[nGMM] - new_s;}
+     867           0 :   if(new_s < sigma_min_[nGMM]) {new_s = 2.0 * sigma_min_[nGMM] - new_s;}
+     868             :   // old s2
+     869           0 :   double old_inv_s2 = 1.0 / sigma_[nGMM] / sigma_[nGMM];
+     870             :   // new s2
+     871           0 :   double new_inv_s2 = 1.0 / new_s / new_s;
+     872             : 
+     873             :   // cycle on GMM group and calculate old and new energy
+     874             :   double old_ene = 0.0;
+     875             :   double new_ene = 0.0;
+     876           0 :   double ng = static_cast<double>(GMM_d_grps_[nGMM].size());
+     877             : 
+     878             :   // in case of Gaussian noise
+     879           0 :   if(noise_==0) {
+     880             :     double chi2 = 0.0;
+     881           0 :     for(unsigned i=0; i<GMM_d_grps_[nGMM].size(); ++i) {
+     882             :       // id GMM component
+     883           0 :       int GMMid = GMM_d_grps_[nGMM][i];
+     884             :       // deviation
+     885           0 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+     886             :       // add to chi2
+     887           0 :       chi2 += dev * dev;
+     888             :     }
+     889             :     // final energy calculation: add normalization and prior
+     890           0 :     old_ene = 0.5 * kbt_ * ( chi2 * old_inv_s2 - (ng+prior_) * std::log(old_inv_s2) );
+     891           0 :     new_ene = 0.5 * kbt_ * ( chi2 * new_inv_s2 - (ng+prior_) * std::log(new_inv_s2) );
+     892             :   }
+     893             : 
+     894             :   // in case of Outliers noise
+     895           0 :   if(noise_==1) {
+     896           0 :     for(unsigned i=0; i<GMM_d_grps_[nGMM].size(); ++i) {
+     897             :       // id GMM component
+     898           0 :       int GMMid = GMM_d_grps_[nGMM][i];
+     899             :       // calculate deviation
+     900           0 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+     901             :       // add to energies
+     902           0 :       old_ene += std::log1p( 0.5 * dev * dev * old_inv_s2);
+     903           0 :       new_ene += std::log1p( 0.5 * dev * dev * new_inv_s2);
+     904             :     }
+     905             :     // final energy calculation: add normalization and prior
+     906           0 :     old_ene = kbt_ * ( old_ene + (ng+prior_) * std::log(sigma_[nGMM]) );
+     907           0 :     new_ene = kbt_ * ( new_ene + (ng+prior_) * std::log(new_s) );
+     908             :   }
+     909             : 
+     910             :   // increment number of trials
+     911           0 :   MCtrials_ += 1.0;
+     912             : 
+     913             :   // accept or reject
+     914           0 :   bool accept = doAccept(old_ene/anneal_, new_ene/anneal_, kbt_);
+     915           0 :   if(accept) {
+     916           0 :     sigma_[nGMM] = new_s;
+     917           0 :     MCaccept_ += 1.0;
+     918             :   }
+     919             :   // local communication
+     920           0 :   if(rank_!=0) {
+     921           0 :     for(unsigned i=0; i<sigma_.size(); ++i) sigma_[i] = 0.0;
+     922           0 :     MCaccept_ = 0.0;
+     923             :   }
+     924           0 :   if(size_>1) {
+     925           0 :     comm.Sum(&sigma_[0], sigma_.size());
+     926           0 :     comm.Sum(&MCaccept_, 1);
+     927             :   }
+     928             : 
+     929             :   // update sigma output
+     930           0 :   std::string num; Tools::convert(nGMM, num);
+     931           0 :   getPntrToComponent("sigma-"+num)->set(sigma_[nGMM]);
+     932           0 : }
+     933             : 
+     934           0 : std::vector<double> EMMI::read_exp_errors(const std::string & errfile)
+     935             : {
+     936             :   int nexp, idcomp;
+     937             :   double err;
+     938             :   std::vector<double> exp_err;
+     939             : // open file
+     940           0 :   IFile *ifile = new IFile();
+     941           0 :   if(ifile->FileExist(errfile)) {
+     942           0 :     ifile->open(errfile);
+     943             :     // scan for number of experimental errors
+     944           0 :     ifile->scanField("Nexp", nexp);
+     945             :     // cycle on GMM components
+     946           0 :     while(ifile->scanField("Id",idcomp)) {
+     947             :       // total experimental error
+     948           0 :       double err_tot = 0.0;
+     949             :       // cycle on number of experimental overlaps
+     950           0 :       for(unsigned i=0; i<nexp; ++i) {
+     951           0 :         std::string ss; Tools::convert(i,ss);
+     952           0 :         ifile->scanField("Err"+ss, err);
+     953             :         // add to total error
+     954           0 :         err_tot += err*err;
+     955             :       }
+     956             :       // new line
+     957           0 :       ifile->scanField();
+     958             :       // calculate RMSE
+     959           0 :       err_tot = std::sqrt(err_tot/static_cast<double>(nexp));
+     960             :       // add to global
+     961           0 :       exp_err.push_back(err_tot);
+     962             :     }
+     963           0 :     ifile->close();
+     964             :   } else {
+     965           0 :     error("Cannot find ERR_FILE "+errfile+"\n");
+     966             :   }
+     967           0 :   return exp_err;
+     968             : }
+     969             : 
+     970           0 : std::vector<double> EMMI::read_exp_overlaps(const std::string & ovfile)
+     971             : {
+     972             :   int idcomp;
+     973             :   double ov;
+     974             :   std::vector<double> ovdd;
+     975             : // open file
+     976           0 :   IFile *ifile = new IFile();
+     977           0 :   if(ifile->FileExist(ovfile)) {
+     978           0 :     ifile->open(ovfile);
+     979             :     // cycle on GMM components
+     980           0 :     while(ifile->scanField("Id",idcomp)) {
+     981             :       // read experimental overlap
+     982           0 :       ifile->scanField("Overlap", ov);
+     983             :       // add to ovdd
+     984           0 :       ovdd.push_back(ov);
+     985             :       // new line
+     986           0 :       ifile->scanField();
+     987             :     }
+     988           0 :     ifile->close();
+     989             :   } else {
+     990           0 :     error("Cannot find OV_FILE "+ovfile+"\n");
+     991             :   }
+     992           0 :   return ovdd;
+     993             : }
+     994             : 
+     995          20 : std::vector<double> EMMI::get_GMM_m(std::vector<AtomNumber> &atoms)
+     996             : {
+     997             :   // list of weights - one per atom
+     998             :   std::vector<double> GMM_m_w;
+     999             : 
+    1000          20 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    1001             :   // map of atom types to A and B coefficients of scattering factor
+    1002             :   // f(s) = A * exp(-B*s**2)
+    1003             :   // B is in Angstrom squared
+    1004             :   // map between an atom type and an index
+    1005             :   std::map<std::string, unsigned> type_map;
+    1006          20 :   type_map["C"]=0;
+    1007          20 :   type_map["O"]=1;
+    1008          20 :   type_map["N"]=2;
+    1009          20 :   type_map["S"]=3;
+    1010             :   // fill in sigma std::vector
+    1011          20 :   GMM_m_s_.push_back(0.01*15.146);  // type 0
+    1012          20 :   GMM_m_s_.push_back(0.01*8.59722); // type 1
+    1013          20 :   GMM_m_s_.push_back(0.01*11.1116); // type 2
+    1014          20 :   GMM_m_s_.push_back(0.01*15.8952); // type 3
+    1015             :   // fill in weight std::vector
+    1016          20 :   GMM_m_w_.push_back(2.49982); // type 0
+    1017          20 :   GMM_m_w_.push_back(1.97692); // type 1
+    1018          20 :   GMM_m_w_.push_back(2.20402); // type 2
+    1019          20 :   GMM_m_w_.push_back(5.14099); // type 3
+    1020             : 
+    1021             :   // check if MOLINFO line is present
+    1022          20 :   if( moldat ) {
+    1023          20 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+    1024       10876 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    1025             :       // get atom name
+    1026       10856 :       std::string name = moldat->getAtomName(atoms[i]);
+    1027             :       char type;
+    1028             :       // get atom type
+    1029       10856 :       char first = name.at(0);
+    1030             :       // GOLDEN RULE: type is first letter, if not a number
+    1031       10856 :       if (!isdigit(first)) {
+    1032             :         type = first;
+    1033             :         // otherwise is the second
+    1034             :       } else {
+    1035           0 :         type = name.at(1);
+    1036             :       }
+    1037             :       // check if key in map
+    1038       10856 :       std::string type_s = std::string(1,type);
+    1039       10856 :       if(type_map.find(type_s) != type_map.end()) {
+    1040             :         // save atom type
+    1041       10856 :         GMM_m_type_.push_back(type_map[type_s]);
+    1042             :         // this will be normalized in the final density
+    1043       10856 :         GMM_m_w.push_back(GMM_m_w_[type_map[type_s]]);
+    1044             :       } else {
+    1045           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    1046             :       }
+    1047             :     }
+    1048             :   } else {
+    1049           0 :     error("MOLINFO DATA not found\n");
+    1050             :   }
+    1051          20 :   return GMM_m_w;
+    1052             : }
+    1053             : 
+    1054        1962 : void EMMI::check_GMM_d(const VectorGeneric<6> &cov, double w)
+    1055             : {
+    1056             : 
+    1057             : // check if positive defined, by calculating the 3 leading principal minors
+    1058        1962 :   double pm1 = cov[0];
+    1059        1962 :   double pm2 = cov[0]*cov[3]-cov[1]*cov[1];
+    1060        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]);
+    1061             : // apply Sylvester’s criterion
+    1062        1962 :   if(pm1<=0.0 || pm2<=0.0 || pm3<=0.0)
+    1063           0 :     error("check data GMM: covariance matrix is not positive defined");
+    1064             : 
+    1065             : // check if weight is positive
+    1066        1962 :   if(w<=0) error("check data GMM: weight must be positive");
+    1067        1962 : }
+    1068             : 
+    1069             : // read GMM data file in PLUMED format:
+    1070          20 : void EMMI::get_GMM_d(const std::string & GMM_file)
+    1071             : {
+    1072          20 :   VectorGeneric<6> cov;
+    1073             : 
+    1074             : // open file
+    1075             :   auto ifile=Tools::make_unique<IFile>();
+    1076          20 :   if(ifile->FileExist(GMM_file)) {
+    1077          20 :     ifile->open(GMM_file);
+    1078             :     int idcomp;
+    1079        3964 :     while(ifile->scanField("Id",idcomp)) {
+    1080             :       int beta;
+    1081             :       double w, m0, m1, m2;
+    1082        3924 :       ifile->scanField("Weight",w);
+    1083        3924 :       ifile->scanField("Mean_0",m0);
+    1084        3924 :       ifile->scanField("Mean_1",m1);
+    1085        3924 :       ifile->scanField("Mean_2",m2);
+    1086        3924 :       ifile->scanField("Cov_00",cov[0]);
+    1087        3924 :       ifile->scanField("Cov_01",cov[1]);
+    1088        3924 :       ifile->scanField("Cov_02",cov[2]);
+    1089        3924 :       ifile->scanField("Cov_11",cov[3]);
+    1090        3924 :       ifile->scanField("Cov_12",cov[4]);
+    1091        3924 :       ifile->scanField("Cov_22",cov[5]);
+    1092        1962 :       ifile->scanField("Beta",beta);
+    1093             :       // check input
+    1094        1962 :       check_GMM_d(cov, w);
+    1095             :       // check beta
+    1096        1962 :       if(beta<0) error("Beta must be positive!");
+    1097             :       // center of the Gaussian
+    1098        1962 :       GMM_d_m_.push_back(Vector(m0,m1,m2));
+    1099             :       // covariance matrix
+    1100        1962 :       GMM_d_cov_.push_back(cov);
+    1101             :       // weight
+    1102        1962 :       GMM_d_w_.push_back(w);
+    1103             :       // beta
+    1104        1962 :       GMM_d_beta_.push_back(beta);
+    1105             :       // new line
+    1106        1962 :       ifile->scanField();
+    1107             :     }
+    1108             :   } else {
+    1109           0 :     error("Cannot find GMM_FILE "+GMM_file+"\n");
+    1110             :   }
+    1111             :   // now create a set from beta (unique set of values)
+    1112          20 :   std::set<int> bu(GMM_d_beta_.begin(), GMM_d_beta_.end());
+    1113             :   // now prepare the group std::vector
+    1114          20 :   GMM_d_grps_.resize(bu.size());
+    1115             :   // and fill it in
+    1116        1982 :   for(unsigned i=0; i<GMM_d_beta_.size(); ++i) {
+    1117        1962 :     if(GMM_d_beta_[i]>=GMM_d_grps_.size()) error("Check Beta values");
+    1118        1962 :     GMM_d_grps_[GMM_d_beta_[i]].push_back(i);
+    1119             :   }
+    1120          20 : }
+    1121             : 
+    1122          20 : void EMMI::calculate_useful_stuff(double reso)
+    1123             : {
+    1124             :   // We use the following definition for resolution:
+    1125             :   // the Fourier transform of the density distribution in real space
+    1126             :   // f(s) falls to 1/e of its maximum value at wavenumber 1/resolution
+    1127             :   // i.e. from f(s) = A * exp(-B*s**2) -> Res = std::sqrt(B).
+    1128             :   // average value of B
+    1129             :   double Bave = 0.0;
+    1130       10876 :   for(unsigned i=0; i<GMM_m_type_.size(); ++i) {
+    1131       10856 :     Bave += GMM_m_s_[GMM_m_type_[i]];
+    1132             :   }
+    1133          20 :   Bave /= static_cast<double>(GMM_m_type_.size());
+    1134             :   // calculate blur factor
+    1135             :   double blur = 0.0;
+    1136          20 :   if(reso*reso>Bave) blur = reso*reso-Bave;
+    1137          36 :   else warning("PLUMED should not be used with maps at resolution better than 0.3 nm");
+    1138             :   // add blur to B
+    1139         100 :   for(unsigned i=0; i<GMM_m_s_.size(); ++i) GMM_m_s_[i] += blur;
+    1140             :   // calculate average resolution
+    1141             :   double ave_res = 0.0;
+    1142       10876 :   for(unsigned i=0; i<GMM_m_type_.size(); ++i) {
+    1143       10856 :     ave_res += std::sqrt(GMM_m_s_[GMM_m_type_[i]]);
+    1144             :   }
+    1145          20 :   ave_res = ave_res / static_cast<double>(GMM_m_type_.size());
+    1146          20 :   log.printf("  experimental map resolution : %3.2f\n", reso);
+    1147          20 :   log.printf("  predicted map resolution : %3.2f\n", ave_res);
+    1148          20 :   log.printf("  blur factor : %f\n", blur);
+    1149             :   // now calculate useful stuff
+    1150          20 :   VectorGeneric<6> cov, sum, inv_sum;
+    1151             :   // cycle on all atoms types (4 for the moment)
+    1152         100 :   for(unsigned i=0; i<GMM_m_s_.size(); ++i) {
+    1153             :     // the Gaussian in density (real) space is the FT of scattering factor
+    1154             :     // f(r) = A * (pi/B)**1.5 * exp(-pi**2/B*r**2)
+    1155          80 :     double s = std::sqrt ( 0.5 * GMM_m_s_[i] ) / pi;
+    1156             :     // covariance matrix for spherical Gaussian
+    1157          80 :     cov[0]=s*s; cov[1]=0.0; cov[2]=0.0;
+    1158          80 :     cov[3]=s*s; cov[4]=0.0;
+    1159          80 :     cov[5]=s*s;
+    1160             :     // cycle on all data GMM
+    1161        7928 :     for(unsigned j=0; j<GMM_d_m_.size(); ++j) {
+    1162             :       // we need the sum of the covariance matrices
+    1163       54936 :       for(unsigned k=0; k<6; ++k) sum[k] = cov[k] + GMM_d_cov_[j][k];
+    1164             :       // and to calculate its determinant
+    1165        7848 :       double det = sum[0]*(sum[3]*sum[5]-sum[4]*sum[4]);
+    1166        7848 :       det -= sum[1]*(sum[1]*sum[5]-sum[4]*sum[2]);
+    1167        7848 :       det += sum[2]*(sum[1]*sum[4]-sum[3]*sum[2]);
+    1168             :       // calculate prefactor - model weights are already normalized
+    1169        7848 :       double pre_fact =  cfact_ / std::sqrt(det) * GMM_d_w_[j] * GMM_m_w_[i];
+    1170             :       // and its inverse
+    1171        7848 :       inv_sum[0] = (sum[3]*sum[5] - sum[4]*sum[4])/det;
+    1172        7848 :       inv_sum[1] = (sum[2]*sum[4] - sum[1]*sum[5])/det;
+    1173        7848 :       inv_sum[2] = (sum[1]*sum[4] - sum[2]*sum[3])/det;
+    1174        7848 :       inv_sum[3] = (sum[0]*sum[5] - sum[2]*sum[2])/det;
+    1175        7848 :       inv_sum[4] = (sum[2]*sum[1] - sum[0]*sum[4])/det;
+    1176        7848 :       inv_sum[5] = (sum[0]*sum[3] - sum[1]*sum[1])/det;
+    1177             :       // now we store the prefactor
+    1178        7848 :       pre_fact_.push_back(pre_fact);
+    1179             :       // and the inverse of the sum
+    1180        7848 :       inv_cov_md_.push_back(inv_sum);
+    1181             :     }
+    1182             :   }
+    1183             :   // tabulate exponential
+    1184          20 :   dexp_ = dpcutoff_ / static_cast<double> (nexp_-1);
+    1185    20000020 :   for(unsigned i=0; i<nexp_; ++i) {
+    1186    20000000 :     tab_exp_.push_back(std::exp(-static_cast<double>(i) * dexp_));
+    1187             :   }
+    1188          20 : }
+    1189             : 
+    1190             : // get prefactors
+    1191     1621458 : double EMMI::get_prefactor_inverse
+    1192             : (const VectorGeneric<6> &GMM_cov_0, const VectorGeneric<6> &GMM_cov_1,
+    1193             :  double GMM_w_0, double GMM_w_1,
+    1194             :  VectorGeneric<6> &sum, VectorGeneric<6> &inv_sum)
+    1195             : {
+    1196             : // we need the sum of the covariance matrices
+    1197    11350206 :   for(unsigned k=0; k<6; ++k) sum[k] = GMM_cov_0[k] + GMM_cov_1[k];
+    1198             : 
+    1199             : // and to calculate its determinant
+    1200     1621458 :   double det = sum[0]*(sum[3]*sum[5]-sum[4]*sum[4]);
+    1201     1621458 :   det -= sum[1]*(sum[1]*sum[5]-sum[4]*sum[2]);
+    1202     1621458 :   det += sum[2]*(sum[1]*sum[4]-sum[3]*sum[2]);
+    1203             : 
+    1204             : // the prefactor is
+    1205     1621458 :   double pre_fact =  cfact_ / std::sqrt(det) * GMM_w_0 * GMM_w_1;
+    1206             : 
+    1207             : // and its inverse
+    1208     1621458 :   inv_sum[0] = (sum[3]*sum[5] - sum[4]*sum[4])/det;
+    1209     1621458 :   inv_sum[1] = (sum[2]*sum[4] - sum[1]*sum[5])/det;
+    1210     1621458 :   inv_sum[2] = (sum[1]*sum[4] - sum[2]*sum[3])/det;
+    1211     1621458 :   inv_sum[3] = (sum[0]*sum[5] - sum[2]*sum[2])/det;
+    1212     1621458 :   inv_sum[4] = (sum[2]*sum[1] - sum[0]*sum[4])/det;
+    1213     1621458 :   inv_sum[5] = (sum[0]*sum[3] - sum[1]*sum[1])/det;
+    1214             : 
+    1215             : // return pre-factor
+    1216     1621458 :   return pre_fact;
+    1217             : }
+    1218             : 
+    1219        1962 : double EMMI::get_self_overlap(unsigned id)
+    1220             : {
+    1221             :   double ov_tot = 0.0;
+    1222        1962 :   VectorGeneric<6> sum, inv_sum;
+    1223        1962 :   Vector ov_der;
+    1224             : // start loop
+    1225     1623420 :   for(unsigned i=0; i<GMM_d_m_.size(); ++i) {
+    1226             :     // call auxiliary method
+    1227     1621458 :     double pre_fact = get_prefactor_inverse(GMM_d_cov_[id], GMM_d_cov_[i],
+    1228     1621458 :                                             GMM_d_w_[id],   GMM_d_w_[i], sum, inv_sum);
+    1229             :     // add overlap to ov_tot
+    1230     1621458 :     ov_tot += get_overlap(GMM_d_m_[id], GMM_d_m_[i], pre_fact, inv_sum, ov_der);
+    1231             :   }
+    1232             : // and return it
+    1233        1962 :   return ov_tot;
+    1234             : }
+    1235             : 
+    1236             : // get overlap and derivatives
+    1237     3732816 : double EMMI::get_overlap(const Vector &m_m, const Vector &d_m, double pre_fact,
+    1238             :                          const VectorGeneric<6> &inv_cov_md, Vector &ov_der)
+    1239             : {
+    1240     3732816 :   Vector md;
+    1241             :   // calculate std::vector difference m_m-d_m with/without pbc
+    1242     3732816 :   if(pbc_) md = pbcDistance(d_m, m_m);
+    1243     3732816 :   else     md = delta(d_m, m_m);
+    1244             :   // calculate product of transpose of md and inv_cov_md
+    1245     3732816 :   double p_x = md[0]*inv_cov_md[0]+md[1]*inv_cov_md[1]+md[2]*inv_cov_md[2];
+    1246     3732816 :   double p_y = md[0]*inv_cov_md[1]+md[1]*inv_cov_md[3]+md[2]*inv_cov_md[4];
+    1247     3732816 :   double p_z = md[0]*inv_cov_md[2]+md[1]*inv_cov_md[4]+md[2]*inv_cov_md[5];
+    1248             :   // calculate product of prod and md
+    1249     3732816 :   double ov = md[0]*p_x+md[1]*p_y+md[2]*p_z;
+    1250             :   // final calculation
+    1251     3732816 :   ov = pre_fact * std::exp(-0.5*ov);
+    1252             :   // derivatives
+    1253     3732816 :   ov_der = ov * Vector(p_x, p_y, p_z);
+    1254     3732816 :   return ov;
+    1255             : }
+    1256             : 
+    1257             : // get the exponent of the overlap
+    1258    59085036 : double EMMI::get_exp_overlap(const Vector &m_m, const Vector &d_m,
+    1259             :                              const VectorGeneric<6> &inv_cov_md)
+    1260             : {
+    1261    59085036 :   Vector md;
+    1262             :   // calculate std::vector difference m_m-d_m with/without pbc
+    1263    59085036 :   if(pbc_) md = pbcDistance(d_m, m_m);
+    1264    59085036 :   else     md = delta(d_m, m_m);
+    1265             :   // calculate product of transpose of md and inv_cov_md
+    1266    59085036 :   double p_x = md[0]*inv_cov_md[0]+md[1]*inv_cov_md[1]+md[2]*inv_cov_md[2];
+    1267    59085036 :   double p_y = md[0]*inv_cov_md[1]+md[1]*inv_cov_md[3]+md[2]*inv_cov_md[4];
+    1268    59085036 :   double p_z = md[0]*inv_cov_md[2]+md[1]*inv_cov_md[4]+md[2]*inv_cov_md[5];
+    1269             :   // calculate product of prod and md
+    1270    59085036 :   double ov = md[0]*p_x+md[1]*p_y+md[2]*p_z;
+    1271    59085036 :   return ov;
+    1272             : }
+    1273             : 
+    1274       16355 : void EMMI::update_neighbor_list()
+    1275             : {
+    1276             :   // dimension of GMM and atom std::vectors
+    1277       16355 :   unsigned GMM_d_size = GMM_d_m_.size();
+    1278       16355 :   unsigned GMM_m_size = GMM_m_type_.size();
+    1279             :   // local neighbor list
+    1280             :   std::vector < unsigned > nl_l;
+    1281             :   // clear old neighbor list
+    1282       16355 :   nl_.clear();
+    1283             : 
+    1284             :   // cycle on GMM components - in parallel
+    1285      116273 :   for(unsigned id=rank_; id<GMM_d_size; id+=size_) {
+    1286             :     // overlap lists and map
+    1287             :     std::vector<double> ov_l;
+    1288             :     std::map<double, unsigned> ov_m;
+    1289             :     // total overlap with id
+    1290             :     double ov_tot = 0.0;
+    1291             :     // cycle on all atoms
+    1292    59184954 :     for(unsigned im=0; im<GMM_m_size; ++im) {
+    1293             :       // get index in auxiliary lists
+    1294    59085036 :       unsigned kaux = GMM_m_type_[im] * GMM_d_size + id;
+    1295             :       // calculate exponent of overlap
+    1296    59085036 :       double expov = get_exp_overlap(GMM_d_m_[id], getPosition(im), inv_cov_md_[kaux]);
+    1297             :       // get index of 0.5*expov in tabulated exponential
+    1298    59085036 :       unsigned itab = static_cast<unsigned> (round( 0.5*expov/dexp_ ));
+    1299             :       // check boundaries and skip atom in case
+    1300    59085036 :       if(itab >= tab_exp_.size()) continue;
+    1301             :       // in case calculate overlap
+    1302     4133388 :       double ov = pre_fact_[kaux] * tab_exp_[itab];
+    1303             :       // add to list
+    1304     4133388 :       ov_l.push_back(ov);
+    1305             :       // and map to retrieve atom index
+    1306     4133388 :       ov_m[ov] = im;
+    1307             :       // increase ov_tot
+    1308     4133388 :       ov_tot += ov;
+    1309             :     }
+    1310             :     // check if zero size -> ov_tot = 0
+    1311       99918 :     if(ov_l.size()==0) continue;
+    1312             :     // define cutoff
+    1313       99842 :     double ov_cut = ov_tot * nl_cutoff_;
+    1314             :     // sort ov_l in ascending order
+    1315       99842 :     std::sort(ov_l.begin(), ov_l.end());
+    1316             :     // integrate ov_l
+    1317             :     double res = 0.0;
+    1318     2146102 :     for(unsigned i=0; i<ov_l.size(); ++i) {
+    1319     2146102 :       res += ov_l[i];
+    1320             :       // if exceeding the cutoff for overlap, stop
+    1321     2146102 :       if(res >= ov_cut) break;
+    1322             :       else ov_m.erase(ov_l[i]);
+    1323             :     }
+    1324             :     // now add atoms to neighborlist
+    1325     2186970 :     for(std::map<double, unsigned>::iterator it=ov_m.begin(); it!=ov_m.end(); ++it)
+    1326     2087128 :       nl_l.push_back(id*GMM_m_size+it->second);
+    1327             :     // end cycle on GMM components in parallel
+    1328             :   }
+    1329             :   // find total dimension of neighborlist
+    1330       16355 :   std::vector <int> recvcounts(size_, 0);
+    1331       16355 :   recvcounts[rank_] = nl_l.size();
+    1332       16355 :   comm.Sum(&recvcounts[0], size_);
+    1333             :   int tot_size = accumulate(recvcounts.begin(), recvcounts.end(), 0);
+    1334             :   // resize neighbor stuff
+    1335       16355 :   nl_.resize(tot_size);
+    1336             :   // calculate std::vector of displacement
+    1337       16355 :   std::vector<int> disp(size_);
+    1338       16355 :   disp[0] = 0;
+    1339             :   int rank_size = 0;
+    1340       27257 :   for(unsigned i=0; i<size_-1; ++i) {
+    1341       10902 :     rank_size += recvcounts[i];
+    1342       10902 :     disp[i+1] = rank_size;
+    1343             :   }
+    1344             :   // Allgather neighbor list
+    1345       16355 :   comm.Allgatherv(&nl_l[0], recvcounts[rank_], &nl_[0], &recvcounts[0], &disp[0]);
+    1346             :   // now resize derivatives
+    1347       16355 :   ovmd_der_.resize(tot_size);
+    1348       16355 : }
+    1349             : 
+    1350          30 : void EMMI::prepare()
+    1351             : {
+    1352          30 :   if(getExchangeStep()) first_time_=true;
+    1353          30 : }
+    1354             : 
+    1355             : // overlap calculator
+    1356       16365 : void EMMI::calculate_overlap() {
+    1357             : 
+    1358       16365 :   if(first_time_ || getExchangeStep() || getStep()%nl_stride_==0) {
+    1359       16355 :     update_neighbor_list();
+    1360       16355 :     first_time_=false;
+    1361             :   }
+    1362             : 
+    1363             :   // clean temporary std::vectors
+    1364      174342 :   for(unsigned i=0; i<ovmd_.size(); ++i)     ovmd_[i] = 0.0;
+    1365     3168864 :   for(unsigned i=0; i<ovmd_der_.size(); ++i) ovmd_der_[i] = Vector(0,0,0);
+    1366             : 
+    1367             :   // we have to cycle over all model and data GMM components in the neighbor list
+    1368       16365 :   unsigned GMM_d_size = GMM_d_m_.size();
+    1369       16365 :   unsigned GMM_m_size = GMM_m_type_.size();
+    1370     2127723 :   for(unsigned i=rank_; i<nl_.size(); i=i+size_) {
+    1371             :     // get data (id) and atom (im) indexes
+    1372     2111358 :     unsigned id = nl_[i] / GMM_m_size;
+    1373     2111358 :     unsigned im = nl_[i] % GMM_m_size;
+    1374             :     // get index in auxiliary lists
+    1375     2111358 :     unsigned kaux = GMM_m_type_[im] * GMM_d_size + id;
+    1376             :     // add overlap with im component of model GMM
+    1377     2111358 :     ovmd_[id] += get_overlap(GMM_d_m_[id], getPosition(im), pre_fact_[kaux],
+    1378     2111358 :                              inv_cov_md_[kaux], ovmd_der_[i]);
+    1379             :   }
+    1380             :   // communicate stuff
+    1381       16365 :   if(size_>1) {
+    1382       10902 :     comm.Sum(&ovmd_[0], ovmd_.size());
+    1383       10902 :     comm.Sum(&ovmd_der_[0][0], 3*ovmd_der_.size());
+    1384             :   }
+    1385       16365 : }
+    1386             : 
+    1387           0 : double EMMI::scaleEnergy(double s)
+    1388             : {
+    1389             :   double ene = 0.0;
+    1390           0 :   for(unsigned i=0; i<ovdd_.size(); ++i) {
+    1391           0 :     ene += std::log( abs ( s * ovmd_ave_[i] - ovdd_[i] ) );
+    1392             :   }
+    1393           0 :   return ene;
+    1394             : }
+    1395             : 
+    1396           0 : double EMMI::doRegression()
+    1397             : {
+    1398             : // standard MC parameters
+    1399             :   unsigned MCsteps = 100000;
+    1400             :   double kbtmin = 1.0;
+    1401             :   double kbtmax = 10.0;
+    1402             :   unsigned ncold = 5000;
+    1403             :   unsigned nhot = 2000;
+    1404             :   double MCacc = 0.0;
+    1405             :   double kbt, ebest, scale_best;
+    1406             : 
+    1407             : // initial value of scale factor and energy
+    1408           0 :   double scale = random_.RandU01() * ( scale_max_ - scale_min_ ) + scale_min_;
+    1409           0 :   double ene = scaleEnergy(scale);
+    1410             : // set best energy
+    1411           0 :   ebest = ene;
+    1412             : 
+    1413             : // MC loop
+    1414           0 :   for(unsigned istep=0; istep<MCsteps; ++istep) {
+    1415             :     // get temperature
+    1416           0 :     if(istep%(ncold+nhot)<ncold) kbt = kbtmin;
+    1417             :     else kbt = kbtmax;
+    1418             :     // propose move in scale
+    1419           0 :     double ds = dscale_ * ( 2.0 * random_.RandU01() - 1.0 );
+    1420           0 :     double new_scale = scale + ds;
+    1421             :     // check boundaries
+    1422           0 :     if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+    1423           0 :     if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+    1424             :     // new energy
+    1425           0 :     double new_ene = scaleEnergy(new_scale);
+    1426             :     // accept or reject
+    1427           0 :     bool accept = doAccept(ene, new_ene, kbt);
+    1428             :     // in case of acceptance
+    1429           0 :     if(accept) {
+    1430             :       scale = new_scale;
+    1431             :       ene = new_ene;
+    1432           0 :       MCacc += 1.0;
+    1433             :     }
+    1434             :     // save best
+    1435           0 :     if(ene<ebest) {
+    1436           0 :       ebest = ene;
+    1437           0 :       scale_best = scale;
+    1438             :     }
+    1439             :   }
+    1440             : // calculate acceptance
+    1441           0 :   double accscale = MCacc / static_cast<double>(MCsteps);
+    1442             : // global communication
+    1443           0 :   if(!no_aver_ && nrep_>1) {
+    1444           0 :     if(replica_!=0) {
+    1445           0 :       scale_best = 0.0;
+    1446           0 :       ebest = 0.0;
+    1447           0 :       accscale = 0.0;
+    1448             :     }
+    1449           0 :     if(rank_==0) {
+    1450           0 :       multi_sim_comm.Sum(&scale_best, 1);
+    1451           0 :       multi_sim_comm.Sum(&ebest, 1);
+    1452           0 :       multi_sim_comm.Sum(&accscale, 1);
+    1453             :     }
+    1454             :   }
+    1455             :   // local communication
+    1456           0 :   if(rank_!=0) {
+    1457           0 :     scale_best = 0.0;
+    1458           0 :     ebest = 0.0;
+    1459           0 :     accscale = 0.0;
+    1460             :   }
+    1461           0 :   if(size_>1) {
+    1462           0 :     comm.Sum(&scale_best, 1);
+    1463           0 :     comm.Sum(&ebest, 1);
+    1464           0 :     comm.Sum(&accscale, 1);
+    1465             :   }
+    1466             : // set scale parameters
+    1467           0 :   getPntrToComponent("accscale")->set(accscale);
+    1468           0 :   getPntrToComponent("enescale")->set(ebest);
+    1469             : // return scale value
+    1470           0 :   return scale_best;
+    1471             : }
+    1472             : 
+    1473           0 : double EMMI::get_annealing(long long int step)
+    1474             : {
+    1475             : // default no annealing
+    1476             :   double fact = 1.0;
+    1477             : // position in annealing cycle
+    1478           0 :   unsigned nc = step%(4*nanneal_);
+    1479             : // useful doubles
+    1480           0 :   double ncd = static_cast<double>(nc);
+    1481           0 :   double nn  = static_cast<double>(nanneal_);
+    1482             : // set fact
+    1483           0 :   if(nc>=nanneal_   && nc<2*nanneal_) fact = (kanneal_-1.0) / nn * ( ncd - nn ) + 1.0;
+    1484           0 :   if(nc>=2*nanneal_ && nc<3*nanneal_) fact = kanneal_;
+    1485           0 :   if(nc>=3*nanneal_)                  fact = (1.0-kanneal_) / nn * ( ncd - 3.0*nn) + kanneal_;
+    1486           0 :   return fact;
+    1487             : }
+    1488             : 
+    1489       16365 : void EMMI::get_weights(double &weight, double &norm, double &neff)
+    1490             : {
+    1491       16365 :   const double dnrep = static_cast<double>(nrep_);
+    1492             :   // calculate the weights either from BIAS
+    1493       16365 :   if(do_reweight_) {
+    1494          12 :     std::vector<double> bias(nrep_,0);
+    1495          12 :     if(rank_==0) {
+    1496          12 :       bias[replica_] = getArgument(0);
+    1497          12 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1498             :     }
+    1499          12 :     comm.Sum(&bias[0], nrep_);
+    1500             : 
+    1501             :     // accumulate weights
+    1502          12 :     if(!first_time_w_) {
+    1503          30 :       for(unsigned i=0; i<nrep_; ++i) {
+    1504          20 :         const double delta=bias[i]-average_weights_[i];
+    1505             :         // FIXME: multiplying by fractional decay here causes problems with numerical derivatives,
+    1506             :         // probably because we're making several calls to calculate(), causing accumulation
+    1507             :         // of epsilons. Maybe we can work on a temporary copy of the action instead?
+    1508          20 :         average_weights_[i]+=decay_w_*delta;
+    1509             :       }
+    1510             :     } else {
+    1511           2 :       first_time_w_ = false;
+    1512           6 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[i] = bias[i];
+    1513             :     }
+    1514             : 
+    1515             :     // set average back into bias and set norm to one
+    1516          12 :     const double maxbias = *(std::max_element(average_weights_.begin(), average_weights_.end()));
+    1517          36 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[i]-maxbias)/kbt_);
+    1518             :     // set local weight, norm and weight variance
+    1519          12 :     weight = bias[replica_];
+    1520             :     double w2=0.;
+    1521          36 :     for(unsigned i=0; i<nrep_; ++i) {
+    1522          24 :       w2 += bias[i]*bias[i];
+    1523          24 :       norm += bias[i];
+    1524             :     }
+    1525          12 :     neff = norm*norm/w2;
+    1526          24 :     getPntrToComponent("weight")->set(weight/norm);
+    1527             :   } else {
+    1528             :     // or arithmetic ones
+    1529       16353 :     neff = dnrep;
+    1530       16353 :     weight = 1.0;
+    1531       16353 :     norm = dnrep;
+    1532             :   }
+    1533       16365 :   getPntrToComponent("neff")->set(neff);
+    1534       16365 : }
+    1535             : 
+    1536       16365 : void EMMI::calculate()
+    1537             : {
+    1538             : 
+    1539             : // calculate CV
+    1540       16365 :   calculate_overlap();
+    1541             : 
+    1542             :   // rescale factor for ensemble average
+    1543       16365 :   double weight = 0.;
+    1544       16365 :   double neff = 0.;
+    1545       16365 :   double norm = 0.;
+    1546       16365 :   get_weights(weight, norm, neff);
+    1547             : 
+    1548             :   // in case of ensemble averaging, calculate average overlap
+    1549       16365 :   if(!no_aver_ && nrep_>1) {
+    1550             :     // if master node, calculate average across replicas
+    1551          12 :     if(rank_==0) {
+    1552       10812 :       for(unsigned i=0; i<ovmd_.size(); ++i) ovmd_ave_[i] = weight / norm * ovmd_[i];
+    1553          12 :       multi_sim_comm.Sum(&ovmd_ave_[0], ovmd_ave_.size());
+    1554             :     } else {
+    1555           0 :       for(unsigned i=0; i<ovmd_ave_.size(); ++i) ovmd_ave_[i] = 0.0;
+    1556             :     }
+    1557             :     // local communication
+    1558          12 :     if(size_>1) comm.Sum(&ovmd_ave_[0], ovmd_ave_.size());
+    1559             :   } else {
+    1560      163530 :     for(unsigned i=0; i<ovmd_.size(); ++i) ovmd_ave_[i] = ovmd_[i];
+    1561             :   }
+    1562             : 
+    1563             :   // get time step
+    1564       16365 :   long long int step = getStep();
+    1565             : 
+    1566             :   // do regression
+    1567       16365 :   if(nregres_>0) {
+    1568           0 :     if(step%nregres_==0 && !getExchangeStep()) scale_ = doRegression();
+    1569             :     // set scale component
+    1570           0 :     getPntrToComponent("scale")->set(scale_);
+    1571             :   }
+    1572             : 
+    1573             :   // write model overlap to file
+    1574       16365 :   if(ovstride_>0 && step%ovstride_==0) write_model_overlap(step);
+    1575             : 
+    1576             :   // clear energy and virial
+    1577       16365 :   ene_ = 0.0;
+    1578       16365 :   virial_.zero();
+    1579             : 
+    1580             :   // Gaussian noise
+    1581       16365 :   if(noise_==0) calculate_Gauss();
+    1582             : 
+    1583             :   // Outliers noise
+    1584       16365 :   if(noise_==1) calculate_Outliers();
+    1585             : 
+    1586             :   // Marginal noise
+    1587       16365 :   if(noise_==2) calculate_Marginal();
+    1588             : 
+    1589             :   // get annealing rescale factor
+    1590       16365 :   if(nanneal_>0) {
+    1591           0 :     anneal_ = get_annealing(step);
+    1592           0 :     getPntrToComponent("anneal")->set(anneal_);
+    1593             :   }
+    1594             : 
+    1595             :   // annealing rescale
+    1596       16365 :   ene_ /= anneal_;
+    1597             : 
+    1598       16365 :   std::vector<double> GMMid_der_av_(GMMid_der_.size(), 0.0);
+    1599             :   // in case of ensemble averaging
+    1600       16365 :   if(!no_aver_ && nrep_>1) {
+    1601             :     // if master node, sum der_GMMid derivatives and ene
+    1602          12 :     if(rank_==0) {
+    1603       10812 :       for(unsigned i=0; i<GMMid_der_.size(); ++i) {
+    1604       10800 :         GMMid_der_av_[i] = (weight / norm) * GMMid_der_[i];
+    1605             :       }
+    1606          12 :       multi_sim_comm.Sum(&GMMid_der_av_[0], GMMid_der_av_.size());
+    1607          12 :       multi_sim_comm.Sum(&ene_, 1);
+    1608             :     } else {
+    1609             :       // set der_GMMid derivatives and energy to zero
+    1610           0 :       for(unsigned i=0; i<GMMid_der_av_.size(); ++i) GMMid_der_av_[i]=0.0;
+    1611           0 :       ene_ = 0.0;
+    1612             :     }
+    1613             :     // local communication
+    1614          12 :     if(size_>1) {
+    1615           0 :       comm.Sum(&GMMid_der_av_[0], GMMid_der_av_.size());
+    1616           0 :       comm.Sum(&ene_, 1);
+    1617             :     }
+    1618             :   } else {
+    1619      163530 :     for (unsigned i = 0; i < GMMid_der_.size(); ++i) {
+    1620      147177 :       GMMid_der_av_[i] = GMMid_der_[i];
+    1621             :     }
+    1622             :   }
+    1623             : 
+    1624             :   // clean temporary std::vector
+    1625     9860991 :   for(unsigned i=0; i<atom_der_.size(); ++i) atom_der_[i] = Vector(0,0,0);
+    1626             : 
+    1627             :   // get derivatives of bias with respect to atoms
+    1628     2127723 :   for(unsigned i=rank_; i<nl_.size(); i=i+size_) {
+    1629             :     // get indexes of data and model component
+    1630     2111358 :     unsigned id = nl_[i] / GMM_m_type_.size();
+    1631     2111358 :     unsigned im = nl_[i] % GMM_m_type_.size();
+    1632             :     // chain rule + replica normalization
+    1633     2111358 :     Vector tot_der = GMMid_der_av_[id] * ovmd_der_[i] * scale_ / anneal_;
+    1634     2111358 :     Vector pos;
+    1635     2111358 :     if(pbc_) pos = pbcDistance(GMM_d_m_[id], getPosition(im)) + GMM_d_m_[id];
+    1636     2111358 :     else     pos = getPosition(im);
+    1637             :     // increment derivatives and virial
+    1638     2111358 :     atom_der_[im] += tot_der;
+    1639     2111358 :     virial_ += Tensor(pos, -tot_der);
+    1640             :   }
+    1641             : 
+    1642             :   // communicate local derivatives and virial
+    1643       16365 :   if(size_>1) {
+    1644       10902 :     comm.Sum(&atom_der_[0][0], 3*atom_der_.size());
+    1645       10902 :     comm.Sum(virial_);
+    1646             :   }
+    1647             : 
+    1648             :   // set derivatives, virial, and score
+    1649     9860991 :   for(unsigned i=0; i<atom_der_.size(); ++i) setAtomsDerivatives(getPntrToComponent("scoreb"), i, atom_der_[i]);
+    1650       16365 :   setBoxDerivatives(getPntrToComponent("scoreb"), virial_);
+    1651       16365 :   getPntrToComponent("scoreb")->set(ene_);
+    1652             : 
+    1653       16365 :   if (do_reweight_) {
+    1654             :     double w_tmp = 0.;
+    1655       10812 :     for (unsigned i = 0; i < ovmd_.size(); ++i) {
+    1656       10800 :       w_tmp += (ovmd_[i] - ovmd_ave_[i]) * GMMid_der_[i];
+    1657             :     }
+    1658          12 :     w_tmp *= scale_ * (weight / norm) / kbt_ * decay_w_;
+    1659             : 
+    1660          12 :     setArgDerivatives(getPntrToComponent("scoreb"), w_tmp);
+    1661          24 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1662             :   }
+    1663             : 
+    1664             :   // This part is needed only for Gaussian and Outliers noise models
+    1665       16365 :   if(noise_!=2) {
+    1666             : 
+    1667             :     // do Montecarlo
+    1668       10914 :     if(dsigma_[0]>0 && step%MCstride_==0 && !getExchangeStep()) doMonteCarlo();
+    1669             : 
+    1670             :     // print status
+    1671       10914 :     if(step%statusstride_==0) print_status(step);
+    1672             : 
+    1673             :     // calculate acceptance ratio
+    1674       10914 :     double acc = MCaccept_ / MCtrials_;
+    1675             : 
+    1676             :     // set value
+    1677       21828 :     getPntrToComponent("acc")->set(acc);
+    1678             : 
+    1679             :   }
+    1680             : 
+    1681       16365 : }
+    1682             : 
+    1683        5463 : void EMMI::calculate_Gauss()
+    1684             : {
+    1685             :   // cycle on all the GMM groups
+    1686       10926 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1687             :     double eneg = 0.0;
+    1688             :     // cycle on all the members of the group
+    1689       65322 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1690             :       // id of the GMM component
+    1691       59859 :       int GMMid = GMM_d_grps_[i][j];
+    1692             :       // calculate deviation
+    1693       59859 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] ) / sigma_[i];
+    1694             :       // add to group energy
+    1695       59859 :       eneg += 0.5 * dev * dev;
+    1696             :       // store derivative for later
+    1697       59859 :       GMMid_der_[GMMid] = kbt_ * dev / sigma_[i];
+    1698             :     }
+    1699             :     // add to total energy along with normalizations and prior
+    1700        5463 :     ene_ += kbt_ * ( eneg + (static_cast<double>(GMM_d_grps_[i].size())+prior_) * std::log(sigma_[i]) );
+    1701             :   }
+    1702        5463 : }
+    1703             : 
+    1704        5451 : void EMMI::calculate_Outliers()
+    1705             : {
+    1706             :   // cycle on all the GMM groups
+    1707       10902 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1708             :     // cycle on all the members of the group
+    1709             :     double eneg = 0.0;
+    1710       54510 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1711             :       // id of the GMM component
+    1712       49059 :       int GMMid = GMM_d_grps_[i][j];
+    1713             :       // calculate deviation
+    1714       49059 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] ) / sigma_[i];
+    1715             :       // add to group energy
+    1716       49059 :       eneg += std::log1p( 0.5 * dev * dev );
+    1717             :       // store derivative for later
+    1718       49059 :       GMMid_der_[GMMid] = kbt_ / ( 1.0 + 0.5 * dev * dev ) * dev / sigma_[i];
+    1719             :     }
+    1720             :     // add to total energy along with normalizations and prior
+    1721        5451 :     ene_ += kbt_ * ( eneg + (static_cast<double>(GMM_d_grps_[i].size())+prior_) * std::log(sigma_[i]) );
+    1722             :   }
+    1723        5451 : }
+    1724             : 
+    1725        5451 : void EMMI::calculate_Marginal()
+    1726             : {
+    1727             :   // cycle on all the GMM groups
+    1728       10902 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1729             :     // cycle on all the members of the group
+    1730       54510 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1731             :       // id of the GMM component
+    1732       49059 :       int GMMid = GMM_d_grps_[i][j];
+    1733             :       // calculate deviation
+    1734       49059 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+    1735             :       // calculate errf
+    1736       49059 :       double errf = erf ( dev * inv_sqrt2_ / sigma_min_[i] );
+    1737             :       // add to group energy
+    1738       49059 :       ene_ += -kbt_ * std::log ( 0.5 / dev * errf ) ;
+    1739             :       // store derivative for later
+    1740       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;
+    1741             :     }
+    1742             :   }
+    1743        5451 : }
+    1744             : 
+    1745             : }
+    1746             : }
+
+
+
+ + + + +
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 000000000..d027a5174 --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.func-sort-c.html @@ -0,0 +1,176 @@ + + + + + + + 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:356475.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..0fae661e7 --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.func.html @@ -0,0 +1,176 @@ + + + + + + + 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:356475.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..fc34bbf23 --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.gcov.html @@ -0,0 +1,1653 @@ + + + + + + + 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:356475.4 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.addOutputComponent("scoreb","default","Bayesian score");
+     255           4 :   keys.addOutputComponent("scale", "default","scale factor");
+     256           4 :   keys.addOutputComponent("offset","default","offset");
+     257           4 :   keys.addOutputComponent("accB",  "default", "Bfactor MC acceptance");
+     258           4 :   keys.addOutputComponent("kbt",   "default", "temperature in energy unit");
+     259           4 :   keys.addOutputComponent("corr",  "CORRELATION", "correlation coefficient");
+     260           2 : }
+     261             : 
+     262           0 : EMMIVOX::EMMIVOX(const ActionOptions&ao):
+     263             :   PLUMED_COLVAR_INIT(ao),
+     264           0 :   nl_dist_cutoff_(1.0), nl_gauss_cutoff_(3.0), nl_stride_(50),
+     265           0 :   first_time_(true), no_aver_(false), do_corr_(false),
+     266           0 :   scale_(1.), offset_(0.),
+     267           0 :   dbfact_(0.0), bfactmin_(0.05), bfactmax_(5.0),
+     268           0 :   bfactsig_(0.1), bfactnoc_(false), bfactread_(false),
+     269           0 :   MCBstride_(1), MCBaccept_(0.), MCBtrials_(0.), bfactemin_(false),
+     270           0 :   martini_(false), statusstride_(0), first_status_(true),
+     271           0 :   eps_(0.0001), mapstride_(0), gpu_(false)
+     272             : {
+     273             :   // set constants
+     274           0 :   inv_sqrt2_ = 1.0/sqrt(2.0);
+     275           0 :   sqrt2_pi_  = sqrt(2.0 / M_PI);
+     276           0 :   inv_pi2_   = 0.5 / M_PI / M_PI;
+     277             : 
+     278             :   // list of atoms
+     279             :   std::vector<AtomNumber> atoms;
+     280           0 :   parseAtomList("ATOMS", atoms);
+     281             : 
+     282             :   // file with experimental cryo-EM map
+     283             :   std::string datafile;
+     284           0 :   parse("DATA_FILE", datafile);
+     285             : 
+     286             :   // neighbor list cutoffs
+     287           0 :   parse("NL_DIST_CUTOFF",nl_dist_cutoff_);
+     288           0 :   parse("NL_GAUSS_CUTOFF",nl_gauss_cutoff_);
+     289             :   // checks
+     290           0 :   if(nl_dist_cutoff_<=0. && nl_gauss_cutoff_<=0.) error("You must specify either NL_DIST_CUTOFF or NL_GAUSS_CUTOFF or both");
+     291           0 :   if(nl_gauss_cutoff_<=0.) nl_gauss_cutoff_ = 1.0e+10;
+     292           0 :   if(nl_dist_cutoff_<=0.) nl_dist_cutoff_ = 1.0e+10;
+     293             :   // neighbor list update stride
+     294           0 :   parse("NL_STRIDE",nl_stride_);
+     295           0 :   if(nl_stride_<=0) error("NL_STRIDE must be explicitly specified and positive");
+     296             : 
+     297             :   // minimum value for error
+     298           0 :   double sigma_min = 0.2;
+     299           0 :   parse("SIGMA_MIN", sigma_min);
+     300           0 :   if(sigma_min<0.) error("SIGMA_MIN must be greater or equal to zero");
+     301             : 
+     302             :   // status file parameters
+     303           0 :   parse("WRITE_STRIDE", statusstride_);
+     304           0 :   if(statusstride_<=0) error("you must specify a positive WRITE_STRIDE");
+     305           0 :   parse("STATUS_FILE",  statusfilename_);
+     306           0 :   if(statusfilename_=="") statusfilename_ = "EMMIStatus"+getLabel();
+     307             : 
+     308             :   // integral of the experimetal density
+     309             :   double norm_d;
+     310           0 :   parse("NORM_DENSITY", norm_d);
+     311             : 
+     312             :   // temperature
+     313           0 :   kbt_ = getkBT();
+     314             : 
+     315             :   // scale and offset
+     316           0 :   parse("SCALE", scale_);
+     317           0 :   parse("OFFSET",offset_);
+     318             : 
+     319             :   // B-factors MC
+     320           0 :   parse("DBFACT",dbfact_);
+     321             :   // read Bfactors
+     322           0 :   parseFlag("BFACT_READ",bfactread_);
+     323             :   // do not use chains
+     324           0 :   parseFlag("BFACT_NOCHAIN",bfactnoc_);
+     325             :   // other parameters
+     326           0 :   if(dbfact_>0.) {
+     327           0 :     parse("MCBFACT_STRIDE",MCBstride_);
+     328           0 :     parse("BFACT_MAX",bfactmax_);
+     329           0 :     parse("BFACT_SIGMA",bfactsig_);
+     330           0 :     parseFlag("BFACT_MINIMIZE",bfactemin_);
+     331             :     // checks
+     332           0 :     if(MCBstride_<=0) error("you must specify a positive MCBFACT_STRIDE");
+     333           0 :     if(bfactmax_<=bfactmin_) error("you must specify a positive BFACT_MAX");
+     334           0 :     if(MCBstride_%nl_stride_!=0) error("MCBFACT_STRIDE must be multiple of NL_STRIDE");
+     335           0 :     if(bfactsig_<=0.) error("you must specify a positive BFACT_SIGMA");
+     336             :   }
+     337             : 
+     338             :   // read map resolution
+     339             :   double reso;
+     340           0 :   parse("RESOLUTION", reso);
+     341           0 :   if(reso<=0.) error("RESOLUTION must be strictly positive");
+     342             : 
+     343             :   // averaging or not
+     344           0 :   parseFlag("NO_AVER",no_aver_);
+     345             : 
+     346             :   // calculate correlation coefficient
+     347           0 :   parseFlag("CORRELATION",do_corr_);
+     348             : 
+     349             :   // write density file
+     350           0 :   parse("WRITE_MAP_STRIDE", mapstride_);
+     351           0 :   parse("WRITE_MAP", mapfilename_);
+     352           0 :   if(mapstride_>0 && mapfilename_=="") error("With WRITE_MAP_STRIDE you must specify WRITE_MAP");
+     353             : 
+     354             :   // use GPU?
+     355           0 :   parseFlag("GPU",gpu_);
+     356             :   // set device
+     357           0 :   if (gpu_ && torch::cuda::is_available()) {
+     358           0 :     device_t_ = torch::kCUDA;
+     359             :   } else {
+     360           0 :     device_t_ = torch::kCPU;
+     361           0 :     gpu_ = false;
+     362             :   }
+     363             : 
+     364             : // Martini model
+     365           0 :   parseFlag("MARTINI",martini_);
+     366             : 
+     367             :   // check read
+     368           0 :   checkRead();
+     369             : 
+     370             :   // set parallel stuff
+     371           0 :   unsigned mpisize=comm.Get_size();
+     372           0 :   if(mpisize>1) error("EMMIVOX supports only OpenMP parallelization");
+     373             : 
+     374             :   // get number of replicas
+     375           0 :   if(no_aver_) {
+     376           0 :     nrep_ = 1;
+     377             :   } else {
+     378           0 :     nrep_ = multi_sim_comm.Get_size();
+     379             :   }
+     380           0 :   replica_ = multi_sim_comm.Get_rank();
+     381             : 
+     382           0 :   if(nrep_>1 && dbfact_>0) error("Bfactor sampling not supported with ensemble averaging");
+     383             : 
+     384           0 :   log.printf("  number of atoms involved : %u\n", atoms.size());
+     385           0 :   log.printf("  experimental density map : %s\n", datafile.c_str());
+     386           0 :   if(no_aver_) log.printf("  without ensemble averaging\n");
+     387           0 :   if(gpu_) {log.printf("  running on GPU \n");}
+     388           0 :   else {log.printf("  running on CPU \n");}
+     389           0 :   if(nl_dist_cutoff_ <1.0e+10) log.printf("  neighbor list distance cutoff : %lf\n", nl_dist_cutoff_);
+     390           0 :   if(nl_gauss_cutoff_<1.0e+10) log.printf("  neighbor list Gaussian sigma cutoff : %lf\n", nl_gauss_cutoff_);
+     391           0 :   log.printf("  neighbor list update stride : %u\n",  nl_stride_);
+     392           0 :   log.printf("  minimum density error : %f\n", sigma_min);
+     393           0 :   log.printf("  scale factor : %lf\n", scale_);
+     394           0 :   log.printf("  offset : %lf\n", offset_);
+     395           0 :   log.printf("  reading/writing to status file : %s\n", statusfilename_.c_str());
+     396           0 :   log.printf("  with stride : %u\n", statusstride_);
+     397           0 :   if(dbfact_>0) {
+     398           0 :     log.printf("  maximum Bfactor MC move : %f\n", dbfact_);
+     399           0 :     log.printf("  stride MC move : %u\n", MCBstride_);
+     400           0 :     log.printf("  using prior with sigma : %f\n", bfactsig_);
+     401             :   }
+     402           0 :   if(bfactread_) log.printf("  reading Bfactors from file : %s\n", statusfilename_.c_str());
+     403           0 :   log.printf("  temperature of the system in energy unit : %f\n", kbt_);
+     404           0 :   if(nrep_>1) {
+     405           0 :     log.printf("  number of replicas for averaging: %u\n", nrep_);
+     406           0 :     log.printf("  replica ID : %u\n", replica_);
+     407             :   }
+     408           0 :   if(mapstride_>0) {
+     409           0 :     log.printf("  writing model density to file : %s\n", mapfilename_.c_str());
+     410           0 :     log.printf("  with stride : %u\n", mapstride_);
+     411             :   }
+     412           0 :   if(martini_) log.printf("  using Martini scattering factors\n");
+     413             : 
+     414             :   // calculate model constant parameters
+     415           0 :   std::vector<double> Model_w = get_Model_param(atoms);
+     416             : 
+     417             :   // read experimental map and errors
+     418           0 :   get_exp_data(datafile);
+     419           0 :   log.printf("  number of voxels : %u\n", static_cast<unsigned>(ovdd_.size()));
+     420             : 
+     421             :   // normalize atom weight map
+     422             :   double norm_m = accumulate(Model_w.begin(),  Model_w.end(),  0.0);
+     423             :   // renormalization and constant factor on atom types
+     424           0 :   for(unsigned i=0; i<Model_w_.size(); ++i) {
+     425           0 :     Vector5d cf;
+     426           0 :     for(unsigned j=0; j<5; ++j) {
+     427           0 :       Model_w_[i][j] *= norm_d / norm_m;
+     428           0 :       cf[j] = Model_w_[i][j]/pow( 2.0*pi, 1.5 );
+     429             :     }
+     430           0 :     cfact_.push_back(cf);
+     431             :   }
+     432             : 
+     433             :   // median density
+     434           0 :   double ovdd_m = get_median(ovdd_);
+     435             :   // median experimental error
+     436           0 :   double err_m  = get_median(exp_err_);
+     437             :   // minimum error
+     438           0 :   double minerr = sigma_min*ovdd_m;
+     439             :   // print out statistics
+     440           0 :   log.printf("     median density : %lf\n", ovdd_m);
+     441           0 :   log.printf("     minimum error  : %lf\n", minerr);
+     442           0 :   log.printf("     median error   : %lf\n", err_m);
+     443             :   // populate ismin: cycle on all voxels
+     444           0 :   for(unsigned id=0; id<ovdd_.size(); ++id) {
+     445             :     // define smin
+     446           0 :     double smin = std::max(minerr, exp_err_[id]);
+     447             :     // and to ismin_
+     448           0 :     ismin_.push_back(1.0/smin);
+     449             :   }
+     450             : 
+     451             :   // prepare gpu stuff: map centers, data, and error
+     452           0 :   prepare_gpu();
+     453             : 
+     454             :   // initialize Bfactors
+     455           0 :   initialize_Bfactor(reso);
+     456             : 
+     457             :   // read status file if restarting
+     458           0 :   if(getRestart() || bfactread_) read_status();
+     459             : 
+     460             :   // prepare auxiliary vectors
+     461           0 :   get_auxiliary_vectors();
+     462             : 
+     463             :   // prepare other vectors: data and derivatives
+     464           0 :   ovmd_.resize(ovdd_.size());
+     465           0 :   atom_der_.resize(Model_type_.size());
+     466           0 :   score_der_.resize(ovdd_.size());
+     467             : 
+     468             :   // add components
+     469           0 :   addComponentWithDerivatives("scoreb"); componentIsNotPeriodic("scoreb");
+     470           0 :   addComponent("scale");                 componentIsNotPeriodic("scale");
+     471           0 :   addComponent("offset");                componentIsNotPeriodic("offset");
+     472           0 :   addComponent("kbt");                   componentIsNotPeriodic("kbt");
+     473           0 :   if(dbfact_>0)   {addComponent("accB"); componentIsNotPeriodic("accB");}
+     474           0 :   if(do_corr_)    {addComponent("corr"); componentIsNotPeriodic("corr");}
+     475             : 
+     476             :   // initialize random seed
+     477           0 :   unsigned iseed = time(NULL)+replica_;
+     478           0 :   random_.setSeed(-iseed);
+     479             : 
+     480             :   // request atoms
+     481           0 :   requestAtoms(atoms);
+     482             : 
+     483             :   // print bibliography
+     484           0 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     485           0 :   log<<plumed.cite("Hoff, Thomasen, Lindorff-Larsen, Bonomi, bioRxiv (2023) doi: 10.1101/2023.10.18.562710");
+     486           0 :   if(!no_aver_ && nrep_>1)log<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     487           0 :   log<<"\n";
+     488           0 : }
+     489             : 
+     490           0 : void EMMIVOX::prepare_gpu()
+     491             : {
+     492             :   // number of data points
+     493           0 :   int nd = ovdd_.size();
+     494             :   // 1) put ismin_ on device_t_
+     495           0 :   ismin_gpu_ = torch::from_blob(ismin_.data(), {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+     496             :   // 2) put ovdd_ on device_t_
+     497           0 :   ovdd_gpu_  = torch::from_blob(ovdd_.data(),  {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+     498             :   // 3) put Map_m_ on device_t_
+     499           0 :   std::vector<double> Map_m_gpu(3*nd);
+     500           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     501             :   for(int i=0; i<nd; ++i) {
+     502             :     Map_m_gpu[i]      = Map_m_[i][0];
+     503             :     Map_m_gpu[i+nd]   = Map_m_[i][1];
+     504             :     Map_m_gpu[i+2*nd] = Map_m_[i][2];
+     505             :   }
+     506             :   // libtorch tensor
+     507           0 :   Map_m_gpu_ = torch::from_blob(Map_m_gpu.data(), {3,nd}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     508           0 : }
+     509             : 
+     510           0 : void EMMIVOX::write_model_density(long int step)
+     511             : {
+     512           0 :   OFile ovfile;
+     513           0 :   ovfile.link(*this);
+     514           0 :   std::string num; Tools::convert(step,num);
+     515           0 :   std::string name = mapfilename_+"-"+num;
+     516           0 :   ovfile.open(name);
+     517             :   ovfile.setHeavyFlush();
+     518           0 :   ovfile.fmtField("%10.7e ");
+     519             : // write density
+     520           0 :   for(unsigned i=0; i<ovmd_.size(); ++i) {
+     521           0 :     ovfile.printField("Model", ovmd_[i]);
+     522           0 :     ovfile.printField("ModelScaled", scale_ * ovmd_[i] + offset_);
+     523           0 :     ovfile.printField("Data", ovdd_[i]);
+     524           0 :     ovfile.printField();
+     525             :   }
+     526           0 :   ovfile.close();
+     527           0 : }
+     528             : 
+     529           0 : double EMMIVOX::get_median(std::vector<double> v)
+     530             : {
+     531             : // dimension of vector
+     532           0 :   unsigned size = v.size();
+     533             : // in case of only one entry
+     534           0 :   if (size==1) {
+     535           0 :     return v[0];
+     536             :   } else {
+     537             :     // reorder vector
+     538           0 :     sort(v.begin(), v.end());
+     539             :     // odd or even?
+     540           0 :     if (size%2==0) {
+     541           0 :       return (v[size/2-1]+v[size/2])/2.0;
+     542             :     } else {
+     543           0 :       return v[size/2];
+     544             :     }
+     545             :   }
+     546             : }
+     547             : 
+     548           0 : void EMMIVOX::read_status()
+     549             : {
+     550             :   double MDtime;
+     551             : // open file
+     552           0 :   IFile *ifile = new IFile();
+     553           0 :   ifile->link(*this);
+     554           0 :   if(ifile->FileExist(statusfilename_)) {
+     555           0 :     ifile->open(statusfilename_);
+     556           0 :     while(ifile->scanField("MD_time", MDtime)) {
+     557             :       // read scale and offset
+     558           0 :       ifile->scanField("scale", scale_);
+     559           0 :       ifile->scanField("offset", offset_);
+     560             :       // read bfactors if doing fitting of reading it at restart
+     561           0 :       if(dbfact_>0 || bfactread_) {
+     562             :         // cycle on residues
+     563           0 :         for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+     564             :           // key: pair of residue/chain IDs
+     565             :           std::pair<unsigned,std::string> key = Model_rlist_[ir];
+     566             :           // convert ires to std::string
+     567           0 :           std::string num; Tools::convert(key.first,num);
+     568             :           // read entry
+     569           0 :           std::string ch = key.second;
+     570           0 :           if(ch==" ") ch="";
+     571           0 :           ifile->scanField("bf-"+num+":"+ch, Model_b_[key]);
+     572             :         }
+     573             :       }
+     574             :       // new line
+     575           0 :       ifile->scanField();
+     576             :     }
+     577           0 :     ifile->close();
+     578             :   } else {
+     579           0 :     error("Cannot find status file "+statusfilename_+"\n");
+     580             :   }
+     581           0 :   delete ifile;
+     582           0 : }
+     583             : 
+     584           0 : void EMMIVOX::print_status(long int step)
+     585             : {
+     586             : // if first time open the file
+     587           0 :   if(first_status_) {
+     588           0 :     first_status_ = false;
+     589           0 :     statusfile_.link(*this);
+     590           0 :     statusfile_.open(statusfilename_);
+     591             :     statusfile_.setHeavyFlush();
+     592           0 :     statusfile_.fmtField("%10.7e ");
+     593             :   }
+     594             : // write fields
+     595           0 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     596           0 :   statusfile_.printField("MD_time", MDtime);
+     597             :   // write scale and offset
+     598           0 :   statusfile_.printField("scale", scale_);
+     599           0 :   statusfile_.printField("offset", offset_);
+     600             :   // write bfactors only if doing fitting or reading bfactors
+     601           0 :   if(dbfact_>0 || bfactread_) {
+     602             :     // cycle on residues
+     603           0 :     for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+     604             :       // key: pair of residue/chain IDs
+     605             :       std::pair<unsigned,std::string> key = Model_rlist_[ir];
+     606             :       // bfactor from map
+     607           0 :       double bf = Model_b_[key];
+     608             :       // convert ires to std::string
+     609           0 :       std::string num; Tools::convert(key.first,num);
+     610             :       // print entry
+     611           0 :       statusfile_.printField("bf-"+num+":"+key.second, bf);
+     612             :     }
+     613             :   }
+     614           0 :   statusfile_.printField();
+     615           0 : }
+     616             : 
+     617           0 : bool EMMIVOX::doAccept(double oldE, double newE, double kbt)
+     618             : {
+     619             :   bool accept = false;
+     620             :   // calculate delta energy
+     621           0 :   double delta = ( newE - oldE ) / kbt;
+     622             :   // if delta is negative always accept move
+     623           0 :   if( delta < 0.0 ) {
+     624             :     accept = true;
+     625             :   } else {
+     626             :     // otherwise extract random number
+     627           0 :     double s = random_.RandU01();
+     628           0 :     if( s < exp(-delta) ) { accept = true; }
+     629             :   }
+     630           0 :   return accept;
+     631             : }
+     632             : 
+     633           0 : std::vector<double> EMMIVOX::get_Model_param(std::vector<AtomNumber> &atoms)
+     634             : {
+     635             :   // check if MOLINFO line is present
+     636           0 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     637           0 :   if(!moldat) error("MOLINFO DATA not found\n");
+     638           0 :   log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     639             : 
+     640             :   // list of weights - one per atom
+     641             :   std::vector<double> Model_w;
+     642             :   // 5-Gaussians parameters
+     643             :   // map of atom types to A and B coefficients of scattering factor
+     644             :   // f(s) = A * exp(-B*s**2)
+     645             :   // B is in Angstrom squared
+     646             :   // Elastic atomic scattering factors of electrons for neutral atoms
+     647             :   // and s up to 6.0 A^-1: as implemented in PLUMED
+     648             :   // map between an atom type and an index
+     649             :   std::map<std::string, unsigned> type_map;
+     650             :   // atomistic types
+     651           0 :   type_map["C"]=0;  type_map["O"]=1;  type_map["N"]=2;
+     652           0 :   type_map["S"]=3;  type_map["P"]=4;  type_map["F"]=5;
+     653           0 :   type_map["NA"]=6; type_map["MG"]=7; type_map["CL"]=8;
+     654           0 :   type_map["CA"]=9; type_map["K"]=10; type_map["ZN"]=11;
+     655             :   // Martini types
+     656           0 :   type_map["ALA_BB"]=12;    type_map["ALA_SC1"]=13;   type_map["CYS_BB"]=14;
+     657           0 :   type_map["CYS_SC1"]=15;   type_map["ASP_BB"]=16;    type_map["ASP_SC1"]=17;
+     658           0 :   type_map["GLU_BB"]=18;    type_map["GLU_SC1"]=19;   type_map["PHE_BB"]=20;
+     659           0 :   type_map["PHE_SC1"]=21;   type_map["PHE_SC2"]=22;   type_map["PHE_SC3"]=23;
+     660           0 :   type_map["GLY_BB"]=24;    type_map["HIS_BB"]=25;    type_map["HIS_SC1"]=26;
+     661           0 :   type_map["HIS_SC2"]=27;   type_map["HIS_SC3"]=28;   type_map["ILE_BB"]=29;
+     662           0 :   type_map["ILE_SC1"]=30;   type_map["LYS_BB"]=31;    type_map["LYS_SC1"]=32;
+     663           0 :   type_map["LYS_SC2"]=33;   type_map["LEU_BB"]=34;    type_map["LEU_SC1"]=35;
+     664           0 :   type_map["MET_BB"]=36;    type_map["MET_SC1"]=37;   type_map["ASN_BB"]=38;
+     665           0 :   type_map["ASN_SC1"]=39;   type_map["PRO_BB"]=40;    type_map["PRO_SC1"]=41;
+     666           0 :   type_map["GLN_BB"]=42;    type_map["GLN_SC1"]=43;   type_map["ARG_BB"]=44;
+     667           0 :   type_map["ARG_SC1"]=45;   type_map["ARG_SC2"]=46;   type_map["SER_BB"]=47;
+     668           0 :   type_map["SER_SC1"]=48;   type_map["THR_BB"]=49;    type_map["THR_SC1"]=50;
+     669           0 :   type_map["VAL_BB"]=51;    type_map["VAL_SC1"]=52;   type_map["TRP_BB"]=53;
+     670           0 :   type_map["TRP_SC1"]=54;   type_map["TRP_SC2"]=55;   type_map["TRP_SC3"]=56;
+     671           0 :   type_map["TRP_SC4"]=57;   type_map["TRP_SC5"]=58;   type_map["TYR_BB"]=59;
+     672           0 :   type_map["TYR_SC1"]=60;   type_map["TYR_SC2"]=61;   type_map["TYR_SC3"]=62;
+     673           0 :   type_map["TYR_SC4"]=63;
+     674             :   // fill in sigma vector for atoms
+     675           0 :   Model_s_.push_back(0.01*Vector5d(0.114,1.0825,5.4281,17.8811,51.1341));   // C
+     676           0 :   Model_s_.push_back(0.01*Vector5d(0.0652,0.6184,2.9449,9.6298,28.2194));   // O
+     677           0 :   Model_s_.push_back(0.01*Vector5d(0.0541,0.5165,2.8207,10.6297,34.3764));  // N
+     678           0 :   Model_s_.push_back(0.01*Vector5d(0.0838,0.7788,4.3462,15.5846,44.63655)); // S
+     679           0 :   Model_s_.push_back(0.01*Vector5d(0.0977,0.9084,4.9654,18.5471,54.3648));  // P
+     680           0 :   Model_s_.push_back(0.01*Vector5d(0.0613,0.5753,2.6858,8.8214,25.6668));   // F
+     681           0 :   Model_s_.push_back(0.01*Vector5d(0.1684,1.7150,8.8386,50.8265,147.2073)); // NA
+     682           0 :   Model_s_.push_back(0.01*Vector5d(0.1356,1.3579,6.9255,32.3165,92.1138));  // MG
+     683           0 :   Model_s_.push_back(0.01*Vector5d(0.0694,0.6443,3.5351,12.5058,35.8633));  // CL
+     684           0 :   Model_s_.push_back(0.01*Vector5d(0.1742,1.8329,8.8407,47.4583,134.9613)); // CA
+     685           0 :   Model_s_.push_back(0.01*Vector5d(0.1660,1.6906,8.7447,46.7825,165.6923)); // K
+     686           0 :   Model_s_.push_back(0.01*Vector5d(0.0876,0.8650,3.8612,18.8726,64.7016));  // ZN
+     687             :   // fill in sigma vector for Martini beads
+     688           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // ALA_BB
+     689           0 :   Model_s_.push_back(0.01*Vector5d(0.500000,0.500000,0.500000,0.500000,0.500000)); // ALA_SC1
+     690           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // CYS_BB
+     691           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // CYS_SC1
+     692           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ASP_BB
+     693           0 :   Model_s_.push_back(0.01*Vector5d(17.000000,17.000000,17.000000,17.000000,17.000000)); // ASP_SC1
+     694           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // GLU_BB
+     695           0 :   Model_s_.push_back(0.01*Vector5d(24.000000,24.000000,24.000000,24.000000,24.000000)); // GLU_SC1
+     696           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // PHE_BB
+     697           0 :   Model_s_.push_back(0.01*Vector5d(17.500000,17.500000,17.500000,17.500000,17.500000)); // PHE_SC1
+     698           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // PHE_SC2
+     699           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // PHE_SC3
+     700           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // GLY_BB
+     701           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // HIS_BB
+     702           0 :   Model_s_.push_back(0.01*Vector5d(11.500000,11.500000,11.500000,11.500000,11.500000)); // HIS_SC1
+     703           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // HIS_SC2
+     704           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // HIS_SC3
+     705           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ILE_BB
+     706           0 :   Model_s_.push_back(0.01*Vector5d(25.500000,25.500000,25.500000,25.500000,25.500000)); // ILE_SC1
+     707           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // LYS_BB
+     708           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // LYS_SC1
+     709           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // LYS_SC2
+     710           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // LEU_BB
+     711           0 :   Model_s_.push_back(0.01*Vector5d(21.500000,21.500000,21.500000,21.500000,21.500000)); // LEU_SC1
+     712           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // MET_BB
+     713           0 :   Model_s_.push_back(0.01*Vector5d(22.500000,22.500000,22.500000,22.500000,22.500000)); // MET_SC1
+     714           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // ASN_BB
+     715           0 :   Model_s_.push_back(0.01*Vector5d(18.500000,18.500000,18.500000,18.500000,18.500000)); // ASN_SC1
+     716           0 :   Model_s_.push_back(0.01*Vector5d(23.500000,23.500000,23.500000,23.500000,23.500000)); // PRO_BB
+     717           0 :   Model_s_.push_back(0.01*Vector5d(17.500000,17.500000,17.500000,17.500000,17.500000)); // PRO_SC1
+     718           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // GLN_BB
+     719           0 :   Model_s_.push_back(0.01*Vector5d(24.500000,24.500000,24.500000,24.500000,24.500000)); // GLN_SC1
+     720           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ARG_BB
+     721           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // ARG_SC1
+     722           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // ARG_SC2
+     723           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // SER_BB
+     724           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // SER_SC1
+     725           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // THR_BB
+     726           0 :   Model_s_.push_back(0.01*Vector5d(17.000000,17.000000,17.000000,17.000000,17.000000)); // THR_SC1
+     727           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // VAL_BB
+     728           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // VAL_SC1
+     729           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // TRP_BB
+     730           0 :   Model_s_.push_back(0.01*Vector5d(11.500000,11.500000,11.500000,11.500000,11.500000)); // TRP_SC1
+     731           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // TRP_SC2
+     732           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TRP_SC3
+     733           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TRP_SC4
+     734           0 :   Model_s_.push_back(0.01*Vector5d(9.500000,9.500000,9.500000,9.500000,9.500000)); // TRP_SC5
+     735           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // TYR_BB
+     736           0 :   Model_s_.push_back(0.01*Vector5d(12.000000,12.000000,12.000000,12.000000,12.000000)); // TYR_SC1
+     737           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TYR_SC2
+     738           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TYR_SC3
+     739           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // TYR_SC4
+     740             :   // fill in weight vector for atoms
+     741           0 :   Model_w_.push_back(Vector5d(0.0489,0.2091,0.7537,1.1420,0.3555)); // C
+     742           0 :   Model_w_.push_back(Vector5d(0.0365,0.1729,0.5805,0.8814,0.3121)); // O
+     743           0 :   Model_w_.push_back(Vector5d(0.0267,0.1328,0.5301,1.1020,0.4215)); // N
+     744           0 :   Model_w_.push_back(Vector5d(0.0915,0.4312,1.0847,2.4671,1.0852)); // S
+     745           0 :   Model_w_.push_back(Vector5d(0.1005,0.4615,1.0663,2.5854,1.2725)); // P
+     746           0 :   Model_w_.push_back(Vector5d(0.0382,0.1822,0.5972,0.7707,0.2130)); // F
+     747           0 :   Model_w_.push_back(Vector5d(0.1260,0.6442,0.8893,1.8197,1.2988)); // NA
+     748           0 :   Model_w_.push_back(Vector5d(0.1130,0.5575,0.9046,2.1580,1.4735)); // MG
+     749           0 :   Model_w_.push_back(Vector5d(0.0799,0.3891,1.0037,2.3332,1.0507)); // CL
+     750           0 :   Model_w_.push_back(Vector5d(0.2355,0.9916,2.3959,3.7252,2.5647)); // CA
+     751           0 :   Model_w_.push_back(Vector5d(0.2149,0.8703,2.4999,2.3591,3.0318)); // K
+     752           0 :   Model_w_.push_back(Vector5d(0.1780,0.8096,1.6744,1.9499,1.4495)); // ZN
+     753             :   // fill in weight vector for Martini beads
+     754           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ALA_BB
+     755           0 :   Model_w_.push_back(Vector5d(0.100000,0.100000,0.100000,0.100000,0.100000)); // ALA_SC1
+     756           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // CYS_BB
+     757           0 :   Model_w_.push_back(Vector5d(1.100000,1.100000,1.100000,1.100000,1.100000)); // CYS_SC1
+     758           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ASP_BB
+     759           0 :   Model_w_.push_back(Vector5d(1.700000,1.700000,1.700000,1.700000,1.700000)); // ASP_SC1
+     760           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // GLU_BB
+     761           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // GLU_SC1
+     762           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // PHE_BB
+     763           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // PHE_SC1
+     764           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // PHE_SC2
+     765           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // PHE_SC3
+     766           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // GLY_BB
+     767           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // HIS_BB
+     768           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // HIS_SC1
+     769           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // HIS_SC2
+     770           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // HIS_SC3
+     771           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ILE_BB
+     772           0 :   Model_w_.push_back(Vector5d(2.000000,2.000000,2.000000,2.000000,2.000000)); // ILE_SC1
+     773           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // LYS_BB
+     774           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // LYS_SC1
+     775           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // LYS_SC2
+     776           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // LEU_BB
+     777           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // LEU_SC1
+     778           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // MET_BB
+     779           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // MET_SC1
+     780           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ASN_BB
+     781           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ASN_SC1
+     782           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // PRO_BB
+     783           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // PRO_SC1
+     784           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // GLN_BB
+     785           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // GLN_SC1
+     786           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ARG_BB
+     787           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // ARG_SC1
+     788           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ARG_SC2
+     789           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // SER_BB
+     790           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // SER_SC1
+     791           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // THR_BB
+     792           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // THR_SC1
+     793           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // VAL_BB
+     794           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // VAL_SC1
+     795           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // TRP_BB
+     796           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC1
+     797           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TRP_SC2
+     798           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC3
+     799           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC4
+     800           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TRP_SC5
+     801           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // TYR_BB
+     802           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC1
+     803           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC2
+     804           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC3
+     805           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TYR_SC4
+     806             :   // cycle on atoms
+     807           0 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     808             :     // get atom name
+     809           0 :     std::string name = moldat->getAtomName(atoms[i]);
+     810             :     // get residue name
+     811           0 :     std::string resname = moldat->getResidueName(atoms[i]);
+     812             :     // type of atoms/bead
+     813             :     std::string type_s;
+     814             :     // Martini model
+     815           0 :     if(martini_) {
+     816           0 :       type_s = resname+"_"+name;
+     817             :       // Atomistic model
+     818             :     } else {
+     819             :       char type;
+     820             :       // get atom type
+     821           0 :       char first = name.at(0);
+     822             :       // GOLDEN RULE: type is first letter, if not a number
+     823           0 :       if (!isdigit(first)) {
+     824             :         type = first;
+     825             :         // otherwise is the second
+     826             :       } else {
+     827           0 :         type = name.at(1);
+     828             :       }
+     829             :       // convert to std::string
+     830           0 :       type_s = std::string(1,type);
+     831             :       // special cases
+     832           0 :       if(name=="SOD" || name=="NA" || name =="Na") type_s = "NA";
+     833           0 :       if(name=="MG"  || name=="Mg")                type_s = "MG";
+     834           0 :       if(name=="CLA" || name=="CL" || name =="Cl") type_s = "CL";
+     835           0 :       if((resname=="CAL" || resname=="CA") && (name=="CAL" || name=="CA" || name =="C0")) type_s = "CA";
+     836           0 :       if(name=="POT" || name=="K")                 type_s = "K";
+     837           0 :       if(name=="ZN"  || name=="Zn")                type_s = "ZN";
+     838             :     }
+     839             :     // check if key in map
+     840           0 :     if(type_map.find(type_s) != type_map.end()) {
+     841             :       // save atom type
+     842           0 :       Model_type_.push_back(type_map[type_s]);
+     843             :       // this will be normalized in the final density
+     844           0 :       Vector5d w = Model_w_[type_map[type_s]];
+     845           0 :       Model_w.push_back(w[0]+w[1]+w[2]+w[3]+w[4]);
+     846             :       // get residue id
+     847           0 :       unsigned ires = moldat->getResidueNumber(atoms[i]);
+     848             :       // and chain
+     849           0 :       std::string c ("*");
+     850           0 :       if(!bfactnoc_) c = moldat->getChainID(atoms[i]);
+     851             :       // define pair residue/chain IDs
+     852             :       std::pair<unsigned,std::string> key = std::make_pair(ires,c);
+     853             :       // add to map between residue/chain and list of atoms
+     854           0 :       Model_resmap_[key].push_back(i);
+     855             :       // and global list of residue/chain per atom
+     856           0 :       Model_res_.push_back(key);
+     857             :       // initialize Bfactor map
+     858           0 :       Model_b_[key] = 0.0;
+     859             :     } else {
+     860           0 :       error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+     861             :     }
+     862             :   }
+     863             :   // create ordered vector of residue-chain IDs
+     864           0 :   for(unsigned i=0; i<Model_res_.size(); ++i) {
+     865             :     std::pair<unsigned,std::string> key = Model_res_[i];
+     866             :     // search in Model_rlist_
+     867           0 :     if(find(Model_rlist_.begin(), Model_rlist_.end(), key) == Model_rlist_.end())
+     868           0 :       Model_rlist_.push_back(key);
+     869             :   }
+     870             :   // return weights
+     871           0 :   return Model_w;
+     872             : }
+     873             : 
+     874             : // read experimental data file in PLUMED format:
+     875           0 : void EMMIVOX::get_exp_data(const std::string &datafile)
+     876             : {
+     877           0 :   Vector pos;
+     878             :   double dens, err;
+     879             :   int idcomp;
+     880             : 
+     881             : // open file
+     882           0 :   IFile *ifile = new IFile();
+     883           0 :   if(ifile->FileExist(datafile)) {
+     884           0 :     ifile->open(datafile);
+     885           0 :     while(ifile->scanField("Id",idcomp)) {
+     886           0 :       ifile->scanField("Pos_0",pos[0]);
+     887           0 :       ifile->scanField("Pos_1",pos[1]);
+     888           0 :       ifile->scanField("Pos_2",pos[2]);
+     889           0 :       ifile->scanField("Density",dens);
+     890           0 :       ifile->scanField("Error",err);
+     891             :       // voxel center
+     892           0 :       Map_m_.push_back(pos);
+     893             :       // experimental density
+     894           0 :       ovdd_.push_back(dens);
+     895             :       // error
+     896           0 :       exp_err_.push_back(err);
+     897             :       // new line
+     898           0 :       ifile->scanField();
+     899             :     }
+     900           0 :     ifile->close();
+     901             :   } else {
+     902           0 :     error("Cannot find DATA_FILE "+datafile+"\n");
+     903             :   }
+     904           0 :   delete ifile;
+     905           0 : }
+     906             : 
+     907           0 : void EMMIVOX::initialize_Bfactor(double reso)
+     908             : {
+     909           0 :   double bfactini = 0.0;
+     910             :   // if doing Bfactor Monte Carlo
+     911           0 :   if(dbfact_>0) {
+     912             :     // initialize B factor based on empirical relation between resolution and average bfactor
+     913             :     // calculated on ~8000 cryo-EM data with resolution < 5 Ang
+     914             :     // Bfact = A*reso**2+B; with A=6.95408 B=-2.45697/100.0 nm^2
+     915           0 :     bfactini = 6.95408*reso*reso - 0.01*2.45697;
+     916             :     // check for min and max
+     917           0 :     bfactini = std::min(bfactmax_, std::max(bfactmin_, bfactini));
+     918             :   }
+     919             :   // set initial Bfactor
+     920           0 :   for(std::map< std::pair<unsigned,std::string>, double>::iterator it=Model_b_.begin(); it!=Model_b_.end(); ++it) {
+     921           0 :     it->second = bfactini;
+     922             :   }
+     923           0 :   log.printf("  experimental map resolution : %3.2f\n", reso);
+     924             :   // if doing Bfactor Monte Carlo
+     925           0 :   if(dbfact_>0) {
+     926           0 :     log.printf("  minimum Bfactor value : %3.2f\n", bfactmin_);
+     927           0 :     log.printf("  maximum Bfactor value : %3.2f\n", bfactmax_);
+     928           0 :     log.printf("  initial Bfactor value : %3.2f\n", bfactini);
+     929             :   }
+     930           0 : }
+     931             : 
+     932             : // prepare auxiliary vectors
+     933           0 : void EMMIVOX::get_auxiliary_vectors()
+     934             : {
+     935             : // number of atoms
+     936           0 :   unsigned natoms = Model_res_.size();
+     937             : // clear lists
+     938           0 :   pref_.clear(); invs2_.clear(); cut_.clear();
+     939             : // resize
+     940           0 :   pref_.resize(natoms); invs2_.resize(natoms); cut_.resize(natoms);
+     941             : // cycle on all atoms
+     942           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     943             :   for(unsigned im=0; im<natoms; ++im) {
+     944             :     // get atom type
+     945             :     unsigned atype = Model_type_[im];
+     946             :     // get residue/chain IDs
+     947             :     std::pair<unsigned,std::string> key = Model_res_[im];
+     948             :     // get bfactor
+     949             :     double bfact = Model_b_[key];
+     950             :     // sigma for 5 gaussians
+     951             :     Vector5d m_s = Model_s_[atype];
+     952             :     // calculate constant quantities
+     953             :     Vector5d pref, invs2;
+     954             :     // calculate cutoff
+     955             :     double n = 0.0;
+     956             :     double d = 0.0;
+     957             :     for(unsigned j=0; j<5; ++j) {
+     958             :       // total value of b
+     959             :       double m_b = m_s[j] + bfact/4.0;
+     960             :       // calculate invs2
+     961             :       invs2[j] = 1.0/(inv_pi2_*m_b);
+     962             :       // prefactor
+     963             :       pref[j]  = cfact_[atype][j] * pow(invs2[j],1.5);
+     964             :       // cutoff
+     965             :       n += pref[j] / invs2[j];
+     966             :       d += pref[j];
+     967             :     }
+     968             :     // put into global lists
+     969             :     pref_[im]  = pref;
+     970             :     invs2_[im] = invs2;
+     971             :     cut_[im] = std::min(nl_dist_cutoff_, sqrt(n/d)*nl_gauss_cutoff_);
+     972             :   }
+     973             :   // push to GPU
+     974           0 :   push_auxiliary_gpu();
+     975           0 : }
+     976             : 
+     977           0 : void EMMIVOX::push_auxiliary_gpu()
+     978             : {
+     979             :   // 1) create vector of pref_ and invs2_
+     980           0 :   int natoms = Model_type_.size();
+     981           0 :   std::vector<double> pref(5*natoms), invs2(5*natoms);
+     982           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     983             :   for(int i=0; i<natoms; ++i) {
+     984             :     for(int j=0; j<5; ++j) {
+     985             :       pref[i+j*natoms]  = pref_[i][j];
+     986             :       invs2[i+j*natoms] = invs2_[i][j];
+     987             :     }
+     988             :   }
+     989             :   // 2) initialize gpu tensors
+     990           0 :   pref_gpu_  = torch::from_blob(pref.data(),  {5,natoms}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     991           0 :   invs2_gpu_ = torch::from_blob(invs2.data(), {5,natoms}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     992           0 : }
+     993             : 
+     994           0 : void EMMIVOX::get_close_residues()
+     995             : {
+     996             :   // clear neighbor list
+     997           0 :   nl_res_.clear(); nl_res_.resize(Model_rlist_.size());
+     998             : 
+     999             :   // loop in parallel
+    1000           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1001             :   {
+    1002             :     // private variable
+    1003             :     std::vector< std::vector<unsigned> > nl_res_l(Model_rlist_.size());
+    1004             :     // cycle on residues/chains #1
+    1005             :     #pragma omp for
+    1006             :     for(unsigned i=0; i<Model_rlist_.size()-1; ++i) {
+    1007             : 
+    1008             :       // key1: pair of residue/chain IDs
+    1009             :       std::pair<unsigned,std::string> key1 = Model_rlist_[i];
+    1010             : 
+    1011             :       // cycle over residues/chains #2
+    1012             :       for(unsigned j=i+1; j<Model_rlist_.size(); ++j) {
+    1013             : 
+    1014             :         // key2: pair of residue/chain IDs
+    1015             :         std::pair<unsigned,std::string> key2 = Model_rlist_[j];
+    1016             : 
+    1017             :         // set flag neighbor
+    1018             :         bool neigh = false;
+    1019             : 
+    1020             :         // cycle over all the atoms belonging to key1
+    1021             :         for(unsigned im1=0; im1<Model_resmap_[key1].size(); ++im1) {
+    1022             :           // get atom position #1
+    1023             :           Vector pos1 = getPosition(Model_resmap_[key1][im1]);
+    1024             :           // cycle over all the atoms belonging to key2
+    1025             :           for(unsigned im2=0; im2<Model_resmap_[key2].size(); ++im2) {
+    1026             :             // get atom position #2
+    1027             :             Vector pos2 = getPosition(Model_resmap_[key2][im2]);
+    1028             :             // if closer than 0.5 nm, then residues key1 and key2 are neighbors
+    1029             :             if(delta(pos1,pos2).modulo()<0.5) {
+    1030             :               // set neighbors
+    1031             :               neigh = true;
+    1032             :               // and exit
+    1033             :               break;
+    1034             :             }
+    1035             :           }
+    1036             :           // check if neighbor already found
+    1037             :           if(neigh) break;
+    1038             :         }
+    1039             : 
+    1040             :         // if neighbors, add to local list
+    1041             :         if(neigh) {
+    1042             :           nl_res_l[i].push_back(j);
+    1043             :           nl_res_l[j].push_back(i);
+    1044             :         }
+    1045             :       }
+    1046             :     }
+    1047             :     // add to global list
+    1048             :     #pragma omp critical
+    1049             :     {
+    1050             :       for(unsigned i=0; i<nl_res_.size(); ++i)
+    1051             :         nl_res_[i].insert(nl_res_[i].end(), nl_res_l[i].begin(), nl_res_l[i].end());
+    1052             :     }
+    1053             :   }
+    1054           0 : }
+    1055             : 
+    1056           0 : void EMMIVOX::doMonteCarloBfact()
+    1057             : {
+    1058             : // update residue neighbor list
+    1059           0 :   get_close_residues();
+    1060             : 
+    1061             : // cycle over residues/chains
+    1062           0 :   for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+    1063             : 
+    1064             :     // key: pair of residue/chain IDs
+    1065             :     std::pair<unsigned,std::string> key = Model_rlist_[ir];
+    1066             :     // old bfactor
+    1067           0 :     double bfactold = Model_b_[key];
+    1068             : 
+    1069             :     // propose move in bfactor
+    1070           0 :     double bfactnew = bfactold + dbfact_ * ( 2.0 * random_.RandU01() - 1.0 );
+    1071             :     // check boundaries
+    1072           0 :     if(bfactnew > bfactmax_) {bfactnew = 2.0*bfactmax_ - bfactnew;}
+    1073           0 :     if(bfactnew < bfactmin_) {bfactnew = 2.0*bfactmin_ - bfactnew;}
+    1074             : 
+    1075             :     // useful quantities
+    1076             :     std::map<unsigned, double> deltaov;
+    1077             : 
+    1078           0 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1079             :     {
+    1080             :       // private variables
+    1081             :       std::map<unsigned, double> deltaov_l;
+    1082             :       #pragma omp for
+    1083             :       // cycle over all the atoms belonging to key (residue/chain)
+    1084             :       for(unsigned ia=0; ia<Model_resmap_[key].size(); ++ia) {
+    1085             : 
+    1086             :         // get atom id
+    1087             :         unsigned im = Model_resmap_[key][ia];
+    1088             :         // get atom type
+    1089             :         unsigned atype = Model_type_[im];
+    1090             :         // sigma for 5 Gaussians
+    1091             :         Vector5d m_s = Model_s_[atype];
+    1092             :         // prefactors
+    1093             :         Vector5d cfact = cfact_[atype];
+    1094             :         // and position
+    1095             :         Vector pos = getPosition(im);
+    1096             : 
+    1097             :         // cycle on all the neighboring voxels affected by a change in Bfactor
+    1098             :         for(unsigned i=0; i<Model_nb_[im].size(); ++i) {
+    1099             :           // voxel id
+    1100             :           unsigned id = Model_nb_[im][i];
+    1101             :           // get contribution to density in id before change
+    1102             :           double dold = get_overlap(Map_m_[id], pos, cfact, m_s, bfactold);
+    1103             :           // get contribution after change
+    1104             :           double dnew = get_overlap(Map_m_[id], pos, cfact, m_s, bfactnew);
+    1105             :           // update delta density
+    1106             :           deltaov_l[id] += dnew-dold;
+    1107             :         }
+    1108             :       }
+    1109             :       // add to global list
+    1110             :       #pragma omp critical
+    1111             :       {
+    1112             :         for(std::map<unsigned,double>::iterator itov=deltaov_l.begin(); itov!=deltaov_l.end(); ++itov)
+    1113             :           deltaov[itov->first] += itov->second;
+    1114             :       }
+    1115             :     }
+    1116             : 
+    1117             :     // now calculate new and old score
+    1118             :     double old_ene = 0.0;
+    1119             :     double new_ene = 0.0;
+    1120             : 
+    1121             :     // cycle on all affected voxels
+    1122           0 :     for(std::map<unsigned,double>::iterator itov=deltaov.begin(); itov!=deltaov.end(); ++itov) {
+    1123             :       // id of the component
+    1124           0 :       unsigned id = itov->first;
+    1125             :       // new value
+    1126           0 :       double ovmdnew = ovmd_[id]+itov->second;
+    1127             :       // deviations
+    1128           0 :       double devold = scale_ * ovmd_[id] + offset_ - ovdd_[id];
+    1129           0 :       double devnew = scale_ * ovmdnew   + offset_ - ovdd_[id];
+    1130             :       // inverse of sigma_min
+    1131           0 :       double ismin = ismin_[id];
+    1132             :       // scores
+    1133           0 :       if(devold==0.0) {
+    1134           0 :         old_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1135             :       } else {
+    1136           0 :         old_ene += -kbt_ * std::log( 0.5 / devold * erf ( devold * inv_sqrt2_ * ismin ));
+    1137             :       }
+    1138           0 :       if(devnew==0.0) {
+    1139           0 :         new_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1140             :       } else {
+    1141           0 :         new_ene += -kbt_ * std::log( 0.5 / devnew * erf ( devnew * inv_sqrt2_ * ismin ));
+    1142             :       }
+    1143             :     }
+    1144             : 
+    1145             :     // list of neighboring residues
+    1146           0 :     std::vector<unsigned> close = nl_res_[ir];
+    1147             :     // add restraint to keep Bfactors of close residues close
+    1148           0 :     for(unsigned i=0; i<close.size(); ++i) {
+    1149             :       // residue/chain IDs of neighbor
+    1150           0 :       std::pair<unsigned,std::string> keyn = Model_rlist_[close[i]];
+    1151             :       // deviations
+    1152           0 :       double devold = bfactold - Model_b_[keyn];
+    1153           0 :       double devnew = bfactnew - Model_b_[keyn];
+    1154             :       // inverse of sigma_min
+    1155           0 :       double ismin = 1.0 / bfactsig_;
+    1156             :       // scores
+    1157           0 :       if(devold==0.0) {
+    1158           0 :         old_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1159             :       } else {
+    1160           0 :         old_ene += -kbt_ * std::log( 0.5 / devold * erf ( devold * inv_sqrt2_ * ismin ));
+    1161             :       }
+    1162           0 :       if(devnew==0.0) {
+    1163           0 :         new_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1164             :       } else {
+    1165           0 :         new_ene += -kbt_ * std::log( 0.5 / devnew * erf ( devnew * inv_sqrt2_ * ismin ));
+    1166             :       }
+    1167             :     }
+    1168             : 
+    1169             :     // increment number of trials
+    1170           0 :     MCBtrials_ += 1.0;
+    1171             : 
+    1172             :     // accept or reject
+    1173             :     bool accept = false;
+    1174           0 :     if(bfactemin_) {
+    1175           0 :       if(new_ene < old_ene) accept = true;
+    1176             :     } else {
+    1177           0 :       accept = doAccept(old_ene, new_ene, kbt_);
+    1178             :     }
+    1179             : 
+    1180             :     // in case of acceptance
+    1181           0 :     if(accept) {
+    1182             :       // update acceptance rate
+    1183           0 :       MCBaccept_ += 1.0;
+    1184             :       // update bfactor
+    1185           0 :       Model_b_[key] = bfactnew;
+    1186             :       // change all the ovmd_ affected
+    1187           0 :       for(std::map<unsigned,double>::iterator itov=deltaov.begin(); itov!=deltaov.end(); ++itov)
+    1188           0 :         ovmd_[itov->first] += itov->second;
+    1189             :     }
+    1190             : 
+    1191             :   } // end cycle on bfactors
+    1192             : 
+    1193             : // update auxiliary lists (to update pref_gpu_, invs2_gpu_, and cut_ on CPU/GPU)
+    1194           0 :   get_auxiliary_vectors();
+    1195             : // update neighbor list (new cut_ + update pref_nl_gpu_ and invs2_nl_gpu_ on GPU)
+    1196           0 :   update_neighbor_list();
+    1197             : // recalculate fmod (to update derivatives)
+    1198           0 :   calculate_fmod();
+    1199           0 : }
+    1200             : 
+    1201             : // get overlap
+    1202           0 : double EMMIVOX::get_overlap(const Vector &d_m, const Vector &m_m,
+    1203             :                             const Vector5d &cfact, const Vector5d &m_s, double bfact)
+    1204             : {
+    1205             :   // calculate vector difference
+    1206           0 :   Vector md = delta(m_m, d_m);
+    1207             :   // norm squared
+    1208           0 :   double md2 = md[0]*md[0]+md[1]*md[1]+md[2]*md[2];
+    1209             :   // cycle on 5 Gaussians
+    1210             :   double ov_tot = 0.0;
+    1211           0 :   for(unsigned j=0; j<5; ++j) {
+    1212             :     // total value of b
+    1213           0 :     double m_b = m_s[j]+bfact/4.0;
+    1214             :     // calculate invs2
+    1215           0 :     double invs2 = 1.0/(inv_pi2_*m_b);
+    1216             :     // final calculation
+    1217           0 :     ov_tot += cfact[j] * pow(invs2, 1.5) * std::exp(-0.5 * md2 * invs2);
+    1218             :   }
+    1219           0 :   return ov_tot;
+    1220             : }
+    1221             : 
+    1222           0 : void EMMIVOX::update_neighbor_sphere()
+    1223             : {
+    1224             :   // number of atoms
+    1225           0 :   unsigned natoms = Model_type_.size();
+    1226             :   // clear neighbor sphere
+    1227             :   ns_.clear();
+    1228             :   // store reference positions
+    1229           0 :   refpos_ = getPositions();
+    1230             : 
+    1231             :   // cycle on voxels - in parallel
+    1232           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1233             :   {
+    1234             :     // private variables
+    1235             :     std::vector< std::pair<unsigned,unsigned> > ns_l;
+    1236             :     #pragma omp for
+    1237             :     for(unsigned id=0; id<ovdd_.size(); ++id) {
+    1238             :       // grid point
+    1239             :       Vector d_m = Map_m_[id];
+    1240             :       // cycle on atoms
+    1241             :       for(unsigned im=0; im<natoms; ++im) {
+    1242             :         // calculate distance
+    1243             :         double dist = delta(getPosition(im), d_m).modulo();
+    1244             :         // add to local list
+    1245             :         if(dist<=2.0*cut_[im]) ns_l.push_back(std::make_pair(id,im));
+    1246             :       }
+    1247             :     }
+    1248             :     // add to global list
+    1249             :     #pragma omp critical
+    1250             :     ns_.insert(ns_.end(), ns_l.begin(), ns_l.end());
+    1251             :   }
+    1252           0 : }
+    1253             : 
+    1254           0 : bool EMMIVOX::do_neighbor_sphere()
+    1255             : {
+    1256           0 :   std::vector<double> dist(getPositions().size());
+    1257             :   bool update = false;
+    1258             : 
+    1259             : // calculate displacement
+    1260           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1261             :   for(unsigned im=0; im<dist.size(); ++im) {
+    1262             :     dist[im] = delta(getPosition(im),refpos_[im]).modulo()/cut_[im];
+    1263             :   }
+    1264             : 
+    1265             : // check if update or not
+    1266           0 :   double maxdist = *max_element(dist.begin(), dist.end());
+    1267           0 :   if(maxdist>=1.0) update=true;
+    1268             : 
+    1269             : // return if update or not
+    1270           0 :   return update;
+    1271             : }
+    1272             : 
+    1273           0 : void EMMIVOX::update_neighbor_list()
+    1274             : {
+    1275             :   // number of atoms
+    1276           0 :   unsigned natoms = Model_type_.size();
+    1277             :   // clear neighbor list
+    1278             :   nl_.clear();
+    1279             : 
+    1280             :   // cycle on neighbour sphere - in parallel
+    1281           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1282             :   {
+    1283             :     // private variables
+    1284             :     std::vector< std::pair<unsigned,unsigned> > nl_l;
+    1285             :     #pragma omp for
+    1286             :     for(unsigned long long i=0; i<ns_.size(); ++i) {
+    1287             :       // calculate distance
+    1288             :       double dist = delta(Map_m_[ns_[i].first], getPosition(ns_[i].second)).modulo();
+    1289             :       // add to local neighbour list
+    1290             :       if(dist<=cut_[ns_[i].second]) nl_l.push_back(ns_[i]);
+    1291             :     }
+    1292             :     // add to global list
+    1293             :     #pragma omp critical
+    1294             :     nl_.insert(nl_.end(), nl_l.begin(), nl_l.end());
+    1295             :   }
+    1296             : 
+    1297             :   // new dimension of neighbor list
+    1298             :   unsigned long long nl_size = nl_.size();
+    1299             :   // now resize derivatives
+    1300           0 :   ovmd_der_.resize(nl_size);
+    1301             : 
+    1302             :   // in case of B-factors sampling - at the right step
+    1303           0 :   if(dbfact_>0 && getStep()%MCBstride_==0) {
+    1304             :     // clear vectors
+    1305           0 :     Model_nb_.clear(); Model_nb_.resize(natoms);
+    1306             :     // cycle over the neighbor list to creat a list of voxels per atom
+    1307           0 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1308             :     {
+    1309             :       // private variables
+    1310             :       std::vector< std::vector<unsigned> > Model_nb_l(natoms);
+    1311             :       #pragma omp for
+    1312             :       for(unsigned long long i=0; i<nl_size; ++i) {
+    1313             :         Model_nb_l[nl_[i].second].push_back(nl_[i].first);
+    1314             :       }
+    1315             :       // add to global list
+    1316             :       #pragma omp critical
+    1317             :       {
+    1318             :         for(unsigned i=0; i<natoms; ++i)
+    1319             :           Model_nb_[i].insert(Model_nb_[i].end(), Model_nb_l[i].begin(), Model_nb_l[i].end());
+    1320             :       }
+    1321             :     }
+    1322             :   }
+    1323             : 
+    1324             :   // transfer data to gpu
+    1325           0 :   update_gpu();
+    1326           0 : }
+    1327             : 
+    1328           0 : void EMMIVOX::update_gpu()
+    1329             : {
+    1330             :   // dimension of neighbor list
+    1331             :   long long nl_size = nl_.size();
+    1332             :   // create useful vectors
+    1333           0 :   std::vector<int> nl_id(nl_size), nl_im(nl_size);
+    1334           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1335             :   for(unsigned long long i=0; i<nl_size; ++i) {
+    1336             :     nl_id[i] = static_cast<int>(nl_[i].first);
+    1337             :     nl_im[i] = static_cast<int>(nl_[i].second);
+    1338             :   }
+    1339             :   // create tensors on device
+    1340           0 :   nl_id_gpu_ = torch::from_blob(nl_id.data(), {nl_size}, torch::kInt32).clone().to(device_t_);
+    1341           0 :   nl_im_gpu_ = torch::from_blob(nl_im.data(), {nl_size}, torch::kInt32).clone().to(device_t_);
+    1342             :   // now we need to create pref_nl_gpu_ [5,nl_size]
+    1343           0 :   pref_nl_gpu_  = torch::index_select(pref_gpu_,1,nl_im_gpu_);
+    1344             :   // and invs2_nl_gpu_ [5,nl_size]
+    1345           0 :   invs2_nl_gpu_ = torch::index_select(invs2_gpu_,1,nl_im_gpu_);
+    1346             :   // and Map_m_nl_gpu_ [3,nl_size]
+    1347           0 :   Map_m_nl_gpu_ = torch::index_select(Map_m_gpu_,1,nl_id_gpu_);
+    1348           0 : }
+    1349             : 
+    1350           0 : void EMMIVOX::prepare()
+    1351             : {
+    1352           0 :   if(getExchangeStep()) first_time_=true;
+    1353           0 : }
+    1354             : 
+    1355             : // calculate forward model on gpu
+    1356           0 : void EMMIVOX::calculate_fmod()
+    1357             : {
+    1358             :   // number of atoms
+    1359           0 :   int natoms = Model_type_.size();
+    1360             :   // number of data points
+    1361           0 :   int nd = ovdd_.size();
+    1362             : 
+    1363             :   // fill positions in in parallel
+    1364           0 :   std::vector<double> posg(3*natoms);
+    1365           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1366             :   for (int i=0; i<natoms; ++i) {
+    1367             :     // fill vectors
+    1368             :     posg[i]          = getPosition(i)[0];
+    1369             :     posg[i+natoms]   = getPosition(i)[1];
+    1370             :     posg[i+2*natoms] = getPosition(i)[2];
+    1371             :   }
+    1372             :   // transfer positions to pos_gpu [3,natoms]
+    1373           0 :   torch::Tensor pos_gpu = torch::from_blob(posg.data(), {3,natoms}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+    1374             :   // create pos_nl_gpu_ [3,nl_size]
+    1375           0 :   torch::Tensor pos_nl_gpu = torch::index_select(pos_gpu,1,nl_im_gpu_);
+    1376             :   // calculate vector difference [3,nl_size]
+    1377           0 :   torch::Tensor md = Map_m_nl_gpu_ - pos_nl_gpu;
+    1378             :   // calculate norm squared by column [1,nl_size]
+    1379           0 :   torch::Tensor md2 = torch::sum(md*md,0);
+    1380             :   // calculate density [5,nl_size]
+    1381           0 :   torch::Tensor ov = pref_nl_gpu_ * torch::exp(-0.5 * md2 * invs2_nl_gpu_);
+    1382             :   // and derivatives [5,nl_size]
+    1383           0 :   ovmd_der_gpu_ = invs2_nl_gpu_ * ov;
+    1384             :   // sum density over 5 columns [1,nl_size]
+    1385           0 :   ov = torch::sum(ov,0);
+    1386             :   // sum contributions from the same atom
+    1387           0 :   auto options = torch::TensorOptions().device(device_t_).dtype(torch::kFloat32);
+    1388           0 :   ovmd_gpu_ = torch::zeros({nd}, options);
+    1389           0 :   ovmd_gpu_.index_add_(0, nl_id_gpu_, ov);
+    1390             :   // sum derivatives over 5 rows [1,nl_size] and multiply by md [3,nl_size]
+    1391           0 :   ovmd_der_gpu_ = md * torch::sum(ovmd_der_gpu_,0);
+    1392             : 
+    1393             :   // in case of metainference: average them across replicas
+    1394           0 :   if(!no_aver_ && nrep_>1) {
+    1395             :     // communicate ovmd_gpu_ to CPU [1, nd]
+    1396           0 :     torch::Tensor ovmd_cpu = ovmd_gpu_.detach().to(torch::kCPU).to(torch::kFloat64);
+    1397             :     // and put them in ovmd_
+    1398           0 :     ovmd_ = std::vector<double>(ovmd_cpu.data_ptr<double>(), ovmd_cpu.data_ptr<double>() + ovmd_cpu.numel());
+    1399             :     // sum across replicas
+    1400           0 :     multi_sim_comm.Sum(&ovmd_[0], nd);
+    1401             :     // and divide by number of replicas
+    1402           0 :     double escale = 1.0 / static_cast<double>(nrep_);
+    1403           0 :     for(int i=0; i<nd; ++i) ovmd_[i] *= escale;
+    1404             :     // put back on device
+    1405           0 :     ovmd_gpu_ = torch::from_blob(ovmd_.data(), {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+    1406             :   }
+    1407             : 
+    1408             :   // communicate back model density
+    1409             :   // this is needed only in certain situations
+    1410           0 :   long int step = getStep();
+    1411             :   bool do_comm = false;
+    1412           0 :   if(mapstride_>0 && step%mapstride_==0) do_comm = true;
+    1413           0 :   if(dbfact_>0    && step%MCBstride_==0) do_comm = true;
+    1414           0 :   if(do_corr_) do_comm = true;
+    1415             :   // in case of metainference: already communicated
+    1416           0 :   if(!no_aver_ && nrep_>1) do_comm = false;
+    1417           0 :   if(do_comm) {
+    1418             :     // communicate ovmd_gpu_ to CPU [1, nd]
+    1419           0 :     torch::Tensor ovmd_cpu = ovmd_gpu_.detach().to(torch::kCPU).to(torch::kFloat64);
+    1420             :     // and put them in ovmd_
+    1421           0 :     ovmd_ = std::vector<double>(ovmd_cpu.data_ptr<double>(), ovmd_cpu.data_ptr<double>() + ovmd_cpu.numel());
+    1422             :   }
+    1423           0 : }
+    1424             : 
+    1425             : // calculate score
+    1426           0 : void EMMIVOX::calculate_score()
+    1427             : {
+    1428             :   // number of atoms
+    1429           0 :   int natoms = Model_type_.size();
+    1430             : 
+    1431             :   // calculate deviation model/data [1, nd]
+    1432           0 :   torch::Tensor dev = scale_ * ovmd_gpu_ + offset_ - ovdd_gpu_;
+    1433             :   // error function [1, nd]
+    1434           0 :   torch::Tensor errf = torch::erf( dev * inv_sqrt2_ * ismin_gpu_ );
+    1435             :   // take care of dev = zero
+    1436           0 :   torch::Tensor zeros_d = torch::ne(dev, 0.0);
+    1437             :   // redefine dev
+    1438           0 :   dev = dev * zeros_d + eps_ * torch::logical_not(zeros_d);
+    1439             :   // take care of errf = zero
+    1440           0 :   torch::Tensor zeros_e = torch::ne(errf, 0.0);
+    1441             :   // redefine errf
+    1442           0 :   errf = errf * zeros_e + eps_ * torch::logical_not(zeros_e);
+    1443             :   // logical AND: both dev and errf different from zero
+    1444             :   torch::Tensor zeros = torch::logical_and(zeros_d, zeros_e);
+    1445             :   // energy - with limit dev going to zero
+    1446           0 :   torch::Tensor ene = 0.5 * ( errf / dev * zeros + torch::logical_not(zeros) * sqrt2_pi_ *  ismin_gpu_);
+    1447             :   // logarithm and sum
+    1448           0 :   ene = -kbt_ * torch::sum(torch::log(ene));
+    1449             :   // and derivatives [1, nd]
+    1450           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 );
+    1451             :   // tensor for derivatives wrt atoms [1, nl_size]
+    1452           0 :   torch::Tensor der_gpu = torch::index_select(d_der,0,nl_id_gpu_);
+    1453             :   // multiply by ovmd_der_gpu_ and scale [3, nl_size]
+    1454           0 :   der_gpu = ovmd_der_gpu_ * scale_ * der_gpu;
+    1455             :   // sum contributions for each atom
+    1456           0 :   auto options = torch::TensorOptions().device(device_t_).dtype(torch::kFloat32);
+    1457           0 :   torch::Tensor atoms_der_gpu = torch::zeros({3,natoms}, options);
+    1458           0 :   atoms_der_gpu.index_add_(1, nl_im_gpu_, der_gpu);
+    1459             : 
+    1460             :   // FINAL STUFF
+    1461             :   //
+    1462             :   // 1) communicate total energy to CPU
+    1463           0 :   torch::Tensor ene_cpu = ene.detach().to(torch::kCPU).to(torch::kFloat64);
+    1464           0 :   ene_ = *ene_cpu.data_ptr<double>();
+    1465             :   // with marginal, simply multiply by number of replicas!
+    1466           0 :   if(!no_aver_ && nrep_>1) ene_ *= static_cast<double>(nrep_);
+    1467             :   //
+    1468             :   // 2) communicate derivatives to CPU
+    1469           0 :   torch::Tensor atom_der_cpu = atoms_der_gpu.detach().to(torch::kCPU).to(torch::kFloat64);
+    1470             :   // convert to std::vector<double>
+    1471           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());
+    1472             :   // and put in atom_der_
+    1473           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1474             :   for(int i=0; i<natoms; ++i) {
+    1475             :     atom_der_[i] = Vector(atom_der[i],atom_der[i+natoms],atom_der[i+2*natoms]);
+    1476             :   }
+    1477             :   //
+    1478             :   // 3) calculate virial on CPU
+    1479           0 :   Tensor virial;
+    1480             :   // declare omp reduction for Tensors
+    1481             :   #pragma omp declare reduction( sumTensor : Tensor : omp_out += omp_in )
+    1482             : 
+    1483           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads()) reduction (sumTensor : virial)
+    1484             :   for(int i=0; i<natoms; ++i) {
+    1485             :     virial += Tensor(getPosition(i), -atom_der_[i]);
+    1486             :   }
+    1487             :   // store virial
+    1488           0 :   virial_ = virial;
+    1489           0 : }
+    1490             : 
+    1491           0 : void EMMIVOX::calculate()
+    1492             : {
+    1493             :   // get time step
+    1494           0 :   long int step = getStep();
+    1495             : 
+    1496             :   // set temperature value
+    1497           0 :   getPntrToComponent("kbt")->set(kbt_);
+    1498             : 
+    1499             :   // neighbor list update
+    1500           0 :   if(first_time_ || getExchangeStep() || step%nl_stride_==0) {
+    1501             :     // check if time to update neighbor sphere
+    1502             :     bool update = false;
+    1503           0 :     if(first_time_ || getExchangeStep()) update = true;
+    1504           0 :     else update = do_neighbor_sphere();
+    1505             :     // update neighbor sphere
+    1506           0 :     if(update) update_neighbor_sphere();
+    1507             :     // update neighbor list
+    1508           0 :     update_neighbor_list();
+    1509             :     // set flag
+    1510           0 :     first_time_=false;
+    1511             :   }
+    1512             : 
+    1513             :   // calculate forward model
+    1514           0 :   calculate_fmod();
+    1515             : 
+    1516             :   // Monte Carlo on bfactors
+    1517           0 :   if(dbfact_>0) {
+    1518             :     double acc = 0.0;
+    1519             :     // do Monte Carlo
+    1520           0 :     if(step%MCBstride_==0 && !getExchangeStep() && step>0) doMonteCarloBfact();
+    1521             :     // calculate acceptance ratio
+    1522           0 :     if(MCBtrials_>0) acc = MCBaccept_ / MCBtrials_;
+    1523             :     // set value
+    1524           0 :     getPntrToComponent("accB")->set(acc);
+    1525             :   }
+    1526             : 
+    1527             :   // calculate score
+    1528           0 :   calculate_score();
+    1529             : 
+    1530             :   // set score, virial, and derivatives
+    1531           0 :   Value* score = getPntrToComponent("scoreb");
+    1532           0 :   score->set(ene_);
+    1533           0 :   setBoxDerivatives(score, virial_);
+    1534           0 :   #pragma omp parallel for
+    1535             :   for(unsigned i=0; i<atom_der_.size(); ++i) setAtomsDerivatives(score, i, atom_der_[i]);
+    1536             :   // set scale and offset value
+    1537           0 :   getPntrToComponent("scale")->set(scale_);
+    1538           0 :   getPntrToComponent("offset")->set(offset_);
+    1539             :   // calculate correlation coefficient
+    1540           0 :   if(do_corr_) calculate_corr();
+    1541             :   // PRINT other quantities to files
+    1542             :   // - status file
+    1543           0 :   if(step%statusstride_==0) print_status(step);
+    1544             :   // - density file
+    1545           0 :   if(mapstride_>0 && step%mapstride_==0) write_model_density(step);
+    1546           0 : }
+    1547             : 
+    1548           0 : void EMMIVOX::calculate_corr()
+    1549             : {
+    1550             : // number of data points
+    1551           0 :   double nd = static_cast<double>(ovdd_.size());
+    1552             : // average ovmd_ and ovdd_
+    1553           0 :   double ave_md = std::accumulate(ovmd_.begin(), ovmd_.end(), 0.) / nd;
+    1554           0 :   double ave_dd = std::accumulate(ovdd_.begin(), ovdd_.end(), 0.) / nd;
+    1555             : // calculate correlation
+    1556             :   double num = 0.;
+    1557             :   double den1 = 0.;
+    1558             :   double den2 = 0.;
+    1559           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads()) reduction( + : num, den1, den2)
+    1560             :   for(unsigned i=0; i<ovdd_.size(); ++i) {
+    1561             :     double md = ovmd_[i]-ave_md;
+    1562             :     double dd = ovdd_[i]-ave_dd;
+    1563             :     num  += md*dd;
+    1564             :     den1 += md*md;
+    1565             :     den2 += dd*dd;
+    1566             :   }
+    1567             : // correlation coefficient
+    1568           0 :   double cc = num / sqrt(den1*den2);
+    1569             : // set plumed
+    1570           0 :   getPntrToComponent("corr")->set(cc);
+    1571           0 : }
+    1572             : 
+    1573             : 
+    1574             : }
+    1575             : }
+    1576             : 
+    1577             : #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 000000000..d8e36d4e6 --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:353794.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..37b125c7f --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:353794.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..fc2828b6e --- /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:353794.6 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the fret efficiency between the input pair of atoms");
+     100          16 : }
+     101             : 
+     102          14 : FretEfficiency::FretEfficiency(const ActionOptions&ao):
+     103             :   PLUMED_COLVAR_INIT(ao),
+     104          14 :   pbc(true)
+     105             : {
+     106             :   std::vector<AtomNumber> atoms;
+     107          28 :   parseAtomList("ATOMS",atoms);
+     108          14 :   if(atoms.size()!=2)
+     109           0 :     error("Number of specified atoms should be 2");
+     110          14 :   parse("R0",R0_);
+     111          14 :   bool nopbc=!pbc;
+     112          14 :   parseFlag("NOPBC",nopbc);
+     113          14 :   pbc=!nopbc;
+     114          14 :   checkRead();
+     115             : 
+     116          14 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+     117          14 :   log.printf("  with Forster radius set to %lf\n",R0_);
+     118             : 
+     119          14 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     120           0 :   else    log.printf("  without periodic boundary conditions\n");
+     121             : 
+     122          28 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     123             : 
+     124          14 :   addValueWithDerivatives();
+     125          14 :   setNotPeriodic();
+     126             : 
+     127          14 :   requestAtoms(atoms);
+     128          14 : }
+     129             : 
+     130             : 
+     131             : // calculator
+     132         238 : void FretEfficiency::calculate() {
+     133             : 
+     134         238 :   if(pbc) makeWhole();
+     135             : 
+     136         238 :   Vector distance=delta(getPosition(0),getPosition(1));
+     137         238 :   const double dist_mod=distance.modulo();
+     138         238 :   const double inv_dist_mod=1.0/dist_mod;
+     139             : 
+     140         238 :   const double ratiosix=std::pow(dist_mod/R0_,6);
+     141         238 :   const double fret_eff = 1.0/(1.0+ratiosix);
+     142             : 
+     143         238 :   const double der = -6.0*fret_eff*fret_eff*ratiosix*inv_dist_mod;
+     144             : 
+     145         238 :   setAtomsDerivatives(0,-inv_dist_mod*der*distance);
+     146         476 :   setAtomsDerivatives(1, inv_dist_mod*der*distance);
+     147             :   setBoxDerivativesNoPbc();
+     148         238 :   setValue(fret_eff);
+     149             : 
+     150         238 : }
+     151             : 
+     152             : }
+     153             : }
+     154             : 
+     155             : 
+     156             : 
+
+
+
+ + + + +
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 000000000..91ed4d494 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:15917193.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..633d2c588 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:15917193.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..ccc12e612 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.gcov.html @@ -0,0 +1,469 @@ + + + + + + + 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:15917193.0 %
Date:2024-10-17 16:45:00Functions: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 3J coupling constants for a dihedral angle.
+      33             : 
+      34             : The J-coupling between two atoms is given by the Karplus relation:
+      35             : 
+      36             : \f[
+      37             : ^3J(\theta)=A\cos^2(\theta+\Delta\theta)+B\cos(\theta+\Delta\theta)+C
+      38             : \f]
+      39             : 
+      40             : where \f$A\f$, \f$B\f$ and \f$C\f$ are the Karplus parameters and \f$\Delta\theta\f$ is an additional constant
+      41             : added on to the dihedral angle \f$\theta\f$. The Karplus parameters are determined empirically and are dependent
+      42             : on the type of J-coupling.
+      43             : 
+      44             : This collective variable computes the J-couplings for a set of atoms defining a dihedral angle. You can specify
+      45             : the atoms involved using the \ref MOLINFO notation. You can also specify the experimental couplings using the
+      46             :  COUPLING keywords. These will be included in the output. You must choose the type of
+      47             : coupling using the type keyword, you can also supply custom Karplus parameters using TYPE=CUSTOM and the A, B, C
+      48             : and SHIFT keywords. You will need to make sure you are using the correct dihedral angle:
+      49             : 
+      50             : - Ha-N: \f$\psi\f$
+      51             : - Ha-HN: \f$\phi\f$
+      52             : - N-C\f$\gamma\f$: \f$\chi_1\f$
+      53             : - CO-C\f$\gamma\f$: \f$\chi_1\f$
+      54             : 
+      55             : J-couplings can be used to calculate a Metainference score using the internal keyword DOSCORE and all the options
+      56             : of \ref METAINFERENCE .
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : In the following example we calculate the Ha-N J-coupling from a set of atoms involved in
+      61             : dihedral \f$\psi\f$ angles in the peptide backbone. We also add the experimental data points and compute
+      62             : the correlation and other measures and finally print the results.
+      63             : 
+      64             : \plumedfile
+      65             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      66             : MOLINFO MOLTYPE=protein STRUCTURE=peptide.pdb
+      67             : WHOLEMOLECULES ENTITY0=1-111
+      68             : 
+      69             : JCOUPLING ...
+      70             :     TYPE=HAN
+      71             :     ATOMS1=@psi-2 COUPLING1=-0.49
+      72             :     ATOMS2=@psi-4 COUPLING2=-0.54
+      73             :     ATOMS3=@psi-5 COUPLING3=-0.53
+      74             :     ATOMS4=@psi-7 COUPLING4=-0.39
+      75             :     ATOMS5=@psi-8 COUPLING5=-0.39
+      76             :     LABEL=jhan
+      77             : ... JCOUPLING
+      78             : 
+      79             : jhanst: STATS ARG=(jhan\.j-.*) PARARG=(jhan\.exp-.*)
+      80             : 
+      81             : PRINT ARG=jhanst.*,jhan.* FILE=COLVAR STRIDE=100
+      82             : \endplumedfile
+      83             : 
+      84             : */
+      85             : //+ENDPLUMEDOC
+      86             : 
+      87             : class JCoupling :
+      88             :   public MetainferenceBase
+      89             : {
+      90             : private:
+      91             :   bool pbc;
+      92             :   enum { HAN, HAHN, CCG, NCG, CUSTOM };
+      93             :   unsigned ncoupl_;
+      94             :   double ka_;
+      95             :   double kb_;
+      96             :   double kc_;
+      97             :   double kshift_;
+      98             : 
+      99             : public:
+     100             :   static void registerKeywords(Keywords& keys);
+     101             :   explicit JCoupling(const ActionOptions&);
+     102             :   void calculate() override;
+     103             :   void update() override;
+     104             : };
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(JCoupling, "JCOUPLING")
+     107             : 
+     108           8 : void JCoupling::registerKeywords(Keywords& keys) {
+     109           8 :   MetainferenceBase::registerKeywords(keys);
+     110          16 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     111          16 :   keys.add("numbered", "ATOMS", "the 4 atoms involved in each of the bonds for which you wish to calculate the J-coupling. "
+     112             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one J-coupling will be "
+     113             :            "calculated for each ATOMS keyword you specify.");
+     114          16 :   keys.reset_style("ATOMS", "atoms");
+     115          16 :   keys.add("compulsory", "TYPE", "Type of J-coupling to compute (HAN,HAHN,CCG,NCG,CUSTOM)");
+     116          16 :   keys.add("optional", "A", "Karplus parameter A");
+     117          16 :   keys.add("optional", "B", "Karplus parameter B");
+     118          16 :   keys.add("optional", "C", "Karplus parameter C");
+     119          16 :   keys.add("optional", "SHIFT", "Angle shift in radians");
+     120          16 :   keys.add("numbered", "COUPLING", "Add an experimental value for each coupling");
+     121          16 :   keys.addOutputComponent("j", "default", "the calculated J-coupling");
+     122          16 :   keys.addOutputComponent("exp", "COUPLING", "the experimental J-coupling");
+     123           8 : }
+     124             : 
+     125           6 : JCoupling::JCoupling(const ActionOptions&ao):
+     126             :   PLUMED_METAINF_INIT(ao),
+     127           6 :   pbc(true)
+     128             : {
+     129           6 :   bool nopbc = !pbc;
+     130           6 :   parseFlag("NOPBC", nopbc);
+     131           6 :   pbc =! nopbc;
+     132             : 
+     133             :   // Read in the atoms
+     134             :   std::vector<AtomNumber> t, atoms;
+     135           6 :   for (int i = 1; ; ++i) {
+     136          68 :     parseAtomList("ATOMS", i, t );
+     137          34 :     if (t.empty()) {
+     138             :       break;
+     139             :     }
+     140             : 
+     141          28 :     if (t.size() != 4) {
+     142             :       std::string ss;
+     143           0 :       Tools::convert(i, ss);
+     144           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     145             :     }
+     146             : 
+     147             :     // This makes the distance calculation easier later on (see Torsion implementation)
+     148          28 :     atoms.push_back(t[0]);
+     149          28 :     atoms.push_back(t[1]);
+     150          28 :     atoms.push_back(t[1]);
+     151          28 :     atoms.push_back(t[2]);
+     152          28 :     atoms.push_back(t[2]);
+     153          28 :     atoms.push_back(t[3]);
+     154          28 :     t.resize(0);
+     155          28 :   }
+     156             : 
+     157             :   // We now have 6 atoms per datapoint
+     158           6 :   ncoupl_ = atoms.size()/6;
+     159             : 
+     160             :   // Parse J-Coupling type, this will determine the Karplus parameters
+     161             :   unsigned jtype_ = CUSTOM;
+     162             :   std::string string_type;
+     163          12 :   parse("TYPE", string_type);
+     164           6 :   if(string_type == "HAN") {
+     165             :     jtype_ = HAN;
+     166           5 :   } else if(string_type == "HAHN") {
+     167             :     jtype_ = HAHN;
+     168           2 :   } else if(string_type == "CCG") {
+     169             :     jtype_ = CCG;
+     170           1 :   } else if(string_type == "NCG") {
+     171             :     jtype_ = NCG;
+     172           0 :   } else if(string_type == "CUSTOM") {
+     173             :     jtype_ = CUSTOM;
+     174             :   } else {
+     175           0 :     error("Unknown J-coupling type!");
+     176             :   }
+     177             : 
+     178             :   // Optionally add an experimental value (like with RDCs)
+     179             :   std::vector<double> coupl;
+     180           6 :   coupl.resize( ncoupl_ );
+     181             :   unsigned ntarget=0;
+     182          13 :   for(unsigned i=0; i<ncoupl_; ++i) {
+     183          24 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     184           7 :     ntarget++;
+     185             :   }
+     186             :   bool addcoupling=false;
+     187           6 :   if(ntarget!=ncoupl_ && ntarget!=0) error("found wrong number of COUPLING values");
+     188           6 :   if(ntarget==ncoupl_) addcoupling=true;
+     189           6 :   if(getDoScore()&&!addcoupling) error("with DOSCORE you need to set the COUPLING values");
+     190             : 
+     191             :   // For custom types we allow use of custom Karplus parameters
+     192           6 :   if (jtype_ == CUSTOM) {
+     193           0 :     parse("A", ka_);
+     194           0 :     parse("B", kb_);
+     195           0 :     parse("C", kc_);
+     196           0 :     parse("SHIFT", kshift_);
+     197             :   }
+     198             : 
+     199           6 :   log << "  Bibliography ";
+     200          12 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     201             : 
+     202             :   // Set Karplus parameters
+     203           6 :   switch (jtype_) {
+     204           1 :   case HAN:
+     205           1 :     ka_ = -0.88;
+     206           1 :     kb_ = -0.61;
+     207           1 :     kc_ = -0.27;
+     208           1 :     kshift_ = pi / 3.0;
+     209           2 :     log << plumed.cite("Wang A C, Bax A, J. Am. Chem. Soc. 117, 1810 (1995)");
+     210           1 :     log<<"\n";
+     211           1 :     log.printf("  J-coupling type is HAN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     212             :     break;
+     213           3 :   case HAHN:
+     214           3 :     ka_ = 7.09;
+     215           3 :     kb_ = -1.42;
+     216           3 :     kc_ = 1.55;
+     217           3 :     kshift_ = -pi / 3.0;
+     218           6 :     log << plumed.cite("Hu J-S, Bax A, J. Am. Chem. Soc. 119, 6360 (1997)");
+     219           3 :     log<<"\n";
+     220           3 :     log.printf("  J-coupling type is HAHN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     221             :     break;
+     222           1 :   case CCG:
+     223           1 :     ka_ = 2.31;
+     224           1 :     kb_ = -0.87;
+     225           1 :     kc_ = 0.55;
+     226           1 :     kshift_ = (2.0 * pi) / 3.0;
+     227           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     228           1 :     log<<"\n";
+     229           1 :     log.printf("  J-coupling type is CCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     230             :     break;
+     231           1 :   case NCG:
+     232           1 :     ka_ = 1.29;
+     233           1 :     kb_ = -0.49;
+     234           1 :     kc_ = 0.37;
+     235           1 :     kshift_ = 0.0;
+     236           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     237           1 :     log<<"\n";
+     238           1 :     log.printf("  J-coupling type is NCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     239             :     break;
+     240           0 :   case CUSTOM:
+     241           0 :     log<<"\n";
+     242           0 :     log.printf("  J-coupling type is custom, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     243             :     break;
+     244             :   }
+     245             : 
+     246          34 :   for (unsigned i = 0; i < ncoupl_; ++i) {
+     247          28 :     log.printf("  The %uth J-Coupling is calculated from atoms : %d %d %d %d.",
+     248          28 :                i+1, atoms[6*i].serial(), atoms[6*i+1].serial(), atoms[6*i+3].serial(), atoms[6*i+5].serial());
+     249          28 :     if (addcoupling) {
+     250           7 :       log.printf(" Experimental J-Coupling is %f.", coupl[i]);
+     251             :     }
+     252          28 :     log.printf("\n");
+     253             :   }
+     254             : 
+     255           6 :   if (pbc) {
+     256           0 :     log.printf("  using periodic boundary conditions\n");
+     257             :   } else {
+     258           6 :     log.printf("  without periodic boundary conditions\n");
+     259             :   }
+     260             : 
+     261           6 :   if(!getDoScore()) {
+     262          26 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     263          21 :       std::string num; Tools::convert(i, num);
+     264          42 :       addComponentWithDerivatives("j-" + num);
+     265          42 :       componentIsNotPeriodic("j-" + num);
+     266             :     }
+     267             :   } else {
+     268           8 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     269           7 :       std::string num; Tools::convert(i, num);
+     270          14 :       addComponent("j-" + num);
+     271          14 :       componentIsNotPeriodic("j-" + num);
+     272             :     }
+     273             :   }
+     274             : 
+     275           6 :   if (addcoupling||getDoScore()) {
+     276           8 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     277           7 :       std::string num; Tools::convert(i, num);
+     278          14 :       addComponent("exp-" + num);
+     279           7 :       componentIsNotPeriodic("exp-" + num);
+     280           7 :       Value* comp = getPntrToComponent("exp-" + num);
+     281           7 :       comp->set(coupl[i]);
+     282             :     }
+     283             :   }
+     284             : 
+     285           6 :   requestAtoms(atoms, false);
+     286           6 :   if(getDoScore()) {
+     287           1 :     setParameters(coupl);
+     288           1 :     Initialise(ncoupl_);
+     289             :   }
+     290           6 :   setDerivatives();
+     291           6 :   checkRead();
+     292           6 : }
+     293             : 
+     294          16 : void JCoupling::calculate()
+     295             : {
+     296          16 :   if (pbc) makeWhole();
+     297          16 :   std::vector<Vector> deriv(ncoupl_*6);
+     298          16 :   std::vector<double> j(ncoupl_,0.);
+     299             : 
+     300          16 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+     301             :   {
+     302             :     #pragma omp for
+     303             :     // Loop through atoms, with steps of 6 atoms (one iteration per datapoint)
+     304             :     for (unsigned r=0; r<ncoupl_; r++) {
+     305             :       // Index is the datapoint index
+     306             :       unsigned a0 = 6*r;
+     307             : 
+     308             :       // 6 atoms -> 3 vectors
+     309             :       Vector d0 = delta(getPosition(a0+1), getPosition(a0));
+     310             :       Vector d1 = delta(getPosition(a0+3), getPosition(a0+2));
+     311             :       Vector d2 = delta(getPosition(a0+5), getPosition(a0+4));
+     312             : 
+     313             :       // Calculate dihedral with 3 vectors, get the derivatives
+     314             :       Vector dd0, dd1, dd2;
+     315             :       PLMD::Torsion t;
+     316             :       double torsion = t.compute(d0, d1, d2, dd0, dd1, dd2);
+     317             : 
+     318             :       // Calculate the Karplus relation and its derivative
+     319             :       double theta = torsion + kshift_;
+     320             :       double cos_theta = std::cos(theta);
+     321             :       double sin_theta = std::sin(theta);
+     322             :       j[r] = ka_*cos_theta*cos_theta + kb_*cos_theta + kc_;
+     323             :       double derj = -2.*ka_*sin_theta*cos_theta - kb_*sin_theta;
+     324             : 
+     325             :       dd0 *= derj;
+     326             :       dd1 *= derj;
+     327             :       dd2 *= derj;
+     328             : 
+     329             :       if(getDoScore()) setCalcData(r, j[r]);
+     330             :       deriv[a0] =  dd0;
+     331             :       deriv[a0+1] = -dd0;
+     332             :       deriv[a0+2] =  dd1;
+     333             :       deriv[a0+3] = -dd1;
+     334             :       deriv[a0+4] =  dd2;
+     335             :       deriv[a0+5] = -dd2;
+     336             :     }
+     337             :   }
+     338             : 
+     339          16 :   if(getDoScore()) {
+     340             :     /* Metainference */
+     341           6 :     double score = getScore();
+     342           6 :     setScore(score);
+     343             : 
+     344             :     /* calculate final derivatives */
+     345           6 :     Tensor virial;
+     346           6 :     Value* val=getPntrToComponent("score");
+     347          48 :     for (unsigned r=0; r<ncoupl_; r++) {
+     348          42 :       const unsigned a0 = 6*r;
+     349          42 :       setAtomsDerivatives(val, a0, deriv[a0]*getMetaDer(r));
+     350          42 :       setAtomsDerivatives(val, a0+1, deriv[a0+1]*getMetaDer(r));
+     351          42 :       setAtomsDerivatives(val, a0+2, deriv[a0+2]*getMetaDer(r));
+     352          42 :       setAtomsDerivatives(val, a0+3, deriv[a0+3]*getMetaDer(r));
+     353          42 :       setAtomsDerivatives(val, a0+4, deriv[a0+4]*getMetaDer(r));
+     354          42 :       setAtomsDerivatives(val, a0+5, deriv[a0+5]*getMetaDer(r));
+     355          42 :       virial-=Tensor(getPosition(a0), deriv[a0]*getMetaDer(r));
+     356          42 :       virial-=Tensor(getPosition(a0+1), deriv[a0+1]*getMetaDer(r));
+     357          42 :       virial-=Tensor(getPosition(a0+2), deriv[a0+2]*getMetaDer(r));
+     358          42 :       virial-=Tensor(getPosition(a0+3), deriv[a0+3]*getMetaDer(r));
+     359          42 :       virial-=Tensor(getPosition(a0+4), deriv[a0+4]*getMetaDer(r));
+     360          42 :       virial-=Tensor(getPosition(a0+5), deriv[a0+5]*getMetaDer(r));
+     361             :     }
+     362           6 :     setBoxDerivatives(val, virial);
+     363             :   } else {
+     364          66 :     for (unsigned r=0; r<ncoupl_; r++) {
+     365          56 :       const unsigned a0 = 6*r;
+     366          56 :       std::string num; Tools::convert(r,num);
+     367          56 :       Value* val=getPntrToComponent("j-"+num);
+     368          56 :       val->set(j[r]);
+     369          56 :       setAtomsDerivatives(val, a0, deriv[a0]);
+     370          56 :       setAtomsDerivatives(val, a0+1, deriv[a0+1]);
+     371          56 :       setAtomsDerivatives(val, a0+2, deriv[a0+2]);
+     372          56 :       setAtomsDerivatives(val, a0+3, deriv[a0+3]);
+     373          56 :       setAtomsDerivatives(val, a0+4, deriv[a0+4]);
+     374          56 :       setAtomsDerivatives(val, a0+5, deriv[a0+5]);
+     375          56 :       Tensor virial;
+     376          56 :       virial-=Tensor(getPosition(a0), deriv[a0]);
+     377          56 :       virial-=Tensor(getPosition(a0+1), deriv[a0+1]);
+     378          56 :       virial-=Tensor(getPosition(a0+2), deriv[a0+2]);
+     379          56 :       virial-=Tensor(getPosition(a0+3), deriv[a0+3]);
+     380          56 :       virial-=Tensor(getPosition(a0+4), deriv[a0+4]);
+     381          56 :       virial-=Tensor(getPosition(a0+5), deriv[a0+5]);
+     382          56 :       setBoxDerivatives(val, virial);
+     383             :     }
+     384             :   }
+     385          16 : }
+     386             : 
+     387          16 : void JCoupling::update() {
+     388             :   // write status file
+     389          16 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     390          16 : }
+     391             : 
+     392             : }
+     393             : }
+
+
+
+ + + + +
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 000000000..b2a7984c7 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func-sort-c.html @@ -0,0 +1,180 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..222c27ae3 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func.html @@ -0,0 +1,180 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a7d90d8ec --- /dev/null +++ b/coverage/isdb/Metainference.cpp.gcov.html @@ -0,0 +1,1878 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..052fff4e5 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html @@ -0,0 +1,184 @@ + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75388485.2 %
Date:2024-10-17 16:45:00Functions: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
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv112
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE112
_ZN4PLMD4isdb17MetainferenceBaseD2Ev112
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE128
_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 000000000..3e0ec5052 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func.html @@ -0,0 +1,184 @@ + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75388485.2 %
Date:2024-10-17 16:45:00Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv112
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv717
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv717
_ZN4PLMD4isdb17MetainferenceBase5applyEv717
_ZN4PLMD4isdb17MetainferenceBase8setScoreEd2225
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv2747
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE12016
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2771792
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv2828290
+
+
+ + + +
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 000000000..ea636c5bf --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv717
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv112
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv717
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE12016
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv2747
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2771792
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv2828290
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase5applyEv717
_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 000000000..b6776e153 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.gcov.html @@ -0,0 +1,462 @@ + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-10-17 16:45:00Functions: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       22634 :   return doscore_;
+     221             : }
+     222             : 
+     223             : inline
+     224             : unsigned MetainferenceBase::getWstride()
+     225             : {
+     226        1434 :   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         112 : void MetainferenceBase::setDerivatives() {
+     282             :   // Get appropriate number of derivatives
+     283             :   // Derivatives are first for arguments and then for atoms
+     284             :   unsigned nder;
+     285         112 :   if( getNumberOfAtoms()>0 ) {
+     286         112 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     287             :   } else {
+     288           0 :     nder = getNumberOfArguments();
+     289             :   }
+     290             : 
+     291             :   // Resize all derivative arrays
+     292         112 :   forces.resize( nder ); forcesToApply.resize( nder );
+     293       21460 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     294         112 : }
+     295             : 
+     296             : inline
+     297        2747 : void MetainferenceBase::turnOnDerivatives() {
+     298        2747 :   ActionWithValue::turnOnDerivatives();
+     299        2747 : }
+     300             : 
+     301             : inline
+     302     2828290 : unsigned MetainferenceBase::getNumberOfDerivatives() {
+     303     2828290 :   if( getNumberOfAtoms()>0 ) {
+     304     2828290 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     305             :   }
+     306           0 :   return getNumberOfArguments();
+     307             : }
+     308             : 
+     309             : inline
+     310         717 : void MetainferenceBase::lockRequests() {
+     311             :   ActionAtomistic::lockRequests();
+     312             :   ActionWithArguments::lockRequests();
+     313         717 : }
+     314             : 
+     315             : inline
+     316         717 : void MetainferenceBase::unlockRequests() {
+     317             :   ActionAtomistic::unlockRequests();
+     318             :   ActionWithArguments::unlockRequests();
+     319         717 : }
+     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         717 : void MetainferenceBase::apply() {
+     340         717 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     341       32982 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     342       32265 :     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         717 :   if( wasforced ) {
+     348         350 :     unsigned ind=0; addForcesOnArguments( 0, forcesToApply, ind, getLabel() );
+     349         350 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, ind );
+     350             :   }
+     351         717 : }
+     352             : 
+     353             : inline
+     354             : void MetainferenceBase::setArgDerivatives(Value *v, const double &d) {
+     355         160 :   v->addDerivative(0,d);
+     356             : }
+     357             : 
+     358             : inline
+     359     2771792 : void MetainferenceBase::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
+     360     2771792 :   const unsigned noa=getNumberOfArguments();
+     361     2771792 :   v->addDerivative(noa+3*i+0,d[0]);
+     362     2771792 :   v->addDerivative(noa+3*i+1,d[1]);
+     363     2771792 :   v->addDerivative(noa+3*i+2,d[2]);
+     364     2771792 : }
+     365             : 
+     366             : inline
+     367       12016 : void MetainferenceBase::setBoxDerivatives(Value* v,const Tensor&d) {
+     368       12016 :   const unsigned noa=getNumberOfArguments();
+     369             :   const unsigned nat=getNumberOfAtoms();
+     370       12016 :   v->addDerivative(noa+3*nat+0,d(0,0));
+     371       12016 :   v->addDerivative(noa+3*nat+1,d(0,1));
+     372       12016 :   v->addDerivative(noa+3*nat+2,d(0,2));
+     373       12016 :   v->addDerivative(noa+3*nat+3,d(1,0));
+     374       12016 :   v->addDerivative(noa+3*nat+4,d(1,1));
+     375       12016 :   v->addDerivative(noa+3*nat+5,d(1,2));
+     376       12016 :   v->addDerivative(noa+3*nat+6,d(2,0));
+     377       12016 :   v->addDerivative(noa+3*nat+7,d(2,1));
+     378       12016 :   v->addDerivative(noa+3*nat+8,d(2,2));
+     379       12016 : }
+     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 000000000..e76555e03 --- /dev/null +++ b/coverage/isdb/NOE.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:10110398.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..208a84d24 --- /dev/null +++ b/coverage/isdb/NOE.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:10110398.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..bbc033346 --- /dev/null +++ b/coverage/isdb/NOE.cpp.gcov.html @@ -0,0 +1,349 @@ + + + + + + + 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:10110398.1 %
Date:2024-10-17 16:45:00Functions: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 :   MetainferenceBase::registerKeywords(keys);
+      86          26 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      87          26 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+      88             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+      89             :            "calculated for each ATOM keyword you specify.");
+      90          26 :   keys.add("numbered","GROUPB","the atoms involved in each of the contacts you wish to calculate. "
+      91             :            "Keywords like GROUPB1, GROUPB2, GROUPB3,... should be listed and one contact will be "
+      92             :            "calculated for each ATOM keyword you specify.");
+      93          26 :   keys.reset_style("GROUPA","atoms");
+      94          26 :   keys.reset_style("GROUPB","atoms");
+      95          26 :   keys.add("numbered","NOEDIST","Add an experimental value for each NOE.");
+      96          26 :   keys.addOutputComponent("noe","default","the # NOE");
+      97          26 :   keys.addOutputComponent("exp","NOEDIST","the # NOE experimental distance");
+      98          13 : }
+      99             : 
+     100          11 : NOE::NOE(const ActionOptions&ao):
+     101             :   PLUMED_METAINF_INIT(ao),
+     102          11 :   pbc(true)
+     103             : {
+     104          11 :   bool nopbc=!pbc;
+     105          11 :   parseFlag("NOPBC",nopbc);
+     106          11 :   pbc=!nopbc;
+     107             : 
+     108             :   // Read in the atoms
+     109             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     110          22 :   for(int i=1;; ++i ) {
+     111          66 :     parseAtomList("GROUPA", i, t );
+     112          33 :     if( t.empty() ) break;
+     113          55 :     for(unsigned j=0; j<t.size(); j++) ga_lista.push_back(t[j]);
+     114          22 :     nga.push_back(t.size());
+     115          22 :     t.resize(0);
+     116          22 :   }
+     117             :   std::vector<unsigned> ngb;
+     118          22 :   for(int i=1;; ++i ) {
+     119          66 :     parseAtomList("GROUPB", i, t );
+     120          33 :     if( t.empty() ) break;
+     121          55 :     for(unsigned j=0; j<t.size(); j++) gb_lista.push_back(t[j]);
+     122          22 :     ngb.push_back(t.size());
+     123          22 :     if(ngb[i-1]!=nga[i-1]) error("The same number of atoms is expected for the same GROUPA-GROUPB couple");
+     124          22 :     t.resize(0);
+     125          22 :   }
+     126          11 :   if(nga.size()!=ngb.size()) error("There should be the same number of GROUPA and GROUPB keywords");
+     127             :   // Create neighbour lists
+     128          22 :   nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,false,true,pbc,getPbc(),comm);
+     129             : 
+     130             :   // Optionally add an experimental value (like with RDCs)
+     131             :   std::vector<double> noedist;
+     132          11 :   noedist.resize( nga.size() );
+     133             :   unsigned ntarget=0;
+     134          29 :   for(unsigned i=0; i<nga.size(); ++i) {
+     135          40 :     if( !parseNumbered( "NOEDIST", i+1, noedist[i] ) ) break;
+     136          18 :     ntarget++;
+     137             :   }
+     138             :   bool addexp=false;
+     139          11 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of NOEDIST values");
+     140          11 :   if(ntarget==nga.size()) addexp=true;
+     141          11 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the NOEDIST values");
+     142             : 
+     143             :   // Output details of all contacts
+     144             :   unsigned index=0;
+     145          33 :   for(unsigned i=0; i<nga.size(); ++i) {
+     146          22 :     log.printf("  The %uth NOE is calculated using %u equivalent couples of atoms\n", i, nga[i]);
+     147          55 :     for(unsigned j=0; j<nga[i]; j++) {
+     148          33 :       log.printf("    couple %u is %d %d.\n", j, ga_lista[index].serial(), gb_lista[index].serial() );
+     149          33 :       index++;
+     150             :     }
+     151             :   }
+     152          11 :   tot_size = index;
+     153             : 
+     154          11 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     155           0 :   else         log.printf("  without periodic boundary conditions\n");
+     156             : 
+     157          22 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     158             : 
+     159          11 :   if(!getDoScore()) {
+     160          21 :     for(unsigned i=0; i<nga.size(); i++) {
+     161          14 :       std::string num; Tools::convert(i,num);
+     162          28 :       addComponentWithDerivatives("noe-"+num);
+     163          28 :       componentIsNotPeriodic("noe-"+num);
+     164             :     }
+     165           7 :     if(addexp) {
+     166          15 :       for(unsigned i=0; i<nga.size(); i++) {
+     167          10 :         std::string num; Tools::convert(i,num);
+     168          20 :         addComponent("exp-"+num);
+     169          10 :         componentIsNotPeriodic("exp-"+num);
+     170          10 :         Value* comp=getPntrToComponent("exp-"+num);
+     171          10 :         comp->set(noedist[i]);
+     172             :       }
+     173             :     }
+     174             :   } else {
+     175          12 :     for(unsigned i=0; i<nga.size(); i++) {
+     176           8 :       std::string num; Tools::convert(i,num);
+     177          16 :       addComponent("noe-"+num);
+     178          16 :       componentIsNotPeriodic("noe-"+num);
+     179             :     }
+     180          12 :     for(unsigned i=0; i<nga.size(); i++) {
+     181           8 :       std::string num; Tools::convert(i,num);
+     182          16 :       addComponent("exp-"+num);
+     183           8 :       componentIsNotPeriodic("exp-"+num);
+     184           8 :       Value* comp=getPntrToComponent("exp-"+num);
+     185           8 :       comp->set(noedist[i]);
+     186             :     }
+     187             :   }
+     188             : 
+     189          11 :   requestAtoms(nl->getFullAtomList(), false);
+     190          11 :   if(getDoScore()) {
+     191           4 :     setParameters(noedist);
+     192           4 :     Initialise(nga.size());
+     193             :   }
+     194          11 :   setDerivatives();
+     195          11 :   checkRead();
+     196          11 : }
+     197             : 
+     198         456 : void NOE::calculate()
+     199             : {
+     200         456 :   const unsigned ngasz=nga.size();
+     201         456 :   std::vector<Vector> deriv(tot_size, Vector{0,0,0});
+     202             : 
+     203         456 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     204             :   for(unsigned i=0; i<ngasz; i++) {
+     205             :     Tensor dervir;
+     206             :     double noe=0;
+     207             :     unsigned index=0;
+     208             :     for(unsigned k=0; k<i; k++) index+=nga[k];
+     209             :     std::string num; Tools::convert(i,num);
+     210             :     Value* val=getPntrToComponent("noe-"+num);
+     211             :     // cycle over equivalent atoms
+     212             :     for(unsigned j=0; j<nga[i]; j++) {
+     213             :       const unsigned i0=nl->getClosePair(index+j).first;
+     214             :       const unsigned i1=nl->getClosePair(index+j).second;
+     215             : 
+     216             :       Vector distance;
+     217             :       if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     218             :       else    distance=delta(getPosition(i0),getPosition(i1));
+     219             : 
+     220             :       const double ir2=1./distance.modulo2();
+     221             :       const double ir6=ir2*ir2*ir2;
+     222             :       const double ir8=6*ir6*ir2;
+     223             : 
+     224             :       noe += ir6;
+     225             :       deriv[index+j] = ir8*distance;
+     226             :       if(!getDoScore()) {
+     227             :         dervir += Tensor(distance, deriv[index+j]);
+     228             :         setAtomsDerivatives(val, i0,  deriv[index+j]);
+     229             :         setAtomsDerivatives(val, i1, -deriv[index+j]);
+     230             :       }
+     231             :     }
+     232             :     val->set(noe);
+     233             :     if(!getDoScore()) {
+     234             :       setBoxDerivatives(val, dervir);
+     235             :     } else setCalcData(i, noe);
+     236             :   }
+     237             : 
+     238         456 :   if(getDoScore()) {
+     239             :     /* Metainference */
+     240          48 :     Tensor dervir;
+     241          48 :     double score = getScore();
+     242          48 :     setScore(score);
+     243             : 
+     244             :     /* calculate final derivatives */
+     245          48 :     Value* val=getPntrToComponent("score");
+     246         144 :     for(unsigned i=0; i<ngasz; i++) {
+     247             :       unsigned index=0;
+     248         144 :       for(unsigned k=0; k<i; k++) index+=nga[k];
+     249             :       // cycle over equivalent atoms
+     250         240 :       for(unsigned j=0; j<nga[i]; j++) {
+     251         144 :         const unsigned i0=nl->getClosePair(index+j).first;
+     252         144 :         const unsigned i1=nl->getClosePair(index+j).second;
+     253             : 
+     254         144 :         Vector distance;
+     255         144 :         if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     256           0 :         else    distance=delta(getPosition(i0),getPosition(i1));
+     257             : 
+     258         144 :         dervir += Tensor(distance,deriv[index+j]*getMetaDer(i));
+     259         144 :         setAtomsDerivatives(val, i0,  deriv[index+j]*getMetaDer(i));
+     260         144 :         setAtomsDerivatives(val, i1, -deriv[index+j]*getMetaDer(i));
+     261             :       }
+     262             :     }
+     263          48 :     setBoxDerivatives(val, dervir);
+     264             :   }
+     265         456 : }
+     266             : 
+     267         132 : void NOE::update() {
+     268             :   // write status file
+     269         132 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     270         132 : }
+     271             : 
+     272             : }
+     273             : }
+
+
+
+ + + + +
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 000000000..3b75e1515 --- /dev/null +++ b/coverage/isdb/PRE.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:11812892.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..00b2af1aa --- /dev/null +++ b/coverage/isdb/PRE.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:11812892.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..5894eaaa9 --- /dev/null +++ b/coverage/isdb/PRE.cpp.gcov.html @@ -0,0 +1,415 @@ + + + + + + + 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:11812892.2 %
Date:2024-10-17 16:45:00Functions: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 :   MetainferenceBase::registerKeywords(keys);
+      93          12 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      94          12 :   keys.addFlag("NORATIO",false,"Set to TRUE if you want to compute PRE without Intensity Ratio");
+      95          12 :   keys.add("compulsory","INEPT","is the INEPT time (in ms).");
+      96          12 :   keys.add("compulsory","TAUC","is the correlation time (in ns) for this electron-nuclear interaction.");
+      97          12 :   keys.add("compulsory","OMEGA","is the Larmor frequency of the nuclear spin (in MHz).");
+      98          12 :   keys.add("atoms","SPINLABEL","The atom to be used as the paramagnetic center.");
+      99          12 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+     100             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+     101             :            "calculated for each ATOM keyword you specify.");
+     102          12 :   keys.reset_style("GROUPA","atoms");
+     103          12 :   keys.add("numbered","RTWO","The relaxation of the atom/atoms in the corresponding GROUPA of atoms. "
+     104             :            "Keywords like RTWO1, RTWO2, RTWO3,... should be listed.");
+     105          12 :   keys.add("numbered","PREINT","Add an experimental value for each PRE.");
+     106          12 :   keys.addOutputComponent("pre","default","the # PRE");
+     107          12 :   keys.addOutputComponent("exp","PREINT","the # PRE experimental intensity");
+     108           6 : }
+     109             : 
+     110           4 : PRE::PRE(const ActionOptions&ao):
+     111             :   PLUMED_METAINF_INIT(ao),
+     112           4 :   pbc(true),
+     113           4 :   doratio(true)
+     114             : {
+     115           4 :   bool nopbc=!pbc;
+     116           4 :   parseFlag("NOPBC",nopbc);
+     117           4 :   pbc=!nopbc;
+     118             : 
+     119           4 :   bool noratio=!doratio;
+     120           4 :   parseFlag("NORATIO",noratio);
+     121           4 :   doratio=!noratio;
+     122             : 
+     123             :   std::vector<AtomNumber> atom;
+     124           8 :   parseAtomList("SPINLABEL",atom);
+     125           4 :   if(atom.size()!=1) error("Number of specified atom should be 1");
+     126             : 
+     127             :   // Read in the atoms
+     128             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     129          12 :   for(int i=1;; ++i ) {
+     130          32 :     parseAtomList("GROUPA", i, t );
+     131          16 :     if( t.empty() ) break;
+     132          28 :     for(unsigned j=0; j<t.size(); j++) {ga_lista.push_back(t[j]); gb_lista.push_back(atom[0]);}
+     133          12 :     nga.push_back(t.size());
+     134          12 :     t.resize(0);
+     135          12 :   }
+     136             : 
+     137             :   // Read in reference values
+     138           4 :   rtwo.resize( nga.size() );
+     139           4 :   if(doratio) {
+     140             :     unsigned ntarget=0;
+     141           4 :     for(unsigned i=0; i<nga.size(); ++i) {
+     142           8 :       if( !parseNumbered( "RTWO", i+1, rtwo[i] ) ) break;
+     143           0 :       ntarget++;
+     144             :     }
+     145           4 :     if( ntarget==0 ) {
+     146           4 :       parse("RTWO",rtwo[0]);
+     147          12 :       for(unsigned i=1; i<nga.size(); ++i) rtwo[i]=rtwo[0];
+     148           0 :     } else if( ntarget!=nga.size() ) error("found wrong number of RTWO values");
+     149             :   }
+     150             : 
+     151           4 :   double tauc=0.;
+     152           4 :   parse("TAUC",tauc);
+     153           4 :   if(tauc==0.) error("TAUC must be set");
+     154             : 
+     155           4 :   double omega=0.;
+     156           4 :   parse("OMEGA",omega);
+     157           4 :   if(omega==0.) error("OMEGA must be set");
+     158             : 
+     159           4 :   inept=0.;
+     160           4 :   if(doratio) {
+     161           4 :     parse("INEPT",inept);
+     162           4 :     if(inept==0.) error("INEPT must be set");
+     163           4 :     inept *= 0.001; // ms2s
+     164             :   }
+     165             : 
+     166             :   const double ns2s   = 0.000000001;
+     167             :   const double MHz2Hz = 1000000.;
+     168             :   const double Kappa  = 12300000000.00; // this is 1/15*S*(S+1)*gamma^2*g^2*beta^2
+     169             :   // where gamma is the nuclear gyromagnetic ratio,
+     170             :   // g is the electronic g factor, and beta is the Bohr magneton
+     171             :   // in nm^6/s^2
+     172           4 :   constant = (4.*tauc*ns2s+(3.*tauc*ns2s)/(1+omega*omega*MHz2Hz*MHz2Hz*tauc*tauc*ns2s*ns2s))*Kappa;
+     173             : 
+     174             :   // Optionally add an experimental value (like with RDCs)
+     175             :   std::vector<double> exppre;
+     176           4 :   exppre.resize( nga.size() );
+     177             :   unsigned ntarget=0;
+     178          10 :   for(unsigned i=0; i<nga.size(); ++i) {
+     179          16 :     if( !parseNumbered( "PREINT", i+1, exppre[i] ) ) break;
+     180           6 :     ntarget++;
+     181             :   }
+     182             :   bool addexp=false;
+     183           4 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of PREINT values");
+     184           4 :   if(ntarget==nga.size()) addexp=true;
+     185           4 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the PREINT values");
+     186             : 
+     187             :   // Create neighbour lists
+     188           8 :   nl=Tools::make_unique<NeighborList>(gb_lista,ga_lista,false,true,pbc,getPbc(),comm);
+     189             : 
+     190             :   // Output details of all contacts
+     191             :   unsigned index=0;
+     192          16 :   for(unsigned i=0; i<nga.size(); ++i) {
+     193          12 :     log.printf("  The %uth PRE is calculated using %u equivalent atoms:\n", i, nga[i]);
+     194          12 :     log.printf("    %d", ga_lista[index].serial());
+     195          12 :     index++;
+     196          16 :     for(unsigned j=1; j<nga[i]; j++) {
+     197           4 :       log.printf(" %d", ga_lista[index].serial());
+     198           4 :       index++;
+     199             :     }
+     200          12 :     log.printf("\n");
+     201             :   }
+     202           4 :   tot_size = index;
+     203             : 
+     204           4 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     205           0 :   else         log.printf("  without periodic boundary conditions\n");
+     206             : 
+     207           8 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     208             : 
+     209           4 :   if(!getDoScore()) {
+     210           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     211           6 :       std::string num; Tools::convert(i,num);
+     212          12 :       addComponentWithDerivatives("pre-"+num);
+     213          12 :       componentIsNotPeriodic("pre-"+num);
+     214             :     }
+     215           2 :     if(addexp) {
+     216           0 :       for(unsigned i=0; i<nga.size(); i++) {
+     217           0 :         std::string num; Tools::convert(i,num);
+     218           0 :         addComponent("exp-"+num);
+     219           0 :         componentIsNotPeriodic("exp-"+num);
+     220           0 :         Value* comp=getPntrToComponent("exp-"+num);
+     221           0 :         comp->set(exppre[i]);
+     222             :       }
+     223             :     }
+     224             :   } else {
+     225           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     226           6 :       std::string num; Tools::convert(i,num);
+     227          12 :       addComponent("pre-"+num);
+     228          12 :       componentIsNotPeriodic("pre-"+num);
+     229             :     }
+     230           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     231           6 :       std::string num; Tools::convert(i,num);
+     232          12 :       addComponent("exp-"+num);
+     233           6 :       componentIsNotPeriodic("exp-"+num);
+     234           6 :       Value* comp=getPntrToComponent("exp-"+num);
+     235           6 :       comp->set(exppre[i]);
+     236             :     }
+     237             :   }
+     238             : 
+     239           4 :   requestAtoms(nl->getFullAtomList(), false);
+     240           4 :   if(getDoScore()) {
+     241           2 :     setParameters(exppre);
+     242           2 :     Initialise(nga.size());
+     243             :   }
+     244           4 :   setDerivatives();
+     245           4 :   checkRead();
+     246           4 : }
+     247             : 
+     248         350 : void PRE::calculate()
+     249             : {
+     250         350 :   std::vector<Vector> deriv(tot_size, Vector{0,0,0});
+     251         350 :   std::vector<double> fact(nga.size(), 0.);
+     252             : 
+     253             :   // cycle over the number of PRE
+     254         350 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     255             :   for(unsigned i=0; i<nga.size(); i++) {
+     256             :     Tensor dervir;
+     257             :     double pre=0;
+     258             :     unsigned index=0;
+     259             :     for(unsigned k=0; k<i; k++) index+=nga[k];
+     260             :     const double c_aver=constant/static_cast<double>(nga[i]);
+     261             :     std::string num; Tools::convert(i,num);
+     262             :     Value* val=getPntrToComponent("pre-"+num);
+     263             :     // cycle over equivalent atoms
+     264             :     for(unsigned j=0; j<nga[i]; j++) {
+     265             :       // the first atom is always the same (the paramagnetic group)
+     266             :       const unsigned i0=nl->getClosePair(index+j).first;
+     267             :       const unsigned i1=nl->getClosePair(index+j).second;
+     268             : 
+     269             :       Vector distance;
+     270             :       if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     271             :       else    distance=delta(getPosition(i0),getPosition(i1));
+     272             : 
+     273             :       const double r2=distance.modulo2();
+     274             :       const double r6=r2*r2*r2;
+     275             :       const double r8=r6*r2;
+     276             :       const double tmpir6=c_aver/r6;
+     277             :       const double tmpir8=-6.*c_aver/r8;
+     278             : 
+     279             :       pre += tmpir6;
+     280             :       deriv[index+j] = -tmpir8*distance;
+     281             :       if(!getDoScore()) dervir   +=  Tensor(distance,deriv[index+j]);
+     282             :     }
+     283             :     double tmpratio;
+     284             :     if(!doratio) {
+     285             :       tmpratio = pre ; //prova a caso per vedere se lui da problemi
+     286             :       fact[i] = 1.; //prova a caso per vedere se lui da problemi
+     287             :     } else {
+     288             :       tmpratio = rtwo[i]*std::exp(-pre*inept) / (rtwo[i]+pre);
+     289             :       fact[i] = -tmpratio*(inept+1./(rtwo[i]+pre));
+     290             :     }
+     291             :     const double ratio = tmpratio;
+     292             :     val->set(ratio) ;
+     293             :     if(!getDoScore()) {
+     294             :       setBoxDerivatives(val, fact[i]*dervir);
+     295             :       for(unsigned j=0; j<nga[i]; j++) {
+     296             :         const unsigned i0=nl->getClosePair(index+j).first;
+     297             :         const unsigned i1=nl->getClosePair(index+j).second;
+     298             :         setAtomsDerivatives(val, i0,  fact[i]*deriv[index+j]);
+     299             :         setAtomsDerivatives(val, i1, -fact[i]*deriv[index+j]);
+     300             :       }
+     301             :     } else setCalcData(i, ratio);
+     302             :   }
+     303             : 
+     304         350 :   if(getDoScore()) {
+     305             :     /* Metainference */
+     306         175 :     Tensor dervir;
+     307         175 :     double score = getScore();
+     308         175 :     setScore(score);
+     309             : 
+     310             :     /* calculate final derivatives */
+     311         175 :     Value* val=getPntrToComponent("score");
+     312         700 :     for(unsigned i=0; i<nga.size(); i++) {
+     313             :       unsigned index=0;
+     314        1050 :       for(unsigned k=0; k<i; k++) index+=nga[k];
+     315             :       // cycle over equivalent atoms
+     316        1225 :       for(unsigned j=0; j<nga[i]; j++) {
+     317         700 :         const unsigned i0=nl->getClosePair(index+j).first;
+     318         700 :         const unsigned i1=nl->getClosePair(index+j).second;
+     319             : 
+     320         700 :         Vector distance;
+     321         700 :         if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     322           0 :         else    distance=delta(getPosition(i0),getPosition(i1));
+     323             : 
+     324         700 :         dervir += Tensor(distance,fact[i]*deriv[index+j]*getMetaDer(i));
+     325         700 :         setAtomsDerivatives(val, i0,  fact[i]*deriv[index+j]*getMetaDer(i));
+     326         700 :         setAtomsDerivatives(val, i1, -fact[i]*deriv[index+j]*getMetaDer(i));
+     327             :       }
+     328             :     }
+     329         175 :     setBoxDerivatives(val, dervir);
+     330             :   }
+     331         350 : }
+     332             : 
+     333          20 : void PRE::update() {
+     334             :   // write status file
+     335          20 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     336          20 : }
+     337             : 
+     338             : }
+     339             : }
+
+
+
+ + + + +
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 000000000..d911c8cd1 --- /dev/null +++ b/coverage/isdb/RDC.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:16918093.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..aea0ee099 --- /dev/null +++ b/coverage/isdb/RDC.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:16918093.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..adbe0d1d7 --- /dev/null +++ b/coverage/isdb/RDC.cpp.gcov.html @@ -0,0 +1,596 @@ + + + + + + + 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:16918093.9 %
Date:2024-10-17 16:45:00Functions: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 :   MetainferenceBase::registerKeywords(keys);
+     225          66 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     226          66 :   keys.add("numbered","ATOMS","the couple of atoms involved in each of the bonds for which you wish to calculate the RDC. "
+     227             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one dipolar coupling will be "
+     228             :            "calculated for each ATOMS keyword you specify.");
+     229          66 :   keys.reset_style("ATOMS","atoms");
+     230          66 :   keys.add("compulsory","GYROM","1.","Add the product of the gyromagnetic constants for the bond. ");
+     231          66 :   keys.add("compulsory","SCALE","1.","Add the scaling factor to take into account concentration and other effects. ");
+     232          66 :   keys.addFlag("SVD",false,"Set to TRUE if you want to back calculate using Single Value Decomposition (need GSL at compilation time).");
+     233          66 :   keys.add("numbered","COUPLING","Add an experimental value for each coupling (needed by SVD and useful for STATS).");
+     234          66 :   keys.addOutputComponent("rdc","default","the calculated # RDC");
+     235          66 :   keys.addOutputComponent("exp","SVD/COUPLING","the experimental # RDC");
+     236          66 :   keys.addOutputComponent("Sxx","SVD","Tensor component");
+     237          66 :   keys.addOutputComponent("Syy","SVD","Tensor component");
+     238          66 :   keys.addOutputComponent("Szz","SVD","Tensor component");
+     239          66 :   keys.addOutputComponent("Sxy","SVD","Tensor component");
+     240          66 :   keys.addOutputComponent("Sxz","SVD","Tensor component");
+     241          66 :   keys.addOutputComponent("Syz","SVD","Tensor component");
+     242          33 : }
+     243             : 
+     244          29 : RDC::RDC(const ActionOptions&ao):
+     245             :   PLUMED_METAINF_INIT(ao),
+     246          29 :   Const(1.),
+     247          29 :   mu_s(1.),
+     248          29 :   scale(1.),
+     249          29 :   pbc(true)
+     250             : {
+     251          29 :   bool nopbc=!pbc;
+     252          29 :   parseFlag("NOPBC",nopbc);
+     253          29 :   pbc=!nopbc;
+     254             : 
+     255             :   const double RDCConst = 0.3356806;
+     256             :   const double PCSConst = 1.0;
+     257             : 
+     258          29 :   if( getName().find("RDC")!=std::string::npos) { Const *= RDCConst; }
+     259           0 :   else if( getName().find("PCS")!=std::string::npos) { Const *= PCSConst; }
+     260             : 
+     261             :   // Read in the atoms
+     262             :   std::vector<AtomNumber> t, atoms;
+     263          29 :   for(int i=1;; ++i ) {
+     264         292 :     parseAtomList("ATOMS", i, t );
+     265         146 :     if( t.empty() ) break;
+     266         117 :     if( t.size()!=2 ) {
+     267           0 :       std::string ss; Tools::convert(i,ss);
+     268           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     269             :     }
+     270         117 :     atoms.push_back(t[0]);
+     271         117 :     atoms.push_back(t[1]);
+     272         117 :     t.resize(0);
+     273         117 :   }
+     274             : 
+     275          29 :   const unsigned ndata = atoms.size()/2;
+     276             : 
+     277             :   // Read in GYROMAGNETIC constants
+     278          29 :   parse("GYROM", mu_s);
+     279          29 :   if(mu_s==0.) error("GYROM cannot be 0");
+     280             : 
+     281             :   // Read in SCALING factors
+     282          29 :   parse("SCALE", scale);
+     283          29 :   if(scale==0.) error("SCALE cannot be 0");
+     284             : 
+     285          29 :   svd=false;
+     286          29 :   parseFlag("SVD",svd);
+     287             : #ifndef __PLUMED_HAS_GSL
+     288             :   if(svd) error("You CANNOT use SVD without GSL. Recompile PLUMED with GSL!\n");
+     289             : #endif
+     290          29 :   if(svd&&getDoScore()) error("It is not possible to use SVD and METAINFERENCE together");
+     291             : 
+     292             :   // Optionally add an experimental value
+     293          29 :   coupl.resize( ndata );
+     294             :   unsigned ntarget=0;
+     295          82 :   for(unsigned i=0; i<ndata; ++i) {
+     296         138 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     297          53 :     ntarget++;
+     298             :   }
+     299             :   bool addexp=false;
+     300          29 :   if(ntarget!=ndata && ntarget!=0) error("found wrong number of COUPLING values");
+     301          29 :   if(ntarget==ndata) addexp=true;
+     302          29 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the COUPLING values");
+     303          29 :   if(svd&&!addexp) error("with SVD you need to set the COUPLING values");
+     304             : 
+     305             : 
+     306             :   // Output details of all contacts
+     307          29 :   log.printf("  Gyromagnetic moment is %f. Scaling factor is %f.",mu_s,scale);
+     308         146 :   for(unsigned i=0; i<ndata; ++i) {
+     309         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());
+     310         117 :     if(addexp) log.printf(" Experimental coupling is %f.", coupl[i]);
+     311         117 :     log.printf("\n");
+     312             :   }
+     313             : 
+     314          29 :   log<<"  Bibliography "
+     315          58 :      <<plumed.cite("Camilloni C, Vendruscolo M, J. Phys. Chem. B 119, 653 (2015)")
+     316          87 :      <<plumed.cite("Camilloni C, Vendruscolo M, Biochemistry 54, 7470 (2015)");
+     317          58 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     318             : 
+     319             : 
+     320          29 :   if(!getDoScore()&&!svd) {
+     321          80 :     for(unsigned i=0; i<ndata; i++) {
+     322          64 :       std::string num; Tools::convert(i,num);
+     323         128 :       addComponentWithDerivatives("rdc-"+num);
+     324         128 :       componentIsNotPeriodic("rdc-"+num);
+     325             :     }
+     326          16 :     if(addexp) {
+     327           0 :       for(unsigned i=0; i<ndata; i++) {
+     328           0 :         std::string num; Tools::convert(i,num);
+     329           0 :         addComponent("exp-"+num);
+     330           0 :         componentIsNotPeriodic("exp-"+num);
+     331           0 :         Value* comp=getPntrToComponent("exp-"+num);
+     332           0 :         comp->set(coupl[i]);
+     333             :       }
+     334             :     }
+     335             :   } else {
+     336          66 :     for(unsigned i=0; i<ndata; i++) {
+     337          53 :       std::string num; Tools::convert(i,num);
+     338         106 :       addComponentWithDerivatives("rdc-"+num);
+     339         106 :       componentIsNotPeriodic("rdc-"+num);
+     340             :     }
+     341          66 :     for(unsigned i=0; i<ndata; i++) {
+     342          53 :       std::string num; Tools::convert(i,num);
+     343         106 :       addComponent("exp-"+num);
+     344          53 :       componentIsNotPeriodic("exp-"+num);
+     345          53 :       Value* comp=getPntrToComponent("exp-"+num);
+     346          53 :       comp->set(coupl[i]);
+     347             :     }
+     348             :   }
+     349             : 
+     350          29 :   if(svd) {
+     351           3 :     addComponent("Sxx"); componentIsNotPeriodic("Sxx");
+     352           3 :     addComponent("Syy"); componentIsNotPeriodic("Syy");
+     353           3 :     addComponent("Szz"); componentIsNotPeriodic("Szz");
+     354           3 :     addComponent("Sxy"); componentIsNotPeriodic("Sxy");
+     355           3 :     addComponent("Sxz"); componentIsNotPeriodic("Sxz");
+     356           3 :     addComponent("Syz"); componentIsNotPeriodic("Syz");
+     357             :   }
+     358             : 
+     359          29 :   requestAtoms(atoms, false);
+     360          29 :   if(getDoScore()) {
+     361          12 :     setParameters(coupl);
+     362          12 :     Initialise(coupl.size());
+     363             :   }
+     364          29 :   setDerivatives();
+     365          29 :   checkRead();
+     366          29 : }
+     367             : 
+     368           5 : void RDC::do_svd()
+     369             : {
+     370             : #ifdef __PLUMED_HAS_GSL
+     371           5 :   gsl_vector_unique_ptr rdc_vec(gsl_vector_alloc(coupl.size())),
+     372           5 :                         S(gsl_vector_alloc(5)),
+     373           5 :                         Stmp(gsl_vector_alloc(5)),
+     374           5 :                         work(gsl_vector_alloc(5)),
+     375           5 :                         bc(gsl_vector_alloc(coupl.size()));
+     376             : 
+     377           5 :   gsl_matrix_unique_ptr coef_mat(gsl_matrix_alloc(coupl.size(),5)),
+     378           5 :                         A(gsl_matrix_alloc(coupl.size(),5)),
+     379           5 :                         V(gsl_matrix_alloc(5,5));
+     380             : 
+     381           5 :   gsl_matrix_set_zero(coef_mat.get());
+     382           5 :   gsl_vector_set_zero(bc.get());
+     383             : 
+     384             :   unsigned index=0;
+     385           5 :   std::vector<double> dmax(coupl.size());
+     386          30 :   for(unsigned r=0; r<getNumberOfAtoms(); r+=2) {
+     387          25 :     Vector  distance;
+     388          25 :     if(pbc) distance = pbcDistance(getPosition(r),getPosition(r+1));
+     389           0 :     else    distance = delta(getPosition(r),getPosition(r+1));
+     390          25 :     double d    = distance.modulo();
+     391          25 :     double d2   = d*d;
+     392          25 :     double d3   = d2*d;
+     393          25 :     double id3  = 1./d3;
+     394          25 :     double max  = -Const*mu_s*scale;
+     395          25 :     dmax[index] = id3*max;
+     396          25 :     double mu_x = distance[0]/d;
+     397          25 :     double mu_y = distance[1]/d;
+     398          25 :     double mu_z = distance[2]/d;
+     399          25 :     gsl_vector_set(rdc_vec.get(),index,coupl[index]/dmax[index]);
+     400          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));
+     401          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));
+     402          25 :     gsl_matrix_set(coef_mat.get(),index,2,gsl_matrix_get(coef_mat.get(),index,2)+(2.0*mu_x*mu_y));
+     403          25 :     gsl_matrix_set(coef_mat.get(),index,3,gsl_matrix_get(coef_mat.get(),index,3)+(2.0*mu_x*mu_z));
+     404          25 :     gsl_matrix_set(coef_mat.get(),index,4,gsl_matrix_get(coef_mat.get(),index,4)+(2.0*mu_y*mu_z));
+     405          25 :     index++;
+     406             :   }
+     407           5 :   gsl_matrix_memcpy(A.get(),coef_mat.get());
+     408           5 :   gsl_linalg_SV_decomp(A.get(), V.get(), Stmp.get(), work.get());
+     409           5 :   gsl_linalg_SV_solve(A.get(), V.get(), Stmp.get(), rdc_vec.get(), S.get());
+     410             :   /* tensor */
+     411             :   Value* tensor;
+     412           5 :   tensor=getPntrToComponent("Sxx");
+     413           5 :   double Sxx = gsl_vector_get(S.get(),0);
+     414             :   tensor->set(Sxx);
+     415           5 :   tensor=getPntrToComponent("Syy");
+     416           5 :   double Syy = gsl_vector_get(S.get(),1);
+     417             :   tensor->set(Syy);
+     418           5 :   tensor=getPntrToComponent("Szz");
+     419           5 :   double Szz = -Sxx-Syy;
+     420             :   tensor->set(Szz);
+     421           5 :   tensor=getPntrToComponent("Sxy");
+     422           5 :   double Sxy = gsl_vector_get(S.get(),2);
+     423             :   tensor->set(Sxy);
+     424           5 :   tensor=getPntrToComponent("Sxz");
+     425           5 :   double Sxz = gsl_vector_get(S.get(),3);
+     426             :   tensor->set(Sxz);
+     427           5 :   tensor=getPntrToComponent("Syz");
+     428           5 :   double Syz = gsl_vector_get(S.get(),4);
+     429             :   tensor->set(Syz);
+     430             : 
+     431           5 :   gsl_blas_dgemv(CblasNoTrans, 1.0, coef_mat.get(), S.get(), 0., bc.get());
+     432          30 :   for(index=0; index<coupl.size(); index++) {
+     433          25 :     double rdc = gsl_vector_get(bc.get(),index)*dmax[index];
+     434          25 :     Value* val=getPntrToComponent(index);
+     435             :     val->set(rdc);
+     436             :   }
+     437             : #endif
+     438           5 : }
+     439             : 
+     440        2172 : void RDC::calculate()
+     441             : {
+     442        2172 :   if(svd) {
+     443           5 :     do_svd();
+     444           5 :     return;
+     445             :   }
+     446             : 
+     447        2167 :   const double max  = -Const*scale*mu_s;
+     448             :   const unsigned N=getNumberOfAtoms();
+     449        2167 :   std::vector<Vector> dRDC(N/2, Vector{0.,0.,0.});
+     450             : 
+     451             :   /* RDC Calculations and forces */
+     452        2167 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+     453             :   {
+     454             :     #pragma omp for
+     455             :     for(unsigned r=0; r<N; r+=2)
+     456             :     {
+     457             :       const unsigned index=r/2;
+     458             :       Vector  distance;
+     459             :       if(pbc) distance   = pbcDistance(getPosition(r),getPosition(r+1));
+     460             :       else    distance   = delta(getPosition(r),getPosition(r+1));
+     461             :       const double d2    = distance.modulo2();
+     462             :       const double ind   = 1./std::sqrt(d2);
+     463             :       const double ind2  = 1./d2;
+     464             :       const double ind3  = ind2*ind;
+     465             :       const double x2    = distance[0]*distance[0]*ind2;
+     466             :       const double y2    = distance[1]*distance[1]*ind2;
+     467             :       const double z2    = distance[2]*distance[2]*ind2;
+     468             :       const double dmax  = ind3*max;
+     469             :       const double ddmax = dmax*ind2;
+     470             : 
+     471             :       const double rdc   = 0.5*dmax*(3.*z2-1.);
+     472             :       const double prod_xy = (x2+y2-4.*z2);
+     473             :       const double prod_z =  (3.*x2 + 3.*y2 - 2.*z2);
+     474             : 
+     475             :       dRDC[index] = -1.5*ddmax*distance;
+     476             :       dRDC[index][0] *= prod_xy;
+     477             :       dRDC[index][1] *= prod_xy;
+     478             :       dRDC[index][2] *= prod_z;
+     479             : 
+     480             :       std::string num; Tools::convert(index,num);
+     481             :       Value* val=getPntrToComponent("rdc-"+num);
+     482             :       val->set(rdc);
+     483             :       if(!getDoScore()) {
+     484             :         setBoxDerivatives(val, Tensor(distance,dRDC[index]));
+     485             :         setAtomsDerivatives(val, r,  dRDC[index]);
+     486             :         setAtomsDerivatives(val, r+1, -dRDC[index]);
+     487             :       } else setCalcData(index, rdc);
+     488             :     }
+     489             :   }
+     490             : 
+     491        2167 :   if(getDoScore()) {
+     492             :     /* Metainference */
+     493        1824 :     Tensor dervir;
+     494        1824 :     double score = getScore();
+     495        1824 :     setScore(score);
+     496             : 
+     497             :     /* calculate final derivatives */
+     498        1824 :     Value* val=getPntrToComponent("score");
+     499        9120 :     for(unsigned r=0; r<N; r+=2)
+     500             :     {
+     501        7296 :       const unsigned index=r/2;
+     502        7296 :       Vector  distance;
+     503        7296 :       if(pbc) distance   = pbcDistance(getPosition(r),getPosition(r+1));
+     504           0 :       else    distance   = delta(getPosition(r),getPosition(r+1));
+     505        7296 :       const Vector der = dRDC[index]*getMetaDer(index);
+     506        7296 :       dervir += Tensor(distance, der);
+     507        7296 :       setAtomsDerivatives(val, r,  der);
+     508        7296 :       setAtomsDerivatives(val, r+1, -der);
+     509             :     }
+     510        1824 :     setBoxDerivatives(val, dervir);
+     511             :   }
+     512             : }
+     513             : 
+     514         327 : void RDC::update() {
+     515             :   // write status file
+     516         327 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     517         327 : }
+     518             : 
+     519             : }
+     520             : }
+
+
+
+ + + + +
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 000000000..6f2e0b354 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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:2018510.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..c2df658f0 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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:2018510.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..133b4706d --- /dev/null +++ b/coverage/isdb/Rescale.cpp.gcov.html @@ -0,0 +1,588 @@ + + + + + + + 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:2018510.8 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.addOutputComponent("igamma",  "default","gamma parameter");
+     181           4 :   keys.addOutputComponent("accgamma","default","MC acceptance for gamma");
+     182           4 :   keys.addOutputComponent("wtbias",  "default","well-tempered bias");
+     183           2 : }
+     184             : 
+     185           0 : Rescale::Rescale(const ActionOptions&ao):
+     186             :   PLUMED_BIAS_INIT(ao),
+     187           0 :   nores_(0), Biaspace_(1), first_bias_(true),
+     188           0 :   MCsteps_(1), MCstride_(1), MCfirst_(-1), MCaccgamma_(0)
+     189             : {
+     190             :   // set up replica stuff
+     191           0 :   if(comm.Get_rank()==0) {
+     192           0 :     nrep_    = multi_sim_comm.Get_size();
+     193           0 :     replica_ = multi_sim_comm.Get_rank();
+     194             :   } else {
+     195           0 :     nrep_    = 0;
+     196           0 :     replica_ = 0;
+     197             :   }
+     198           0 :   comm.Sum(&nrep_,1);
+     199           0 :   comm.Sum(&replica_,1);
+     200             : 
+     201             :   // wt-parameters
+     202           0 :   parse("W0", w0_);
+     203           0 :   parse("BIASFACTOR", biasf_);
+     204             : 
+     205             :   // selector name
+     206           0 :   parse("SELECTOR", selector_);
+     207             : 
+     208             :   // number of bins for gamma ladder
+     209             :   unsigned nbin;
+     210           0 :   parse("NBIN", nbin);
+     211             : 
+     212             :   // number of bias
+     213           0 :   parse("NOT_RESCALED", nores_);
+     214           0 :   if(nores_>0 && nores_!=nbin) error("The number of non scaled arguments must be equal to either 0 or the number of bins");
+     215             : 
+     216             :   // maximum value of rescale
+     217             :   std::vector<double> max_rescale;
+     218           0 :   parseVector("MAX_RESCALE", max_rescale);
+     219             :   // check dimension of max_rescale
+     220           0 :   if(max_rescale.size()!=(getNumberOfArguments()-nores_))
+     221           0 :     error("Size of MAX_RESCALE array must be equal to the number of arguments that will to be scaled");
+     222             : 
+     223             :   // calculate exponents
+     224           0 :   double igamma_max = static_cast<double>(nbin);
+     225           0 :   for(unsigned i=0; i<max_rescale.size(); ++i)
+     226           0 :     expo_.push_back(std::log(max_rescale[i])/std::log(igamma_max));
+     227             : 
+     228             :   // allocate gamma grid and set bias to zero
+     229           0 :   for(unsigned i=0; i<nbin; ++i) {
+     230             :     // bias grid
+     231           0 :     bias_.push_back(0.0);
+     232             :     // gamma ladder
+     233           0 :     double gamma = std::exp( static_cast<double>(i) / static_cast<double>(nbin-1) * std::log(igamma_max) );
+     234           0 :     gamma_.push_back(gamma);
+     235             :   }
+     236             :   // print bias to file
+     237           0 :   parse("BSTRIDE", Biasstride_);
+     238           0 :   parse("BFILE",   Biasfilename_);
+     239             : 
+     240             :   // create vectors of shared arguments
+     241             :   // by default they are all shared
+     242           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) shared_.push_back(1);
+     243             :   // share across replicas or not
+     244             :   std::vector<unsigned> not_shared;
+     245           0 :   parseVector("NOT_SHARED", not_shared);
+     246             :   // and change the non-shared
+     247           0 :   for(unsigned i=0; i<not_shared.size(); ++i) {
+     248           0 :     if((not_shared[i]-1)>=(getNumberOfArguments()-nores_) && nrep_>1)
+     249           0 :       error("NOT_RESCALED args must always be shared when using multiple replicas");
+     250           0 :     if((not_shared[i]-1)>=getNumberOfArguments())
+     251           0 :       error("NOT_SHARED args should be lower than total number of arguments");
+     252           0 :     shared_[not_shared[i]-1] = 0;
+     253             :   }
+     254             : 
+     255             :   // monte carlo stuff
+     256           0 :   parse("MC_STEPS",MCsteps_);
+     257           0 :   parse("MC_STRIDE",MCstride_);
+     258             :   // adjust for multiple-time steps
+     259           0 :   MCstride_ *= getStride();
+     260             :   // read bias deposition pace
+     261           0 :   parse("PACE", Biaspace_);
+     262             :   // multiply by MCstride
+     263           0 :   Biaspace_ *= MCstride_;
+     264             : 
+     265             :   // get temperature
+     266           0 :   kbt_=getkBT();
+     267             : 
+     268           0 :   checkRead();
+     269             : 
+     270           0 :   log.printf("  temperature of the system in energy unit %f\n",kbt_);
+     271           0 :   log.printf("  name of the SELECTOR use for this action %s\n",selector_.c_str());
+     272           0 :   log.printf("  number of bins in grid %u\n",nbin);
+     273           0 :   log.printf("  number of arguments that will not be scaled %u\n",nores_);
+     274           0 :   if(nrep_>1) log<<"  number of arguments that will not be summed across replicas "<<not_shared.size()<<"\n";
+     275           0 :   log.printf("  biasfactor %f\n",biasf_);
+     276           0 :   log.printf("  initial hills height %f\n",w0_);
+     277           0 :   log.printf("  stride to write bias to file %u\n",Biasstride_);
+     278           0 :   log.printf("  write bias to file : %s\n",Biasfilename_.c_str());
+     279           0 :   log.printf("  number of replicas %u\n",nrep_);
+     280           0 :   log.printf("  number of MC steps %d\n",MCsteps_);
+     281           0 :   log.printf("  do MC every %d steps\n", MCstride_);
+     282           0 :   log.printf("\n");
+     283             : 
+     284           0 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     285             : 
+     286             : 
+     287             :   // add components
+     288           0 :   addComponent("igamma");   componentIsNotPeriodic("igamma");
+     289           0 :   addComponent("accgamma"); componentIsNotPeriodic("accgamma");
+     290           0 :   addComponent("wtbias");   componentIsNotPeriodic("wtbias");
+     291             : 
+     292             :   // initialize random seed
+     293           0 :   srand (time(NULL));
+     294             : 
+     295             :   // read bias if restarting
+     296           0 :   if(getRestart()) read_bias();
+     297           0 : }
+     298             : 
+     299           0 : Rescale::~Rescale()
+     300             : {
+     301           0 :   Biasfile_.close();
+     302           0 : }
+     303             : 
+     304           0 : void Rescale::read_bias()
+     305             : {
+     306             : // open file
+     307             :   auto ifile=Tools::make_unique<IFile>();
+     308           0 :   ifile->link(*this);
+     309           0 :   if(ifile->FileExist(Biasfilename_)) {
+     310           0 :     ifile->open(Biasfilename_);
+     311             :     // read all the lines, store last value of bias
+     312             :     double MDtime;
+     313           0 :     while(ifile->scanField("MD_time",MDtime)) {
+     314           0 :       for(unsigned i=0; i<bias_.size(); ++i) {
+     315             :         // convert i to string
+     316           0 :         std::stringstream ss;
+     317             :         ss << i;
+     318             :         // label
+     319           0 :         std::string label = "b" + ss.str();
+     320             :         // read entry
+     321           0 :         ifile->scanField(label, bias_[i]);
+     322           0 :       }
+     323             :       // new line
+     324           0 :       ifile->scanField();
+     325             :     }
+     326           0 :     ifile->close();
+     327             :   } else {
+     328           0 :     error("Cannot find bias file "+Biasfilename_+"\n");
+     329             :   }
+     330           0 : }
+     331             : 
+     332           0 : unsigned Rescale::proposeMove(unsigned x, unsigned xmin, unsigned xmax)
+     333             : {
+     334           0 :   int xmin_i = static_cast<int>(xmin);
+     335           0 :   int xmax_i = static_cast<int>(xmax);
+     336             :   int dx;
+     337           0 :   int r = rand() % 2;
+     338           0 :   if( r % 2 == 0 ) dx = +1;
+     339             :   else             dx = -1;
+     340             : // new index, integer
+     341           0 :   int x_new = static_cast<int>(x) + dx;
+     342             : // check boundaries
+     343           0 :   if(x_new >= xmax_i) x_new = xmax_i-1;
+     344             :   if(x_new <  xmin_i) x_new = xmin_i;
+     345           0 :   return static_cast<unsigned>(x_new);
+     346             : }
+     347             : 
+     348           0 : bool Rescale::doAccept(double oldE, double newE)
+     349             : {
+     350             :   bool accept = false;
+     351             :   // calculate delta energy
+     352           0 :   double delta = ( newE - oldE ) / kbt_;
+     353             :   // if delta is negative always accept move
+     354           0 :   if( delta < 0.0 ) {
+     355             :     accept = true;
+     356             :   } else {
+     357             :     // otherwise extract random number
+     358           0 :     double s = static_cast<double>(rand()) / RAND_MAX;
+     359           0 :     if( s < std::exp(-delta) ) { accept = true; }
+     360             :   }
+     361           0 :   return accept;
+     362             : }
+     363             : 
+     364           0 : void Rescale::doMonteCarlo(unsigned igamma, double oldE,
+     365             :                            const std::vector<double> & args, const std::vector<double> & bargs)
+     366             : {
+     367             :   double oldB, newB;
+     368             : 
+     369             : // cycle on MC steps
+     370           0 :   for(unsigned i=0; i<MCsteps_; ++i) {
+     371             :     // propose move in igamma
+     372           0 :     unsigned new_igamma = proposeMove(igamma, 0, gamma_.size());
+     373             :     // calculate new energy
+     374             :     double newE = 0.0;
+     375           0 :     for(unsigned j=0; j<args.size(); ++j) {
+     376             :       // calculate energy term
+     377           0 :       double fact = 1.0/pow(gamma_[new_igamma], expo_[j]) - 1.0;
+     378           0 :       newE += args[j] * fact;
+     379             :     }
+     380             :     // calculate contributions from non-rescaled terms
+     381           0 :     if(bargs.size()>0) {
+     382           0 :       oldB = bias_[igamma]+bargs[igamma];
+     383           0 :       newB = bias_[new_igamma]+bargs[new_igamma];
+     384             :     } else {
+     385           0 :       oldB = bias_[igamma];
+     386           0 :       newB = bias_[new_igamma];
+     387             :     }
+     388             :     // accept or reject
+     389           0 :     bool accept = doAccept(oldE+oldB, newE+newB);
+     390           0 :     if(accept) {
+     391           0 :       igamma = new_igamma;
+     392             :       oldE = newE;
+     393           0 :       MCaccgamma_++;
+     394             :     }
+     395             :   }
+     396             : // send values of gamma to all replicas
+     397           0 :   if(comm.Get_rank()==0) {
+     398           0 :     if(multi_sim_comm.Get_rank()!=0) igamma = 0;
+     399           0 :     multi_sim_comm.Sum(&igamma, 1);
+     400             :   } else {
+     401           0 :     igamma = 0;
+     402             :   }
+     403             : // local communication
+     404           0 :   comm.Sum(&igamma, 1);
+     405             : 
+     406             : // set the value of gamma into passMap
+     407           0 :   plumed.passMap[selector_]=static_cast<double>(igamma);
+     408           0 : }
+     409             : 
+     410           0 : void Rescale::print_bias(long long int step)
+     411             : {
+     412             : // if first time open the file
+     413           0 :   if(first_bias_) {
+     414           0 :     first_bias_ = false;
+     415           0 :     Biasfile_.link(*this);
+     416           0 :     Biasfile_.open(Biasfilename_);
+     417             :     Biasfile_.setHeavyFlush();
+     418           0 :     Biasfile_.fmtField("%30.5f");
+     419             :   }
+     420             : 
+     421             : // write fields
+     422           0 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     423           0 :   Biasfile_.printField("MD_time", MDtime);
+     424           0 :   for(unsigned i=0; i<bias_.size(); ++i) {
+     425             :     // convert i to string
+     426           0 :     std::stringstream ss;
+     427             :     ss << i;
+     428             :     // label
+     429           0 :     std::string label = "b" + ss.str();
+     430             :     // print entry
+     431           0 :     Biasfile_.printField(label, bias_[i]);
+     432           0 :   }
+     433           0 :   Biasfile_.printField();
+     434           0 : }
+     435             : 
+     436           0 : void Rescale::calculate()
+     437             : {
+     438             :   // get the current value of the selector
+     439           0 :   unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     440             : 
+     441             :   // collect data from other replicas
+     442           0 :   std::vector<double> all_args(getNumberOfArguments(), 0.0);
+     443             :   // first calculate arguments
+     444           0 :   for(unsigned i=0; i<all_args.size(); ++i) {
+     445           0 :     double arg = getArgument(i);
+     446             :     // sum shared arguments across replicas
+     447           0 :     if(shared_[i]==1) {
+     448           0 :       if(comm.Get_rank()==0) multi_sim_comm.Sum(arg);
+     449           0 :       else                   arg = 0.0;
+     450           0 :       if(comm.Get_size()>1)  comm.Sum(arg);
+     451             :     }
+     452             :     // put into all_args
+     453           0 :     all_args[i] = arg;
+     454             :   }
+     455             : 
+     456             :   // now separate terms that should be rescaled
+     457             :   std::vector<double> args;
+     458           0 :   if(getNumberOfArguments()-nores_>0) args.resize(getNumberOfArguments()-nores_);
+     459           0 :   for(unsigned i=0; i<args.size(); ++i)  args[i]  = all_args[i];
+     460             :   // and terms that should not
+     461             :   std::vector<double> bargs;
+     462           0 :   if(nores_>0) bargs.resize(nores_);
+     463           0 :   for(unsigned i=0; i<bargs.size(); ++i) bargs[i] = all_args[i+args.size()];
+     464             : 
+     465             :   // calculate energy and forces, only on rescaled terms
+     466             :   double ene = 0.0;
+     467           0 :   for(unsigned i=0; i<args.size(); ++i) {
+     468             :     // calculate energy term
+     469           0 :     double fact = 1.0/pow(gamma_[igamma], expo_[i]) - 1.0;
+     470           0 :     ene += args[i] * fact;
+     471             :     // add force
+     472           0 :     setOutputForce(i, -fact);
+     473             :   }
+     474             : 
+     475             :   // set to zero on the others
+     476           0 :   for(unsigned i=0; i<bargs.size(); ++i) setOutputForce(i+args.size(), 0.0);
+     477             : 
+     478             :   // set value of the bias
+     479           0 :   setBias(ene);
+     480             :   // set value of the wt-bias
+     481           0 :   getPntrToComponent("wtbias")->set(bias_[igamma]);
+     482             :   // set values of gamma
+     483           0 :   getPntrToComponent("igamma")->set(igamma);
+     484             :   // get time step
+     485           0 :   long long int step = getStep();
+     486           0 :   if(MCfirst_==-1) MCfirst_=step;
+     487             :   // calculate gamma acceptance
+     488           0 :   double MCtrials = std::floor(static_cast<double>(step-MCfirst_) / static_cast<double>(MCstride_))+1.0;
+     489           0 :   double accgamma = static_cast<double>(MCaccgamma_) / static_cast<double>(MCsteps_) / MCtrials;
+     490           0 :   getPntrToComponent("accgamma")->set(accgamma);
+     491             : 
+     492             :   // do MC at the right time step
+     493           0 :   if(step%MCstride_==0&&!getExchangeStep()) doMonteCarlo(igamma, ene, args, bargs);
+     494             : 
+     495             :   // add well-tempered like bias
+     496           0 :   if(step%Biaspace_==0) {
+     497             :     // get updated igamma
+     498           0 :     unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     499             :     // add "Gaussian"
+     500           0 :     double kbDT = kbt_ * ( biasf_ - 1.0 );
+     501           0 :     bias_[igamma] += w0_ * std::exp(-bias_[igamma] / kbDT);
+     502             :   }
+     503             : 
+     504             :   // print bias
+     505           0 :   if(step%Biasstride_==0) print_bias(step);
+     506             : 
+     507           0 : }
+     508             : 
+     509             : 
+     510             : }
+     511             : }
+     512             : 
+
+
+
+ + + + +
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 000000000..b14d5fc14 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func-sort-c.html @@ -0,0 +1,164 @@ + + + + + + + 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:5227686176.2 %
Date:2024-10-17 16:45:00Functions: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_EEd4
_ZN4PLMD4isdb4SAXS19resolution_functionEv4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_6
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_6
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd8
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_RKS5_IjSaIjEE10
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE12
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE12
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj16
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev16
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE16
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE44
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_204
_ZN4PLMD4isdb4SAXS6updateEv204
_ZN4PLMD4isdb4SAXS9calculateEv204
_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 000000000..1ba947762 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func.html @@ -0,0 +1,164 @@ + + + + + + + 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:5227686176.2 %
Date:2024-10-17 16:45:00Functions:212391.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd8
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_204
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_0
_ZN4PLMD4isdb4SAXS13interpolationERSt6vectorINS1_12SplineCoeffsESaIS3_EEd134310
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj16
_ZN4PLMD4isdb4SAXS13spline_coeffsERSt6vectorIdSaIdEES5_814
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE12
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev16
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_RKS5_IjSaIjEE10
_ZN4PLMD4isdb4SAXS16calculateAFFsansERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd4
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE16
_ZN4PLMD4isdb4SAXS19resolution_functionEv4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_6
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_6
_ZN4PLMD4isdb4SAXS3i0eEd660
_ZN4PLMD4isdb4SAXS6chbevlEdRKSt6vectorIdSaIdEE660
_ZN4PLMD4isdb4SAXS6updateEv204
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE12
_ZN4PLMD4isdb4SAXS9calculateEv204
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE44
_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 000000000..750a5ac03 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.gcov.html @@ -0,0 +1,8730 @@ + + + + + + + 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:5227686176.2 %
Date:2024-10-17 16:45:00Functions: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             : Three 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             : - 5'-phosphorylated end with an additional hydroxyl moiety at P (the residue name in the PDB must be followed by
+      99             : "T", e.g., DCT or CT for cytosine in DNA and RNA, respectively);
+     100             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by
+     101             : "3", e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+     102             : An additional bead type is available for proteins:
+     103             : - Cysteine residue involved in disulfide bridge (the residue in the PDB must be named CYX).
+     104             : 
+     105             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+     106             : to the SAXS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     107             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     108             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     109             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     110             : using the SOLVDENS keyword.
+     111             : 
+     112             : The ABSOLUTE flag can be used in order to calculate intensities in the absolute scale. It is only available for
+     113             : the ATOMISTIC scheme and cannot be used with SCALE_EXPINT.
+     114             : 
+     115             : By default SAXS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on
+     116             : a GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     117             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     118             : 
+     119             : \par Examples
+     120             : in the following example the SAXS intensities are calculated using single-bead per residue approximation, with a
+     121             : SASA threshold of 1 square nanometer and a solvation term of 0.04. Each experimental intensity is divided by
+     122             : 1.4002, which is the corresponding theoretical intensity value at q = 0. The form factors are selected according
+     123             : to the PDB file specified by TEMPLATE keyword.
+     124             : 
+     125             : \plumedfile
+     126             : MOLINFO STRUCTURE=template_AA.pdb
+     127             : 
+     128             : SAXS ...
+     129             : LABEL=SAXS
+     130             : ATOMS=1-355
+     131             : ONEBEAD
+     132             : TEMPLATE=template_AA.pdb
+     133             : SOLVDENS=0.334
+     134             : SOLVATION_CORRECTION=0.04
+     135             : SOLVATION_STRIDE=1
+     136             : SASA_CUTOFF=1.0
+     137             : SCALE_EXPINT=1.4002
+     138             : QVALUE1=0.03 EXPINT1=1.0902
+     139             : QVALUE2=0.06 EXPINT2=0.790632
+     140             : QVALUE3=0.09 EXPINT3=0.453808
+     141             : QVALUE4=0.12 EXPINT4=0.254737
+     142             : QVALUE5=0.15 EXPINT5=0.154928
+     143             : QVALUE6=0.18 EXPINT6=0.0921503
+     144             : QVALUE7=0.21 EXPINT7=0.052633
+     145             : QVALUE8=0.24 EXPINT8=0.0276557
+     146             : QVALUE9=0.27 EXPINT9=0.0122775
+     147             : QVALUE10=0.30 EXPINT10=0.00880634
+     148             : ... SAXS
+     149             : 
+     150             : PRINT ARG=(SAXS\.q-.*),(SAXS\.exp-.*) FILE=saxsdata STRIDE=1
+     151             : 
+     152             : \endplumedfile
+     153             : 
+     154             : */
+     155             : //+ENDPLUMEDOC
+     156             : 
+     157             : //+PLUMEDOC ISDB_COLVAR SANS
+     158             : /*
+     159             : Calculates SANS intensity.
+     160             : 
+     161             : SANS intensities are calculated for a set of scattering vectors using QVALUE keywords numbered from 1.
+     162             : Form factors are automatically assigned to atoms using the ATOMISTIC flag by reading a PDB file, by reading
+     163             : the scattering lengths with the PARAMETERS keyword from input or with the PARAMETERSFILE keyword or, alternatively,
+     164             : a ONEBEAD coarse-grained implementation is available.
+     165             : 
+     166             : Both for ATOMISTIC and ONEBEAD the user must provide an all-atom PDB file via MOLINFO before the SANS instruction.
+     167             : 
+     168             : ONEBEAD scheme consists in a single-bead per amino acid residue or three-bead for nucleic acid residue (one for
+     169             : the phosphate group, one for the pentose sugar, one for the nucleobase). PLUMED creates a virtual bead on which
+     170             : the SANS calculations are performed, centred on the COM of all atoms belonging to the bead. It is possible to
+     171             : account for the contribution of the solvation layer to the SANS intensity by adding a correction term for the
+     172             : solvent accessible beads only: the form factors of the amino acids / phosphate groups / pentose sugars /
+     173             : nucleobases with a SASA (computed via LCPO algorithm) greater than a threshold are corrected according to an
+     174             : electron density term. Both the surface cut-off threshold and the electron density term can be set by the user
+     175             : with the SASA_CUTOFF and SOLVATION_CORRECTION keywords. Moreover, SASA stride calculation can be modified using
+     176             : SOLVATION_STRIDE, which is set to 10 steps by default. The deuteration of the solvent-exposed residues is chosen
+     177             : with a probability equal to the deuterium concentration in the buffer. The deuterated residues are updated with a
+     178             : stride equal to SOLVATION_STRIDE. The fraction of deuterated water can be set with DEUTER_CONC, the default value
+     179             : is 0.
+     180             : ONEBEAD requires an additional PDB file to perform mapping conversion, which must be provided via TEMPLATE
+     181             : keyword. This PDB file should only include the atoms for which the SANS intensity will be computed.
+     182             : The AMBER OL3 (RNA) and OL15 (DNA) naming is required for nucleic acids.
+     183             : Two additional bead types are available for DNA and RNA besides phosphate group, pentose sugar, and nucleobase:
+     184             : - 5'-end pentose sugar capped with an hydroxyl moiety at C5' (the residue name in the PDB must be followed by "5",
+     185             : e.g., DC5 or C5 for cytosine in DNA and RNA, respectively);
+     186             : - 5'-phosphorylated end with an additional hydroxyl moiety at P (the residue name in the PDB must be followed by
+     187             : "T", e.g., DCT or CT for cytosine in DNA and RNA, respectively);
+     188             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by "3",
+     189             : e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+     190             : An additional bead type is available for proteins:
+     191             : - Cysteine residue involved in disulfide bridge (the residue in the PDB must be named CYX).
+     192             : 
+     193             : PLEASE NOTE: at the moment, we DO NOT explicitly take into account deuterated residues in the ATOMISTIC
+     194             : representation, but we correct the solvent contribution via the DEUTER_CONC keyword.
+     195             : 
+     196             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+     197             : to the SANS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     198             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     199             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     200             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     201             : using the SOLVDENS keyword.
+     202             : 
+     203             : The ABSOLUTE flag can be used in order to calculate intensities in the absolute scale. It is only available for
+     204             : the ATOMISTIC scheme and cannot be used with SCALE_EXPINT.
+     205             : 
+     206             : By default SANS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on a
+     207             : GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     208             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     209             : 
+     210             : \par Examples
+     211             : in the following example the SANS intensities are calculated at atomistic resolution. The form factors are assigned
+     212             : according to the PDB file specified in the MOLINFO. Each experimental intensity is divided by 1.4002, which is the
+     213             : corresponding theoretical intensity value at q = 0. The deuterated water fraction is set to 48%.
+     214             : 
+     215             : \plumedfile
+     216             : MOLINFO STRUCTURE=template_AA.pdb
+     217             : 
+     218             : SANS ...
+     219             : LABEL=SANS
+     220             : ATOMS=1-355
+     221             : ATOMISTIC
+     222             : SCALE_EXPINT=1.4002
+     223             : DEUTER_CONC=0.48
+     224             : QVALUE1=0.03 EXPINT1=1.0902
+     225             : QVALUE2=0.06 EXPINT2=0.790632
+     226             : QVALUE3=0.09 EXPINT3=0.453808
+     227             : QVALUE4=0.12 EXPINT4=0.254737
+     228             : QVALUE5=0.15 EXPINT5=0.154928
+     229             : QVALUE6=0.18 EXPINT6=0.0921503
+     230             : QVALUE7=0.21 EXPINT7=0.052633
+     231             : QVALUE8=0.24 EXPINT8=0.0276557
+     232             : QVALUE9=0.27 EXPINT9=0.0122775
+     233             : QVALUE10=0.30 EXPINT10=0.00880634
+     234             : ... SANS
+     235             : 
+     236             : PRINT ARG=(SANS\.q-.*),(SANS\.exp-.*) FILE=sansdata STRIDE=1
+     237             : 
+     238             : \endplumedfile
+     239             : 
+     240             : */
+     241             : //+ENDPLUMEDOC
+     242             : 
+     243             : class SAXS :
+     244             :   public MetainferenceBase
+     245             : {
+     246             : private:
+     247             :   enum { H, C, N, O, P, S, NTT };
+     248             :   enum { ALA_BB, ARG_BB, ARG_SC1, ARG_SC2, ASN_BB, ASN_SC1, ASP_BB, ASP_SC1, CYS_BB, CYS_SC1,
+     249             :          GLN_BB, GLN_SC1, GLU_BB, GLU_SC1, GLY_BB, HIS_BB, HIS_SC1, HIS_SC2, HIS_SC3, ILE_BB,
+     250             :          ILE_SC1, LEU_BB, LEU_SC1, LYS_BB, LYS_SC1, LYS_SC2, MET_BB, MET_SC1, PHE_BB, PHE_SC1,
+     251             :          PHE_SC2, PHE_SC3, PRO_BB, PRO_SC1, SER_BB, SER_SC1, THR_BB, THR_SC1, TRP_BB, TRP_SC1,
+     252             :          TRP_SC2, TRP_SC3, TRP_SC4, TYR_BB, TYR_SC1, TYR_SC2, TYR_SC3, VAL_BB, VAL_SC1, A_BB1,
+     253             :          A_BB2, A_BB3, A_SC1, A_SC2, A_SC3, A_SC4, A_3TE, A_5TE, A_TE3, A_TE5, C_BB1, C_BB2,
+     254             :          C_BB3, C_SC1, C_SC2, C_SC3, C_3TE, C_5TE, C_TE3, C_TE5, G_BB1, G_BB2, G_BB3, G_SC1,
+     255             :          G_SC2, G_SC3, G_SC4, G_3TE, G_5TE, G_TE3, G_TE5, U_BB1, U_BB2, U_BB3, U_SC1, U_SC2,
+     256             :          U_SC3, U_3TE, U_5TE, U_TE3, U_TE5, DA_BB1, DA_BB2, DA_BB3, DA_SC1, DA_SC2, DA_SC3,
+     257             :          DA_SC4, DA_3TE, DA_5TE, DA_TE3, DA_TE5, DC_BB1, DC_BB2, DC_BB3, DC_SC1, DC_SC2, DC_SC3,
+     258             :          DC_3TE, DC_5TE, DC_TE3, DC_TE5, DG_BB1, DG_BB2, DG_BB3, DG_SC1, DG_SC2, DG_SC3, DG_SC4,
+     259             :          DG_3TE, DG_5TE, DG_TE3, DG_TE5, DT_BB1, DT_BB2, DT_BB3, DT_SC1, DT_SC2, DT_SC3, DT_3TE,
+     260             :          DT_5TE, DT_TE3, DT_TE5, NMARTINI
+     261             :        };
+     262             :   enum { TRP,
+     263             :          TYR,
+     264             :          PHE,
+     265             :          HIS,
+     266             :          HIP,
+     267             :          ARG,
+     268             :          LYS,
+     269             :          CYS,
+     270             :          CYX,
+     271             :          ASP,
+     272             :          GLU,
+     273             :          ILE,
+     274             :          LEU,
+     275             :          MET,
+     276             :          ASN,
+     277             :          PRO,
+     278             :          GLN,
+     279             :          SER,
+     280             :          THR,
+     281             :          VAL,
+     282             :          ALA,
+     283             :          GLY,
+     284             :          BB_PO2,
+     285             :          BB_PO3,
+     286             :          BB_DNA,
+     287             :          BB_DNA_5,
+     288             :          BB_DNA_3,
+     289             :          BB_RNA,
+     290             :          BB_RNA_5,
+     291             :          BB_RNA_3,
+     292             :          BASE_A,
+     293             :          BASE_C,
+     294             :          BASE_T,
+     295             :          BASE_G,
+     296             :          BASE_U,
+     297             :          NONEBEAD
+     298             :        };
+     299             :   struct SplineCoeffs {
+     300             :     double a;
+     301             :     double b;
+     302             :     double c;
+     303             :     double d;
+     304             :     double x;
+     305             :   };
+     306             :   bool saxs;
+     307             :   bool absolute;
+     308             :   bool pbc;
+     309             :   bool serial;
+     310             :   bool gpu;
+     311             :   bool onebead;
+     312             :   bool resolution;
+     313             :   bool isFirstStep;
+     314             :   int  deviceid;
+     315             :   unsigned nres;
+     316             :   std::vector<unsigned> atoi;
+     317             :   std::vector<unsigned> atoms_per_bead;
+     318             :   std::vector<double>   atoms_masses;
+     319             :   std::vector<double>   q_list;
+     320             :   std::vector<double>   FF_rank;
+     321             :   std::vector<std::vector<double> > FF_value_vacuum;
+     322             :   std::vector<std::vector<double> > FF_value_solv;
+     323             :   std::vector<std::vector<double> > FF_value_mixed;
+     324             :   std::vector<std::vector<double> > FF_value;
+     325             :   std::vector<std::vector<float> >  FFf_value;
+     326             :   // SANS:
+     327             :   std::vector<std::vector<double> > FF_value_vacuum_H;
+     328             :   std::vector<std::vector<double> > FF_value_solv_H;
+     329             :   std::vector<std::vector<double> > FF_value_mixed_H;
+     330             :   std::vector<std::vector<double> > FF_value_vacuum_D;
+     331             :   std::vector<std::vector<double> > FF_value_mixed_D;
+     332             : 
+     333             :   std::vector<std::vector<double> > LCPOparam;
+     334             :   std::vector<unsigned> residue_atom;
+     335             : 
+     336             :   double rho, rho_corr, sasa_cutoff;
+     337             :   double deuter_conc;
+     338             :   unsigned solv_stride;
+     339             :   std::vector<double> Iq0_vac;
+     340             :   std::vector<double> Iq0_solv;
+     341             :   std::vector<double> Iq0_mix;
+     342             :   double Iq0;
+     343             : 
+     344             :   // SANS:
+     345             :   std::vector<double> Iq0_vac_H;
+     346             :   std::vector<double> Iq0_solv_H;
+     347             :   std::vector<double> Iq0_mix_H;
+     348             :   std::vector<double> Iq0_vac_D;
+     349             :   std::vector<double> Iq0_mix_D;
+     350             :   unsigned int Nj;
+     351             :   std::vector<std::vector<double> > qj_list;
+     352             :   std::vector<std::vector<double> > Rij;
+     353             :   std::vector<double> sigma_res;
+     354             : 
+     355             :   // Chebyshev polynomial coefficients for i0e(x) used for resolution function
+     356             :   // values taken from cephes library
+     357             :   const std::vector<double> A = {
+     358             :     -4.41534164647933937950E-18,
+     359             :       3.33079451882223809783E-17,
+     360             :       -2.43127984654795469359E-16,
+     361             :       1.71539128555513303061E-15,
+     362             :       -1.16853328779934516808E-14,
+     363             :       7.67618549860493561688E-14,
+     364             :       -4.85644678311192946090E-13,
+     365             :       2.95505266312963983461E-12,
+     366             :       -1.72682629144155570723E-11,
+     367             :       9.67580903537323691224E-11,
+     368             :       -5.18979560163526290666E-10,
+     369             :       2.65982372468238665035E-9,
+     370             :       -1.30002500998624804212E-8,
+     371             :       6.04699502254191894932E-8,
+     372             :       -2.67079385394061173391E-7,
+     373             :       1.11738753912010371815E-6,
+     374             :       -4.41673835845875056359E-6,
+     375             :       1.64484480707288970893E-5,
+     376             :       -5.75419501008210370398E-5,
+     377             :       1.88502885095841655729E-4,
+     378             :       -5.76375574538582365885E-4,
+     379             :       1.63947561694133579842E-3,
+     380             :       -4.32430999505057594430E-3,
+     381             :       1.05464603945949983183E-2,
+     382             :       -2.37374148058994688156E-2,
+     383             :       4.93052842396707084878E-2,
+     384             :       -9.49010970480476444210E-2,
+     385             :       1.71620901522208775349E-1,
+     386             :       -3.04682672343198398683E-1,
+     387             :       6.76795274409476084995E-1
+     388             :     };
+     389             :   const std::vector<double> B = {
+     390             :     -7.23318048787475395456E-18,
+     391             :       -4.83050448594418207126E-18,
+     392             :       4.46562142029675999901E-17,
+     393             :       3.46122286769746109310E-17,
+     394             :       -2.82762398051658348494E-16,
+     395             :       -3.42548561967721913462E-16,
+     396             :       1.77256013305652638360E-15,
+     397             :       3.81168066935262242075E-15,
+     398             :       -9.55484669882830764870E-15,
+     399             :       -4.15056934728722208663E-14,
+     400             :       1.54008621752140982691E-14,
+     401             :       3.85277838274214270114E-13,
+     402             :       7.18012445138366623367E-13,
+     403             :       -1.79417853150680611778E-12,
+     404             :       -1.32158118404477131188E-11,
+     405             :       -3.14991652796324136454E-11,
+     406             :       1.18891471078464383424E-11,
+     407             :       4.94060238822496958910E-10,
+     408             :       3.39623202570838634515E-9,
+     409             :       2.26666899049817806459E-8,
+     410             :       2.04891858946906374183E-7,
+     411             :       2.89137052083475648297E-6,
+     412             :       6.88975834691682398426E-5,
+     413             :       3.36911647825569408990E-3,
+     414             :       8.04490411014108831608E-1
+     415             :     };
+     416             : 
+     417             :   void calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     418             :   void calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     419             :   void getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter);
+     420             :   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);
+     421             :   unsigned getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms);
+     422             :   double calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho);
+     423             :   std::map<std::string, std::vector<double> > setupLCPOparam();
+     424             :   void readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms);
+     425             :   void calcNlist(std::vector<std::vector<int> > &Nlist);
+     426             :   void sasa_calculate(std::vector<bool> &solv_res);
+     427             :   // SANS:
+     428             :   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);
+     429             :   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);
+     430             :   double calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc);
+     431             :   void resolution_function();
+     432             :   std::vector<SplineCoeffs> spline_coeffs(std::vector<double> &x, std::vector<double> &y);
+     433             :   inline double interpolation(std::vector<SplineCoeffs> &coeffs, double x);
+     434             :   inline double i0e(double x);
+     435             :   double chbevl(double x, const std::vector<double> &coeffs);
+     436             : 
+     437             : public:
+     438             :   static void registerKeywords( Keywords& keys );
+     439             :   explicit SAXS(const ActionOptions&);
+     440             :   void calculate() override;
+     441             :   void update() override;
+     442             : };
+     443             : 
+     444             : PLUMED_REGISTER_ACTION(SAXS,"SAXS")
+     445             : PLUMED_REGISTER_ACTION(SAXS,"SANS")
+     446             : 
+     447          48 : void SAXS::registerKeywords(Keywords& keys) {
+     448          48 :   MetainferenceBase::registerKeywords(keys);
+     449          96 :   keys.addFlag("NOPBC",false,"Ignore the periodic boundary conditions when calculating distances");
+     450          96 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     451          96 :   keys.add("compulsory","DEVICEID","-1","Identifier of the GPU to be used");
+     452          96 :   keys.addFlag("GPU",false,"Calculate SAXS using ARRAYFIRE on an accelerator device");
+     453          96 :   keys.addFlag("ABSOLUTE",false,"Absolute intensity: the intensities for each q-value are not normalised for the intensity at q=0.");
+     454          96 :   keys.addFlag("ATOMISTIC",false,"Calculate SAXS for an atomistic model");
+     455          96 :   keys.addFlag("MARTINI",false,"Calculate SAXS for a Martini model");
+     456          96 :   keys.addFlag("ONEBEAD",false,"calculate SAXS for a single bead model");
+     457          96 :   keys.add("compulsory","TEMPLATE","template.pdb","A PDB file is required for ONEBEAD mapping");
+     458          96 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein");
+     459          96 :   keys.add("numbered","QVALUE","Selected scattering lengths in inverse angstroms are given as QVALUE1, QVALUE2, ...");
+     460          96 :   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");
+     461          96 :   keys.add("optional","PARAMETERSFILE","Read the PARAMETERS from a file");
+     462          96 :   keys.add("compulsory","DEUTER_CONC","0.","Fraction of deuterated solvent");
+     463          96 :   keys.add("compulsory","SOLVDENS","0.334","Density of the solvent to be used for the correction of atomistic form factors");
+     464          96 :   keys.add("compulsory","SOLVATION_CORRECTION","0.0","Solvation layer electron density correction (ONEBEAD only)");
+     465          96 :   keys.add("compulsory","SASA_CUTOFF","1.0","SASA value to consider a residue as exposed to the solvent (ONEBEAD only)");
+     466          96 :   keys.add("numbered","EXPINT","Add an experimental value for each q value");
+     467          96 :   keys.add("numbered","SIGMARES","Variance of Gaussian distribution describing the deviation in the scattering angle for each q value");
+     468          96 :   keys.add("compulsory","N","10","Number of points in the resolution function integral");
+     469          96 :   keys.add("compulsory","SOLVATION_STRIDE","10","Number of steps between every new residues solvation estimation via LCPO (ONEBEAD only)");
+     470          96 :   keys.add("compulsory","SCALE_EXPINT","1.0","Scaling value for experimental data normalization");
+     471          96 :   keys.addOutputComponent("q","default","The # SAXS of q");
+     472          96 :   keys.addOutputComponent("exp","EXPINT","The # experimental intensity");
+     473          48 : }
+     474             : 
+     475          44 : SAXS::SAXS(const ActionOptions&ao):
+     476             :   PLUMED_METAINF_INIT(ao),
+     477          44 :   saxs(true),
+     478          44 :   absolute(false),
+     479          44 :   pbc(true),
+     480          44 :   serial(false),
+     481          44 :   gpu(false),
+     482          44 :   onebead(false),
+     483          44 :   isFirstStep(true),
+     484          44 :   deviceid(-1)
+     485             : {
+     486          44 :   if( getName().find("SAXS")!=std::string::npos) { saxs=true; }
+     487          14 :   else if( getName().find("SANS")!=std::string::npos) { saxs=false; }
+     488             : 
+     489             :   std::vector<AtomNumber> atoms;
+     490          88 :   parseAtomList("ATOMS",atoms);
+     491          44 :   unsigned size = atoms.size();
+     492             : 
+     493          44 :   parseFlag("SERIAL",serial);
+     494             : 
+     495          44 :   bool nopbc=!pbc;
+     496          44 :   parseFlag("NOPBC",nopbc);
+     497          44 :   pbc=!nopbc;
+     498          44 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     499          28 :   else         log.printf("  without periodic boundary conditions\n");
+     500             : 
+     501          44 :   parseFlag("GPU",gpu);
+     502             : #ifndef  __PLUMED_HAS_ARRAYFIRE
+     503          44 :   if(gpu) error("To use the GPU mode PLUMED must be compiled with ARRAYFIRE");
+     504             : #endif
+     505             : 
+     506          44 :   parse("DEVICEID",deviceid);
+     507             : #ifdef  __PLUMED_HAS_ARRAYFIRE
+     508             :   if(gpu&&comm.Get_rank()==0) {
+     509             :     // if not set try to check the one set by the API
+     510             :     if(deviceid==-1) deviceid=plumed.getGpuDeviceId();
+     511             :     // if still not set use 0
+     512             :     if(deviceid==-1) deviceid=0;
+     513             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+     514             :     af::setDevice(afcu::getNativeId(deviceid));
+     515             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+     516             :     af::setDevice(afcl::getNativeId(deviceid));
+     517             : #else
+     518             :     af::setDevice(deviceid);
+     519             : #endif
+     520             :     af::info();
+     521             :   }
+     522             : #endif
+     523             : 
+     524          44 :   bool atomistic=false;
+     525          44 :   parseFlag("ATOMISTIC",atomistic);
+     526          44 :   if(atomistic) log.printf("  using ATOMISTIC form factors\n");
+     527          44 :   bool martini=false;
+     528          44 :   parseFlag("MARTINI",martini);
+     529          44 :   if(martini) log.printf("  using MARTINI form factors\n");
+     530          44 :   onebead=false;
+     531          44 :   parseFlag("ONEBEAD",onebead);
+     532          44 :   if(onebead) log.printf("  using ONEBEAD form factors\n");
+     533             :   bool fromfile=false;
+     534             :   std::string parametersfile;
+     535          88 :   parse("PARAMETERSFILE",parametersfile);
+     536          44 :   if (parametersfile.length() != 0) fromfile=true;
+     537           4 :   if(fromfile) log.printf("  will read form factors from file\n");
+     538          44 :   parseFlag("ABSOLUTE",absolute);
+     539             : 
+     540          44 :   if(martini&&atomistic) error("You cannot use MARTINI and ATOMISTIC at the same time");
+     541          44 :   if(martini&&onebead) error("You cannot use MARTINI and ONEBEAD at the same time");
+     542          44 :   if(onebead&&atomistic) error("You cannot use ONEBEAD and ATOMISTIC at the same time");
+     543          44 :   if((martini)&&(!saxs)) error("MARTINI cannot be used with SANS");
+     544          44 :   if((fromfile)&&((atomistic)||(martini)||(onebead))) {
+     545           0 :     error("You cannot read parameters from file and use ATOMISTIC/MARTINI/ONEBEAD");
+     546             :   }
+     547             : 
+     548             :   unsigned ntarget=0;
+     549             :   for(unsigned i=0;; ++i) {
+     550             :     double t_list;
+     551         976 :     if( !parseNumbered( "QVALUE", i+1, t_list) ) break;
+     552         444 :     if(t_list<=0.) error("QVALUE cannot be less or equal to zero!\n");
+     553         444 :     if(onebead&&t_list>0.3) error("ONEBEAD mapping QVALUE must be smaller or equal to 0.3");
+     554         444 :     q_list.push_back(t_list);
+     555         444 :     ntarget++;
+     556         444 :   }
+     557             :   const unsigned numq = ntarget;
+     558             : 
+     559         488 :   for(unsigned i=0; i<numq; ++i) {
+     560         444 :     if(q_list[i]==0.) error("it is not possible to set q=0\n");
+     561         444 :     if(i>0&&q_list[i]<q_list[i-1]) error("QVALUE must be in ascending order");
+     562         444 :     log.printf("  my q: %lf \n",q_list[i]);
+     563             :   }
+     564             : 
+     565          44 :   rho = 0.334;
+     566          44 :   parse("SOLVDENS", rho);
+     567          44 :   log.printf("  Solvent density: %lf\n", rho);
+     568             : 
+     569          44 :   double scale_expint=1.;
+     570          44 :   parse("SCALE_EXPINT",scale_expint);
+     571             : 
+     572          44 :   if((!atomistic&&absolute)||(absolute&&scale_expint!=1)) error("ABSOLUTE can be used only combined with ATOMISTIC without SCALE_EXPINT");
+     573          56 :   if(atomistic) log.printf("  Scale for intensities: %s\n", absolute ? "absolute" : "normalised");
+     574             : 
+     575          44 :   double correction = 0.00;
+     576          44 :   parse("SOLVATION_CORRECTION", correction);
+     577          44 :   rho_corr=rho-correction;
+     578          44 :   if(onebead) log.printf("  Solvation density contribution: %lf\n", correction);
+     579          44 :   if((atomistic||martini||fromfile)&&(rho_corr!=rho)) log.printf("  Solvation density contribution is taken into account in ONEBEAD only\n");
+     580             : 
+     581          44 :   solv_stride = 10;
+     582          44 :   parse("SOLVATION_STRIDE", solv_stride);
+     583          44 :   if(solv_stride < 1.) error("SOLVATION_STRIDE must be greater than 0");
+     584          44 :   if(onebead&&(rho_corr!=rho)) log.printf("  SASA calculation stride: %u\n", solv_stride);
+     585             : 
+     586          44 :   sasa_cutoff = 1.0;
+     587          44 :   parse("SASA_CUTOFF", sasa_cutoff);
+     588          44 :   if(sasa_cutoff <= 0.) error("SASA_CUTOFF must be greater than 0");
+     589             : 
+     590          44 :   deuter_conc = 0.;
+     591          44 :   parse("DEUTER_CONC", deuter_conc);
+     592          44 :   if ((deuter_conc)&&(fromfile)) error("DEUTER_CONC cannot be used with PARAMETERSFILE");
+     593          44 :   if(deuter_conc < 0. || deuter_conc > 1.) error("DEUTER_CONC must be in 0-1 range");
+     594          44 :   if ((atomistic||onebead)&&(!saxs)) log.printf("  Solvent deuterium fraction: %lf/1.000000\n", deuter_conc);
+     595             : 
+     596          44 :   PDB pdb;
+     597          44 :   if(onebead) {
+     598             :     std::string template_name;
+     599          16 :     parse("TEMPLATE",template_name);
+     600          16 :     log.printf("  Template for ONEBEAD mapping conversion: %s\n", template_name.c_str());
+     601          16 :     if( !pdb.read(template_name,usingNaturalUnits(),1.) ) plumed_merror("missing input file " + template_name);
+     602             :   }
+     603             : 
+     604             :   // preliminary mapping for onebead representation
+     605          44 :   if(onebead) {
+     606          16 :     LCPOparam.resize(size);
+     607          16 :     nres = getOnebeadMapping(pdb, atoms);
+     608          16 :     if(saxs) {
+     609          10 :       Iq0_vac.resize(nres);
+     610          10 :       Iq0_solv.resize(nres);
+     611          10 :       Iq0_mix.resize(nres);
+     612             :     } else { // SANS
+     613           6 :       Iq0_vac_H.resize(nres);
+     614           6 :       Iq0_solv_H.resize(nres);
+     615           6 :       Iq0_mix_H.resize(nres);
+     616           6 :       Iq0_vac_D.resize(nres);
+     617           6 :       Iq0_mix_D.resize(nres);
+     618             :     }
+     619          16 :     atoi.resize(nres);
+     620             :   } else {
+     621          28 :     atoi.resize(size);
+     622             :   }
+     623             : 
+     624          44 :   Iq0=0;
+     625             :   std::vector<std::vector<long double> > FF_tmp;
+     626             :   std::vector<std::vector<long double> > FF_tmp_vac;
+     627             :   std::vector<std::vector<long double> > FF_tmp_mix;
+     628             :   std::vector<std::vector<long double> > FF_tmp_solv;
+     629             :   // SANS
+     630             :   std::vector<std::vector<long double> > FF_tmp_vac_H;
+     631             :   std::vector<std::vector<long double> > FF_tmp_mix_H;
+     632             :   std::vector<std::vector<long double> > FF_tmp_solv_H;
+     633             :   std::vector<std::vector<long double> > FF_tmp_vac_D;
+     634             :   std::vector<std::vector<long double> > FF_tmp_mix_D;
+     635             :   std::vector<std::vector<long double> > parameter_H;
+     636             :   std::vector<std::vector<long double> > parameter_D;
+     637             : 
+     638          44 :   if(!atomistic&&!martini&&!onebead&&!fromfile) { // read PARAMETERS from PLUMED file
+     639           4 :     if (saxs) {
+     640             :       // read in parameter std::vector
+     641             :       std::vector<std::vector<long double> > parameter;
+     642           4 :       parameter.resize(size);
+     643             :       ntarget=0;
+     644          36 :       for(unsigned i=0; i<size; ++i) {
+     645          64 :         if( !parseNumberedVector( "PARAMETERS", i+1, parameter[i]) ) break;
+     646          32 :         ntarget++;
+     647             :       }
+     648           4 :       if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     649           4 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     650          36 :       for(unsigned i=0; i<size; ++i) {
+     651          32 :         atoi[i]=i;
+     652         128 :         for(unsigned k=0; k<numq; ++k) {
+     653         480 :           for(unsigned j=0; j<parameter[i].size(); ++j) {
+     654         384 :             FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     655             :           }
+     656             :         }
+     657             :       }
+     658          36 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     659           4 :       Iq0 *= Iq0;
+     660           4 :     }
+     661             :     else { // SANS
+     662             :       std::vector<long double> parameter;
+     663           0 :       parameter.resize(size);
+     664             :       ntarget=0;
+     665           0 :       for(unsigned i=0; i<size; ++i) {
+     666           0 :         if( !parseNumbered( "PARAMETERS", i+1, parameter[i]) ) break;
+     667           0 :         ntarget++;
+     668             :       }
+     669           0 :       if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     670           0 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     671           0 :       for(unsigned i=0; i<size; ++i) {
+     672           0 :         atoi[i]=i;
+     673           0 :         for(unsigned k=0; k<numq; ++k) {
+     674           0 :           FF_tmp[k][i]+= parameter[i];
+     675             :         }
+     676             :       }
+     677           0 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i];
+     678           0 :       Iq0 *= Iq0;
+     679             :     }
+     680          40 :   } else if (fromfile) { // read PARAMETERS from user-provided file
+     681           4 :     log.printf("  Reading PARAMETERS from file: %s\n", parametersfile.c_str());
+     682           4 :     if (saxs) {
+     683           0 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     684             :       std::vector<std::vector<long double> > parameter;
+     685           0 :       parameter.resize(size);
+     686             : 
+     687           0 :       IFile ifile;
+     688           0 :       ifile.open(parametersfile);
+     689             :       std::string line;
+     690             : 
+     691             :       ntarget=0;
+     692           0 :       while(ifile.getline(line)) {
+     693           0 :         Tools::ltrim(line);
+     694           0 :         Tools::trimComments(line);
+     695           0 :         if (line.empty()) continue;
+     696           0 :         if (ntarget > size) error("PARAMETERSFILE has more PARAMETERS than there are scattering centers");
+     697           0 :         std::string num; Tools::convert(ntarget+1,num);
+     698           0 :         std::vector<std::string> lineread{line};
+     699           0 :         if (!Tools::parseVector(lineread, "PARAMETERS"+num, parameter[ntarget], -1)) error("Missing PARAMETERS or PARAMETERS not sorted");
+     700             :         ntarget++;
+     701           0 :       }
+     702           0 :       if( ntarget!=size ) error("found wrong number of PARAMETERS in file");
+     703             : 
+     704           0 :       for(unsigned i=0; i<size; ++i) {
+     705           0 :         atoi[i]=i;
+     706           0 :         for(unsigned k=0; k<numq; ++k) {
+     707           0 :           for(unsigned j=0; j<parameter[i].size(); ++j) {
+     708           0 :             FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     709             :           }
+     710             :         }
+     711             :       }
+     712           0 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     713           0 :       Iq0 *= Iq0;
+     714           0 :     } else { // SANS
+     715           4 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     716             : 
+     717           4 :       IFile ifile;
+     718           4 :       ifile.open(parametersfile);
+     719             :       std::string line;
+     720             : 
+     721             :       ntarget=0;
+     722        1084 :       while(ifile.getline(line)) {
+     723        1080 :         Tools::ltrim(line);
+     724        1080 :         Tools::trimComments(line);
+     725        1080 :         if (line.empty()) continue;
+     726        1080 :         if (ntarget > size) error("PARAMETERSFILE has more PARAMETERS than there are scattering centers");
+     727        1080 :         std::string num; Tools::convert(ntarget+1,num);
+     728        2160 :         std::vector<std::string> lineread{line};
+     729             :         long double scatlen;
+     730        1080 :         atoi[ntarget]=ntarget;
+     731        2160 :         if (!Tools::parse(lineread, "PARAMETERS"+num, scatlen, -1)) error("Missing PARAMETERS or PARAMETERS not sorted");
+     732       17280 :         for(unsigned k=0; k<numq; ++k) {
+     733       16200 :           FF_tmp[k][ntarget] = scatlen;
+     734             :         }
+     735             :         ntarget++;
+     736        1080 :       }
+     737           4 :       if( ntarget!=size ) error("found wrong number of PARAMETERS in file");
+     738        1084 :       for(unsigned i=0; i<size; ++i) Iq0+=FF_tmp[0][i];
+     739           4 :       Iq0 *= Iq0;
+     740           4 :     }
+     741          36 :   } else if(onebead) {
+     742          16 :     if(saxs) {
+     743             :       // read built-in ONEBEAD parameters
+     744          10 :       FF_tmp_vac.resize(numq,std::vector<long double>(NONEBEAD));
+     745          10 :       FF_tmp_mix.resize(numq,std::vector<long double>(NONEBEAD));
+     746          10 :       FF_tmp_solv.resize(numq,std::vector<long double>(NONEBEAD));
+     747          10 :       std::vector<std::vector<long double> > parameter_vac(NONEBEAD);
+     748          10 :       std::vector<std::vector<long double> > parameter_mix(NONEBEAD);
+     749          10 :       std::vector<std::vector<long double> > parameter_solv(NONEBEAD);
+     750          10 :       getOnebeadparam(pdb, atoms, parameter_vac, parameter_mix, parameter_solv, residue_atom);
+     751         360 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     752        3500 :         for(unsigned k=0; k<numq; ++k) {
+     753       25200 :           for(unsigned j=0; j<parameter_vac[i].size(); ++j) {
+     754       22050 :             FF_tmp_vac[k][i]+= parameter_vac[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     755             :           }
+     756       25200 :           for(unsigned j=0; j<parameter_mix[i].size(); ++j) {
+     757       22050 :             FF_tmp_mix[k][i]+= parameter_mix[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     758             :           }
+     759       25200 :           for(unsigned j=0; j<parameter_solv[i].size(); ++j) {
+     760       22050 :             FF_tmp_solv[k][i]+= parameter_solv[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     761             :           }
+     762             :         }
+     763             :       }
+     764        2166 :       for(unsigned i=0; i<nres; ++i) {
+     765        2156 :         Iq0_vac[i]=parameter_vac[atoi[i]][0];
+     766        2156 :         Iq0_mix[i]=parameter_mix[atoi[i]][0];
+     767        2156 :         Iq0_solv[i]=parameter_solv[atoi[i]][0];
+     768             :       }
+     769          10 :     } else { // SANS
+     770             :       // read built-in ONEBEAD parameters
+     771           6 :       FF_tmp_vac_H.resize(numq,std::vector<long double>(NONEBEAD));
+     772           6 :       FF_tmp_mix_H.resize(numq,std::vector<long double>(NONEBEAD));
+     773           6 :       FF_tmp_solv_H.resize(numq,std::vector<long double>(NONEBEAD));
+     774           6 :       FF_tmp_vac_D.resize(numq,std::vector<long double>(NONEBEAD));
+     775           6 :       FF_tmp_mix_D.resize(numq,std::vector<long double>(NONEBEAD));
+     776           6 :       std::vector<std::vector<long double> > parameter_vac_H(NONEBEAD);
+     777           6 :       std::vector<std::vector<long double> > parameter_mix_H(NONEBEAD);
+     778           6 :       std::vector<std::vector<long double> > parameter_solv_H(NONEBEAD);
+     779           6 :       std::vector<std::vector<long double> > parameter_vac_D(NONEBEAD);
+     780           6 :       std::vector<std::vector<long double> > parameter_mix_D(NONEBEAD);
+     781           6 :       getOnebeadparam_sansH(pdb, atoms, parameter_vac_H, parameter_mix_H, parameter_solv_H);
+     782           6 :       getOnebeadparam_sansD(pdb, atoms, parameter_vac_D, parameter_mix_D);
+     783         216 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     784        2100 :         for(unsigned k=0; k<numq; ++k) {
+     785       15120 :           for(unsigned j=0; j<parameter_vac_H[i].size(); ++j) { // same number of parameters
+     786       13230 :             FF_tmp_vac_H[k][i]+= parameter_vac_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     787       13230 :             FF_tmp_vac_D[k][i]+= parameter_vac_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     788             :           }
+     789       15120 :           for(unsigned j=0; j<parameter_mix_H[i].size(); ++j) {
+     790       13230 :             FF_tmp_mix_H[k][i]+= parameter_mix_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     791       13230 :             FF_tmp_mix_D[k][i]+= parameter_mix_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     792             :           }
+     793       15120 :           for(unsigned j=0; j<parameter_solv_H[i].size(); ++j) {
+     794       13230 :             FF_tmp_solv_H[k][i]+= parameter_solv_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     795             :           }
+     796             :         }
+     797             :       }
+     798        1316 :       for(unsigned i=0; i<nres; ++i) {
+     799        1310 :         Iq0_vac_H[i]=parameter_vac_H[atoi[i]][0];
+     800        1310 :         Iq0_mix_H[i]=parameter_mix_H[atoi[i]][0];
+     801        1310 :         Iq0_solv_H[i]=parameter_solv_H[atoi[i]][0];
+     802        1310 :         Iq0_vac_D[i]=parameter_vac_D[atoi[i]][0];
+     803        1310 :         Iq0_mix_D[i]=parameter_mix_D[atoi[i]][0];
+     804             :       }
+     805           6 :     }
+     806          20 :   } else if(martini) {
+     807             :     // read built-in MARTINI parameters
+     808          16 :     FF_tmp.resize(numq,std::vector<long double>(NMARTINI));
+     809             :     std::vector<std::vector<long double> > parameter;
+     810           8 :     parameter.resize(NMARTINI);
+     811           8 :     getMartiniFFparam(atoms, parameter);
+     812        1072 :     for(unsigned i=0; i<NMARTINI; ++i) {
+     813       17024 :       for(unsigned k=0; k<numq; ++k) {
+     814      127680 :         for(unsigned j=0; j<parameter[i].size(); ++j) {
+     815      111720 :           FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     816             :         }
+     817             :       }
+     818             :     }
+     819        8400 :     for(unsigned i=0; i<size; ++i) Iq0+=parameter[atoi[i]][0];
+     820           8 :     Iq0 *= Iq0;
+     821          20 :   } else if(atomistic) {
+     822          12 :     FF_tmp.resize(numq,std::vector<long double>(NTT));
+     823          12 :     if(saxs) Iq0=calculateAFF(atoms, FF_tmp, rho);
+     824           4 :     else Iq0=calculateAFFsans(atoms, FF_tmp, deuter_conc);
+     825          12 :     Iq0 *= Iq0;
+     826             :   }
+     827             : 
+     828             : 
+     829             :   std::vector<double> expint;
+     830          44 :   expint.resize( numq );
+     831             :   ntarget=0;
+     832         236 :   for(unsigned i=0; i<numq; ++i) {
+     833         440 :     if( !parseNumbered( "EXPINT", i+1, expint[i] ) ) break;
+     834         192 :     ntarget++;
+     835             :   }
+     836         236 :   std::transform(expint.begin(), expint.begin() + ntarget, expint.begin(), [scale_expint](double x) { return x / scale_expint; });
+     837             :   bool exp=false;
+     838          44 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of EXPINT values");
+     839          44 :   if(ntarget==numq) exp=true;
+     840          44 :   if(getDoScore()&&!exp) error("with DOSCORE you need to set the EXPINT values");
+     841             : 
+     842          44 :   sigma_res.resize( numq );
+     843          44 :   resolution=false;
+     844             :   ntarget=0;
+     845         104 :   for(unsigned i=0; i<numq; ++i) {
+     846         200 :     if( !parseNumbered( "SIGMARES", i+1, sigma_res[i] ) ) break;
+     847          60 :     ntarget++;
+     848             :   }
+     849          44 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of SIGMARES values");
+     850          44 :   if(ntarget==numq) resolution=true;
+     851             : 
+     852          44 :   if(gpu && resolution) error("Resolution function is not supported in GPUs");
+     853             : 
+     854          44 :   Nj = 10;
+     855          44 :   parse("N", Nj);
+     856          44 :   if (Nj < 2) error("N should be larger than 1");
+     857          44 :   if (resolution) log.printf("  Resolution function with N: %d\n", Nj);
+     858             : 
+     859          44 :   if(!gpu) {
+     860          44 :     FF_rank.resize(numq);
+     861             :     unsigned n_atom_types;
+     862          44 :     if(onebead) {
+     863          16 :       FF_value.resize(nres,std::vector<double>(numq));
+     864             :       n_atom_types=NONEBEAD;
+     865          16 :       if(saxs) {
+     866          10 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     867          10 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     868          20 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     869             :       } else {
+     870           6 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     871           6 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     872           6 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     873           6 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     874          12 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     875             :       }
+     876             :     } else {
+     877          56 :       FF_value.resize(size,std::vector<double>(numq));
+     878             :     }
+     879         488 :     for(unsigned k=0; k<numq; ++k) {
+     880         444 :       if(!onebead) {
+     881      523104 :         for(unsigned i=0; i<size; ++i) FF_value[i][k] = static_cast<double>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     882      523104 :         for(unsigned i=0; i<size; ++i) FF_rank[k] += FF_value[i][k]*FF_value[i][k];
+     883             :       } else {
+     884         144 :         if(saxs) {
+     885        3240 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     886        3150 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     887        3150 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     888        3150 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     889             :           }
+     890             :         } else { // SANS
+     891        1944 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     892        1890 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     893        1890 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     894        1890 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     895        1890 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     896        1890 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     897             :           }
+     898             :         }
+     899             :       }
+     900             :     }
+     901             :   } else {
+     902             :     unsigned n_atom_types;
+     903           0 :     if(onebead) {
+     904           0 :       FFf_value.resize(numq,std::vector<float>(nres));
+     905             :       n_atom_types=NONEBEAD;
+     906           0 :       if(saxs) {
+     907           0 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     908           0 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     909           0 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     910             :       } else { // SANS
+     911           0 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     912           0 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     913           0 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     914           0 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     915           0 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     916             :       }
+     917             :     } else {
+     918           0 :       FFf_value.resize(numq,std::vector<float>(size));
+     919             :     }
+     920           0 :     for(unsigned k=0; k<numq; ++k) {
+     921           0 :       if(!onebead) {
+     922           0 :         for(unsigned i=0; i<size; ++i) {
+     923           0 :           FFf_value[k][i] = static_cast<float>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     924             :         }
+     925             :       } else {
+     926           0 :         if(saxs) {
+     927           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     928           0 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     929           0 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     930           0 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     931             :           }
+     932             :         } else { // SANS
+     933           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     934           0 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     935           0 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     936           0 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     937           0 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     938           0 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     939             :           }
+     940             :         }
+     941             :       }
+     942             :     }
+     943             :   }
+     944             : 
+     945          44 :   if(!getDoScore()) {
+     946         408 :     for(unsigned i=0; i<numq; ++i) {
+     947         372 :       std::string num; Tools::convert(i,num);
+     948         744 :       addComponentWithDerivatives("q-"+num);
+     949         744 :       componentIsNotPeriodic("q-"+num);
+     950             :     }
+     951          36 :     if(exp) {
+     952         128 :       for(unsigned i=0; i<numq; ++i) {
+     953         120 :         std::string num; Tools::convert(i,num);
+     954         240 :         addComponent("exp-"+num);
+     955         120 :         componentIsNotPeriodic("exp-"+num);
+     956         120 :         Value* comp=getPntrToComponent("exp-"+num);
+     957         120 :         comp->set(expint[i]);
+     958             :       }
+     959             :     }
+     960             :   } else {
+     961          80 :     for(unsigned i=0; i<numq; ++i) {
+     962          72 :       std::string num; Tools::convert(i,num);
+     963         144 :       addComponent("q-"+num);
+     964         144 :       componentIsNotPeriodic("q-"+num);
+     965             :     }
+     966          80 :     for(unsigned i=0; i<numq; ++i) {
+     967          72 :       std::string num; Tools::convert(i,num);
+     968         144 :       addComponent("exp-"+num);
+     969          72 :       componentIsNotPeriodic("exp-"+num);
+     970          72 :       Value* comp=getPntrToComponent("exp-"+num);
+     971          72 :       comp->set(expint[i]);
+     972             :     }
+     973             :   }
+     974             : 
+     975             :   // convert units to nm^-1
+     976         488 :   for(unsigned i=0; i<numq; ++i) {
+     977         444 :     q_list[i]=q_list[i]*10.0;    // factor 10 to convert from A^-1 to nm^-1
+     978         444 :     if (resolution) sigma_res[i]=sigma_res[i]*10.0;
+     979             :   }
+     980             : 
+     981             :   // compute resolution function after converting units
+     982          44 :   if (resolution) {
+     983           4 :     qj_list.resize(numq, std::vector<double>(Nj));
+     984           4 :     Rij.resize(numq, std::vector<double>(Nj));
+     985             :     // compute Rij and qj_list
+     986           4 :     resolution_function();
+     987             :   }
+     988             : 
+     989          44 :   log<<"  Bibliography ";
+     990          44 :   if(onebead) {
+     991          32 :     log<<plumed.cite("Ballabio, Paissoni, Bollati, de Rosa, Capelli, Camilloni, J. Chem. Theory Comput., 19, 22, 8401-8413 (2023)");
+     992             :   }
+     993          44 :   if(martini) {
+     994          16 :     log<<plumed.cite("Niebling, Björling, Westenhoff, J. Appl. Crystallogr., 47, 1190–1198 (2014)");
+     995          16 :     log<<plumed.cite("Paissoni, Jussupow, Camilloni, J. Appl. Crystallogr., 52, 394-402 (2019)");
+     996             :   }
+     997          44 :   if(atomistic) {
+     998          24 :     log<<plumed.cite("Fraser, MacRae, Suzuki, J. Appl. Crystallogr., 11, 693–694 (1978)");
+     999          24 :     log<<plumed.cite("Brown, Fox, Maslen, O'Keefe, Willis, International Tables for Crystallography, C, 554–595 (International Union of Crystallography, 2006)");
+    1000             :   }
+    1001          44 :   if(resolution) {
+    1002           8 :     log<<plumed.cite("Pedersen, Posselt, Mortensen, J. Appl. Crystallogr., 23, 321–333 (1990)");
+    1003             :   }
+    1004             : 
+    1005          88 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+    1006          44 :   log<<"\n";
+    1007             : 
+    1008          44 :   requestAtoms(atoms, false);
+    1009             : 
+    1010          44 :   if(getDoScore()) {
+    1011           8 :     setParameters(expint);
+    1012           8 :     Initialise(numq);
+    1013             :   }
+    1014          44 :   setDerivatives();
+    1015          44 :   checkRead();
+    1016          88 : }
+    1017             : 
+    1018             : // calculates SASA neighbor list
+    1019          12 : void SAXS::calcNlist(std::vector<std::vector<int> > &Nlist)
+    1020             : {
+    1021             :   unsigned natoms = getNumberOfAtoms();
+    1022       42680 :   for(unsigned i = 0; i < natoms; ++i) {
+    1023       42668 :     if (LCPOparam[i].size()>0) {
+    1024    36236236 :       for (unsigned j = 0; j < i; ++j) {
+    1025    36216204 :         if (LCPOparam[j].size()>0) {
+    1026    16741476 :           double Delta_ij_mod = modulo(delta(getPosition(i), getPosition(j)))*10.;
+    1027    16741476 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+    1028    16741476 :           if(Delta_ij_mod < overlapD) {
+    1029      391272 :             Nlist.at(i).push_back(j);
+    1030      391272 :             Nlist.at(j).push_back(i);
+    1031             :           }
+    1032             :         }
+    1033             :       }
+    1034             :     }
+    1035             :   }
+    1036             : 
+    1037          12 : }
+    1038             : 
+    1039             : // calculates SASA according to LCPO algorithm
+    1040          12 : void SAXS::sasa_calculate(std::vector<bool> &solv_res) {
+    1041             :   unsigned natoms = getNumberOfAtoms();
+    1042          12 :   std::vector<std::vector<int> > Nlist(natoms);
+    1043          12 :   calcNlist(Nlist);
+    1044          12 :   std::vector<double> sasares(nres, 0.);
+    1045             : 
+    1046          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1047             :   {
+    1048             :     std::vector<double> private_sasares(nres, 0.);
+    1049             :     #pragma omp for
+    1050             :     for (unsigned i = 0; i < natoms; ++i) {
+    1051             :       if (LCPOparam[i].size() > 1 && LCPOparam[i][1] > 0.0) {
+    1052             :         double Aij = 0.0;
+    1053             :         double Aijk = 0.0;
+    1054             :         double Ajk = 0.0;
+    1055             :         double ri = LCPOparam[i][0];
+    1056             :         double S1 = 4.*M_PI*ri*ri;
+    1057             :         for (unsigned j = 0; j < Nlist[i].size(); ++j) {
+    1058             :           double d_ij = modulo(delta( getPosition(i), getPosition(Nlist[i][j]) ))*10.;
+    1059             :           double rj = LCPOparam[Nlist[i][j]][0];
+    1060             :           double Aijt = (2.*M_PI*ri*(ri-d_ij/2.-((ri*ri-rj*rj)/(2.*d_ij))));
+    1061             :           double Ajkt = 0.0;
+    1062             :           for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); ++k) {
+    1063             :             if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+    1064             :               double d_jk = modulo(delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) ))*10.;
+    1065             :               double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+    1066             :               double sjk =  (2.*M_PI*rj*(rj-d_jk/2.-((rj*rj-rk*rk)/(2.*d_jk))));
+    1067             :               Ajkt += sjk;
+    1068             :             }
+    1069             :           }
+    1070             :           Aijk += (Aijt * Ajkt);
+    1071             :           Aij += Aijt;
+    1072             :           Ajk += Ajkt;
+    1073             :         }
+    1074             :         double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1075             :         if (sasai > 0) {
+    1076             :           private_sasares[residue_atom[i]] += sasai / 100.0;
+    1077             :         }
+    1078             :       }
+    1079             :     }
+    1080             :     #pragma omp critical
+    1081             :     { // combining private_sasares into sasares
+    1082             :       for (unsigned i = 0; i < nres; ++i) {
+    1083             :         sasares[i] += private_sasares[i];
+    1084             :       }
+    1085             :     }
+    1086             :   }
+    1087        2632 :   for(unsigned i=0; i<nres; ++i) { // updating solv_res based on sasares
+    1088        2620 :     if(sasares[i]>sasa_cutoff) solv_res[i] = 1;
+    1089             :     else solv_res[i] = 0;
+    1090             :   }
+    1091          12 : }
+    1092             : 
+    1093           0 : void SAXS::calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+    1094             : {
+    1095             : #ifdef __PLUMED_HAS_ARRAYFIRE
+    1096             :   unsigned size;
+    1097             :   if(onebead) size = nres;
+    1098             :   else size = getNumberOfAtoms();
+    1099             :   const unsigned numq = q_list.size();
+    1100             : 
+    1101             :   std::vector<float> sum;
+    1102             :   sum.resize(numq);
+    1103             : 
+    1104             :   std::vector<float> dd;
+    1105             :   dd.resize(size*3*numq);
+    1106             : 
+    1107             :   // on gpu only the master rank run the calculation
+    1108             :   if(comm.Get_rank()==0) {
+    1109             :     std::vector<float> posi;
+    1110             :     posi.resize(3*size);
+    1111             :     #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1112             :     for (unsigned i=0; i<size; ++i) {
+    1113             :       const Vector tmp = pos[i];
+    1114             :       posi[3*i]   = static_cast<float>(tmp[0]);
+    1115             :       posi[3*i+1] = static_cast<float>(tmp[1]);
+    1116             :       posi[3*i+2] = static_cast<float>(tmp[2]);
+    1117             :     }
+    1118             : 
+    1119             :     // create array a and b containing atomic coordinates
+    1120             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+    1121             :     af::setDevice(afcu::getNativeId(deviceid));
+    1122             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+    1123             :     af::setDevice(afcl::getNativeId(deviceid));
+    1124             : #else
+    1125             :     af::setDevice(deviceid);
+    1126             : #endif
+    1127             :     // 3,size,1,1
+    1128             :     af::array pos_a = af::array(3, size, &posi.front());
+    1129             :     // size,3,1,1
+    1130             :     pos_a = af::moddims(pos_a.T(), size, 3, 1);
+    1131             :     // size,3,1,1
+    1132             :     af::array pos_b = pos_a(af::span, af::span);
+    1133             :     // size,1,3,1
+    1134             :     pos_a = af::moddims(pos_a, size, 1, 3);
+    1135             :     // 1,size,3,1
+    1136             :     pos_b = af::moddims(pos_b, 1, size, 3);
+    1137             : 
+    1138             :     // size,size,3,1
+    1139             :     af::array pos_a_t = af::tile(pos_a, 1, size, 1);
+    1140             :     // size,size,3,1: for some reason we need this
+    1141             :     pos_a_t = af::moddims(pos_a_t, size, size, 3);
+    1142             :     // size,size,3,1
+    1143             :     af::array pos_b_t = af::tile(pos_b, size, 1, 1);
+    1144             :     // size,size,3,1: for some reason we need this
+    1145             :     pos_b_t = af::moddims(pos_b_t, size, size, 3);
+    1146             :     // size,size,3,1
+    1147             :     af::array xyz_dist = pos_a_t - pos_b_t;
+    1148             :     // size,size,1,1
+    1149             :     af::array square = af::sum(xyz_dist*xyz_dist,2);
+    1150             :     // size,size,1,1
+    1151             :     af::array dist_sqrt = af::sqrt(square);
+    1152             :     // replace the zero of square with one to avoid nan in the derivatives (the number does not matter because this are multiplied by zero)
+    1153             :     af::replace(square,!(af::iszero(square)),1.);
+    1154             :     // size,size,3,1
+    1155             :     xyz_dist = xyz_dist / af::tile(square, 1, 1, 3);
+    1156             :     // numq,1,1,1
+    1157             :     af::array sum_device   = af::constant(0, numq, f32);
+    1158             :     // numq,size,3,1
+    1159             :     af::array deriv_device = af::constant(0, numq, size, 3, f32);
+    1160             : 
+    1161             :     for (unsigned k=0; k<numq; ++k) {
+    1162             :       // calculate FF matrix
+    1163             :       // size,1,1,1
+    1164             :       af::array AFF_value(size, &FFf_value[k].front());
+    1165             :       // size,size,1,1
+    1166             :       af::array FFdist_mod = af::tile(AFF_value(af::span), 1, size)*af::transpose(af::tile(AFF_value(af::span), 1, size));
+    1167             : 
+    1168             :       // get q
+    1169             :       const float qvalue = static_cast<float>(q_list[k]);
+    1170             :       // size,size,1,1
+    1171             :       af::array dist_q = qvalue*dist_sqrt;
+    1172             :       // size,size,1
+    1173             :       af::array dist_sin = af::sin(dist_q)/dist_q;
+    1174             :       af::replace(dist_sin,!(af::isNaN(dist_sin)),1.);
+    1175             :       // 1,1,1,1
+    1176             :       sum_device(k) = af::sum(af::flat(dist_sin)*af::flat(FFdist_mod));
+    1177             : 
+    1178             :       // size,size,1,1
+    1179             :       af::array tmp = FFdist_mod*(dist_sin - af::cos(dist_q));
+    1180             :       // size,size,3,1
+    1181             :       af::array dd_all = af::tile(tmp, 1, 1, 3)*xyz_dist;
+    1182             :       // it should become 1,size,3
+    1183             :       deriv_device(k, af::span, af::span) = af::sum(dd_all,0);
+    1184             :     }
+    1185             : 
+    1186             :     // read out results
+    1187             :     sum_device.host(&sum.front());
+    1188             : 
+    1189             :     deriv_device = af::reorder(deriv_device, 2, 1, 0);
+    1190             :     deriv_device = af::flat(deriv_device);
+    1191             :     deriv_device.host(&dd.front());
+    1192             :   }
+    1193             : 
+    1194             :   comm.Bcast(dd, 0);
+    1195             :   comm.Bcast(sum, 0);
+    1196             : 
+    1197             :   for(unsigned k=0; k<numq; ++k) {
+    1198             :     std::string num; Tools::convert(k,num);
+    1199             :     Value* val=getPntrToComponent("q-"+num);
+    1200             :     val->set(sum[k]);
+    1201             :     if(getDoScore()) setCalcData(k, sum[k]);
+    1202             :     for(unsigned i=0; i<size; ++i) {
+    1203             :       const unsigned di = k*size*3+i*3;
+    1204             :       deriv[k*size+i] = Vector(2.*dd[di+0],2.*dd[di+1],2.*dd[di+2]);
+    1205             :     }
+    1206             :   }
+    1207             : #endif
+    1208           0 : }
+    1209             : 
+    1210         204 : void SAXS::calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+    1211             : {
+    1212             :   unsigned size;
+    1213         204 :   if(onebead) size = nres;
+    1214             :   else size = getNumberOfAtoms();
+    1215         204 :   const unsigned numq = q_list.size();
+    1216             : 
+    1217         204 :   unsigned stride = comm.Get_size();
+    1218         204 :   unsigned rank   = comm.Get_rank();
+    1219         204 :   if(serial) {
+    1220             :     stride = 1;
+    1221             :     rank   = 0;
+    1222             :   }
+    1223         204 :   std::vector<double> sum(numq,0);
+    1224         204 :   unsigned nt=OpenMP::getNumThreads();
+    1225         204 :   #pragma omp parallel num_threads(nt)
+    1226             :   {
+    1227             :     std::vector<Vector> omp_deriv(deriv.size());
+    1228             :     std::vector<double> omp_sum(numq,0);
+    1229             :     #pragma omp for nowait
+    1230             :     for (unsigned i=rank; i<size-1; i+=stride) {
+    1231             :       Vector posi = pos[i];
+    1232             :       for (unsigned j=i+1; j<size ; ++j) {
+    1233             :         Vector c_distances = delta(posi,pos[j]);
+    1234             :         double m_distances = c_distances.modulo();
+    1235             :         c_distances = c_distances/m_distances/m_distances;
+    1236             :         for (unsigned k=0; k<numq; ++k) {
+    1237             :           unsigned kdx=k*size;
+    1238             :           double qdist = q_list[k]*m_distances;
+    1239             :           double FFF = 2.*FF_value[i][k]*FF_value[j][k];
+    1240             :           double tsq = std::sin(qdist)/qdist;
+    1241             :           double tcq = std::cos(qdist);
+    1242             :           double tmp = FFF*(tcq-tsq);
+    1243             :           Vector dd  = c_distances*tmp;
+    1244             :           if(nt>1) {
+    1245             :             omp_deriv[kdx+i] -=dd;
+    1246             :             omp_deriv[kdx+j] +=dd;
+    1247             :             omp_sum[k] += FFF*tsq;
+    1248             :           } else {
+    1249             :             deriv[kdx+i] -= dd;
+    1250             :             deriv[kdx+j] += dd;
+    1251             :             sum[k] += FFF*tsq;
+    1252             :           }
+    1253             :         }
+    1254             :       }
+    1255             :     }
+    1256             :     #pragma omp critical
+    1257             :     if(nt>1) {
+    1258             :       for(unsigned i=0; i<deriv.size(); ++i) deriv[i]+=omp_deriv[i];
+    1259             :       for(unsigned k=0; k<numq; ++k) sum[k]+=omp_sum[k];
+    1260             :     }
+    1261             :   }
+    1262             : 
+    1263         204 :   if(!serial) {
+    1264         200 :     comm.Sum(&deriv[0][0], 3*deriv.size());
+    1265         200 :     comm.Sum(&sum[0], numq);
+    1266             :   }
+    1267             : 
+    1268         204 :   if (resolution) {
+    1269             :     // get spline for scatering curve
+    1270           4 :     std::vector<SplineCoeffs> scatt_coeffs = spline_coeffs(q_list, sum);
+    1271             : 
+    1272             :     // get spline for the derivatives
+    1273             :     // copy the deriv to a new vector and zero deriv
+    1274           4 :     std::vector<Vector> old_deriv(deriv);
+    1275           4 :     memset(&deriv[0][0], 0.0, deriv.size() * sizeof deriv[0]);
+    1276             : 
+    1277           4 :     unsigned nt=OpenMP::getNumThreads();
+    1278         274 :     for (unsigned i=rank; i<size; i+=stride) {
+    1279         270 :       std::vector<double> deriv_i_x(numq);
+    1280         270 :       std::vector<double> deriv_i_y(numq);
+    1281         270 :       std::vector<double> deriv_i_z(numq);
+    1282             : 
+    1283             :       std::vector<SplineCoeffs> deriv_coeffs_x;
+    1284             :       std::vector<SplineCoeffs> deriv_coeffs_y;
+    1285             :       std::vector<SplineCoeffs> deriv_coeffs_z;
+    1286        4320 :       for (unsigned k=0; k<numq; k++) {
+    1287        4050 :         unsigned kdx = k*size;
+    1288        4050 :         deriv_i_x[k] = old_deriv[kdx+i][0];
+    1289        4050 :         deriv_i_y[k] = old_deriv[kdx+i][1];
+    1290        4050 :         deriv_i_z[k] = old_deriv[kdx+i][2];
+    1291             :       }
+    1292         270 :       deriv_coeffs_x = spline_coeffs(q_list, deriv_i_x);
+    1293         270 :       deriv_coeffs_y = spline_coeffs(q_list, deriv_i_y);
+    1294         270 :       deriv_coeffs_z = spline_coeffs(q_list, deriv_i_z);
+    1295             : 
+    1296             :       // compute derivative with the smearing using the resolution function
+    1297         270 :       #pragma omp parallel for num_threads(nt)
+    1298             :       for (unsigned k=0; k<numq; k++) {
+    1299             :         unsigned kdx = k*size;
+    1300             :         double dq = qj_list[k][1] - qj_list[k][0];
+    1301             :         for (unsigned j=0; j<Nj; j++) {
+    1302             :           deriv[kdx+i][0] += Rij[k][j] * interpolation(deriv_coeffs_x, qj_list[k][j]) * dq;
+    1303             :           deriv[kdx+i][1] += Rij[k][j] * interpolation(deriv_coeffs_y, qj_list[k][j]) * dq;
+    1304             :           deriv[kdx+i][2] += Rij[k][j] * interpolation(deriv_coeffs_z, qj_list[k][j]) * dq;
+    1305             :         }
+    1306             :       }
+    1307             :     }
+    1308             : 
+    1309           4 :     if(!serial) {
+    1310           4 :       comm.Sum(&deriv[0][0], 3*deriv.size());
+    1311             :     }
+    1312             : 
+    1313             :     // compute the smeared spectra using the resolution function
+    1314           4 :     #pragma omp parallel for num_threads(nt)
+    1315             :     for (unsigned i=0; i<numq; i++) {
+    1316             :       sum[i] = 0.;
+    1317             :       double dq = qj_list[i][1] - qj_list[i][0];
+    1318             :       for (unsigned j=0; j<Nj; j++) {
+    1319             :         sum[i] += Rij[i][j] * interpolation(scatt_coeffs, qj_list[i][j]) * dq;
+    1320             :       }
+    1321             :     }
+    1322             :   }
+    1323             : 
+    1324        2088 :   for (unsigned k=0; k<numq; ++k) {
+    1325        1884 :     sum[k]+=FF_rank[k];
+    1326        1884 :     std::string num; Tools::convert(k,num);
+    1327        1884 :     Value* val=getPntrToComponent("q-"+num);
+    1328        1884 :     val->set(sum[k]);
+    1329        1884 :     if(getDoScore()) setCalcData(k, sum[k]);
+    1330             :   }
+    1331         204 : }
+    1332             : 
+    1333         204 : void SAXS::calculate()
+    1334             : {
+    1335         204 :   if(pbc) makeWhole();
+    1336             : 
+    1337         204 :   const size_t size = getNumberOfAtoms();
+    1338             :   const size_t numq = q_list.size();
+    1339             : 
+    1340             :   // these are the derivatives associated to the coarse graining
+    1341         204 :   std::vector<Vector> aa_deriv(size);
+    1342             : 
+    1343             :   size_t beads_size = size;
+    1344         204 :   if(onebead) beads_size = nres;
+    1345             :   // these are the derivatives particle,q
+    1346         204 :   std::vector<Vector> bd_deriv(numq*beads_size);
+    1347             : 
+    1348         204 :   std::vector<Vector> beads_pos(beads_size);
+    1349         204 :   if(onebead) {
+    1350        3482 :     for(unsigned resid=0; resid<nres; resid++) {
+    1351             :       double sum_mass = 0.;
+    1352        3466 :       Vector sum_pos = Vector(0,0,0);
+    1353    12278134 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1354    12274668 :         if(residue_atom[atom_id] == resid) {
+    1355       56586 :           aa_deriv[atom_id] = Vector(atoms_masses[atom_id],atoms_masses[atom_id],atoms_masses[atom_id]);
+    1356       56586 :           sum_pos += atoms_masses[atom_id] * getPosition(atom_id); // getPosition(first_atom+atom_id)
+    1357       56586 :           sum_mass += atoms_masses[atom_id];
+    1358             :         }
+    1359             :       }
+    1360        3466 :       beads_pos[resid] = sum_pos/sum_mass;
+    1361    12278134 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1362    12274668 :         if(residue_atom[atom_id] == resid) {
+    1363       56586 :           aa_deriv[atom_id] /= sum_mass;
+    1364             :         }
+    1365             :       }
+    1366             :     }
+    1367             :     // SASA
+    1368          16 :     std::vector<bool> solv_res(nres, 0);
+    1369          16 :     if(saxs) {
+    1370          10 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1371          10 :         isFirstStep = 0;
+    1372          10 :         if(rho_corr!=rho) sasa_calculate(solv_res);
+    1373          10 :         Iq0=0.;
+    1374        2166 :         for(unsigned i=0; i<nres; ++i) {
+    1375        2156 :           if(solv_res[i] == 1 ) {
+    1376         260 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho_corr*rho_corr)*Iq0_solv[i]-rho_corr*Iq0_mix[i]));
+    1377             :           } else {
+    1378        1896 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho*rho)*Iq0_solv[i]-rho*Iq0_mix[i]));
+    1379             :           }
+    1380             :         }
+    1381             :         // Form Factors
+    1382         100 :         for(unsigned k=0; k<numq; ++k) {
+    1383       19494 :           for(unsigned i=0; i<nres; ++i) {
+    1384       19404 :             if(!gpu) {
+    1385       19404 :               if(solv_res[i] == 0) { // buried
+    1386       17064 :                 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;
+    1387             :               } else { // surface
+    1388        2340 :                 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;
+    1389             :               }
+    1390             :             } else {
+    1391           0 :               if(solv_res[i] == 0) { // buried
+    1392           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);
+    1393             :               } else { // surface
+    1394           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);
+    1395             :               }
+    1396             :             }
+    1397             :           }
+    1398             :         }
+    1399          10 :         if(!gpu) {
+    1400         100 :           for(unsigned k=0; k<numq; ++k) {
+    1401          90 :             FF_rank[k]=0.;
+    1402       19494 :             for(unsigned i=0; i<nres; ++i) {
+    1403       19404 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1404             :             }
+    1405             :           }
+    1406             :         }
+    1407             :       }
+    1408             :     } else { // SANS
+    1409           6 :       std::vector<bool> deut_res(nres, 0);
+    1410           6 :       double solv_sc_length = 0.1*(0.580 + 2.*((1. - deuter_conc) * (-0.374) + deuter_conc * 0.667)); // per water electron (10 electrons)
+    1411           6 :       double rho_sans = rho * solv_sc_length;
+    1412           6 :       double rho_sans_corr = rho_corr * solv_sc_length;
+    1413           6 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1414           6 :         isFirstStep = 0;
+    1415           6 :         if(deuter_conc!=0.||rho != rho_corr) sasa_calculate(solv_res);
+    1416           6 :         Iq0=0.;
+    1417        1316 :         for(unsigned i=0; i<nres; ++i) {
+    1418        1310 :           if(solv_res[i] == 1 ) {
+    1419         260 :             if(rand()/RAND_MAX<deuter_conc) {
+    1420           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]));
+    1421             :               deut_res[i] = 1;
+    1422             :             } else {
+    1423         260 :               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]));
+    1424             :             }
+    1425             :           } else {
+    1426        1050 :             Iq0 += std::sqrt(std::fabs(Iq0_vac_H[i] + rho_sans*rho_sans*Iq0_solv_H[i] - rho_sans*Iq0_mix_H[i]));
+    1427             :           }
+    1428             :         }
+    1429             :         // Form Factors
+    1430          60 :         for(unsigned k=0; k<numq; ++k) {
+    1431       11844 :           for(unsigned i=0; i<nres; ++i) {
+    1432       11790 :             if(!gpu) {
+    1433       11790 :               if(solv_res[i] == 0) { // hydrogen
+    1434        9450 :                 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;
+    1435             :               } else {
+    1436        2340 :                 if(deut_res[i] == 0) {
+    1437        2340 :                   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;
+    1438             :                 } else {
+    1439           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;
+    1440             :                 }
+    1441             :               }
+    1442             :             } else {
+    1443           0 :               if(solv_res[i] == 0) { // hydrogen
+    1444           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);
+    1445             :               } else {
+    1446           0 :                 if(deut_res[i] == 0) {
+    1447           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);
+    1448             :                 } else {
+    1449           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);
+    1450             :                 }
+    1451             :               }
+    1452             :             }
+    1453             :           }
+    1454             :         }
+    1455           6 :         if(!gpu) {
+    1456          60 :           for(unsigned k=0; k<numq; ++k) {
+    1457          54 :             FF_rank[k]=0.;
+    1458       11844 :             for(unsigned i=0; i<nres; ++i) {
+    1459       11790 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1460             :             }
+    1461             :           }
+    1462             :         }
+    1463             :       }
+    1464             :     }
+    1465             :     // not ONEBEAD
+    1466             :   } else {
+    1467       81024 :     for(unsigned i=0; i<size; ++i) {
+    1468       80836 :       beads_pos[i] = getPosition(i);
+    1469             :     }
+    1470         376 :     aa_deriv = std::vector<Vector>(size,(Vector(1,1,1)));
+    1471             :   }
+    1472             : 
+    1473         204 :   if(gpu) calculate_gpu(beads_pos, bd_deriv);
+    1474         204 :   else calculate_cpu(beads_pos, bd_deriv);
+    1475             : 
+    1476         204 :   if(getDoScore()) {
+    1477             :     /* Metainference */
+    1478         168 :     double score = getScore();
+    1479         168 :     setScore(score);
+    1480             :   }
+    1481             : 
+    1482        2088 :   for (unsigned k=0; k<numq; ++k) {
+    1483        1884 :     const unsigned kdx=k*beads_size;
+    1484        1884 :     Tensor deriv_box;
+    1485             :     Value* val;
+    1486        1884 :     if(!getDoScore()) {
+    1487         372 :       std::string num; Tools::convert(k,num);
+    1488         372 :       val=getPntrToComponent("q-"+num);
+    1489             : 
+    1490         372 :       if(onebead) {
+    1491             :         unsigned atom_id=0;
+    1492       31338 :         for(unsigned i=0; i<beads_size; ++i) {
+    1493      540468 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1494      509274 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1495      509274 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1496      509274 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1497      509274 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1498      509274 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1499     1018548 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1500      509274 :             atom_id++;
+    1501             :           }
+    1502             :         }
+    1503             :       } else {
+    1504      501636 :         for(unsigned i=0; i<beads_size; ++i) {
+    1505      501408 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0], \
+    1506      501408 :                                              bd_deriv[kdx+i][1], \
+    1507      501408 :                                              bd_deriv[kdx+i][2]) );
+    1508     1002816 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0], \
+    1509      501408 :                               bd_deriv[kdx+i][1], \
+    1510     1002816 :                               bd_deriv[kdx+i][2]) );
+    1511             :         }
+    1512             :       }
+    1513             :     } else {
+    1514        1512 :       val=getPntrToComponent("score");
+    1515        1512 :       if(onebead) {
+    1516             :         unsigned atom_id=0;
+    1517           0 :         for(unsigned i=0; i<beads_size; ++i) {
+    1518           0 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1519           0 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1520           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1521           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1522           0 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1523           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1524           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1525           0 :             atom_id++;
+    1526             :           }
+    1527             :         }
+    1528             :       } else {
+    1529      450828 :         for(unsigned i=0; i<beads_size; ++i) {
+    1530      449316 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1531      449316 :                                              bd_deriv[kdx+i][1]*getMetaDer(k),
+    1532      449316 :                                              bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1533      898632 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1534      449316 :                               bd_deriv[kdx+i][1]*getMetaDer(k),
+    1535      898632 :                               bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1536             :         }
+    1537             :       }
+    1538             :     }
+    1539        1884 :     setBoxDerivatives(val, -deriv_box);
+    1540             :   }
+    1541         204 : }
+    1542             : 
+    1543         204 : void SAXS::update() {
+    1544             :   // write status file
+    1545         204 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+    1546         204 : }
+    1547             : 
+    1548          16 : unsigned SAXS::getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms) {
+    1549          16 :   std::vector<std::string> chains; pdb.getChainNames( chains );
+    1550             :   std::vector<std::vector<std::string> > AtomResidueName;
+    1551             : 
+    1552             :   // cycle over chains
+    1553          42 :   for(unsigned i=0; i<chains.size(); ++i) {
+    1554             :     unsigned start, end;
+    1555             :     std::string errmsg;
+    1556          26 :     pdb.getResidueRange(chains[i], start, end, errmsg);
+    1557          26 :     AtomResidueName.resize(2);
+    1558             :     // cycle over residues
+    1559        3346 :     for(unsigned res=start; res<=end; res++) {
+    1560        3320 :       std::string Rname = pdb.getResidueName(res, chains[i]);
+    1561        3320 :       Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    1562        3320 :       std::vector<AtomNumber> res_atoms = pdb.getAtomsInResidue(res, chains[i]);
+    1563        3320 :       std::vector<unsigned> tmp_residue_atom; tmp_residue_atom.resize(3,0);
+    1564             :       // cycle over atoms
+    1565       59906 :       for(unsigned a=0; a<res_atoms.size(); a++) {
+    1566             :         // operations shared among all beads
+    1567       56586 :         std::string Aname=pdb.getAtomName(res_atoms[a]);
+    1568       56586 :         AtomResidueName[0].push_back(Aname);
+    1569       56586 :         AtomResidueName[1].push_back(Rname);
+    1570             :         char type;
+    1571       56586 :         char first = Aname.at(0);
+    1572             :         // We assume that element symbol is first letter, if not a number
+    1573       56586 :         if (!isdigit(first)) {
+    1574             :           type = first;
+    1575             :           // otherwise is the second
+    1576             :         } else {
+    1577           0 :           type = Aname.at(1);
+    1578             :         }
+    1579       56586 :         if (type == 'H') atoms_masses.push_back(1.008);
+    1580       16594 :         else if(type == 'C') atoms_masses.push_back(12.011);
+    1581        4416 :         else if(type == 'N') atoms_masses.push_back(14.007);
+    1582        5316 :         else if(type == 'O') atoms_masses.push_back(15.999);
+    1583         132 :         else if(type == 'S') atoms_masses.push_back(32.065);
+    1584          68 :         else if(type == 'P') atoms_masses.push_back(30.974);
+    1585             :         else {
+    1586           0 :           error("Unknown element in mass extraction\n");
+    1587             :         }
+    1588      113172 :         if(pdb.allowedResidue("protein",Rname)) {
+    1589       54262 :           residue_atom.push_back(atoms_per_bead.size());
+    1590             :         } else {
+    1591             :           // check for nucleic acids
+    1592             :           // Pentose bead
+    1593       10450 :           if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  || Aname=="O3'"  ||
+    1594        8500 :               Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  || Aname=="C1'"  || Aname=="H5'"  ||
+    1595        6628 :               Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  || Aname=="H2'"  || Aname=="H2''" ||
+    1596        5732 :               Aname=="H2'2" || Aname=="H1'"  || Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" ||
+    1597        7634 :               Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T"  ||
+    1598             :               Aname=="H3T" ) {
+    1599        1262 :             residue_atom.push_back(atoms_per_bead.size()+0);
+    1600        1262 :             tmp_residue_atom[0]++;
+    1601             :           }
+    1602             :           // Nucleobase bead
+    1603        4686 :           else if(Aname=="N1"  || Aname=="N2"  || Aname=="N3"  || Aname=="N4"  || Aname=="N6"  ||
+    1604        4062 :                   Aname=="N7"  || Aname=="N9"  || Aname=="C2"  || Aname=="C4"  || Aname=="C5"  ||
+    1605        2736 :                   Aname=="C6"  || Aname=="C7"  || Aname=="C8"  || Aname=="O2"  || Aname=="O4"  ||
+    1606        1956 :                   Aname=="O6"  || Aname=="H1"  || Aname=="H2"  || Aname=="H3"  || Aname=="H5"  ||
+    1607        1020 :                   Aname=="H6"  || Aname=="H8"  || Aname=="H21" || Aname=="H22" || Aname=="H41" ||
+    1608        2082 :                   Aname=="H42" || Aname=="H61" || Aname=="H62" || Aname=="H71" || Aname=="H72" ||
+    1609             :                   Aname=="H73" ) {
+    1610         858 :             residue_atom.push_back(atoms_per_bead.size()+1);
+    1611         858 :             tmp_residue_atom[1]++;
+    1612             :           }
+    1613             :           // PO bead
+    1614         204 :           else if(Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" || Aname=="O1P" ||
+    1615         204 :                   Aname=="O2P" || Aname=="O3P" || Aname=="HP"  || Aname=="HOP3" ) {
+    1616         204 :             residue_atom.push_back(atoms_per_bead.size()+2);
+    1617         204 :             tmp_residue_atom[2]++;
+    1618             :           }
+    1619             :           // error
+    1620           0 :           else error("Atom name "+Aname+" cannot be indexed to any bead. Check the PDB.");
+    1621             :         }
+    1622             :       }
+    1623        6640 :       if(pdb.allowedResidue("protein",Rname)) {
+    1624        3242 :         atoms_per_bead.push_back(res_atoms.size());
+    1625             :       } else {
+    1626          78 :         atoms_per_bead.push_back(tmp_residue_atom[0]);
+    1627          78 :         atoms_per_bead.push_back(tmp_residue_atom[1]);
+    1628          78 :         if(tmp_residue_atom[2]>0) atoms_per_bead.push_back(tmp_residue_atom[2]);
+    1629             :       }
+    1630             :     }
+    1631             :   }
+    1632          16 :   readLCPOparam(AtomResidueName, atoms.size());
+    1633          16 :   return atoms_per_bead.size();
+    1634          16 : }
+    1635             : 
+    1636           8 : void SAXS::getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter)
+    1637             : {
+    1638           8 :   parameter[ALA_BB].push_back(9.045);
+    1639           8 :   parameter[ALA_BB].push_back(-0.098114);
+    1640           8 :   parameter[ALA_BB].push_back(7.54281);
+    1641           8 :   parameter[ALA_BB].push_back(-1.97438);
+    1642           8 :   parameter[ALA_BB].push_back(-8.32689);
+    1643           8 :   parameter[ALA_BB].push_back(6.09318);
+    1644           8 :   parameter[ALA_BB].push_back(-1.18913);
+    1645             : 
+    1646           8 :   parameter[ARG_BB].push_back(10.729);
+    1647           8 :   parameter[ARG_BB].push_back(-0.0392574);
+    1648           8 :   parameter[ARG_BB].push_back(1.15382);
+    1649           8 :   parameter[ARG_BB].push_back(-0.155999);
+    1650           8 :   parameter[ARG_BB].push_back(-2.43619);
+    1651           8 :   parameter[ARG_BB].push_back(1.72922);
+    1652           8 :   parameter[ARG_BB].push_back(-0.33799);
+    1653             : 
+    1654           8 :   parameter[ARG_SC1].push_back(-2.796);
+    1655           8 :   parameter[ARG_SC1].push_back(0.472403);
+    1656           8 :   parameter[ARG_SC1].push_back(8.07424);
+    1657           8 :   parameter[ARG_SC1].push_back(4.37299);
+    1658           8 :   parameter[ARG_SC1].push_back(-10.7398);
+    1659           8 :   parameter[ARG_SC1].push_back(4.95677);
+    1660           8 :   parameter[ARG_SC1].push_back(-0.725797);
+    1661             : 
+    1662           8 :   parameter[ARG_SC2].push_back(15.396);
+    1663           8 :   parameter[ARG_SC2].push_back(0.0636736);
+    1664           8 :   parameter[ARG_SC2].push_back(-1.258);
+    1665           8 :   parameter[ARG_SC2].push_back(1.93135);
+    1666           8 :   parameter[ARG_SC2].push_back(-4.45031);
+    1667           8 :   parameter[ARG_SC2].push_back(2.49356);
+    1668           8 :   parameter[ARG_SC2].push_back(-0.410721);
+    1669             : 
+    1670           8 :   parameter[ASN_BB].push_back(10.738);
+    1671           8 :   parameter[ASN_BB].push_back(-0.0402162);
+    1672           8 :   parameter[ASN_BB].push_back(1.03007);
+    1673           8 :   parameter[ASN_BB].push_back(-0.254174);
+    1674           8 :   parameter[ASN_BB].push_back(-2.12015);
+    1675           8 :   parameter[ASN_BB].push_back(1.55535);
+    1676           8 :   parameter[ASN_BB].push_back(-0.30963);
+    1677             : 
+    1678           8 :   parameter[ASN_SC1].push_back(9.249);
+    1679           8 :   parameter[ASN_SC1].push_back(-0.0148678);
+    1680           8 :   parameter[ASN_SC1].push_back(5.52169);
+    1681           8 :   parameter[ASN_SC1].push_back(0.00853212);
+    1682           8 :   parameter[ASN_SC1].push_back(-6.71992);
+    1683           8 :   parameter[ASN_SC1].push_back(3.93622);
+    1684           8 :   parameter[ASN_SC1].push_back(-0.64973);
+    1685             : 
+    1686           8 :   parameter[ASP_BB].push_back(10.695);
+    1687           8 :   parameter[ASP_BB].push_back(-0.0410247);
+    1688           8 :   parameter[ASP_BB].push_back(1.03656);
+    1689           8 :   parameter[ASP_BB].push_back(-0.298558);
+    1690           8 :   parameter[ASP_BB].push_back(-2.06064);
+    1691           8 :   parameter[ASP_BB].push_back(1.53495);
+    1692           8 :   parameter[ASP_BB].push_back(-0.308365);
+    1693             : 
+    1694           8 :   parameter[ASP_SC1].push_back(9.476);
+    1695           8 :   parameter[ASP_SC1].push_back(-0.0254664);
+    1696           8 :   parameter[ASP_SC1].push_back(5.57899);
+    1697           8 :   parameter[ASP_SC1].push_back(-0.395027);
+    1698           8 :   parameter[ASP_SC1].push_back(-5.9407);
+    1699           8 :   parameter[ASP_SC1].push_back(3.48836);
+    1700           8 :   parameter[ASP_SC1].push_back(-0.569402);
+    1701             : 
+    1702           8 :   parameter[CYS_BB].push_back(10.698);
+    1703           8 :   parameter[CYS_BB].push_back(-0.0233493);
+    1704           8 :   parameter[CYS_BB].push_back(1.18257);
+    1705           8 :   parameter[CYS_BB].push_back(0.0684464);
+    1706           8 :   parameter[CYS_BB].push_back(-2.792);
+    1707           8 :   parameter[CYS_BB].push_back(1.88995);
+    1708           8 :   parameter[CYS_BB].push_back(-0.360229);
+    1709             : 
+    1710           8 :   parameter[CYS_SC1].push_back(8.199);
+    1711           8 :   parameter[CYS_SC1].push_back(-0.0261569);
+    1712           8 :   parameter[CYS_SC1].push_back(6.79677);
+    1713           8 :   parameter[CYS_SC1].push_back(-0.343845);
+    1714           8 :   parameter[CYS_SC1].push_back(-5.03578);
+    1715           8 :   parameter[CYS_SC1].push_back(2.7076);
+    1716           8 :   parameter[CYS_SC1].push_back(-0.420714);
+    1717             : 
+    1718           8 :   parameter[GLN_BB].push_back(10.728);
+    1719           8 :   parameter[GLN_BB].push_back(-0.0391984);
+    1720           8 :   parameter[GLN_BB].push_back(1.09264);
+    1721           8 :   parameter[GLN_BB].push_back(-0.261555);
+    1722           8 :   parameter[GLN_BB].push_back(-2.21245);
+    1723           8 :   parameter[GLN_BB].push_back(1.62071);
+    1724           8 :   parameter[GLN_BB].push_back(-0.322325);
+    1725             : 
+    1726           8 :   parameter[GLN_SC1].push_back(8.317);
+    1727           8 :   parameter[GLN_SC1].push_back(-0.229045);
+    1728           8 :   parameter[GLN_SC1].push_back(12.6338);
+    1729           8 :   parameter[GLN_SC1].push_back(-7.6719);
+    1730           8 :   parameter[GLN_SC1].push_back(-5.8376);
+    1731           8 :   parameter[GLN_SC1].push_back(5.53784);
+    1732           8 :   parameter[GLN_SC1].push_back(-1.12604);
+    1733             : 
+    1734           8 :   parameter[GLU_BB].push_back(10.694);
+    1735           8 :   parameter[GLU_BB].push_back(-0.0521961);
+    1736           8 :   parameter[GLU_BB].push_back(1.11153);
+    1737           8 :   parameter[GLU_BB].push_back(-0.491995);
+    1738           8 :   parameter[GLU_BB].push_back(-1.86236);
+    1739           8 :   parameter[GLU_BB].push_back(1.45332);
+    1740           8 :   parameter[GLU_BB].push_back(-0.29708);
+    1741             : 
+    1742           8 :   parameter[GLU_SC1].push_back(8.544);
+    1743           8 :   parameter[GLU_SC1].push_back(-0.249555);
+    1744           8 :   parameter[GLU_SC1].push_back(12.8031);
+    1745           8 :   parameter[GLU_SC1].push_back(-8.42696);
+    1746           8 :   parameter[GLU_SC1].push_back(-4.66486);
+    1747           8 :   parameter[GLU_SC1].push_back(4.90004);
+    1748           8 :   parameter[GLU_SC1].push_back(-1.01204);
+    1749             : 
+    1750           8 :   parameter[GLY_BB].push_back(9.977);
+    1751           8 :   parameter[GLY_BB].push_back(-0.0285799);
+    1752           8 :   parameter[GLY_BB].push_back(1.84236);
+    1753           8 :   parameter[GLY_BB].push_back(-0.0315192);
+    1754           8 :   parameter[GLY_BB].push_back(-2.88326);
+    1755           8 :   parameter[GLY_BB].push_back(1.87323);
+    1756           8 :   parameter[GLY_BB].push_back(-0.345773);
+    1757             : 
+    1758           8 :   parameter[HIS_BB].push_back(10.721);
+    1759           8 :   parameter[HIS_BB].push_back(-0.0379337);
+    1760           8 :   parameter[HIS_BB].push_back(1.06028);
+    1761           8 :   parameter[HIS_BB].push_back(-0.236143);
+    1762           8 :   parameter[HIS_BB].push_back(-2.17819);
+    1763           8 :   parameter[HIS_BB].push_back(1.58357);
+    1764           8 :   parameter[HIS_BB].push_back(-0.31345);
+    1765             : 
+    1766           8 :   parameter[HIS_SC1].push_back(-0.424);
+    1767           8 :   parameter[HIS_SC1].push_back(0.665176);
+    1768           8 :   parameter[HIS_SC1].push_back(3.4369);
+    1769           8 :   parameter[HIS_SC1].push_back(2.93795);
+    1770           8 :   parameter[HIS_SC1].push_back(-5.18288);
+    1771           8 :   parameter[HIS_SC1].push_back(2.12381);
+    1772           8 :   parameter[HIS_SC1].push_back(-0.284224);
+    1773             : 
+    1774           8 :   parameter[HIS_SC2].push_back(5.363);
+    1775           8 :   parameter[HIS_SC2].push_back(-0.0176945);
+    1776           8 :   parameter[HIS_SC2].push_back(2.9506);
+    1777           8 :   parameter[HIS_SC2].push_back(-0.387018);
+    1778           8 :   parameter[HIS_SC2].push_back(-1.83951);
+    1779           8 :   parameter[HIS_SC2].push_back(0.9703);
+    1780           8 :   parameter[HIS_SC2].push_back(-0.1458);
+    1781             : 
+    1782           8 :   parameter[HIS_SC3].push_back(5.784);
+    1783           8 :   parameter[HIS_SC3].push_back(-0.0293129);
+    1784           8 :   parameter[HIS_SC3].push_back(2.74167);
+    1785           8 :   parameter[HIS_SC3].push_back(-0.520875);
+    1786           8 :   parameter[HIS_SC3].push_back(-1.62949);
+    1787           8 :   parameter[HIS_SC3].push_back(0.902379);
+    1788           8 :   parameter[HIS_SC3].push_back(-0.139957);
+    1789             : 
+    1790           8 :   parameter[ILE_BB].push_back(10.699);
+    1791           8 :   parameter[ILE_BB].push_back(-0.0188962);
+    1792           8 :   parameter[ILE_BB].push_back(1.217);
+    1793           8 :   parameter[ILE_BB].push_back(0.242481);
+    1794           8 :   parameter[ILE_BB].push_back(-3.13898);
+    1795           8 :   parameter[ILE_BB].push_back(2.07916);
+    1796           8 :   parameter[ILE_BB].push_back(-0.392574);
+    1797             : 
+    1798           8 :   parameter[ILE_SC1].push_back(-4.448);
+    1799           8 :   parameter[ILE_SC1].push_back(1.20996);
+    1800           8 :   parameter[ILE_SC1].push_back(11.5141);
+    1801           8 :   parameter[ILE_SC1].push_back(6.98895);
+    1802           8 :   parameter[ILE_SC1].push_back(-19.1948);
+    1803           8 :   parameter[ILE_SC1].push_back(9.89207);
+    1804           8 :   parameter[ILE_SC1].push_back(-1.60877);
+    1805             : 
+    1806           8 :   parameter[LEU_BB].push_back(10.692);
+    1807           8 :   parameter[LEU_BB].push_back(-0.0414917);
+    1808           8 :   parameter[LEU_BB].push_back(1.1077);
+    1809           8 :   parameter[LEU_BB].push_back(-0.288062);
+    1810           8 :   parameter[LEU_BB].push_back(-2.17187);
+    1811           8 :   parameter[LEU_BB].push_back(1.59879);
+    1812           8 :   parameter[LEU_BB].push_back(-0.318545);
+    1813             : 
+    1814           8 :   parameter[LEU_SC1].push_back(-4.448);
+    1815           8 :   parameter[LEU_SC1].push_back(2.1063);
+    1816           8 :   parameter[LEU_SC1].push_back(6.72381);
+    1817           8 :   parameter[LEU_SC1].push_back(14.6954);
+    1818           8 :   parameter[LEU_SC1].push_back(-23.7197);
+    1819           8 :   parameter[LEU_SC1].push_back(10.7247);
+    1820           8 :   parameter[LEU_SC1].push_back(-1.59146);
+    1821             : 
+    1822           8 :   parameter[LYS_BB].push_back(10.706);
+    1823           8 :   parameter[LYS_BB].push_back(-0.0468629);
+    1824           8 :   parameter[LYS_BB].push_back(1.09477);
+    1825           8 :   parameter[LYS_BB].push_back(-0.432751);
+    1826           8 :   parameter[LYS_BB].push_back(-1.94335);
+    1827           8 :   parameter[LYS_BB].push_back(1.49109);
+    1828           8 :   parameter[LYS_BB].push_back(-0.302589);
+    1829             : 
+    1830           8 :   parameter[LYS_SC1].push_back(-2.796);
+    1831           8 :   parameter[LYS_SC1].push_back(0.508044);
+    1832           8 :   parameter[LYS_SC1].push_back(7.91436);
+    1833           8 :   parameter[LYS_SC1].push_back(4.54097);
+    1834           8 :   parameter[LYS_SC1].push_back(-10.8051);
+    1835           8 :   parameter[LYS_SC1].push_back(4.96204);
+    1836           8 :   parameter[LYS_SC1].push_back(-0.724414);
+    1837             : 
+    1838           8 :   parameter[LYS_SC2].push_back(3.070);
+    1839           8 :   parameter[LYS_SC2].push_back(-0.0101448);
+    1840           8 :   parameter[LYS_SC2].push_back(4.67994);
+    1841           8 :   parameter[LYS_SC2].push_back(-0.792529);
+    1842           8 :   parameter[LYS_SC2].push_back(-2.09142);
+    1843           8 :   parameter[LYS_SC2].push_back(1.02933);
+    1844           8 :   parameter[LYS_SC2].push_back(-0.137787);
+    1845             : 
+    1846           8 :   parameter[MET_BB].push_back(10.671);
+    1847           8 :   parameter[MET_BB].push_back(-0.0433724);
+    1848           8 :   parameter[MET_BB].push_back(1.13784);
+    1849           8 :   parameter[MET_BB].push_back(-0.40768);
+    1850           8 :   parameter[MET_BB].push_back(-2.00555);
+    1851           8 :   parameter[MET_BB].push_back(1.51673);
+    1852           8 :   parameter[MET_BB].push_back(-0.305547);
+    1853             : 
+    1854           8 :   parameter[MET_SC1].push_back(5.85);
+    1855           8 :   parameter[MET_SC1].push_back(-0.0485798);
+    1856           8 :   parameter[MET_SC1].push_back(17.0391);
+    1857           8 :   parameter[MET_SC1].push_back(-3.65327);
+    1858           8 :   parameter[MET_SC1].push_back(-13.174);
+    1859           8 :   parameter[MET_SC1].push_back(8.68286);
+    1860           8 :   parameter[MET_SC1].push_back(-1.56095);
+    1861             : 
+    1862           8 :   parameter[PHE_BB].push_back(10.741);
+    1863           8 :   parameter[PHE_BB].push_back(-0.0317275);
+    1864           8 :   parameter[PHE_BB].push_back(1.15599);
+    1865           8 :   parameter[PHE_BB].push_back(0.0276187);
+    1866           8 :   parameter[PHE_BB].push_back(-2.74757);
+    1867           8 :   parameter[PHE_BB].push_back(1.88783);
+    1868           8 :   parameter[PHE_BB].push_back(-0.363525);
+    1869             : 
+    1870           8 :   parameter[PHE_SC1].push_back(-0.636);
+    1871           8 :   parameter[PHE_SC1].push_back(0.527882);
+    1872           8 :   parameter[PHE_SC1].push_back(6.77612);
+    1873           8 :   parameter[PHE_SC1].push_back(3.18508);
+    1874           8 :   parameter[PHE_SC1].push_back(-8.92826);
+    1875           8 :   parameter[PHE_SC1].push_back(4.29752);
+    1876           8 :   parameter[PHE_SC1].push_back(-0.65187);
+    1877             : 
+    1878           8 :   parameter[PHE_SC2].push_back(-0.424);
+    1879           8 :   parameter[PHE_SC2].push_back(0.389174);
+    1880           8 :   parameter[PHE_SC2].push_back(4.11761);
+    1881           8 :   parameter[PHE_SC2].push_back(2.29527);
+    1882           8 :   parameter[PHE_SC2].push_back(-4.7652);
+    1883           8 :   parameter[PHE_SC2].push_back(1.97023);
+    1884           8 :   parameter[PHE_SC2].push_back(-0.262318);
+    1885             : 
+    1886           8 :   parameter[PHE_SC3].push_back(-0.424);
+    1887           8 :   parameter[PHE_SC3].push_back(0.38927);
+    1888           8 :   parameter[PHE_SC3].push_back(4.11708);
+    1889           8 :   parameter[PHE_SC3].push_back(2.29623);
+    1890           8 :   parameter[PHE_SC3].push_back(-4.76592);
+    1891           8 :   parameter[PHE_SC3].push_back(1.97055);
+    1892           8 :   parameter[PHE_SC3].push_back(-0.262381);
+    1893             : 
+    1894           8 :   parameter[PRO_BB].push_back(11.434);
+    1895           8 :   parameter[PRO_BB].push_back(-0.033323);
+    1896           8 :   parameter[PRO_BB].push_back(0.472014);
+    1897           8 :   parameter[PRO_BB].push_back(-0.290854);
+    1898           8 :   parameter[PRO_BB].push_back(-1.81409);
+    1899           8 :   parameter[PRO_BB].push_back(1.39751);
+    1900           8 :   parameter[PRO_BB].push_back(-0.280407);
+    1901             : 
+    1902           8 :   parameter[PRO_SC1].push_back(-2.796);
+    1903           8 :   parameter[PRO_SC1].push_back(0.95668);
+    1904           8 :   parameter[PRO_SC1].push_back(6.84197);
+    1905           8 :   parameter[PRO_SC1].push_back(6.43774);
+    1906           8 :   parameter[PRO_SC1].push_back(-12.5068);
+    1907           8 :   parameter[PRO_SC1].push_back(5.64597);
+    1908           8 :   parameter[PRO_SC1].push_back(-0.825206);
+    1909             : 
+    1910           8 :   parameter[SER_BB].push_back(10.699);
+    1911           8 :   parameter[SER_BB].push_back(-0.0325828);
+    1912           8 :   parameter[SER_BB].push_back(1.20329);
+    1913           8 :   parameter[SER_BB].push_back(-0.0674351);
+    1914           8 :   parameter[SER_BB].push_back(-2.60749);
+    1915           8 :   parameter[SER_BB].push_back(1.80318);
+    1916           8 :   parameter[SER_BB].push_back(-0.346803);
+    1917             : 
+    1918           8 :   parameter[SER_SC1].push_back(3.298);
+    1919           8 :   parameter[SER_SC1].push_back(-0.0366801);
+    1920           8 :   parameter[SER_SC1].push_back(5.11077);
+    1921           8 :   parameter[SER_SC1].push_back(-1.46774);
+    1922           8 :   parameter[SER_SC1].push_back(-1.48421);
+    1923           8 :   parameter[SER_SC1].push_back(0.800326);
+    1924           8 :   parameter[SER_SC1].push_back(-0.108314);
+    1925             : 
+    1926           8 :   parameter[THR_BB].push_back(10.697);
+    1927           8 :   parameter[THR_BB].push_back(-0.0242955);
+    1928           8 :   parameter[THR_BB].push_back(1.24671);
+    1929           8 :   parameter[THR_BB].push_back(0.146423);
+    1930           8 :   parameter[THR_BB].push_back(-2.97429);
+    1931           8 :   parameter[THR_BB].push_back(1.97513);
+    1932           8 :   parameter[THR_BB].push_back(-0.371479);
+    1933             : 
+    1934           8 :   parameter[THR_SC1].push_back(2.366);
+    1935           8 :   parameter[THR_SC1].push_back(0.0297604);
+    1936           8 :   parameter[THR_SC1].push_back(11.9216);
+    1937           8 :   parameter[THR_SC1].push_back(-9.32503);
+    1938           8 :   parameter[THR_SC1].push_back(1.9396);
+    1939           8 :   parameter[THR_SC1].push_back(0.0804861);
+    1940           8 :   parameter[THR_SC1].push_back(-0.0302721);
+    1941             : 
+    1942           8 :   parameter[TRP_BB].push_back(10.689);
+    1943           8 :   parameter[TRP_BB].push_back(-0.0265879);
+    1944           8 :   parameter[TRP_BB].push_back(1.17819);
+    1945           8 :   parameter[TRP_BB].push_back(0.0386457);
+    1946           8 :   parameter[TRP_BB].push_back(-2.75634);
+    1947           8 :   parameter[TRP_BB].push_back(1.88065);
+    1948           8 :   parameter[TRP_BB].push_back(-0.360217);
+    1949             : 
+    1950           8 :   parameter[TRP_SC1].push_back(0.084);
+    1951           8 :   parameter[TRP_SC1].push_back(0.752407);
+    1952           8 :   parameter[TRP_SC1].push_back(5.3802);
+    1953           8 :   parameter[TRP_SC1].push_back(4.09281);
+    1954           8 :   parameter[TRP_SC1].push_back(-9.28029);
+    1955           8 :   parameter[TRP_SC1].push_back(4.45923);
+    1956           8 :   parameter[TRP_SC1].push_back(-0.689008);
+    1957             : 
+    1958           8 :   parameter[TRP_SC2].push_back(5.739);
+    1959           8 :   parameter[TRP_SC2].push_back(0.0298492);
+    1960           8 :   parameter[TRP_SC2].push_back(4.60446);
+    1961           8 :   parameter[TRP_SC2].push_back(1.34463);
+    1962           8 :   parameter[TRP_SC2].push_back(-5.69968);
+    1963           8 :   parameter[TRP_SC2].push_back(2.84924);
+    1964           8 :   parameter[TRP_SC2].push_back(-0.433781);
+    1965             : 
+    1966           8 :   parameter[TRP_SC3].push_back(-0.424);
+    1967           8 :   parameter[TRP_SC3].push_back(0.388576);
+    1968           8 :   parameter[TRP_SC3].push_back(4.11859);
+    1969           8 :   parameter[TRP_SC3].push_back(2.29485);
+    1970           8 :   parameter[TRP_SC3].push_back(-4.76255);
+    1971           8 :   parameter[TRP_SC3].push_back(1.96849);
+    1972           8 :   parameter[TRP_SC3].push_back(-0.262015);
+    1973             : 
+    1974           8 :   parameter[TRP_SC4].push_back(-0.424);
+    1975           8 :   parameter[TRP_SC4].push_back(0.387685);
+    1976           8 :   parameter[TRP_SC4].push_back(4.12153);
+    1977           8 :   parameter[TRP_SC4].push_back(2.29144);
+    1978           8 :   parameter[TRP_SC4].push_back(-4.7589);
+    1979           8 :   parameter[TRP_SC4].push_back(1.96686);
+    1980           8 :   parameter[TRP_SC4].push_back(-0.261786);
+    1981             : 
+    1982           8 :   parameter[TYR_BB].push_back(10.689);
+    1983           8 :   parameter[TYR_BB].push_back(-0.0193526);
+    1984           8 :   parameter[TYR_BB].push_back(1.18241);
+    1985           8 :   parameter[TYR_BB].push_back(0.207318);
+    1986           8 :   parameter[TYR_BB].push_back(-3.0041);
+    1987           8 :   parameter[TYR_BB].push_back(1.99335);
+    1988           8 :   parameter[TYR_BB].push_back(-0.376482);
+    1989             : 
+    1990           8 :   parameter[TYR_SC1].push_back(-0.636);
+    1991           8 :   parameter[TYR_SC1].push_back(0.528902);
+    1992           8 :   parameter[TYR_SC1].push_back(6.78168);
+    1993           8 :   parameter[TYR_SC1].push_back(3.17769);
+    1994           8 :   parameter[TYR_SC1].push_back(-8.93667);
+    1995           8 :   parameter[TYR_SC1].push_back(4.30692);
+    1996           8 :   parameter[TYR_SC1].push_back(-0.653993);
+    1997             : 
+    1998           8 :   parameter[TYR_SC2].push_back(-0.424);
+    1999           8 :   parameter[TYR_SC2].push_back(0.388811);
+    2000           8 :   parameter[TYR_SC2].push_back(4.11851);
+    2001           8 :   parameter[TYR_SC2].push_back(2.29545);
+    2002           8 :   parameter[TYR_SC2].push_back(-4.7668);
+    2003           8 :   parameter[TYR_SC2].push_back(1.97131);
+    2004           8 :   parameter[TYR_SC2].push_back(-0.262534);
+    2005             : 
+    2006           8 :   parameter[TYR_SC3].push_back(4.526);
+    2007           8 :   parameter[TYR_SC3].push_back(-0.00381305);
+    2008           8 :   parameter[TYR_SC3].push_back(5.8567);
+    2009           8 :   parameter[TYR_SC3].push_back(-0.214086);
+    2010           8 :   parameter[TYR_SC3].push_back(-4.63649);
+    2011           8 :   parameter[TYR_SC3].push_back(2.52869);
+    2012           8 :   parameter[TYR_SC3].push_back(-0.39894);
+    2013             : 
+    2014           8 :   parameter[VAL_BB].push_back(10.691);
+    2015           8 :   parameter[VAL_BB].push_back(-0.0162929);
+    2016           8 :   parameter[VAL_BB].push_back(1.24446);
+    2017           8 :   parameter[VAL_BB].push_back(0.307914);
+    2018           8 :   parameter[VAL_BB].push_back(-3.27446);
+    2019           8 :   parameter[VAL_BB].push_back(2.14788);
+    2020           8 :   parameter[VAL_BB].push_back(-0.403259);
+    2021             : 
+    2022           8 :   parameter[VAL_SC1].push_back(-3.516);
+    2023           8 :   parameter[VAL_SC1].push_back(1.62307);
+    2024           8 :   parameter[VAL_SC1].push_back(5.43064);
+    2025           8 :   parameter[VAL_SC1].push_back(9.28809);
+    2026           8 :   parameter[VAL_SC1].push_back(-14.9927);
+    2027           8 :   parameter[VAL_SC1].push_back(6.6133);
+    2028           8 :   parameter[VAL_SC1].push_back(-0.964977);
+    2029             : 
+    2030           8 :   parameter[A_BB1].push_back(32.88500000);
+    2031           8 :   parameter[A_BB1].push_back(0.08339900);
+    2032           8 :   parameter[A_BB1].push_back(-7.36054400);
+    2033           8 :   parameter[A_BB1].push_back(2.19220300);
+    2034           8 :   parameter[A_BB1].push_back(-3.56523400);
+    2035           8 :   parameter[A_BB1].push_back(2.33326900);
+    2036           8 :   parameter[A_BB1].push_back(-0.39785500);
+    2037             : 
+    2038           8 :   parameter[A_BB2].push_back(3.80600000);
+    2039           8 :   parameter[A_BB2].push_back(-0.10727600);
+    2040           8 :   parameter[A_BB2].push_back(9.58854100);
+    2041           8 :   parameter[A_BB2].push_back(-6.23740500);
+    2042           8 :   parameter[A_BB2].push_back(-0.48267300);
+    2043           8 :   parameter[A_BB2].push_back(1.14119500);
+    2044           8 :   parameter[A_BB2].push_back(-0.21385600);
+    2045             : 
+    2046           8 :   parameter[A_BB3].push_back(3.59400000);
+    2047           8 :   parameter[A_BB3].push_back(0.04537300);
+    2048           8 :   parameter[A_BB3].push_back(9.59178900);
+    2049           8 :   parameter[A_BB3].push_back(-1.29202200);
+    2050           8 :   parameter[A_BB3].push_back(-7.10851000);
+    2051           8 :   parameter[A_BB3].push_back(4.05571200);
+    2052           8 :   parameter[A_BB3].push_back(-0.63372500);
+    2053             : 
+    2054           8 :   parameter[A_SC1].push_back(6.67100000);
+    2055           8 :   parameter[A_SC1].push_back(-0.00855300);
+    2056           8 :   parameter[A_SC1].push_back(1.63222400);
+    2057           8 :   parameter[A_SC1].push_back(-0.06466200);
+    2058           8 :   parameter[A_SC1].push_back(-1.48694200);
+    2059           8 :   parameter[A_SC1].push_back(0.78544600);
+    2060           8 :   parameter[A_SC1].push_back(-0.12083500);
+    2061             : 
+    2062           8 :   parameter[A_SC2].push_back(5.95100000);
+    2063           8 :   parameter[A_SC2].push_back(-0.02606600);
+    2064           8 :   parameter[A_SC2].push_back(2.54399900);
+    2065           8 :   parameter[A_SC2].push_back(-0.48436900);
+    2066           8 :   parameter[A_SC2].push_back(-1.55357400);
+    2067           8 :   parameter[A_SC2].push_back(0.86466900);
+    2068           8 :   parameter[A_SC2].push_back(-0.13509000);
+    2069             : 
+    2070           8 :   parameter[A_SC3].push_back(11.39400000);
+    2071           8 :   parameter[A_SC3].push_back(0.00871300);
+    2072           8 :   parameter[A_SC3].push_back(-0.23891300);
+    2073           8 :   parameter[A_SC3].push_back(0.48919400);
+    2074           8 :   parameter[A_SC3].push_back(-1.75289400);
+    2075           8 :   parameter[A_SC3].push_back(0.99267500);
+    2076           8 :   parameter[A_SC3].push_back(-0.16291300);
+    2077             : 
+    2078           8 :   parameter[A_SC4].push_back(6.45900000);
+    2079           8 :   parameter[A_SC4].push_back(0.01990600);
+    2080           8 :   parameter[A_SC4].push_back(4.17970400);
+    2081           8 :   parameter[A_SC4].push_back(0.97629900);
+    2082           8 :   parameter[A_SC4].push_back(-5.03297800);
+    2083           8 :   parameter[A_SC4].push_back(2.55576700);
+    2084           8 :   parameter[A_SC4].push_back(-0.39150500);
+    2085             : 
+    2086           8 :   parameter[A_3TE].push_back(4.23000000);
+    2087           8 :   parameter[A_3TE].push_back(0.00064800);
+    2088           8 :   parameter[A_3TE].push_back(0.92124600);
+    2089           8 :   parameter[A_3TE].push_back(0.08064300);
+    2090           8 :   parameter[A_3TE].push_back(-0.39054400);
+    2091           8 :   parameter[A_3TE].push_back(0.12429100);
+    2092           8 :   parameter[A_3TE].push_back(-0.01122700);
+    2093             : 
+    2094           8 :   parameter[A_5TE].push_back(4.23000000);
+    2095           8 :   parameter[A_5TE].push_back(0.00039300);
+    2096           8 :   parameter[A_5TE].push_back(0.92305100);
+    2097           8 :   parameter[A_5TE].push_back(0.07747500);
+    2098           8 :   parameter[A_5TE].push_back(-0.38792100);
+    2099           8 :   parameter[A_5TE].push_back(0.12323800);
+    2100           8 :   parameter[A_5TE].push_back(-0.01106600);
+    2101             : 
+    2102           8 :   parameter[A_TE3].push_back(7.82400000);
+    2103           8 :   parameter[A_TE3].push_back(-0.04881000);
+    2104           8 :   parameter[A_TE3].push_back(8.21557900);
+    2105           8 :   parameter[A_TE3].push_back(-0.89491400);
+    2106           8 :   parameter[A_TE3].push_back(-9.54293700);
+    2107           8 :   parameter[A_TE3].push_back(6.33122200);
+    2108           8 :   parameter[A_TE3].push_back(-1.16672900);
+    2109             : 
+    2110           8 :   parameter[A_TE5].push_back(8.03600000);
+    2111           8 :   parameter[A_TE5].push_back(0.01641200);
+    2112           8 :   parameter[A_TE5].push_back(5.14902200);
+    2113           8 :   parameter[A_TE5].push_back(0.83419700);
+    2114           8 :   parameter[A_TE5].push_back(-7.59068300);
+    2115           8 :   parameter[A_TE5].push_back(4.52063200);
+    2116           8 :   parameter[A_TE5].push_back(-0.78260800);
+    2117             : 
+    2118           8 :   parameter[C_BB1].push_back(32.88500000);
+    2119           8 :   parameter[C_BB1].push_back(0.08311100);
+    2120           8 :   parameter[C_BB1].push_back(-7.35432100);
+    2121           8 :   parameter[C_BB1].push_back(2.18610000);
+    2122           8 :   parameter[C_BB1].push_back(-3.55788300);
+    2123           8 :   parameter[C_BB1].push_back(2.32918700);
+    2124           8 :   parameter[C_BB1].push_back(-0.39720000);
+    2125             : 
+    2126           8 :   parameter[C_BB2].push_back(3.80600000);
+    2127           8 :   parameter[C_BB2].push_back(-0.10808100);
+    2128           8 :   parameter[C_BB2].push_back(9.61612600);
+    2129           8 :   parameter[C_BB2].push_back(-6.28595400);
+    2130           8 :   parameter[C_BB2].push_back(-0.45187000);
+    2131           8 :   parameter[C_BB2].push_back(1.13326000);
+    2132           8 :   parameter[C_BB2].push_back(-0.21320300);
+    2133             : 
+    2134           8 :   parameter[C_BB3].push_back(3.59400000);
+    2135           8 :   parameter[C_BB3].push_back(0.04484200);
+    2136           8 :   parameter[C_BB3].push_back(9.61919800);
+    2137           8 :   parameter[C_BB3].push_back(-1.33582800);
+    2138           8 :   parameter[C_BB3].push_back(-7.07200400);
+    2139           8 :   parameter[C_BB3].push_back(4.03952900);
+    2140           8 :   parameter[C_BB3].push_back(-0.63098200);
+    2141             : 
+    2142           8 :   parameter[C_SC1].push_back(5.95100000);
+    2143           8 :   parameter[C_SC1].push_back(-0.02911300);
+    2144           8 :   parameter[C_SC1].push_back(2.59700400);
+    2145           8 :   parameter[C_SC1].push_back(-0.55507700);
+    2146           8 :   parameter[C_SC1].push_back(-1.56344600);
+    2147           8 :   parameter[C_SC1].push_back(0.88956200);
+    2148           8 :   parameter[C_SC1].push_back(-0.14061300);
+    2149             : 
+    2150           8 :   parameter[C_SC2].push_back(11.62100000);
+    2151           8 :   parameter[C_SC2].push_back(0.01366100);
+    2152           8 :   parameter[C_SC2].push_back(-0.25959200);
+    2153           8 :   parameter[C_SC2].push_back(0.48918300);
+    2154           8 :   parameter[C_SC2].push_back(-1.52550500);
+    2155           8 :   parameter[C_SC2].push_back(0.83644100);
+    2156           8 :   parameter[C_SC2].push_back(-0.13407300);
+    2157             : 
+    2158           8 :   parameter[C_SC3].push_back(5.01900000);
+    2159           8 :   parameter[C_SC3].push_back(-0.03276100);
+    2160           8 :   parameter[C_SC3].push_back(5.53776900);
+    2161           8 :   parameter[C_SC3].push_back(-0.95105000);
+    2162           8 :   parameter[C_SC3].push_back(-3.71130800);
+    2163           8 :   parameter[C_SC3].push_back(2.16146000);
+    2164           8 :   parameter[C_SC3].push_back(-0.34918600);
+    2165             : 
+    2166           8 :   parameter[C_3TE].push_back(4.23000000);
+    2167           8 :   parameter[C_3TE].push_back(0.00057300);
+    2168           8 :   parameter[C_3TE].push_back(0.92174800);
+    2169           8 :   parameter[C_3TE].push_back(0.07964500);
+    2170           8 :   parameter[C_3TE].push_back(-0.38965700);
+    2171           8 :   parameter[C_3TE].push_back(0.12392500);
+    2172           8 :   parameter[C_3TE].push_back(-0.01117000);
+    2173             : 
+    2174           8 :   parameter[C_5TE].push_back(4.23000000);
+    2175           8 :   parameter[C_5TE].push_back(0.00071000);
+    2176           8 :   parameter[C_5TE].push_back(0.92082800);
+    2177           8 :   parameter[C_5TE].push_back(0.08150600);
+    2178           8 :   parameter[C_5TE].push_back(-0.39127000);
+    2179           8 :   parameter[C_5TE].push_back(0.12455900);
+    2180           8 :   parameter[C_5TE].push_back(-0.01126300);
+    2181             : 
+    2182           8 :   parameter[C_TE3].push_back(7.82400000);
+    2183           8 :   parameter[C_TE3].push_back(-0.05848300);
+    2184           8 :   parameter[C_TE3].push_back(8.29319900);
+    2185           8 :   parameter[C_TE3].push_back(-1.12563800);
+    2186           8 :   parameter[C_TE3].push_back(-9.42197600);
+    2187           8 :   parameter[C_TE3].push_back(6.35441700);
+    2188           8 :   parameter[C_TE3].push_back(-1.18356900);
+    2189             : 
+    2190           8 :   parameter[C_TE5].push_back(8.03600000);
+    2191           8 :   parameter[C_TE5].push_back(0.00493500);
+    2192           8 :   parameter[C_TE5].push_back(4.92622000);
+    2193           8 :   parameter[C_TE5].push_back(0.64810700);
+    2194           8 :   parameter[C_TE5].push_back(-7.05100000);
+    2195           8 :   parameter[C_TE5].push_back(4.26064400);
+    2196           8 :   parameter[C_TE5].push_back(-0.74819100);
+    2197             : 
+    2198           8 :   parameter[G_BB1].push_back(32.88500000);
+    2199           8 :   parameter[G_BB1].push_back(0.08325400);
+    2200           8 :   parameter[G_BB1].push_back(-7.35736000);
+    2201           8 :   parameter[G_BB1].push_back(2.18914800);
+    2202           8 :   parameter[G_BB1].push_back(-3.56154800);
+    2203           8 :   parameter[G_BB1].push_back(2.33120600);
+    2204           8 :   parameter[G_BB1].push_back(-0.39752300);
+    2205             : 
+    2206           8 :   parameter[G_BB2].push_back(3.80600000);
+    2207           8 :   parameter[G_BB2].push_back(-0.10788300);
+    2208           8 :   parameter[G_BB2].push_back(9.60930800);
+    2209           8 :   parameter[G_BB2].push_back(-6.27402500);
+    2210           8 :   parameter[G_BB2].push_back(-0.46192700);
+    2211           8 :   parameter[G_BB2].push_back(1.13737000);
+    2212           8 :   parameter[G_BB2].push_back(-0.21383100);
+    2213             : 
+    2214           8 :   parameter[G_BB3].push_back(3.59400000);
+    2215           8 :   parameter[G_BB3].push_back(0.04514500);
+    2216           8 :   parameter[G_BB3].push_back(9.61234700);
+    2217           8 :   parameter[G_BB3].push_back(-1.31542100);
+    2218           8 :   parameter[G_BB3].push_back(-7.09150500);
+    2219           8 :   parameter[G_BB3].push_back(4.04706200);
+    2220           8 :   parameter[G_BB3].push_back(-0.63201000);
+    2221             : 
+    2222           8 :   parameter[G_SC1].push_back(6.67100000);
+    2223           8 :   parameter[G_SC1].push_back(-0.00863200);
+    2224           8 :   parameter[G_SC1].push_back(1.63252300);
+    2225           8 :   parameter[G_SC1].push_back(-0.06567200);
+    2226           8 :   parameter[G_SC1].push_back(-1.48680500);
+    2227           8 :   parameter[G_SC1].push_back(0.78565600);
+    2228           8 :   parameter[G_SC1].push_back(-0.12088900);
+    2229             : 
+    2230           8 :   parameter[G_SC2].push_back(11.39400000);
+    2231           8 :   parameter[G_SC2].push_back(0.00912200);
+    2232           8 :   parameter[G_SC2].push_back(-0.22869000);
+    2233           8 :   parameter[G_SC2].push_back(0.49616400);
+    2234           8 :   parameter[G_SC2].push_back(-1.75039000);
+    2235           8 :   parameter[G_SC2].push_back(0.98649200);
+    2236           8 :   parameter[G_SC2].push_back(-0.16141600);
+    2237             : 
+    2238           8 :   parameter[G_SC3].push_back(10.90100000);
+    2239           8 :   parameter[G_SC3].push_back(0.02208700);
+    2240           8 :   parameter[G_SC3].push_back(0.17032800);
+    2241           8 :   parameter[G_SC3].push_back(0.73280800);
+    2242           8 :   parameter[G_SC3].push_back(-1.95292000);
+    2243           8 :   parameter[G_SC3].push_back(0.98357600);
+    2244           8 :   parameter[G_SC3].push_back(-0.14790900);
+    2245             : 
+    2246           8 :   parameter[G_SC4].push_back(6.45900000);
+    2247           8 :   parameter[G_SC4].push_back(0.02023700);
+    2248           8 :   parameter[G_SC4].push_back(4.17655400);
+    2249           8 :   parameter[G_SC4].push_back(0.98731800);
+    2250           8 :   parameter[G_SC4].push_back(-5.04352800);
+    2251           8 :   parameter[G_SC4].push_back(2.56059400);
+    2252           8 :   parameter[G_SC4].push_back(-0.39234300);
+    2253             : 
+    2254           8 :   parameter[G_3TE].push_back(4.23000000);
+    2255           8 :   parameter[G_3TE].push_back(0.00066300);
+    2256           8 :   parameter[G_3TE].push_back(0.92118800);
+    2257           8 :   parameter[G_3TE].push_back(0.08062700);
+    2258           8 :   parameter[G_3TE].push_back(-0.39041600);
+    2259           8 :   parameter[G_3TE].push_back(0.12419400);
+    2260           8 :   parameter[G_3TE].push_back(-0.01120500);
+    2261             : 
+    2262           8 :   parameter[G_5TE].push_back(4.23000000);
+    2263           8 :   parameter[G_5TE].push_back(0.00062800);
+    2264           8 :   parameter[G_5TE].push_back(0.92133500);
+    2265           8 :   parameter[G_5TE].push_back(0.08029900);
+    2266           8 :   parameter[G_5TE].push_back(-0.39015300);
+    2267           8 :   parameter[G_5TE].push_back(0.12411600);
+    2268           8 :   parameter[G_5TE].push_back(-0.01119900);
+    2269             : 
+    2270           8 :   parameter[G_TE3].push_back(7.82400000);
+    2271           8 :   parameter[G_TE3].push_back(-0.05177400);
+    2272           8 :   parameter[G_TE3].push_back(8.34606700);
+    2273           8 :   parameter[G_TE3].push_back(-1.02936300);
+    2274           8 :   parameter[G_TE3].push_back(-9.55211900);
+    2275           8 :   parameter[G_TE3].push_back(6.37776600);
+    2276           8 :   parameter[G_TE3].push_back(-1.17898000);
+    2277             : 
+    2278           8 :   parameter[G_TE5].push_back(8.03600000);
+    2279           8 :   parameter[G_TE5].push_back(0.00525100);
+    2280           8 :   parameter[G_TE5].push_back(4.71070600);
+    2281           8 :   parameter[G_TE5].push_back(0.66746900);
+    2282           8 :   parameter[G_TE5].push_back(-6.72538700);
+    2283           8 :   parameter[G_TE5].push_back(4.03644100);
+    2284           8 :   parameter[G_TE5].push_back(-0.70605700);
+    2285             : 
+    2286           8 :   parameter[U_BB1].push_back(32.88500000);
+    2287           8 :   parameter[U_BB1].push_back(0.08321400);
+    2288           8 :   parameter[U_BB1].push_back(-7.35634900);
+    2289           8 :   parameter[U_BB1].push_back(2.18826800);
+    2290           8 :   parameter[U_BB1].push_back(-3.56047400);
+    2291           8 :   parameter[U_BB1].push_back(2.33064700);
+    2292           8 :   parameter[U_BB1].push_back(-0.39744000);
+    2293             : 
+    2294           8 :   parameter[U_BB2].push_back(3.80600000);
+    2295           8 :   parameter[U_BB2].push_back(-0.10773100);
+    2296           8 :   parameter[U_BB2].push_back(9.60099900);
+    2297           8 :   parameter[U_BB2].push_back(-6.26131900);
+    2298           8 :   parameter[U_BB2].push_back(-0.46668300);
+    2299           8 :   parameter[U_BB2].push_back(1.13698100);
+    2300           8 :   parameter[U_BB2].push_back(-0.21351600);
+    2301             : 
+    2302           8 :   parameter[U_BB3].push_back(3.59400000);
+    2303           8 :   parameter[U_BB3].push_back(0.04544300);
+    2304           8 :   parameter[U_BB3].push_back(9.59625900);
+    2305           8 :   parameter[U_BB3].push_back(-1.29222200);
+    2306           8 :   parameter[U_BB3].push_back(-7.11143200);
+    2307           8 :   parameter[U_BB3].push_back(4.05687700);
+    2308           8 :   parameter[U_BB3].push_back(-0.63382800);
+    2309             : 
+    2310           8 :   parameter[U_SC1].push_back(5.95100000);
+    2311           8 :   parameter[U_SC1].push_back(-0.02924500);
+    2312           8 :   parameter[U_SC1].push_back(2.59668700);
+    2313           8 :   parameter[U_SC1].push_back(-0.56118700);
+    2314           8 :   parameter[U_SC1].push_back(-1.56477100);
+    2315           8 :   parameter[U_SC1].push_back(0.89265100);
+    2316           8 :   parameter[U_SC1].push_back(-0.14130800);
+    2317             : 
+    2318           8 :   parameter[U_SC2].push_back(10.90100000);
+    2319           8 :   parameter[U_SC2].push_back(0.02178900);
+    2320           8 :   parameter[U_SC2].push_back(0.18839000);
+    2321           8 :   parameter[U_SC2].push_back(0.72223100);
+    2322           8 :   parameter[U_SC2].push_back(-1.92581600);
+    2323           8 :   parameter[U_SC2].push_back(0.96654300);
+    2324           8 :   parameter[U_SC2].push_back(-0.14501300);
+    2325             : 
+    2326           8 :   parameter[U_SC3].push_back(5.24600000);
+    2327           8 :   parameter[U_SC3].push_back(-0.04586500);
+    2328           8 :   parameter[U_SC3].push_back(5.89978100);
+    2329           8 :   parameter[U_SC3].push_back(-1.50664700);
+    2330           8 :   parameter[U_SC3].push_back(-3.17054400);
+    2331           8 :   parameter[U_SC3].push_back(1.93717100);
+    2332           8 :   parameter[U_SC3].push_back(-0.31701000);
+    2333             : 
+    2334           8 :   parameter[U_3TE].push_back(4.23000000);
+    2335           8 :   parameter[U_3TE].push_back(0.00067500);
+    2336           8 :   parameter[U_3TE].push_back(0.92102300);
+    2337           8 :   parameter[U_3TE].push_back(0.08100800);
+    2338           8 :   parameter[U_3TE].push_back(-0.39084300);
+    2339           8 :   parameter[U_3TE].push_back(0.12441900);
+    2340           8 :   parameter[U_3TE].push_back(-0.01124900);
+    2341             : 
+    2342           8 :   parameter[U_5TE].push_back(4.23000000);
+    2343           8 :   parameter[U_5TE].push_back(0.00059000);
+    2344           8 :   parameter[U_5TE].push_back(0.92154600);
+    2345           8 :   parameter[U_5TE].push_back(0.07968200);
+    2346           8 :   parameter[U_5TE].push_back(-0.38950100);
+    2347           8 :   parameter[U_5TE].push_back(0.12382500);
+    2348           8 :   parameter[U_5TE].push_back(-0.01115100);
+    2349             : 
+    2350           8 :   parameter[U_TE3].push_back(7.82400000);
+    2351           8 :   parameter[U_TE3].push_back(-0.02968100);
+    2352           8 :   parameter[U_TE3].push_back(7.93783200);
+    2353           8 :   parameter[U_TE3].push_back(-0.33078100);
+    2354           8 :   parameter[U_TE3].push_back(-10.14120200);
+    2355           8 :   parameter[U_TE3].push_back(6.63334700);
+    2356           8 :   parameter[U_TE3].push_back(-1.22111200);
+    2357             : 
+    2358           8 :   parameter[U_TE5].push_back(8.03600000);
+    2359           8 :   parameter[U_TE5].push_back(-0.00909700);
+    2360           8 :   parameter[U_TE5].push_back(4.33193500);
+    2361           8 :   parameter[U_TE5].push_back(0.43416500);
+    2362           8 :   parameter[U_TE5].push_back(-5.80831400);
+    2363           8 :   parameter[U_TE5].push_back(3.52438800);
+    2364           8 :   parameter[U_TE5].push_back(-0.62382400);
+    2365             : 
+    2366           8 :   parameter[DA_BB1].push_back(32.88500000);
+    2367           8 :   parameter[DA_BB1].push_back(0.08179900);
+    2368           8 :   parameter[DA_BB1].push_back(-7.31735900);
+    2369           8 :   parameter[DA_BB1].push_back(2.15614500);
+    2370           8 :   parameter[DA_BB1].push_back(-3.52263200);
+    2371           8 :   parameter[DA_BB1].push_back(2.30604700);
+    2372           8 :   parameter[DA_BB1].push_back(-0.39270100);
+    2373             : 
+    2374           8 :   parameter[DA_BB2].push_back(3.80600000);
+    2375           8 :   parameter[DA_BB2].push_back(-0.10597700);
+    2376           8 :   parameter[DA_BB2].push_back(9.52537500);
+    2377           8 :   parameter[DA_BB2].push_back(-6.12991000);
+    2378           8 :   parameter[DA_BB2].push_back(-0.54092600);
+    2379           8 :   parameter[DA_BB2].push_back(1.15429100);
+    2380           8 :   parameter[DA_BB2].push_back(-0.21503500);
+    2381             : 
+    2382           8 :   parameter[DA_BB3].push_back(-1.35600000);
+    2383           8 :   parameter[DA_BB3].push_back(0.58928300);
+    2384           8 :   parameter[DA_BB3].push_back(6.71894100);
+    2385           8 :   parameter[DA_BB3].push_back(4.14050900);
+    2386           8 :   parameter[DA_BB3].push_back(-9.65859900);
+    2387           8 :   parameter[DA_BB3].push_back(4.43185000);
+    2388           8 :   parameter[DA_BB3].push_back(-0.64657300);
+    2389             : 
+    2390           8 :   parameter[DA_SC1].push_back(6.67100000);
+    2391           8 :   parameter[DA_SC1].push_back(-0.00871400);
+    2392           8 :   parameter[DA_SC1].push_back(1.63289100);
+    2393           8 :   parameter[DA_SC1].push_back(-0.06637700);
+    2394           8 :   parameter[DA_SC1].push_back(-1.48632900);
+    2395           8 :   parameter[DA_SC1].push_back(0.78551800);
+    2396           8 :   parameter[DA_SC1].push_back(-0.12087300);
+    2397             : 
+    2398           8 :   parameter[DA_SC2].push_back(5.95100000);
+    2399           8 :   parameter[DA_SC2].push_back(-0.02634300);
+    2400           8 :   parameter[DA_SC2].push_back(2.54864300);
+    2401           8 :   parameter[DA_SC2].push_back(-0.49015800);
+    2402           8 :   parameter[DA_SC2].push_back(-1.55386900);
+    2403           8 :   parameter[DA_SC2].push_back(0.86630200);
+    2404           8 :   parameter[DA_SC2].push_back(-0.13546200);
+    2405             : 
+    2406           8 :   parameter[DA_SC3].push_back(11.39400000);
+    2407           8 :   parameter[DA_SC3].push_back(0.00859500);
+    2408           8 :   parameter[DA_SC3].push_back(-0.25471400);
+    2409           8 :   parameter[DA_SC3].push_back(0.48718800);
+    2410           8 :   parameter[DA_SC3].push_back(-1.74520000);
+    2411           8 :   parameter[DA_SC3].push_back(0.99246200);
+    2412           8 :   parameter[DA_SC3].push_back(-0.16351900);
+    2413             : 
+    2414           8 :   parameter[DA_SC4].push_back(6.45900000);
+    2415           8 :   parameter[DA_SC4].push_back(0.01991800);
+    2416           8 :   parameter[DA_SC4].push_back(4.17962300);
+    2417           8 :   parameter[DA_SC4].push_back(0.97469100);
+    2418           8 :   parameter[DA_SC4].push_back(-5.02950400);
+    2419           8 :   parameter[DA_SC4].push_back(2.55371800);
+    2420           8 :   parameter[DA_SC4].push_back(-0.39113400);
+    2421             : 
+    2422           8 :   parameter[DA_3TE].push_back(4.23000000);
+    2423           8 :   parameter[DA_3TE].push_back(0.00062600);
+    2424           8 :   parameter[DA_3TE].push_back(0.92142000);
+    2425           8 :   parameter[DA_3TE].push_back(0.08016400);
+    2426           8 :   parameter[DA_3TE].push_back(-0.39000300);
+    2427           8 :   parameter[DA_3TE].push_back(0.12402500);
+    2428           8 :   parameter[DA_3TE].push_back(-0.01117900);
+    2429             : 
+    2430           8 :   parameter[DA_5TE].push_back(4.23000000);
+    2431           8 :   parameter[DA_5TE].push_back(0.00055500);
+    2432           8 :   parameter[DA_5TE].push_back(0.92183900);
+    2433           8 :   parameter[DA_5TE].push_back(0.07907600);
+    2434           8 :   parameter[DA_5TE].push_back(-0.38895100);
+    2435           8 :   parameter[DA_5TE].push_back(0.12359600);
+    2436           8 :   parameter[DA_5TE].push_back(-0.01111600);
+    2437             : 
+    2438           8 :   parameter[DA_TE3].push_back(2.87400000);
+    2439           8 :   parameter[DA_TE3].push_back(0.00112900);
+    2440           8 :   parameter[DA_TE3].push_back(12.51167200);
+    2441           8 :   parameter[DA_TE3].push_back(-7.67548000);
+    2442           8 :   parameter[DA_TE3].push_back(-2.02234000);
+    2443           8 :   parameter[DA_TE3].push_back(2.50837100);
+    2444           8 :   parameter[DA_TE3].push_back(-0.49458500);
+    2445             : 
+    2446           8 :   parameter[DA_TE5].push_back(8.03600000);
+    2447           8 :   parameter[DA_TE5].push_back(0.00473100);
+    2448           8 :   parameter[DA_TE5].push_back(4.65554400);
+    2449           8 :   parameter[DA_TE5].push_back(0.66424100);
+    2450           8 :   parameter[DA_TE5].push_back(-6.62131300);
+    2451           8 :   parameter[DA_TE5].push_back(3.96107400);
+    2452           8 :   parameter[DA_TE5].push_back(-0.69075800);
+    2453             : 
+    2454           8 :   parameter[DC_BB1].push_back(32.88500000);
+    2455           8 :   parameter[DC_BB1].push_back(0.08189900);
+    2456           8 :   parameter[DC_BB1].push_back(-7.32493500);
+    2457           8 :   parameter[DC_BB1].push_back(2.15976900);
+    2458           8 :   parameter[DC_BB1].push_back(-3.52612100);
+    2459           8 :   parameter[DC_BB1].push_back(2.31058600);
+    2460           8 :   parameter[DC_BB1].push_back(-0.39402700);
+    2461             : 
+    2462           8 :   parameter[DC_BB2].push_back(3.80600000);
+    2463           8 :   parameter[DC_BB2].push_back(-0.10559800);
+    2464           8 :   parameter[DC_BB2].push_back(9.52527700);
+    2465           8 :   parameter[DC_BB2].push_back(-6.12131700);
+    2466           8 :   parameter[DC_BB2].push_back(-0.54899400);
+    2467           8 :   parameter[DC_BB2].push_back(1.15592900);
+    2468           8 :   parameter[DC_BB2].push_back(-0.21494500);
+    2469             : 
+    2470           8 :   parameter[DC_BB3].push_back(-1.35600000);
+    2471           8 :   parameter[DC_BB3].push_back(0.55525700);
+    2472           8 :   parameter[DC_BB3].push_back(6.80305500);
+    2473           8 :   parameter[DC_BB3].push_back(4.05924700);
+    2474           8 :   parameter[DC_BB3].push_back(-9.61034700);
+    2475           8 :   parameter[DC_BB3].push_back(4.41253800);
+    2476           8 :   parameter[DC_BB3].push_back(-0.64315100);
+    2477             : 
+    2478           8 :   parameter[DC_SC1].push_back(5.95100000);
+    2479           8 :   parameter[DC_SC1].push_back(-0.02899900);
+    2480           8 :   parameter[DC_SC1].push_back(2.59587800);
+    2481           8 :   parameter[DC_SC1].push_back(-0.55388300);
+    2482           8 :   parameter[DC_SC1].push_back(-1.56395100);
+    2483           8 :   parameter[DC_SC1].push_back(0.88967400);
+    2484           8 :   parameter[DC_SC1].push_back(-0.14062500);
+    2485             : 
+    2486           8 :   parameter[DC_SC2].push_back(11.62100000);
+    2487           8 :   parameter[DC_SC2].push_back(0.01358100);
+    2488           8 :   parameter[DC_SC2].push_back(-0.24913000);
+    2489           8 :   parameter[DC_SC2].push_back(0.48787200);
+    2490           8 :   parameter[DC_SC2].push_back(-1.52867300);
+    2491           8 :   parameter[DC_SC2].push_back(0.83694900);
+    2492           8 :   parameter[DC_SC2].push_back(-0.13395300);
+    2493             : 
+    2494           8 :   parameter[DC_SC3].push_back(5.01900000);
+    2495           8 :   parameter[DC_SC3].push_back(-0.03298400);
+    2496           8 :   parameter[DC_SC3].push_back(5.54242800);
+    2497           8 :   parameter[DC_SC3].push_back(-0.96081500);
+    2498           8 :   parameter[DC_SC3].push_back(-3.71051600);
+    2499           8 :   parameter[DC_SC3].push_back(2.16500200);
+    2500           8 :   parameter[DC_SC3].push_back(-0.35023400);
+    2501             : 
+    2502           8 :   parameter[DC_3TE].push_back(4.23000000);
+    2503           8 :   parameter[DC_3TE].push_back(0.00055700);
+    2504           8 :   parameter[DC_3TE].push_back(0.92181400);
+    2505           8 :   parameter[DC_3TE].push_back(0.07924000);
+    2506           8 :   parameter[DC_3TE].push_back(-0.38916400);
+    2507           8 :   parameter[DC_3TE].push_back(0.12369900);
+    2508           8 :   parameter[DC_3TE].push_back(-0.01113300);
+    2509             : 
+    2510           8 :   parameter[DC_5TE].push_back(4.23000000);
+    2511           8 :   parameter[DC_5TE].push_back(0.00066500);
+    2512           8 :   parameter[DC_5TE].push_back(0.92103900);
+    2513           8 :   parameter[DC_5TE].push_back(0.08064600);
+    2514           8 :   parameter[DC_5TE].push_back(-0.39034900);
+    2515           8 :   parameter[DC_5TE].push_back(0.12417600);
+    2516           8 :   parameter[DC_5TE].push_back(-0.01120600);
+    2517             : 
+    2518           8 :   parameter[DC_TE3].push_back(2.87400000);
+    2519           8 :   parameter[DC_TE3].push_back(-0.05235500);
+    2520           8 :   parameter[DC_TE3].push_back(13.09201200);
+    2521           8 :   parameter[DC_TE3].push_back(-9.48128200);
+    2522           8 :   parameter[DC_TE3].push_back(-0.14958600);
+    2523           8 :   parameter[DC_TE3].push_back(1.75537200);
+    2524           8 :   parameter[DC_TE3].push_back(-0.39347500);
+    2525             : 
+    2526           8 :   parameter[DC_TE5].push_back(8.03600000);
+    2527           8 :   parameter[DC_TE5].push_back(-0.00513600);
+    2528           8 :   parameter[DC_TE5].push_back(4.67705700);
+    2529           8 :   parameter[DC_TE5].push_back(0.48333300);
+    2530           8 :   parameter[DC_TE5].push_back(-6.34511000);
+    2531           8 :   parameter[DC_TE5].push_back(3.83388500);
+    2532           8 :   parameter[DC_TE5].push_back(-0.67367800);
+    2533             : 
+    2534           8 :   parameter[DG_BB1].push_back(32.88500000);
+    2535           8 :   parameter[DG_BB1].push_back(0.08182900);
+    2536           8 :   parameter[DG_BB1].push_back(-7.32133900);
+    2537           8 :   parameter[DG_BB1].push_back(2.15767900);
+    2538           8 :   parameter[DG_BB1].push_back(-3.52369700);
+    2539           8 :   parameter[DG_BB1].push_back(2.30839600);
+    2540           8 :   parameter[DG_BB1].push_back(-0.39348300);
+    2541             : 
+    2542           8 :   parameter[DG_BB2].push_back(3.80600000);
+    2543           8 :   parameter[DG_BB2].push_back(-0.10618100);
+    2544           8 :   parameter[DG_BB2].push_back(9.54169000);
+    2545           8 :   parameter[DG_BB2].push_back(-6.15177600);
+    2546           8 :   parameter[DG_BB2].push_back(-0.53462400);
+    2547           8 :   parameter[DG_BB2].push_back(1.15581300);
+    2548           8 :   parameter[DG_BB2].push_back(-0.21567000);
+    2549             : 
+    2550           8 :   parameter[DG_BB3].push_back(-1.35600000);
+    2551           8 :   parameter[DG_BB3].push_back(0.57489100);
+    2552           8 :   parameter[DG_BB3].push_back(6.75164700);
+    2553           8 :   parameter[DG_BB3].push_back(4.11300900);
+    2554           8 :   parameter[DG_BB3].push_back(-9.63394600);
+    2555           8 :   parameter[DG_BB3].push_back(4.41675400);
+    2556           8 :   parameter[DG_BB3].push_back(-0.64339900);
+    2557             : 
+    2558           8 :   parameter[DG_SC1].push_back(6.67100000);
+    2559           8 :   parameter[DG_SC1].push_back(-0.00886600);
+    2560           8 :   parameter[DG_SC1].push_back(1.63333000);
+    2561           8 :   parameter[DG_SC1].push_back(-0.06892100);
+    2562           8 :   parameter[DG_SC1].push_back(-1.48683500);
+    2563           8 :   parameter[DG_SC1].push_back(0.78670800);
+    2564           8 :   parameter[DG_SC1].push_back(-0.12113900);
+    2565             : 
+    2566           8 :   parameter[DG_SC2].push_back(11.39400000);
+    2567           8 :   parameter[DG_SC2].push_back(0.00907900);
+    2568           8 :   parameter[DG_SC2].push_back(-0.22475500);
+    2569           8 :   parameter[DG_SC2].push_back(0.49535100);
+    2570           8 :   parameter[DG_SC2].push_back(-1.75324900);
+    2571           8 :   parameter[DG_SC2].push_back(0.98767400);
+    2572           8 :   parameter[DG_SC2].push_back(-0.16150800);
+    2573             : 
+    2574           8 :   parameter[DG_SC3].push_back(10.90100000);
+    2575           8 :   parameter[DG_SC3].push_back(0.02207600);
+    2576           8 :   parameter[DG_SC3].push_back(0.17932200);
+    2577           8 :   parameter[DG_SC3].push_back(0.73253200);
+    2578           8 :   parameter[DG_SC3].push_back(-1.95554900);
+    2579           8 :   parameter[DG_SC3].push_back(0.98339900);
+    2580           8 :   parameter[DG_SC3].push_back(-0.14763600);
+    2581             : 
+    2582           8 :   parameter[DG_SC4].push_back(6.45900000);
+    2583           8 :   parameter[DG_SC4].push_back(0.02018400);
+    2584           8 :   parameter[DG_SC4].push_back(4.17705400);
+    2585           8 :   parameter[DG_SC4].push_back(0.98531700);
+    2586           8 :   parameter[DG_SC4].push_back(-5.04354900);
+    2587           8 :   parameter[DG_SC4].push_back(2.56123700);
+    2588           8 :   parameter[DG_SC4].push_back(-0.39249300);
+    2589             : 
+    2590           8 :   parameter[DG_3TE].push_back(4.23000000);
+    2591           8 :   parameter[DG_3TE].push_back(0.00061700);
+    2592           8 :   parameter[DG_3TE].push_back(0.92140100);
+    2593           8 :   parameter[DG_3TE].push_back(0.08016400);
+    2594           8 :   parameter[DG_3TE].push_back(-0.39003500);
+    2595           8 :   parameter[DG_3TE].push_back(0.12406900);
+    2596           8 :   parameter[DG_3TE].push_back(-0.01119200);
+    2597             : 
+    2598           8 :   parameter[DG_5TE].push_back(4.23000000);
+    2599           8 :   parameter[DG_5TE].push_back(0.00064900);
+    2600           8 :   parameter[DG_5TE].push_back(0.92110500);
+    2601           8 :   parameter[DG_5TE].push_back(0.08031500);
+    2602           8 :   parameter[DG_5TE].push_back(-0.38997000);
+    2603           8 :   parameter[DG_5TE].push_back(0.12401200);
+    2604           8 :   parameter[DG_5TE].push_back(-0.01118100);
+    2605             : 
+    2606           8 :   parameter[DG_TE3].push_back(2.87400000);
+    2607           8 :   parameter[DG_TE3].push_back(0.00182000);
+    2608           8 :   parameter[DG_TE3].push_back(12.41507000);
+    2609           8 :   parameter[DG_TE3].push_back(-7.47384800);
+    2610           8 :   parameter[DG_TE3].push_back(-2.11864700);
+    2611           8 :   parameter[DG_TE3].push_back(2.50112600);
+    2612           8 :   parameter[DG_TE3].push_back(-0.48652200);
+    2613             : 
+    2614           8 :   parameter[DG_TE5].push_back(8.03600000);
+    2615           8 :   parameter[DG_TE5].push_back(0.00676400);
+    2616           8 :   parameter[DG_TE5].push_back(4.65989200);
+    2617           8 :   parameter[DG_TE5].push_back(0.78482500);
+    2618           8 :   parameter[DG_TE5].push_back(-6.86460600);
+    2619           8 :   parameter[DG_TE5].push_back(4.11675400);
+    2620           8 :   parameter[DG_TE5].push_back(-0.72249100);
+    2621             : 
+    2622           8 :   parameter[DT_BB1].push_back(32.88500000);
+    2623           8 :   parameter[DT_BB1].push_back(0.08220100);
+    2624           8 :   parameter[DT_BB1].push_back(-7.33006800);
+    2625           8 :   parameter[DT_BB1].push_back(2.16636500);
+    2626           8 :   parameter[DT_BB1].push_back(-3.53465700);
+    2627           8 :   parameter[DT_BB1].push_back(2.31447600);
+    2628           8 :   parameter[DT_BB1].push_back(-0.39445400);
+    2629             : 
+    2630           8 :   parameter[DT_BB2].push_back(3.80600000);
+    2631           8 :   parameter[DT_BB2].push_back(-0.10723000);
+    2632           8 :   parameter[DT_BB2].push_back(9.56675000);
+    2633           8 :   parameter[DT_BB2].push_back(-6.20236100);
+    2634           8 :   parameter[DT_BB2].push_back(-0.49550400);
+    2635           8 :   parameter[DT_BB2].push_back(1.14300600);
+    2636           8 :   parameter[DT_BB2].push_back(-0.21420000);
+    2637             : 
+    2638           8 :   parameter[DT_BB3].push_back(-1.35600000);
+    2639           8 :   parameter[DT_BB3].push_back(0.56737900);
+    2640           8 :   parameter[DT_BB3].push_back(6.76595400);
+    2641           8 :   parameter[DT_BB3].push_back(4.08976100);
+    2642           8 :   parameter[DT_BB3].push_back(-9.61512500);
+    2643           8 :   parameter[DT_BB3].push_back(4.40975100);
+    2644           8 :   parameter[DT_BB3].push_back(-0.64239800);
+    2645             : 
+    2646           8 :   parameter[DT_SC1].push_back(5.95100000);
+    2647           8 :   parameter[DT_SC1].push_back(-0.02926500);
+    2648           8 :   parameter[DT_SC1].push_back(2.59630300);
+    2649           8 :   parameter[DT_SC1].push_back(-0.56152200);
+    2650           8 :   parameter[DT_SC1].push_back(-1.56532600);
+    2651           8 :   parameter[DT_SC1].push_back(0.89322800);
+    2652           8 :   parameter[DT_SC1].push_back(-0.14142900);
+    2653             : 
+    2654           8 :   parameter[DT_SC2].push_back(10.90100000);
+    2655           8 :   parameter[DT_SC2].push_back(0.02183400);
+    2656           8 :   parameter[DT_SC2].push_back(0.19463000);
+    2657           8 :   parameter[DT_SC2].push_back(0.72393000);
+    2658           8 :   parameter[DT_SC2].push_back(-1.93199500);
+    2659           8 :   parameter[DT_SC2].push_back(0.96856300);
+    2660           8 :   parameter[DT_SC2].push_back(-0.14512600);
+    2661             : 
+    2662           8 :   parameter[DT_SC3].push_back(4.31400000);
+    2663           8 :   parameter[DT_SC3].push_back(-0.07745600);
+    2664           8 :   parameter[DT_SC3].push_back(12.49820300);
+    2665           8 :   parameter[DT_SC3].push_back(-7.64994200);
+    2666           8 :   parameter[DT_SC3].push_back(-3.00359600);
+    2667           8 :   parameter[DT_SC3].push_back(3.26263300);
+    2668           8 :   parameter[DT_SC3].push_back(-0.64498600);
+    2669             : 
+    2670           8 :   parameter[DT_3TE].push_back(4.23000000);
+    2671           8 :   parameter[DT_3TE].push_back(0.00062000);
+    2672           8 :   parameter[DT_3TE].push_back(0.92141100);
+    2673           8 :   parameter[DT_3TE].push_back(0.08030900);
+    2674           8 :   parameter[DT_3TE].push_back(-0.39021500);
+    2675           8 :   parameter[DT_3TE].push_back(0.12414000);
+    2676           8 :   parameter[DT_3TE].push_back(-0.01120100);
+    2677             : 
+    2678           8 :   parameter[DT_5TE].push_back(4.23000000);
+    2679           8 :   parameter[DT_5TE].push_back(0.00063700);
+    2680           8 :   parameter[DT_5TE].push_back(0.92130800);
+    2681           8 :   parameter[DT_5TE].push_back(0.08026900);
+    2682           8 :   parameter[DT_5TE].push_back(-0.39007500);
+    2683           8 :   parameter[DT_5TE].push_back(0.12406600);
+    2684           8 :   parameter[DT_5TE].push_back(-0.01118800);
+    2685             : 
+    2686           8 :   parameter[DT_TE3].push_back(2.87400000);
+    2687           8 :   parameter[DT_TE3].push_back(-0.00251200);
+    2688           8 :   parameter[DT_TE3].push_back(12.43576400);
+    2689           8 :   parameter[DT_TE3].push_back(-7.55343800);
+    2690           8 :   parameter[DT_TE3].push_back(-2.07363500);
+    2691           8 :   parameter[DT_TE3].push_back(2.51279300);
+    2692           8 :   parameter[DT_TE3].push_back(-0.49437100);
+    2693             : 
+    2694           8 :   parameter[DT_TE5].push_back(8.03600000);
+    2695           8 :   parameter[DT_TE5].push_back(0.00119900);
+    2696           8 :   parameter[DT_TE5].push_back(4.91762300);
+    2697           8 :   parameter[DT_TE5].push_back(0.65637000);
+    2698           8 :   parameter[DT_TE5].push_back(-7.23392500);
+    2699           8 :   parameter[DT_TE5].push_back(4.44636600);
+    2700           8 :   parameter[DT_TE5].push_back(-0.79467800);
+    2701             : 
+    2702           8 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    2703           8 :   if( moldat ) {
+    2704        8400 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    2705        8392 :       std::string Aname = moldat->getAtomName(atoms[i]);
+    2706        8392 :       std::string Rname = moldat->getResidueName(atoms[i]);
+    2707        8392 :       if(Rname=="ALA") {
+    2708          72 :         if(Aname=="BB") {
+    2709          72 :           atoi[i]=ALA_BB;
+    2710           0 :         } else error("Atom name not known: "+Aname);
+    2711        8320 :       } else if(Rname=="ARG") {
+    2712         420 :         if(Aname=="BB") {
+    2713         140 :           atoi[i]=ARG_BB;
+    2714         280 :         } else if(Aname=="SC1") {
+    2715         140 :           atoi[i]=ARG_SC1;
+    2716         140 :         } else if(Aname=="SC2") {
+    2717         140 :           atoi[i]=ARG_SC2;
+    2718           0 :         } else error("Atom name not known: "+Aname);
+    2719        7900 :       } else if(Rname=="ASN") {
+    2720         240 :         if(Aname=="BB") {
+    2721         120 :           atoi[i]=ASN_BB;
+    2722         120 :         } else if(Aname=="SC1") {
+    2723         120 :           atoi[i]=ASN_SC1;
+    2724           0 :         } else error("Atom name not known: "+Aname);
+    2725        7660 :       } else if(Rname=="ASP") {
+    2726         368 :         if(Aname=="BB") {
+    2727         184 :           atoi[i]=ASP_BB;
+    2728         184 :         } else if(Aname=="SC1") {
+    2729         184 :           atoi[i]=ASP_SC1;
+    2730           0 :         } else error("Atom name not known: "+Aname);
+    2731        7292 :       } else if(Rname=="CYS") {
+    2732          16 :         if(Aname=="BB") {
+    2733           8 :           atoi[i]=CYS_BB;
+    2734           8 :         } else if(Aname=="SC1") {
+    2735           8 :           atoi[i]=CYS_SC1;
+    2736           0 :         } else error("Atom name not known: "+Aname);
+    2737        7276 :       } else if(Rname=="GLN") {
+    2738         224 :         if(Aname=="BB") {
+    2739         112 :           atoi[i]=GLN_BB;
+    2740         112 :         } else if(Aname=="SC1") {
+    2741         112 :           atoi[i]=GLN_SC1;
+    2742           0 :         } else error("Atom name not known: "+Aname);
+    2743        7052 :       } else if(Rname=="GLU") {
+    2744         480 :         if(Aname=="BB") {
+    2745         240 :           atoi[i]=GLU_BB;
+    2746         240 :         } else if(Aname=="SC1") {
+    2747         240 :           atoi[i]=GLU_SC1;
+    2748           0 :         } else error("Atom name not known: "+Aname);
+    2749        6572 :       } else if(Rname=="GLY") {
+    2750         116 :         if(Aname=="BB") {
+    2751         116 :           atoi[i]=GLY_BB;
+    2752           0 :         } else error("Atom name not known: "+Aname);
+    2753        6456 :       } else if(Rname=="HIS") {
+    2754         576 :         if(Aname=="BB") {
+    2755         144 :           atoi[i]=HIS_BB;
+    2756         432 :         } else if(Aname=="SC1") {
+    2757         144 :           atoi[i]=HIS_SC1;
+    2758         288 :         } else if(Aname=="SC2") {
+    2759         144 :           atoi[i]=HIS_SC2;
+    2760         144 :         } else if(Aname=="SC3") {
+    2761         144 :           atoi[i]=HIS_SC3;
+    2762           0 :         } else error("Atom name not known: "+Aname);
+    2763        5880 :       } else if(Rname=="ILE") {
+    2764         584 :         if(Aname=="BB") {
+    2765         292 :           atoi[i]=ILE_BB;
+    2766         292 :         } else if(Aname=="SC1") {
+    2767         292 :           atoi[i]=ILE_SC1;
+    2768           0 :         } else error("Atom name not known: "+Aname);
+    2769        5296 :       } else if(Rname=="LEU") {
+    2770         448 :         if(Aname=="BB") {
+    2771         224 :           atoi[i]=LEU_BB;
+    2772         224 :         } else if(Aname=="SC1") {
+    2773         224 :           atoi[i]=LEU_SC1;
+    2774           0 :         } else error("Atom name not known: "+Aname);
+    2775        4848 :       } else if(Rname=="LYS") {
+    2776         792 :         if(Aname=="BB") {
+    2777         264 :           atoi[i]=LYS_BB;
+    2778         528 :         } else if(Aname=="SC1") {
+    2779         264 :           atoi[i]=LYS_SC1;
+    2780         264 :         } else if(Aname=="SC2") {
+    2781         264 :           atoi[i]=LYS_SC2;
+    2782           0 :         } else error("Atom name not known: "+Aname);
+    2783        4056 :       } else if(Rname=="MET") {
+    2784          80 :         if(Aname=="BB") {
+    2785          40 :           atoi[i]=MET_BB;
+    2786          40 :         } else if(Aname=="SC1") {
+    2787          40 :           atoi[i]=MET_SC1;
+    2788           0 :         } else error("Atom name not known: "+Aname);
+    2789        3976 :       } else if(Rname=="PHE") {
+    2790         512 :         if(Aname=="BB") {
+    2791         128 :           atoi[i]=PHE_BB;
+    2792         384 :         } else if(Aname=="SC1") {
+    2793         128 :           atoi[i]=PHE_SC1;
+    2794         256 :         } else if(Aname=="SC2") {
+    2795         128 :           atoi[i]=PHE_SC2;
+    2796         128 :         } else if(Aname=="SC3") {
+    2797         128 :           atoi[i]=PHE_SC3;
+    2798           0 :         } else error("Atom name not known: "+Aname);
+    2799        3464 :       } else if(Rname=="PRO") {
+    2800         128 :         if(Aname=="BB") {
+    2801          64 :           atoi[i]=PRO_BB;
+    2802          64 :         } else if(Aname=="SC1") {
+    2803          64 :           atoi[i]=PRO_SC1;
+    2804           0 :         } else error("Atom name not known: "+Aname);
+    2805        3336 :       } else if(Rname=="SER") {
+    2806         248 :         if(Aname=="BB") {
+    2807         124 :           atoi[i]=SER_BB;
+    2808         124 :         } else if(Aname=="SC1") {
+    2809         124 :           atoi[i]=SER_SC1;
+    2810           0 :         } else error("Atom name not known: "+Aname);
+    2811        3088 :       } else if(Rname=="THR") {
+    2812         288 :         if(Aname=="BB") {
+    2813         144 :           atoi[i]=THR_BB;
+    2814         144 :         } else if(Aname=="SC1") {
+    2815         144 :           atoi[i]=THR_SC1;
+    2816           0 :         } else error("Atom name not known: "+Aname);
+    2817        2800 :       } else if(Rname=="TRP") {
+    2818           0 :         if(Aname=="BB") {
+    2819           0 :           atoi[i]=TRP_BB;
+    2820           0 :         } else if(Aname=="SC1") {
+    2821           0 :           atoi[i]=TRP_SC1;
+    2822           0 :         } else if(Aname=="SC2") {
+    2823           0 :           atoi[i]=TRP_SC2;
+    2824           0 :         } else if(Aname=="SC3") {
+    2825           0 :           atoi[i]=TRP_SC3;
+    2826           0 :         } else if(Aname=="SC4") {
+    2827           0 :           atoi[i]=TRP_SC4;
+    2828           0 :         } else error("Atom name not known: "+Aname);
+    2829        2800 :       } else if(Rname=="TYR") {
+    2830         544 :         if(Aname=="BB") {
+    2831         136 :           atoi[i]=TYR_BB;
+    2832         408 :         } else if(Aname=="SC1") {
+    2833         136 :           atoi[i]=TYR_SC1;
+    2834         272 :         } else if(Aname=="SC2") {
+    2835         136 :           atoi[i]=TYR_SC2;
+    2836         136 :         } else if(Aname=="SC3") {
+    2837         136 :           atoi[i]=TYR_SC3;
+    2838           0 :         } else error("Atom name not known: "+Aname);
+    2839        2256 :       } else if(Rname=="VAL") {
+    2840         288 :         if(Aname=="BB") {
+    2841         144 :           atoi[i]=VAL_BB;
+    2842         144 :         } else if(Aname=="SC1") {
+    2843         144 :           atoi[i]=VAL_SC1;
+    2844           0 :         } else error("Atom name not known: "+Aname);
+    2845        1968 :       } else if(Rname=="  A") {
+    2846           0 :         if(Aname=="BB1") {
+    2847           0 :           atoi[i]=A_BB1;
+    2848           0 :         } else if(Aname=="BB2") {
+    2849           0 :           atoi[i]=A_BB2;
+    2850           0 :         } else if(Aname=="BB3") {
+    2851           0 :           atoi[i]=A_BB3;
+    2852           0 :         } else if(Aname=="SC1") {
+    2853           0 :           atoi[i]=A_SC1;
+    2854           0 :         } else if(Aname=="SC2") {
+    2855           0 :           atoi[i]=A_SC2;
+    2856           0 :         } else if(Aname=="SC3") {
+    2857           0 :           atoi[i]=A_SC3;
+    2858           0 :         } else if(Aname=="SC4") {
+    2859           0 :           atoi[i]=A_SC4;
+    2860           0 :         } else if(Aname=="3TE") {
+    2861           0 :           atoi[i]=A_3TE;
+    2862           0 :         } else if(Aname=="5TE") {
+    2863           0 :           atoi[i]=A_5TE;
+    2864           0 :         } else if(Aname=="TE3") {
+    2865           0 :           atoi[i]=A_TE3;
+    2866           0 :         } else if(Aname=="TE5") {
+    2867           0 :           atoi[i]=A_TE5;
+    2868           0 :         } else error("Atom name not known: "+Aname);
+    2869        1968 :       } else if(Rname=="  C") {
+    2870           0 :         if(Aname=="BB1") {
+    2871           0 :           atoi[i]=C_BB1;
+    2872           0 :         } else if(Aname=="BB2") {
+    2873           0 :           atoi[i]=C_BB2;
+    2874           0 :         } else if(Aname=="BB3") {
+    2875           0 :           atoi[i]=C_BB3;
+    2876           0 :         } else if(Aname=="SC1") {
+    2877           0 :           atoi[i]=C_SC1;
+    2878           0 :         } else if(Aname=="SC2") {
+    2879           0 :           atoi[i]=C_SC2;
+    2880           0 :         } else if(Aname=="SC3") {
+    2881           0 :           atoi[i]=C_SC3;
+    2882           0 :         } else if(Aname=="3TE") {
+    2883           0 :           atoi[i]=C_3TE;
+    2884           0 :         } else if(Aname=="5TE") {
+    2885           0 :           atoi[i]=C_5TE;
+    2886           0 :         } else if(Aname=="TE3") {
+    2887           0 :           atoi[i]=C_TE3;
+    2888           0 :         } else if(Aname=="TE5") {
+    2889           0 :           atoi[i]=C_TE5;
+    2890           0 :         } else error("Atom name not known: "+Aname);
+    2891        1968 :       } else if(Rname=="  G") {
+    2892           0 :         if(Aname=="BB1") {
+    2893           0 :           atoi[i]=G_BB1;
+    2894           0 :         } else if(Aname=="BB2") {
+    2895           0 :           atoi[i]=G_BB2;
+    2896           0 :         } else if(Aname=="BB3") {
+    2897           0 :           atoi[i]=G_BB3;
+    2898           0 :         } else if(Aname=="SC1") {
+    2899           0 :           atoi[i]=G_SC1;
+    2900           0 :         } else if(Aname=="SC2") {
+    2901           0 :           atoi[i]=G_SC2;
+    2902           0 :         } else if(Aname=="SC3") {
+    2903           0 :           atoi[i]=G_SC3;
+    2904           0 :         } else if(Aname=="SC4") {
+    2905           0 :           atoi[i]=G_SC4;
+    2906           0 :         } else if(Aname=="3TE") {
+    2907           0 :           atoi[i]=G_3TE;
+    2908           0 :         } else if(Aname=="5TE") {
+    2909           0 :           atoi[i]=G_5TE;
+    2910           0 :         } else if(Aname=="TE3") {
+    2911           0 :           atoi[i]=G_TE3;
+    2912           0 :         } else if(Aname=="TE5") {
+    2913           0 :           atoi[i]=G_TE5;
+    2914           0 :         } else error("Atom name not known: "+Aname);
+    2915        1968 :       } else if(Rname=="  U") {
+    2916           0 :         if(Aname=="BB1") {
+    2917           0 :           atoi[i]=U_BB1;
+    2918           0 :         } else if(Aname=="BB2") {
+    2919           0 :           atoi[i]=U_BB2;
+    2920           0 :         } else if(Aname=="BB3") {
+    2921           0 :           atoi[i]=U_BB3;
+    2922           0 :         } else if(Aname=="SC1") {
+    2923           0 :           atoi[i]=U_SC1;
+    2924           0 :         } else if(Aname=="SC2") {
+    2925           0 :           atoi[i]=U_SC2;
+    2926           0 :         } else if(Aname=="SC3") {
+    2927           0 :           atoi[i]=U_SC3;
+    2928           0 :         } else if(Aname=="3TE") {
+    2929           0 :           atoi[i]=U_3TE;
+    2930           0 :         } else if(Aname=="5TE") {
+    2931           0 :           atoi[i]=U_5TE;
+    2932           0 :         } else if(Aname=="TE3") {
+    2933           0 :           atoi[i]=U_TE3;
+    2934           0 :         } else if(Aname=="TE5") {
+    2935           0 :           atoi[i]=U_TE5;
+    2936           0 :         } else error("Atom name not known: "+Aname);
+    2937        1968 :       } else if(Rname==" DA") {
+    2938         696 :         if(Aname=="BB1") {
+    2939          96 :           atoi[i]=DA_BB1;
+    2940         600 :         } else if(Aname=="BB2") {
+    2941          96 :           atoi[i]=DA_BB2;
+    2942         504 :         } else if(Aname=="BB3") {
+    2943          96 :           atoi[i]=DA_BB3;
+    2944         408 :         } else if(Aname=="SC1") {
+    2945         100 :           atoi[i]=DA_SC1;
+    2946         308 :         } else if(Aname=="SC2") {
+    2947         100 :           atoi[i]=DA_SC2;
+    2948         208 :         } else if(Aname=="SC3") {
+    2949         100 :           atoi[i]=DA_SC3;
+    2950         108 :         } else if(Aname=="SC4") {
+    2951         100 :           atoi[i]=DA_SC4;
+    2952           8 :         } else if(Aname=="3TE") {
+    2953           0 :           atoi[i]=DA_3TE;
+    2954           8 :         } else if(Aname=="5TE") {
+    2955           0 :           atoi[i]=DA_5TE;
+    2956           8 :         } else if(Aname=="TE3") {
+    2957           4 :           atoi[i]=DA_TE3;
+    2958           4 :         } else if(Aname=="TE5") {
+    2959           4 :           atoi[i]=DA_TE5;
+    2960           0 :         } else error("Atom name not known: "+Aname);
+    2961        1272 :       } else if(Rname==" DC") {
+    2962         312 :         if(Aname=="BB1") {
+    2963          52 :           atoi[i]=DC_BB1;
+    2964         260 :         } else if(Aname=="BB2") {
+    2965          52 :           atoi[i]=DC_BB2;
+    2966         208 :         } else if(Aname=="BB3") {
+    2967          52 :           atoi[i]=DC_BB3;
+    2968         156 :         } else if(Aname=="SC1") {
+    2969          52 :           atoi[i]=DC_SC1;
+    2970         104 :         } else if(Aname=="SC2") {
+    2971          52 :           atoi[i]=DC_SC2;
+    2972          52 :         } else if(Aname=="SC3") {
+    2973          52 :           atoi[i]=DC_SC3;
+    2974           0 :         } else if(Aname=="3TE") {
+    2975           0 :           atoi[i]=DC_3TE;
+    2976           0 :         } else if(Aname=="5TE") {
+    2977           0 :           atoi[i]=DC_5TE;
+    2978           0 :         } else if(Aname=="TE3") {
+    2979           0 :           atoi[i]=DC_TE3;
+    2980           0 :         } else if(Aname=="TE5") {
+    2981           0 :           atoi[i]=DC_TE5;
+    2982           0 :         } else error("Atom name not known: "+Aname);
+    2983         960 :       } else if(Rname==" DG") {
+    2984         364 :         if(Aname=="BB1") {
+    2985          52 :           atoi[i]=DG_BB1;
+    2986         312 :         } else if(Aname=="BB2") {
+    2987          52 :           atoi[i]=DG_BB2;
+    2988         260 :         } else if(Aname=="BB3") {
+    2989          52 :           atoi[i]=DG_BB3;
+    2990         208 :         } else if(Aname=="SC1") {
+    2991          52 :           atoi[i]=DG_SC1;
+    2992         156 :         } else if(Aname=="SC2") {
+    2993          52 :           atoi[i]=DG_SC2;
+    2994         104 :         } else if(Aname=="SC3") {
+    2995          52 :           atoi[i]=DG_SC3;
+    2996          52 :         } else if(Aname=="SC4") {
+    2997          52 :           atoi[i]=DG_SC4;
+    2998           0 :         } else if(Aname=="3TE") {
+    2999           0 :           atoi[i]=DG_3TE;
+    3000           0 :         } else if(Aname=="5TE") {
+    3001           0 :           atoi[i]=DG_5TE;
+    3002           0 :         } else if(Aname=="TE3") {
+    3003           0 :           atoi[i]=DG_TE3;
+    3004           0 :         } else if(Aname=="TE5") {
+    3005           0 :           atoi[i]=DG_TE5;
+    3006           0 :         } else error("Atom name not known: "+Aname);
+    3007         596 :       } else if(Rname==" DT") {
+    3008         596 :         if(Aname=="BB1") {
+    3009          96 :           atoi[i]=DT_BB1;
+    3010         500 :         } else if(Aname=="BB2") {
+    3011          96 :           atoi[i]=DT_BB2;
+    3012         404 :         } else if(Aname=="BB3") {
+    3013          96 :           atoi[i]=DT_BB3;
+    3014         308 :         } else if(Aname=="SC1") {
+    3015         100 :           atoi[i]=DT_SC1;
+    3016         208 :         } else if(Aname=="SC2") {
+    3017         100 :           atoi[i]=DT_SC2;
+    3018         108 :         } else if(Aname=="SC3") {
+    3019         100 :           atoi[i]=DT_SC3;
+    3020           8 :         } else if(Aname=="3TE") {
+    3021           0 :           atoi[i]=DT_3TE;
+    3022           8 :         } else if(Aname=="5TE") {
+    3023           0 :           atoi[i]=DT_5TE;
+    3024           8 :         } else if(Aname=="TE3") {
+    3025           4 :           atoi[i]=DT_TE3;
+    3026           4 :         } else if(Aname=="TE5") {
+    3027           4 :           atoi[i]=DT_TE5;
+    3028           0 :         } else error("Atom name not known: "+Aname);
+    3029           0 :       } else error("Residue not known: "+Rname);
+    3030             :     }
+    3031             :   } else {
+    3032           0 :     error("MOLINFO DATA not found\n");
+    3033             :   }
+    3034           8 : }
+    3035             : 
+    3036          10 : 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)
+    3037             : {
+    3038             : 
+    3039          10 :   parameter_solv[TRP].push_back(60737.60249988003);
+    3040          10 :   parameter_solv[TRP].push_back(-77.75716755173752);
+    3041          10 :   parameter_solv[TRP].push_back(-205962.98557711052);
+    3042          10 :   parameter_solv[TRP].push_back(-62013.46984155453);
+    3043          10 :   parameter_solv[TRP].push_back(680710.7592231638);
+    3044          10 :   parameter_solv[TRP].push_back(-681336.8777362367);
+    3045          10 :   parameter_solv[TRP].push_back(211473.65530642506);
+    3046             : 
+    3047          10 :   parameter_solv[TYR].push_back(46250.80359987982);
+    3048          10 :   parameter_solv[TYR].push_back(-45.8287864681578);
+    3049          10 :   parameter_solv[TYR].push_back(-143872.91752817619);
+    3050          10 :   parameter_solv[TYR].push_back(-39049.68736409533);
+    3051          10 :   parameter_solv[TYR].push_back(441321.71874090104);
+    3052          10 :   parameter_solv[TYR].push_back(-434478.0972346327);
+    3053          10 :   parameter_solv[TYR].push_back(133179.3694641212);
+    3054             : 
+    3055          10 :   parameter_solv[PHE].push_back(42407.164900118914);
+    3056          10 :   parameter_solv[PHE].push_back(-159.1980754191431);
+    3057          10 :   parameter_solv[PHE].push_back(-123847.86192757386);
+    3058          10 :   parameter_solv[PHE].push_back(-41797.69041575073);
+    3059          10 :   parameter_solv[PHE].push_back(380283.7035277073);
+    3060          10 :   parameter_solv[PHE].push_back(-361432.67247521743);
+    3061          10 :   parameter_solv[PHE].push_back(107750.64978068044);
+    3062             : 
+    3063          10 :   parameter_solv[HIP].push_back(24473.47360011923);
+    3064          10 :   parameter_solv[HIP].push_back(-111.64156672747428);
+    3065          10 :   parameter_solv[HIP].push_back(-65826.16993707925);
+    3066          10 :   parameter_solv[HIP].push_back(-23305.91329798928);
+    3067          10 :   parameter_solv[HIP].push_back(194795.11911635034);
+    3068          10 :   parameter_solv[HIP].push_back(-180454.49458095312);
+    3069          10 :   parameter_solv[HIP].push_back(52699.374196745615);
+    3070             : 
+    3071          10 :   parameter_solv[ARG].push_back(34106.70239988039);
+    3072          10 :   parameter_solv[ARG].push_back(152.7472727640246);
+    3073          10 :   parameter_solv[ARG].push_back(-117086.49392248681);
+    3074          10 :   parameter_solv[ARG].push_back(-19664.229479267167);
+    3075          10 :   parameter_solv[ARG].push_back(364454.0909203641);
+    3076          10 :   parameter_solv[ARG].push_back(-382075.8018312776);
+    3077          10 :   parameter_solv[ARG].push_back(122775.75036605193);
+    3078             : 
+    3079          10 :   parameter_solv[LYS].push_back(32292.090000118922);
+    3080          10 :   parameter_solv[LYS].push_back(-111.97371180593888);
+    3081          10 :   parameter_solv[LYS].push_back(-91953.10997619898);
+    3082          10 :   parameter_solv[LYS].push_back(-30690.807047993283);
+    3083          10 :   parameter_solv[LYS].push_back(282092.40760143084);
+    3084          10 :   parameter_solv[LYS].push_back(-269503.2592457489);
+    3085          10 :   parameter_solv[LYS].push_back(80777.81552915688);
+    3086             : 
+    3087          10 :   parameter_solv[CYS].push_back(11352.902500119093);
+    3088          10 :   parameter_solv[CYS].push_back(-45.5226331859686);
+    3089          10 :   parameter_solv[CYS].push_back(-20925.085562607524);
+    3090          10 :   parameter_solv[CYS].push_back(-5662.685408989286);
+    3091          10 :   parameter_solv[CYS].push_back(38559.10376731146);
+    3092          10 :   parameter_solv[CYS].push_back(-27885.23426006181);
+    3093          10 :   parameter_solv[CYS].push_back(6280.15058191397);
+    3094             : 
+    3095          10 :   parameter_solv[CYX].push_back(10281.960000119348);
+    3096          10 :   parameter_solv[CYX].push_back(-42.315998754511);
+    3097          10 :   parameter_solv[CYX].push_back(-19328.174487327480);
+    3098          10 :   parameter_solv[CYX].push_back(-5523.191775626829);
+    3099          10 :   parameter_solv[CYX].push_back(38185.463172673335);
+    3100          10 :   parameter_solv[CYX].push_back(-28940.174693042034);
+    3101          10 :   parameter_solv[CYX].push_back(6925.390014187676);
+    3102             : 
+    3103          10 :   parameter_solv[ASP].push_back(13511.73760011933);
+    3104          10 :   parameter_solv[ASP].push_back(-59.929111107656595);
+    3105          10 :   parameter_solv[ASP].push_back(-25849.869639655575);
+    3106          10 :   parameter_solv[ASP].push_back(-7541.669448872824);
+    3107          10 :   parameter_solv[ASP].push_back(50760.92045144903);
+    3108          10 :   parameter_solv[ASP].push_back(-37677.87583269734);
+    3109          10 :   parameter_solv[ASP].push_back(8745.7056219399);
+    3110             : 
+    3111          10 :   parameter_solv[GLU].push_back(20443.280400119456);
+    3112          10 :   parameter_solv[GLU].push_back(-113.77561814283207);
+    3113          10 :   parameter_solv[GLU].push_back(-45587.79314626863);
+    3114          10 :   parameter_solv[GLU].push_back(-16187.556837331254);
+    3115          10 :   parameter_solv[GLU].push_back(112609.65830609271);
+    3116          10 :   parameter_solv[GLU].push_back(-93362.05323205091);
+    3117          10 :   parameter_solv[GLU].push_back(24519.557866124724);
+    3118             : 
+    3119          10 :   parameter_solv[ILE].push_back(27858.948100119596);
+    3120          10 :   parameter_solv[ILE].push_back(-159.27355145839834);
+    3121          10 :   parameter_solv[ILE].push_back(-61571.43463039565);
+    3122          10 :   parameter_solv[ILE].push_back(-21324.879474559468);
+    3123          10 :   parameter_solv[ILE].push_back(144070.7572894681);
+    3124          10 :   parameter_solv[ILE].push_back(-115021.81959095894);
+    3125          10 :   parameter_solv[ILE].push_back(28939.085108838968);
+    3126             : 
+    3127          10 :   parameter_solv[LEU].push_back(27858.948100119596);
+    3128          10 :   parameter_solv[LEU].push_back(-165.61892007509647);
+    3129          10 :   parameter_solv[LEU].push_back(-62564.568746500125);
+    3130          10 :   parameter_solv[LEU].push_back(-22465.332149768525);
+    3131          10 :   parameter_solv[LEU].push_back(151616.79489291538);
+    3132          10 :   parameter_solv[LEU].push_back(-122905.6119395393);
+    3133          10 :   parameter_solv[LEU].push_back(31436.664377885514);
+    3134             : 
+    3135          10 :   parameter_solv[MET].push_back(25609.60090011981);
+    3136          10 :   parameter_solv[MET].push_back(-135.38857843066708);
+    3137          10 :   parameter_solv[MET].push_back(-67771.01108177133);
+    3138          10 :   parameter_solv[MET].push_back(-25228.934337676077);
+    3139          10 :   parameter_solv[MET].push_back(199649.95030712147);
+    3140          10 :   parameter_solv[MET].push_back(-182251.94895101967);
+    3141          10 :   parameter_solv[MET].push_back(52502.88444247481);
+    3142             : 
+    3143          10 :   parameter_solv[ASN].push_back(14376.010000119095);
+    3144          10 :   parameter_solv[ASN].push_back(-67.65579048748472);
+    3145          10 :   parameter_solv[ASN].push_back(-28302.87809850141);
+    3146          10 :   parameter_solv[ASN].push_back(-8577.439830985548);
+    3147          10 :   parameter_solv[ASN].push_back(57532.879075695324);
+    3148          10 :   parameter_solv[ASN].push_back(-43261.79286366774);
+    3149          10 :   parameter_solv[ASN].push_back(10186.448634149085);
+    3150             : 
+    3151          10 :   parameter_solv[PRO].push_back(16866.21690011944);
+    3152          10 :   parameter_solv[PRO].push_back(-70.84327801054884);
+    3153          10 :   parameter_solv[PRO].push_back(-31465.84064925844);
+    3154          10 :   parameter_solv[PRO].push_back(-8653.3693368317);
+    3155          10 :   parameter_solv[PRO].push_back(58032.28250733714);
+    3156          10 :   parameter_solv[PRO].push_back(-41521.01146771431);
+    3157          10 :   parameter_solv[PRO].push_back(9184.530596102064);
+    3158             : 
+    3159          10 :   parameter_solv[GLN].push_back(21503.289600119);
+    3160          10 :   parameter_solv[GLN].push_back(-121.30164008960246);
+    3161          10 :   parameter_solv[GLN].push_back(-50468.580981118175);
+    3162          10 :   parameter_solv[GLN].push_back(-18462.49098408308);
+    3163          10 :   parameter_solv[GLN].push_back(132718.44904081387);
+    3164          10 :   parameter_solv[GLN].push_back(-113787.22666510186);
+    3165          10 :   parameter_solv[GLN].push_back(30920.348610969988);
+    3166             : 
+    3167          10 :   parameter_solv[SER].push_back(9181.472400119354);
+    3168          10 :   parameter_solv[SER].push_back(-28.77519915767741);
+    3169          10 :   parameter_solv[SER].push_back(-15205.543144104717);
+    3170          10 :   parameter_solv[SER].push_back(-3377.782176346411);
+    3171          10 :   parameter_solv[SER].push_back(23345.555771001076);
+    3172          10 :   parameter_solv[SER].push_back(-15312.694356014094);
+    3173          10 :   parameter_solv[SER].push_back(3013.8428466148);
+    3174             : 
+    3175          10 :   parameter_solv[THR].push_back(15020.953600119403);
+    3176          10 :   parameter_solv[THR].push_back(-61.91004832631006);
+    3177          10 :   parameter_solv[THR].push_back(-27814.537889259853);
+    3178          10 :   parameter_solv[THR].push_back(-7532.227289701552);
+    3179          10 :   parameter_solv[THR].push_back(50586.30566118166);
+    3180          10 :   parameter_solv[THR].push_back(-35943.866131120165);
+    3181          10 :   parameter_solv[THR].push_back(7880.093558764326);
+    3182             : 
+    3183          10 :   parameter_solv[VAL].push_back(19647.628900119355);
+    3184          10 :   parameter_solv[VAL].push_back(-89.04983250107853);
+    3185          10 :   parameter_solv[VAL].push_back(-38050.09958470928);
+    3186          10 :   parameter_solv[VAL].push_back(-10921.427112288537);
+    3187          10 :   parameter_solv[VAL].push_back(72774.32322962297);
+    3188          10 :   parameter_solv[VAL].push_back(-52689.060152305225);
+    3189          10 :   parameter_solv[VAL].push_back(11806.492503632868);
+    3190             : 
+    3191          10 :   parameter_solv[ALA].push_back(7515.156100119276);
+    3192          10 :   parameter_solv[ALA].push_back(-20.226381685697746);
+    3193          10 :   parameter_solv[ALA].push_back(-11761.841094237716);
+    3194          10 :   parameter_solv[ALA].push_back(-2341.4929468980367);
+    3195          10 :   parameter_solv[ALA].push_back(16545.385777961936);
+    3196          10 :   parameter_solv[ALA].push_back(-10397.175253025776);
+    3197          10 :   parameter_solv[ALA].push_back(1921.5264606725107);
+    3198             : 
+    3199          10 :   parameter_solv[GLY].push_back(3594.002500119159);
+    3200          10 :   parameter_solv[GLY].push_back(-6.910836154887606);
+    3201          10 :   parameter_solv[GLY].push_back(-4937.354220666574);
+    3202          10 :   parameter_solv[GLY].push_back(-785.4549468992149);
+    3203          10 :   parameter_solv[GLY].push_back(5852.854429532936);
+    3204          10 :   parameter_solv[GLY].push_back(-3391.2927115487832);
+    3205          10 :   parameter_solv[GLY].push_back(552.3280571490722);
+    3206             : 
+    3207          10 :   parameter_solv[HIS].push_back(22888.664100119073);
+    3208          10 :   parameter_solv[HIS].push_back(-133.86265270962434);
+    3209          10 :   parameter_solv[HIS].push_back(-57533.51591635819);
+    3210          10 :   parameter_solv[HIS].push_back(-21767.293192014684);
+    3211          10 :   parameter_solv[HIS].push_back(161255.14120001195);
+    3212          10 :   parameter_solv[HIS].push_back(-142176.64081149307);
+    3213          10 :   parameter_solv[HIS].push_back(39642.61185646193);
+    3214             : 
+    3215          10 :   parameter_mix[TRP].push_back(48294.0117571196);
+    3216          10 :   parameter_mix[TRP].push_back(-205.45879626487798);
+    3217          10 :   parameter_mix[TRP].push_back(-148816.1858118254);
+    3218          10 :   parameter_mix[TRP].push_back(-54968.030079609875);
+    3219          10 :   parameter_mix[TRP].push_back(491793.79967057955);
+    3220          10 :   parameter_mix[TRP].push_back(-476312.9117969879);
+    3221          10 :   parameter_mix[TRP].push_back(144159.96165644142);
+    3222             : 
+    3223          10 :   parameter_mix[TYR].push_back(36984.20240312081);
+    3224          10 :   parameter_mix[TYR].push_back(-83.86380083812203);
+    3225          10 :   parameter_mix[TYR].push_back(-108820.52211887162);
+    3226          10 :   parameter_mix[TYR].push_back(-33934.69818901515);
+    3227          10 :   parameter_mix[TYR].push_back(341504.736372253);
+    3228          10 :   parameter_mix[TYR].push_back(-334008.1748614056);
+    3229          10 :   parameter_mix[TYR].push_back(102033.08077851454);
+    3230             : 
+    3231          10 :   parameter_mix[PHE].push_back(32119.469231338233);
+    3232          10 :   parameter_mix[PHE].push_back(-172.96940450568917);
+    3233          10 :   parameter_mix[PHE].push_back(-85831.4326887122);
+    3234          10 :   parameter_mix[PHE].push_back(-33193.32405438845);
+    3235          10 :   parameter_mix[PHE].push_back(262940.64471909316);
+    3236          10 :   parameter_mix[PHE].push_back(-243540.06898907054);
+    3237          10 :   parameter_mix[PHE].push_back(71084.54387480798);
+    3238             : 
+    3239          10 :   parameter_mix[HIP].push_back(22833.36414923898);
+    3240          10 :   parameter_mix[HIP].push_back(-134.0493955562186);
+    3241          10 :   parameter_mix[HIP].push_back(-55325.55607328898);
+    3242          10 :   parameter_mix[HIP].push_back(-21898.314938881984);
+    3243          10 :   parameter_mix[HIP].push_back(159995.6912885654);
+    3244          10 :   parameter_mix[HIP].push_back(-142968.19796084083);
+    3245          10 :   parameter_mix[HIP].push_back(40417.44581470003);
+    3246             : 
+    3247          10 :   parameter_mix[ARG].push_back(31385.401600920715);
+    3248          10 :   parameter_mix[ARG].push_back(36.114094042884254);
+    3249          10 :   parameter_mix[ARG].push_back(-103730.44467490204);
+    3250          10 :   parameter_mix[ARG].push_back(-27036.249157905615);
+    3251          10 :   parameter_mix[ARG].push_back(347011.0339314942);
+    3252          10 :   parameter_mix[ARG].push_back(-358879.9736802336);
+    3253          10 :   parameter_mix[ARG].push_back(114432.18361399164);
+    3254             : 
+    3255          10 :   parameter_mix[LYS].push_back(25511.35812671878);
+    3256          10 :   parameter_mix[LYS].push_back(-130.4381491986372);
+    3257          10 :   parameter_mix[LYS].push_back(-69258.61236879184);
+    3258          10 :   parameter_mix[LYS].push_back(-27066.36783798707);
+    3259          10 :   parameter_mix[LYS].push_back(220092.65231165203);
+    3260          10 :   parameter_mix[LYS].push_back(-207794.5056092443);
+    3261          10 :   parameter_mix[LYS].push_back(61665.57004630315);
+    3262             : 
+    3263          10 :   parameter_mix[CYS].push_back(11505.517261618916);
+    3264          10 :   parameter_mix[CYS].push_back(-33.60468076978334);
+    3265          10 :   parameter_mix[CYS].push_back(-18328.882710004465);
+    3266          10 :   parameter_mix[CYS].push_back(-3956.9113649567626);
+    3267          10 :   parameter_mix[CYS].push_back(27546.35146501212);
+    3268          10 :   parameter_mix[CYS].push_back(-18024.826330595406);
+    3269          10 :   parameter_mix[CYS].push_back(3551.2207387570024);
+    3270             : 
+    3271          10 :   parameter_mix[CYX].push_back(10746.617793719070);
+    3272          10 :   parameter_mix[CYX].push_back(-37.082746200650);
+    3273          10 :   parameter_mix[CYX].push_back(-17871.552278655203);
+    3274          10 :   parameter_mix[CYX].push_back(-4512.203184574789);
+    3275          10 :   parameter_mix[CYX].push_back(30605.726711712588);
+    3276          10 :   parameter_mix[CYX].push_back(-21530.684072275839);
+    3277          10 :   parameter_mix[CYX].push_back(4694.601090758420);
+    3278             : 
+    3279          10 :   parameter_mix[ASP].push_back(13713.858501879382);
+    3280          10 :   parameter_mix[ASP].push_back(-51.33286241257164);
+    3281          10 :   parameter_mix[ASP].push_back(-23807.8549764091);
+    3282          10 :   parameter_mix[ASP].push_back(-6153.667315935503);
+    3283          10 :   parameter_mix[ASP].push_back(41296.118377286424);
+    3284          10 :   parameter_mix[ASP].push_back(-28740.28391184026);
+    3285          10 :   parameter_mix[ASP].push_back(6132.671533319127);
+    3286             : 
+    3287          10 :   parameter_mix[GLU].push_back(19156.03660739947);
+    3288          10 :   parameter_mix[GLU].push_back(-110.90600703589246);
+    3289          10 :   parameter_mix[GLU].push_back(-40319.3351514524);
+    3290          10 :   parameter_mix[GLU].push_back(-14679.813393816446);
+    3291          10 :   parameter_mix[GLU].push_back(96769.28565573556);
+    3292          10 :   parameter_mix[GLU].push_back(-77909.09315520026);
+    3293          10 :   parameter_mix[GLU].push_back(19770.047062759568);
+    3294             : 
+    3295          10 :   parameter_mix[ILE].push_back(20693.06215917923);
+    3296          10 :   parameter_mix[ILE].push_back(-102.87208880594848);
+    3297          10 :   parameter_mix[ILE].push_back(-41080.44036311675);
+    3298          10 :   parameter_mix[ILE].push_back(-12874.439649378206);
+    3299          10 :   parameter_mix[ILE].push_back(84947.33147117581);
+    3300          10 :   parameter_mix[ILE].push_back(-63779.07871450237);
+    3301          10 :   parameter_mix[ILE].push_back(14938.919981690511);
+    3302             : 
+    3303          10 :   parameter_mix[LEU].push_back(20693.062159179233);
+    3304          10 :   parameter_mix[LEU].push_back(-114.09539845409269);
+    3305          10 :   parameter_mix[LEU].push_back(-42417.3431074524);
+    3306          10 :   parameter_mix[LEU].push_back(-14393.801090829746);
+    3307          10 :   parameter_mix[LEU].push_back(93640.48403643962);
+    3308          10 :   parameter_mix[LEU].push_back(-71990.10354816525);
+    3309          10 :   parameter_mix[LEU].push_back(17299.01082057651);
+    3310             : 
+    3311          10 :   parameter_mix[MET].push_back(22400.800002738917);
+    3312          10 :   parameter_mix[MET].push_back(-138.14469221559762);
+    3313          10 :   parameter_mix[MET].push_back(-53013.97694299946);
+    3314          10 :   parameter_mix[MET].push_back(-21079.899452619244);
+    3315          10 :   parameter_mix[MET].push_back(148607.1089339919);
+    3316          10 :   parameter_mix[MET].push_back(-129827.63962878387);
+    3317          10 :   parameter_mix[MET].push_back(35882.3297822684);
+    3318             : 
+    3319          10 :   parameter_mix[ASN].push_back(14384.287416519475);
+    3320          10 :   parameter_mix[ASN].push_back(-55.24976731179147);
+    3321          10 :   parameter_mix[ASN].push_back(-25372.978199926372);
+    3322          10 :   parameter_mix[ASN].push_back(-6646.452004616925);
+    3323          10 :   parameter_mix[ASN].push_back(44594.5027556148);
+    3324          10 :   parameter_mix[ASN].push_back(-31202.511764907107);
+    3325          10 :   parameter_mix[ASN].push_back(6703.764135873442);
+    3326             : 
+    3327          10 :   parameter_mix[PRO].push_back(13503.797145659117);
+    3328          10 :   parameter_mix[PRO].push_back(-38.58316011847087);
+    3329          10 :   parameter_mix[PRO].push_back(-21446.17847324053);
+    3330          10 :   parameter_mix[PRO].push_back(-4480.55896170459);
+    3331          10 :   parameter_mix[PRO].push_back(31274.287350083254);
+    3332          10 :   parameter_mix[PRO].push_back(-19984.249229169505);
+    3333          10 :   parameter_mix[PRO].push_back(3782.272312712745);
+    3334             : 
+    3335          10 :   parameter_mix[GLN].push_back(19938.23724683901);
+    3336          10 :   parameter_mix[GLN].push_back(-121.24884503048865);
+    3337          10 :   parameter_mix[GLN].push_back(-43928.589472297834);
+    3338          10 :   parameter_mix[GLN].push_back(-16805.069757865473);
+    3339          10 :   parameter_mix[GLN].push_back(112831.61348476357);
+    3340          10 :   parameter_mix[GLN].push_back(-93979.08819184235);
+    3341          10 :   parameter_mix[GLN].push_back(24741.563493163732);
+    3342             : 
+    3343          10 :   parameter_mix[SER].push_back(8813.67020471935);
+    3344          10 :   parameter_mix[SER].push_back(-18.291615317790175);
+    3345          10 :   parameter_mix[SER].push_back(-12585.074732466266);
+    3346          10 :   parameter_mix[SER].push_back(-2064.454891600786);
+    3347          10 :   parameter_mix[SER].push_back(15273.905065790364);
+    3348          10 :   parameter_mix[SER].push_back(-8813.056005263466);
+    3349          10 :   parameter_mix[SER].push_back(1404.9812302289881);
+    3350             : 
+    3351          10 :   parameter_mix[THR].push_back(13233.997179639062);
+    3352          10 :   parameter_mix[THR].push_back(-39.40454157416847);
+    3353          10 :   parameter_mix[THR].push_back(-21430.58717233547);
+    3354          10 :   parameter_mix[THR].push_back(-4566.332853710876);
+    3355          10 :   parameter_mix[THR].push_back(31717.497780073558);
+    3356          10 :   parameter_mix[THR].push_back(-20299.614304281313);
+    3357          10 :   parameter_mix[THR].push_back(3837.207224537505);
+    3358             : 
+    3359          10 :   parameter_mix[VAL].push_back(15135.438016299158);
+    3360          10 :   parameter_mix[VAL].push_back(-51.415141550353205);
+    3361          10 :   parameter_mix[VAL].push_back(-25859.078442379723);
+    3362          10 :   parameter_mix[VAL].push_back(-6007.697291593915);
+    3363          10 :   parameter_mix[VAL].push_back(40997.969600345634);
+    3364          10 :   parameter_mix[VAL].push_back(-27036.257386814148);
+    3365          10 :   parameter_mix[VAL].push_back(5328.922363811635);
+    3366             : 
+    3367          10 :   parameter_mix[ALA].push_back(6586.942863819189);
+    3368          10 :   parameter_mix[ALA].push_back(-10.96713559950907);
+    3369          10 :   parameter_mix[ALA].push_back(-8758.836131731925);
+    3370          10 :   parameter_mix[ALA].push_back(-1223.1723720922605);
+    3371          10 :   parameter_mix[ALA].push_back(9475.182453543037);
+    3372          10 :   parameter_mix[ALA].push_back(-5124.611191433804);
+    3373          10 :   parameter_mix[ALA].push_back(721.7625962949869);
+    3374             : 
+    3375          10 :   parameter_mix[GLY].push_back(3596.0718542192762);
+    3376          10 :   parameter_mix[GLY].push_back(-4.079285964028122);
+    3377          10 :   parameter_mix[GLY].push_back(-4089.4217504382686);
+    3378          10 :   parameter_mix[GLY].push_back(-450.9650932154967);
+    3379          10 :   parameter_mix[GLY].push_back(3737.026778223427);
+    3380          10 :   parameter_mix[GLY].push_back(-1862.9856575810572);
+    3381          10 :   parameter_mix[GLY].push_back(222.97288276257262);
+    3382             : 
+    3383          10 :   parameter_mix[HIS].push_back(21779.124723299232);
+    3384          10 :   parameter_mix[HIS].push_back(-131.4603421188538);
+    3385          10 :   parameter_mix[HIS].push_back(-49068.74667421681);
+    3386          10 :   parameter_mix[HIS].push_back(-18685.909496392127);
+    3387          10 :   parameter_mix[HIS].push_back(127724.60792384286);
+    3388          10 :   parameter_mix[HIS].push_back(-107419.22159440348);
+    3389          10 :   parameter_mix[HIS].push_back(28577.228634530744);
+    3390             : 
+    3391          10 :   parameter_vac[TRP].push_back(9599.949107368187);
+    3392          10 :   parameter_vac[TRP].push_back(-66.35331786175249);
+    3393          10 :   parameter_vac[TRP].push_back(-26311.640290970638);
+    3394          10 :   parameter_vac[TRP].push_back(-11577.314600529338);
+    3395          10 :   parameter_vac[TRP].push_back(85847.52554160352);
+    3396          10 :   parameter_vac[TRP].push_back(-79417.17065742958);
+    3397          10 :   parameter_vac[TRP].push_back(23090.348430572863);
+    3398             : 
+    3399          10 :   parameter_vac[TYR].push_back(7393.553846412945);
+    3400          10 :   parameter_vac[TYR].push_back(-27.51954035778316);
+    3401          10 :   parameter_vac[TYR].push_back(-20329.10485615286);
+    3402          10 :   parameter_vac[TYR].push_back(-7444.276340508767);
+    3403          10 :   parameter_vac[TYR].push_back(66343.22315132803);
+    3404          10 :   parameter_vac[TYR].push_back(-64470.58721639446);
+    3405          10 :   parameter_vac[TYR].push_back(19614.63563898146);
+    3406             : 
+    3407          10 :   parameter_vac[PHE].push_back(6081.874997705279);
+    3408          10 :   parameter_vac[PHE].push_back(-40.474695969500104);
+    3409          10 :   parameter_vac[PHE].push_back(-14354.627390498901);
+    3410          10 :   parameter_vac[PHE].push_back(-6156.69750315959);
+    3411          10 :   parameter_vac[PHE].push_back(42580.84239395237);
+    3412          10 :   parameter_vac[PHE].push_back(-37704.09749809582);
+    3413          10 :   parameter_vac[PHE].push_back(10543.005717478625);
+    3414             : 
+    3415          10 :   parameter_vac[HIP].push_back(5325.791987063724);
+    3416          10 :   parameter_vac[HIP].push_back(-35.512112257530156);
+    3417          10 :   parameter_vac[HIP].push_back(-11488.443296477566);
+    3418          10 :   parameter_vac[HIP].push_back(-4916.724935318093);
+    3419          10 :   parameter_vac[HIP].push_back(32134.338675979947);
+    3420          10 :   parameter_vac[HIP].push_back(-27388.387595464188);
+    3421          10 :   parameter_vac[HIP].push_back(7359.899986748838);
+    3422             : 
+    3423          10 :   parameter_vac[ARG].push_back(7220.306892248294);
+    3424          10 :   parameter_vac[ARG].push_back(-20.65912886190997);
+    3425          10 :   parameter_vac[ARG].push_back(-22700.70129646048);
+    3426          10 :   parameter_vac[ARG].push_back(-8696.901551172636);
+    3427          10 :   parameter_vac[ARG].push_back(83641.36257312517);
+    3428          10 :   parameter_vac[ARG].push_back(-85237.33676336925);
+    3429          10 :   parameter_vac[ARG].push_back(26899.162688310953);
+    3430             : 
+    3431          10 :   parameter_vac[LYS].push_back(5038.613120729022);
+    3432          10 :   parameter_vac[LYS].push_back(-34.08366887546492);
+    3433          10 :   parameter_vac[LYS].push_back(-12812.921120433106);
+    3434          10 :   parameter_vac[LYS].push_back(-5843.761329082788);
+    3435          10 :   parameter_vac[LYS].push_back(42419.08427856609);
+    3436          10 :   parameter_vac[LYS].push_back(-39460.49038159249);
+    3437          10 :   parameter_vac[LYS].push_back(11542.320830663035);
+    3438             : 
+    3439          10 :   parameter_vac[CYS].push_back(2915.0458981763995);
+    3440          10 :   parameter_vac[CYS].push_back(-5.380571839804511);
+    3441          10 :   parameter_vac[CYS].push_back(-3865.366285883624);
+    3442          10 :   parameter_vac[CYS].push_back(-602.3275271136284);
+    3443          10 :   parameter_vac[CYS].push_back(4524.133086072617);
+    3444          10 :   parameter_vac[CYS].push_back(-2537.87137720241);
+    3445          10 :   parameter_vac[CYS].push_back(381.52870758240016);
+    3446             : 
+    3447          10 :   parameter_vac[CYX].push_back(2808.068549348085);
+    3448          10 :   parameter_vac[CYX].push_back(-7.372260063948);
+    3449          10 :   parameter_vac[CYX].push_back(-4017.492317531980);
+    3450          10 :   parameter_vac[CYX].push_back(-840.151815748375);
+    3451          10 :   parameter_vac[CYX].push_back(5800.074437790741);
+    3452          10 :   parameter_vac[CYX].push_back(-3637.868824045027);
+    3453          10 :   parameter_vac[CYX].push_back(659.528934122407);
+    3454             : 
+    3455          10 :   parameter_vac[ASP].push_back(3479.750728224898);
+    3456          10 :   parameter_vac[ASP].push_back(-10.33897891836596);
+    3457          10 :   parameter_vac[ASP].push_back(-5382.628188436401);
+    3458          10 :   parameter_vac[ASP].push_back(-1183.8060939576694);
+    3459          10 :   parameter_vac[ASP].push_back(8100.082378727997);
+    3460          10 :   parameter_vac[ASP].push_back(-5162.630696148773);
+    3461          10 :   parameter_vac[ASP].push_back(958.993022379732);
+    3462             : 
+    3463          10 :   parameter_vac[GLU].push_back(4487.461543955491);
+    3464          10 :   parameter_vac[GLU].push_back(-26.671865751817936);
+    3465          10 :   parameter_vac[GLU].push_back(-8829.738168429001);
+    3466          10 :   parameter_vac[GLU].push_back(-3297.668395415257);
+    3467          10 :   parameter_vac[GLU].push_back(20686.457747123466);
+    3468          10 :   parameter_vac[GLU].push_back(-16030.814134196151);
+    3469          10 :   parameter_vac[GLU].push_back(3858.4457728083275);
+    3470             : 
+    3471          10 :   parameter_vac[ILE].push_back(3842.5968201937776);
+    3472          10 :   parameter_vac[ILE].push_back(-13.848165050578492);
+    3473          10 :   parameter_vac[ILE].push_back(-6480.062699452774);
+    3474          10 :   parameter_vac[ILE].push_back(-1636.3888925440413);
+    3475          10 :   parameter_vac[ILE].push_back(10967.333210698738);
+    3476          10 :   parameter_vac[ILE].push_back(-7483.704914714421);
+    3477          10 :   parameter_vac[ILE].push_back(1548.5696047594895);
+    3478             : 
+    3479          10 :   parameter_vac[LEU].push_back(3842.5968201937785);
+    3480          10 :   parameter_vac[LEU].push_back(-16.2745108270949);
+    3481          10 :   parameter_vac[LEU].push_back(-6807.110269770606);
+    3482          10 :   parameter_vac[LEU].push_back(-1926.6303434106014);
+    3483          10 :   parameter_vac[LEU].push_back(12577.952756390941);
+    3484          10 :   parameter_vac[LEU].push_back(-8829.40489330961);
+    3485          10 :   parameter_vac[LEU].push_back(1882.919316016889);
+    3486             : 
+    3487          10 :   parameter_vac[MET].push_back(4898.512892967389);
+    3488          10 :   parameter_vac[MET].push_back(-30.588244886468207);
+    3489          10 :   parameter_vac[MET].push_back(-10159.093665859045);
+    3490          10 :   parameter_vac[MET].push_back(-4025.0261508449653);
+    3491          10 :   parameter_vac[MET].push_back(26007.394369425827);
+    3492          10 :   parameter_vac[MET].push_back(-21199.218680206573);
+    3493          10 :   parameter_vac[MET].push_back(5423.004225853842);
+    3494             : 
+    3495          10 :   parameter_vac[ASN].push_back(3598.1423998115492);
+    3496          10 :   parameter_vac[ASN].push_back(-10.357995638888545);
+    3497          10 :   parameter_vac[ASN].push_back(-5565.603011562138);
+    3498          10 :   parameter_vac[ASN].push_back(-1190.3294930971967);
+    3499          10 :   parameter_vac[ASN].push_back(8227.920711951123);
+    3500          10 :   parameter_vac[ASN].push_back(-5222.61541118056);
+    3501          10 :   parameter_vac[ASN].push_back(968.593406702772);
+    3502             : 
+    3503          10 :   parameter_vac[PRO].push_back(2702.925890807494);
+    3504          10 :   parameter_vac[PRO].push_back(-4.11690159421177);
+    3505          10 :   parameter_vac[PRO].push_back(-3395.325331307625);
+    3506          10 :   parameter_vac[PRO].push_back(-458.95242128002894);
+    3507          10 :   parameter_vac[PRO].push_back(3584.3640448715823);
+    3508          10 :   parameter_vac[PRO].push_back(-1921.4140769384692);
+    3509          10 :   parameter_vac[PRO].push_back(267.08577848319516);
+    3510             : 
+    3511          10 :   parameter_vac[GLN].push_back(4621.773132292556);
+    3512          10 :   parameter_vac[GLN].push_back(-29.511778489038818);
+    3513          10 :   parameter_vac[GLN].push_back(-9486.077450010192);
+    3514          10 :   parameter_vac[GLN].push_back(-3768.5756897489828);
+    3515          10 :   parameter_vac[GLN].push_back(23828.07111260487);
+    3516          10 :   parameter_vac[GLN].push_back(-19110.205836780202);
+    3517          10 :   parameter_vac[GLN].push_back(4791.718204894083);
+    3518             : 
+    3519          10 :   parameter_vac[SER].push_back(2115.1504654043965);
+    3520          10 :   parameter_vac[SER].push_back(-2.4158378234251234);
+    3521          10 :   parameter_vac[SER].push_back(-2488.1131972903822);
+    3522          10 :   parameter_vac[SER].push_back(-263.64072945387693);
+    3523          10 :   parameter_vac[SER].push_back(2251.376687850687);
+    3524          10 :   parameter_vac[SER].push_back(-1066.0790768852626);
+    3525          10 :   parameter_vac[SER].push_back(105.5155397911316);
+    3526             : 
+    3527          10 :   parameter_vac[THR].push_back(2914.9061707158835);
+    3528          10 :   parameter_vac[THR].push_back(-5.032844592364407);
+    3529          10 :   parameter_vac[THR].push_back(-3903.2546253886653);
+    3530          10 :   parameter_vac[THR].push_back(-559.4734271244915);
+    3531          10 :   parameter_vac[THR].push_back(4315.044828297787);
+    3532          10 :   parameter_vac[THR].push_back(-2331.211908177365);
+    3533          10 :   parameter_vac[THR].push_back(323.76849758109853);
+    3534             : 
+    3535          10 :   parameter_vac[VAL].push_back(2914.8744247581953);
+    3536          10 :   parameter_vac[VAL].push_back(-5.847217106105881);
+    3537          10 :   parameter_vac[VAL].push_back(-4096.370479502377);
+    3538          10 :   parameter_vac[VAL].push_back(-655.2917606620404);
+    3539          10 :   parameter_vac[VAL].push_back(4888.77261250007);
+    3540          10 :   parameter_vac[VAL].push_back(-2765.7552774385167);
+    3541          10 :   parameter_vac[VAL].push_back(421.9081598033515);
+    3542             : 
+    3543          10 :   parameter_vac[ALA].push_back(1443.3438146824446);
+    3544          10 :   parameter_vac[ALA].push_back(-1.1234573178567506);
+    3545          10 :   parameter_vac[ALA].push_back(-1492.4547663363514);
+    3546          10 :   parameter_vac[ALA].push_back(-121.47935619968672);
+    3547          10 :   parameter_vac[ALA].push_back(1139.689871538201);
+    3548          10 :   parameter_vac[ALA].push_back(-483.8336547914466);
+    3549          10 :   parameter_vac[ALA].push_back(32.48231950404626);
+    3550             : 
+    3551          10 :   parameter_vac[GLY].push_back(899.5356000422925);
+    3552          10 :   parameter_vac[GLY].push_back(-0.5200880084066986);
+    3553          10 :   parameter_vac[GLY].push_back(-787.5892053280859);
+    3554          10 :   parameter_vac[GLY].push_back(-56.07596224884467);
+    3555          10 :   parameter_vac[GLY].push_back(546.4212287680981);
+    3556          10 :   parameter_vac[GLY].push_back(-222.2667666932616);
+    3557          10 :   parameter_vac[GLY].push_back(12.474587265791476);
+    3558             : 
+    3559          10 :   parameter_vac[HIS].push_back(5180.842705000207);
+    3560          10 :   parameter_vac[HIS].push_back(-29.578973475252766);
+    3561          10 :   parameter_vac[HIS].push_back(-10323.417251934066);
+    3562          10 :   parameter_vac[HIS].push_back(-3788.977215582307);
+    3563          10 :   parameter_vac[HIS].push_back(24427.720792289427);
+    3564          10 :   parameter_vac[HIS].push_back(-19307.35836837878);
+    3565          10 :   parameter_vac[HIS].push_back(4780.831414992477);
+    3566             : 
+    3567             :   // NUCLEIC ACIDS
+    3568          10 :   parameter_solv[BB_PO3].push_back(1464.5929001192262);
+    3569          10 :   parameter_solv[BB_PO3].push_back(-2.316908934494931);
+    3570          10 :   parameter_solv[BB_PO3].push_back(-1882.4844584696532);
+    3571          10 :   parameter_solv[BB_PO3].push_back(-258.8660305554736);
+    3572          10 :   parameter_solv[BB_PO3].push_back(2007.5216385943972);
+    3573          10 :   parameter_solv[BB_PO3].push_back(-1087.6423562424877);
+    3574          10 :   parameter_solv[BB_PO3].push_back(154.89236486681165);
+    3575             : 
+    3576          10 :   parameter_solv[BB_PO2].push_back(575.5201001192197);
+    3577          10 :   parameter_solv[BB_PO2].push_back(-0.6126595489733868);
+    3578          10 :   parameter_solv[BB_PO2].push_back(-623.3371092254897);
+    3579          10 :   parameter_solv[BB_PO2].push_back(-68.05795957022156);
+    3580          10 :   parameter_solv[BB_PO2].push_back(561.8052621243662);
+    3581          10 :   parameter_solv[BB_PO2].push_back(-283.39573309540344);
+    3582          10 :   parameter_solv[BB_PO2].push_back(35.55001698010027);
+    3583             : 
+    3584          10 :   parameter_solv[BB_DNA].push_back(21211.009600118316);
+    3585          10 :   parameter_solv[BB_DNA].push_back(-90.18805990529991);
+    3586          10 :   parameter_solv[BB_DNA].push_back(-39731.1337351215);
+    3587          10 :   parameter_solv[BB_DNA].push_back(-10920.373563712878);
+    3588          10 :   parameter_solv[BB_DNA].push_back(72882.21702424977);
+    3589          10 :   parameter_solv[BB_DNA].push_back(-51747.487078112754);
+    3590          10 :   parameter_solv[BB_DNA].push_back(11308.67842901876);
+    3591             : 
+    3592          10 :   parameter_solv[BB_DNA_5].push_back(22737.624100119025);
+    3593          10 :   parameter_solv[BB_DNA_5].push_back(-102.72714886664163);
+    3594          10 :   parameter_solv[BB_DNA_5].push_back(-43685.329677789705);
+    3595          10 :   parameter_solv[BB_DNA_5].push_back(-12564.259374093454);
+    3596          10 :   parameter_solv[BB_DNA_5].push_back(83454.87540484876);
+    3597          10 :   parameter_solv[BB_DNA_5].push_back(-60367.15652138888);
+    3598          10 :   parameter_solv[BB_DNA_5].push_back(13507.33372986899);
+    3599             : 
+    3600          10 :   parameter_solv[BB_DNA_3].push_back(22737.62410011902);
+    3601          10 :   parameter_solv[BB_DNA_3].push_back(-101.57816684452263);
+    3602          10 :   parameter_solv[BB_DNA_3].push_back(-43488.53670557616);
+    3603          10 :   parameter_solv[BB_DNA_3].push_back(-12345.056184958417);
+    3604          10 :   parameter_solv[BB_DNA_3].push_back(81963.5236411489);
+    3605          10 :   parameter_solv[BB_DNA_3].push_back(-58791.59443618196);
+    3606          10 :   parameter_solv[BB_DNA_3].push_back(13003.199362335576);
+    3607             : 
+    3608          10 :   parameter_solv[BB_RNA].push_back(23953.752900120977);
+    3609          10 :   parameter_solv[BB_RNA].push_back(-117.35779348824401);
+    3610          10 :   parameter_solv[BB_RNA].push_back(-47644.41735332837);
+    3611          10 :   parameter_solv[BB_RNA].push_back(-14641.556643789863);
+    3612          10 :   parameter_solv[BB_RNA].push_back(96893.48627050382);
+    3613          10 :   parameter_solv[BB_RNA].push_back(-72249.62534169314);
+    3614          10 :   parameter_solv[BB_RNA].push_back(16792.05552105538);
+    3615             : 
+    3616          10 :   parameter_solv[BB_RNA_5].push_back(25574.406400119024);
+    3617          10 :   parameter_solv[BB_RNA_5].push_back(-131.99642772933734);
+    3618          10 :   parameter_solv[BB_RNA_5].push_back(-52136.51404531249);
+    3619          10 :   parameter_solv[BB_RNA_5].push_back(-16682.14273917604);
+    3620          10 :   parameter_solv[BB_RNA_5].push_back(110278.019216394);
+    3621          10 :   parameter_solv[BB_RNA_5].push_back(-83715.92027818545);
+    3622          10 :   parameter_solv[BB_RNA_5].push_back(19875.891337706045);
+    3623             : 
+    3624          10 :   parameter_solv[BB_RNA_3].push_back(25574.406400119024);
+    3625          10 :   parameter_solv[BB_RNA_3].push_back(-127.96875237036166);
+    3626          10 :   parameter_solv[BB_RNA_3].push_back(-51407.183917584385);
+    3627          10 :   parameter_solv[BB_RNA_3].push_back(-15922.900669975606);
+    3628          10 :   parameter_solv[BB_RNA_3].push_back(105078.58889106264);
+    3629          10 :   parameter_solv[BB_RNA_3].push_back(-78289.16276190648);
+    3630          10 :   parameter_solv[BB_RNA_3].push_back(18156.83214344118);
+    3631             : 
+    3632          10 :   parameter_solv[BASE_A].push_back(13282.562500119211);
+    3633          10 :   parameter_solv[BASE_A].push_back(-76.45124168404048);
+    3634          10 :   parameter_solv[BASE_A].push_back(-28376.06994108963);
+    3635          10 :   parameter_solv[BASE_A].push_back(-9972.910773722022);
+    3636          10 :   parameter_solv[BASE_A].push_back(65873.86341939073);
+    3637          10 :   parameter_solv[BASE_A].push_back(-52064.33492910885);
+    3638          10 :   parameter_solv[BASE_A].push_back(12931.608989412513);
+    3639             : 
+    3640          10 :   parameter_solv[BASE_C].push_back(10600.76160011891);
+    3641          10 :   parameter_solv[BASE_C].push_back(-49.1670871249108);
+    3642          10 :   parameter_solv[BASE_C].push_back(-20239.818742072875);
+    3643          10 :   parameter_solv[BASE_C].push_back(-6020.278780090207);
+    3644          10 :   parameter_solv[BASE_C].push_back(39632.13288981881);
+    3645          10 :   parameter_solv[BASE_C].push_back(-28954.779736165576);
+    3646          10 :   parameter_solv[BASE_C].push_back(6551.541109526305);
+    3647             : 
+    3648          10 :   parameter_solv[BASE_G].push_back(15470.384400119934);
+    3649          10 :   parameter_solv[BASE_G].push_back(-93.8013620200972);
+    3650          10 :   parameter_solv[BASE_G].push_back(-36188.29687013545);
+    3651          10 :   parameter_solv[BASE_G].push_back(-13717.685098209471);
+    3652          10 :   parameter_solv[BASE_G].push_back(95658.18473657136);
+    3653          10 :   parameter_solv[BASE_G].push_back(-81262.37811451119);
+    3654          10 :   parameter_solv[BASE_G].push_back(21841.903930943085);
+    3655             : 
+    3656          10 :   parameter_solv[BASE_T].push_back(17210.81610011936);
+    3657          10 :   parameter_solv[BASE_T].push_back(-93.10189802920208);
+    3658          10 :   parameter_solv[BASE_T].push_back(-36466.51927689957);
+    3659          10 :   parameter_solv[BASE_T].push_back(-12425.55615716932);
+    3660          10 :   parameter_solv[BASE_T].push_back(83847.427808925);
+    3661          10 :   parameter_solv[BASE_T].push_back(-66735.64997846584);
+    3662          10 :   parameter_solv[BASE_T].push_back(16757.3463987507);
+    3663             : 
+    3664          10 :   parameter_solv[BASE_U].push_back(10909.802500119395);
+    3665          10 :   parameter_solv[BASE_U].push_back(-46.17712672768298);
+    3666          10 :   parameter_solv[BASE_U].push_back(-20149.67695512526);
+    3667          10 :   parameter_solv[BASE_U].push_back(-5590.242961204435);
+    3668          10 :   parameter_solv[BASE_U].push_back(37169.2740983132);
+    3669          10 :   parameter_solv[BASE_U].push_back(-26475.631627167604);
+    3670          10 :   parameter_solv[BASE_U].push_back(5808.201015156168);
+    3671             : 
+    3672          10 :   parameter_mix[BB_PO3].push_back(3061.4050527391964);
+    3673          10 :   parameter_mix[BB_PO3].push_back(-2.022452986623699);
+    3674          10 :   parameter_mix[BB_PO3].push_back(-2998.2603666141363);
+    3675          10 :   parameter_mix[BB_PO3].push_back(-218.44256405859076);
+    3676          10 :   parameter_mix[BB_PO3].push_back(2113.3633950628328);
+    3677          10 :   parameter_mix[BB_PO3].push_back(-868.4021757095805);
+    3678          10 :   parameter_mix[BB_PO3].push_back(52.19052064107954);
+    3679             : 
+    3680          10 :   parameter_mix[BB_PO2].push_back(1487.2888381188868);
+    3681          10 :   parameter_mix[BB_PO2].push_back(-0.6155376265599789);
+    3682          10 :   parameter_mix[BB_PO2].push_back(-1181.5076027691764);
+    3683          10 :   parameter_mix[BB_PO2].push_back(-66.25027450710594);
+    3684          10 :   parameter_mix[BB_PO2].push_back(697.0421991965113);
+    3685          10 :   parameter_mix[BB_PO2].push_back(-261.8559466354847);
+    3686          10 :   parameter_mix[BB_PO2].push_back(9.974337082362194);
+    3687             : 
+    3688          10 :   parameter_mix[BB_DNA].push_back(17766.29474499878);
+    3689          10 :   parameter_mix[BB_DNA].push_back(-48.97330188566253);
+    3690          10 :   parameter_mix[BB_DNA].push_back(-28199.563596327207);
+    3691          10 :   parameter_mix[BB_DNA].push_back(-5623.82085602494);
+    3692          10 :   parameter_mix[BB_DNA].push_back(39646.22954828498);
+    3693          10 :   parameter_mix[BB_DNA].push_back(-24658.81157651943);
+    3694          10 :   parameter_mix[BB_DNA].push_back(4453.73906293146);
+    3695             : 
+    3696          10 :   parameter_mix[BB_DNA_5].push_back(18696.09744203927);
+    3697          10 :   parameter_mix[BB_DNA_5].push_back(-56.29408880833802);
+    3698          10 :   parameter_mix[BB_DNA_5].push_back(-30486.108599707608);
+    3699          10 :   parameter_mix[BB_DNA_5].push_back(-6524.195857141158);
+    3700          10 :   parameter_mix[BB_DNA_5].push_back(45280.80142686446);
+    3701          10 :   parameter_mix[BB_DNA_5].push_back(-29007.98616567993);
+    3702          10 :   parameter_mix[BB_DNA_5].push_back(5488.566965501818);
+    3703             : 
+    3704          10 :   parameter_mix[BB_DNA_3].push_back(18696.097442039274);
+    3705          10 :   parameter_mix[BB_DNA_3].push_back(-55.5645003501971);
+    3706          10 :   parameter_mix[BB_DNA_3].push_back(-30422.262113654506);
+    3707          10 :   parameter_mix[BB_DNA_3].push_back(-6409.659659309089);
+    3708          10 :   parameter_mix[BB_DNA_3].push_back(44605.76043515699);
+    3709          10 :   parameter_mix[BB_DNA_3].push_back(-28295.62152988411);
+    3710          10 :   parameter_mix[BB_DNA_3].push_back(5262.5765863484);
+    3711             : 
+    3712          10 :   parameter_mix[BB_RNA].push_back(21356.177105457366);
+    3713          10 :   parameter_mix[BB_RNA].push_back(-76.73490647754872);
+    3714          10 :   parameter_mix[BB_RNA].push_back(-36845.234814782816);
+    3715          10 :   parameter_mix[BB_RNA].push_back(-9066.559625582728);
+    3716          10 :   parameter_mix[BB_RNA].push_back(61167.998793390485);
+    3717          10 :   parameter_mix[BB_RNA].push_back(-41467.23384423218);
+    3718          10 :   parameter_mix[BB_RNA].push_back(8518.937793863257);
+    3719             : 
+    3720          10 :   parameter_mix[BB_RNA_5].push_back(22386.63276427916);
+    3721          10 :   parameter_mix[BB_RNA_5].push_back(-85.70426456933487);
+    3722          10 :   parameter_mix[BB_RNA_5].push_back(-39490.50298502025);
+    3723          10 :   parameter_mix[BB_RNA_5].push_back(-10223.702594972712);
+    3724          10 :   parameter_mix[BB_RNA_5].push_back(68450.60459618448);
+    3725          10 :   parameter_mix[BB_RNA_5].push_back(-47409.91098159006);
+    3726          10 :   parameter_mix[BB_RNA_5].push_back(10031.136138513202);
+    3727             : 
+    3728          10 :   parameter_mix[BB_RNA_3].push_back(22386.63276427916);
+    3729          10 :   parameter_mix[BB_RNA_3].push_back(-81.93760812351479);
+    3730          10 :   parameter_mix[BB_RNA_3].push_back(-39031.70571520093);
+    3731          10 :   parameter_mix[BB_RNA_3].push_back(-9666.316086142708);
+    3732          10 :   parameter_mix[BB_RNA_3].push_back(65120.07128126262);
+    3733          10 :   parameter_mix[BB_RNA_3].push_back(-44110.13603681317);
+    3734          10 :   parameter_mix[BB_RNA_3].push_back(9036.76498256983);
+    3735             : 
+    3736          10 :   parameter_mix[BASE_A].push_back(15897.31116611889);
+    3737          10 :   parameter_mix[BASE_A].push_back(-67.86385832953485);
+    3738          10 :   parameter_mix[BASE_A].push_back(-28851.754660951636);
+    3739          10 :   parameter_mix[BASE_A].push_back(-8144.431687170413);
+    3740          10 :   parameter_mix[BASE_A].push_back(53606.39082954489);
+    3741          10 :   parameter_mix[BASE_A].push_back(-38083.51243782253);
+    3742          10 :   parameter_mix[BASE_A].push_back(8293.47107993253);
+    3743             : 
+    3744          10 :   parameter_mix[BASE_C].push_back(11733.2828871599);
+    3745          10 :   parameter_mix[BASE_C].push_back(-38.76775400274115);
+    3746          10 :   parameter_mix[BASE_C].push_back(-19318.84666423464);
+    3747          10 :   parameter_mix[BASE_C].push_back(-4507.915522704176);
+    3748          10 :   parameter_mix[BASE_C].push_back(30576.57671286052);
+    3749          10 :   parameter_mix[BASE_C].push_back(-20132.46696910844);
+    3750          10 :   parameter_mix[BASE_C].push_back(3947.8727087996162);
+    3751             : 
+    3752          10 :   parameter_mix[BASE_G].push_back(19146.612417237808);
+    3753          10 :   parameter_mix[BASE_G].push_back(-102.37046638004914);
+    3754          10 :   parameter_mix[BASE_G].push_back(-38718.96478190546);
+    3755          10 :   parameter_mix[BASE_G].push_back(-13238.106081860074);
+    3756          10 :   parameter_mix[BASE_G].push_back(87309.07460288722);
+    3757          10 :   parameter_mix[BASE_G].push_back(-68364.82442984737);
+    3758          10 :   parameter_mix[BASE_G].push_back(16815.362401369);
+    3759             : 
+    3760          10 :   parameter_mix[BASE_T].push_back(17050.440260819163);
+    3761          10 :   parameter_mix[BASE_T].push_back(-76.33750600643376);
+    3762          10 :   parameter_mix[BASE_T].push_back(-31849.539096715005);
+    3763          10 :   parameter_mix[BASE_T].push_back(-9484.498992751434);
+    3764          10 :   parameter_mix[BASE_T].push_back(62881.895771680494);
+    3765          10 :   parameter_mix[BASE_T].push_back(-46531.948557759024);
+    3766          10 :   parameter_mix[BASE_T].push_back(10734.196329884822);
+    3767             : 
+    3768          10 :   parameter_mix[BASE_U].push_back(11904.095265219023);
+    3769          10 :   parameter_mix[BASE_U].push_back(-34.67511054915295);
+    3770          10 :   parameter_mix[BASE_U].push_back(-18842.275003104005);
+    3771          10 :   parameter_mix[BASE_U].push_back(-3993.1174764890684);
+    3772          10 :   parameter_mix[BASE_U].push_back(27663.625106762345);
+    3773          10 :   parameter_mix[BASE_U].push_back(-17577.387831701515);
+    3774          10 :   parameter_mix[BASE_U].push_back(3273.183903219142);
+    3775             : 
+    3776          10 :   parameter_vac[BB_PO3].push_back(1599.7962466063982);
+    3777          10 :   parameter_vac[BB_PO3].push_back(-0.2734304923675441);
+    3778          10 :   parameter_vac[BB_PO3].push_back(-1023.9448073303214);
+    3779          10 :   parameter_vac[BB_PO3].push_back(-28.78655166266909);
+    3780          10 :   parameter_vac[BB_PO3].push_back(426.4382937268249);
+    3781          10 :   parameter_vac[BB_PO3].push_back(-109.57771615730755);
+    3782          10 :   parameter_vac[BB_PO3].push_back(-10.244595559424265);
+    3783             : 
+    3784          10 :   parameter_vac[BB_PO2].push_back(960.8822037291127);
+    3785          10 :   parameter_vac[BB_PO2].push_back(-0.09312135742159174);
+    3786          10 :   parameter_vac[BB_PO2].push_back(-469.39643497461844);
+    3787          10 :   parameter_vac[BB_PO2].push_back(-9.779346709041985);
+    3788          10 :   parameter_vac[BB_PO2].push_back(162.1581550003227);
+    3789          10 :   parameter_vac[BB_PO2].push_back(-37.06686233305618);
+    3790          10 :   parameter_vac[BB_PO2].push_back(-4.695586672655664);
+    3791             : 
+    3792          10 :   parameter_vac[BB_DNA].push_back(3720.2522996838984);
+    3793          10 :   parameter_vac[BB_DNA].push_back(-5.4229642176938);
+    3794          10 :   parameter_vac[BB_DNA].push_back(-4800.897672711981);
+    3795          10 :   parameter_vac[BB_DNA].push_back(-597.2274673070993);
+    3796          10 :   parameter_vac[BB_DNA].push_back(4825.908840953665);
+    3797          10 :   parameter_vac[BB_DNA].push_back(-2451.397454446564);
+    3798          10 :   parameter_vac[BB_DNA].push_back(294.93071756645685);
+    3799             : 
+    3800          10 :   parameter_vac[BB_DNA_5].push_back(3843.234214262163);
+    3801          10 :   parameter_vac[BB_DNA_5].push_back(-6.423078416284452);
+    3802          10 :   parameter_vac[BB_DNA_5].push_back(-5112.1216386963115);
+    3803          10 :   parameter_vac[BB_DNA_5].push_back(-713.8373583426668);
+    3804          10 :   parameter_vac[BB_DNA_5].push_back(5547.545382516269);
+    3805          10 :   parameter_vac[BB_DNA_5].push_back(-2973.5659871174225);
+    3806          10 :   parameter_vac[BB_DNA_5].push_back(407.2789106630427);
+    3807             : 
+    3808          10 :   parameter_vac[BB_DNA_3].push_back(3843.234214262163);
+    3809          10 :   parameter_vac[BB_DNA_3].push_back(-6.268636561475645);
+    3810          10 :   parameter_vac[BB_DNA_3].push_back(-5103.192931218086);
+    3811          10 :   parameter_vac[BB_DNA_3].push_back(-693.8705734390547);
+    3812          10 :   parameter_vac[BB_DNA_3].push_back(5443.979645097035);
+    3813          10 :   parameter_vac[BB_DNA_3].push_back(-2871.4337477324893);
+    3814          10 :   parameter_vac[BB_DNA_3].push_back(377.3062915349831);
+    3815             : 
+    3816          10 :   parameter_vac[BB_RNA].push_back(4760.071443398374);
+    3817          10 :   parameter_vac[BB_RNA].push_back(-11.0990475402486);
+    3818          10 :   parameter_vac[BB_RNA].push_back(-6934.713566418421);
+    3819          10 :   parameter_vac[BB_RNA].push_back(-1256.5202524085096);
+    3820          10 :   parameter_vac[BB_RNA].push_back(9024.962587066922);
+    3821          10 :   parameter_vac[BB_RNA].push_back(-5386.842667932241);
+    3822          10 :   parameter_vac[BB_RNA].push_back(907.42947751372);
+    3823             : 
+    3824          10 :   parameter_vac[BB_RNA_5].push_back(4899.051406033406);
+    3825          10 :   parameter_vac[BB_RNA_5].push_back(-12.279240472628238);
+    3826          10 :   parameter_vac[BB_RNA_5].push_back(-7276.273570813667);
+    3827          10 :   parameter_vac[BB_RNA_5].push_back(-1400.9520839250868);
+    3828          10 :   parameter_vac[BB_RNA_5].push_back(9912.215823228895);
+    3829          10 :   parameter_vac[BB_RNA_5].push_back(-6079.2565270404075);
+    3830          10 :   parameter_vac[BB_RNA_5].push_back(1073.53428175472);
+    3831             : 
+    3832          10 :   parameter_vac[BB_RNA_3].push_back(4899.051406033406);
+    3833          10 :   parameter_vac[BB_RNA_3].push_back(-11.642804195148194);
+    3834          10 :   parameter_vac[BB_RNA_3].push_back(-7213.774619570996);
+    3835          10 :   parameter_vac[BB_RNA_3].push_back(-1317.4463949342964);
+    3836          10 :   parameter_vac[BB_RNA_3].push_back(9450.928929264686);
+    3837          10 :   parameter_vac[BB_RNA_3].push_back(-5643.856117200917);
+    3838          10 :   parameter_vac[BB_RNA_3].push_back(949.4698817407918);
+    3839             : 
+    3840          10 :   parameter_vac[BASE_A].push_back(4756.697028810353);
+    3841          10 :   parameter_vac[BASE_A].push_back(-12.158940746852812);
+    3842          10 :   parameter_vac[BASE_A].push_back(-7106.473423744205);
+    3843          10 :   parameter_vac[BASE_A].push_back(-1376.295184173137);
+    3844          10 :   parameter_vac[BASE_A].push_back(9747.132255557788);
+    3845          10 :   parameter_vac[BASE_A].push_back(-5900.026637038756);
+    3846          10 :   parameter_vac[BASE_A].push_back(1004.6226388342955);
+    3847             : 
+    3848          10 :   parameter_vac[BASE_C].push_back(3246.698975674651);
+    3849          10 :   parameter_vac[BASE_C].push_back(-6.125036521218687);
+    3850          10 :   parameter_vac[BASE_C].push_back(-4280.666521437201);
+    3851          10 :   parameter_vac[BASE_C].push_back(-684.0183580843932);
+    3852          10 :   parameter_vac[BASE_C].push_back(5077.062889522692);
+    3853          10 :   parameter_vac[BASE_C].push_back(-2870.3239317750963);
+    3854          10 :   parameter_vac[BASE_C].push_back(434.51551177863547);
+    3855             : 
+    3856          10 :   parameter_vac[BASE_G].push_back(5924.105658596052);
+    3857          10 :   parameter_vac[BASE_G].push_back(-23.097956587232552);
+    3858          10 :   parameter_vac[BASE_G].push_back(-10149.526301285418);
+    3859          10 :   parameter_vac[BASE_G].push_back(-2752.9166169522528);
+    3860          10 :   parameter_vac[BASE_G].push_back(18239.32985385683);
+    3861          10 :   parameter_vac[BASE_G].push_back(-12749.277858800957);
+    3862          10 :   parameter_vac[BASE_G].push_back(2715.354663787367);
+    3863             : 
+    3864          10 :   parameter_vac[BASE_T].push_back(4222.889713694404);
+    3865          10 :   parameter_vac[BASE_T].push_back(-12.15861456306705);
+    3866          10 :   parameter_vac[BASE_T].push_back(-6395.50289789404);
+    3867          10 :   parameter_vac[BASE_T].push_back(-1421.3942549301012);
+    3868          10 :   parameter_vac[BASE_T].push_back(9757.061008720135);
+    3869          10 :   parameter_vac[BASE_T].push_back(-6399.630933839126);
+    3870          10 :   parameter_vac[BASE_T].push_back(1258.9874225605438);
+    3871             : 
+    3872          10 :   parameter_vac[BASE_U].push_back(3247.251361465539);
+    3873          10 :   parameter_vac[BASE_U].push_back(-5.211020853261115);
+    3874          10 :   parameter_vac[BASE_U].push_back(-4125.165310360279);
+    3875          10 :   parameter_vac[BASE_U].push_back(-575.1860235473902);
+    3876          10 :   parameter_vac[BASE_U].push_back(4457.6562621371495);
+    3877          10 :   parameter_vac[BASE_U].push_back(-2368.7250146912766);
+    3878          10 :   parameter_vac[BASE_U].push_back(313.23997718445014);
+    3879             : 
+    3880       35262 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    3881       35252 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    3882       35252 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    3883       35252 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    3884       35252 :     if(Rname=="ALA") {
+    3885        1790 :       atoi[residue_atom[i]]=ALA;
+    3886       33462 :     } else if(Rname=="ARG") {
+    3887        2160 :       atoi[residue_atom[i]]=ARG;
+    3888       31302 :     } else if(Rname=="ASN") {
+    3889        1800 :       atoi[residue_atom[i]]=ASN;
+    3890       29502 :     } else if(Rname=="ASP") {
+    3891        1560 :       atoi[residue_atom[i]]=ASP;
+    3892       27942 :     } else if(Rname=="CYS") {
+    3893         120 :       atoi[residue_atom[i]]=CYS;
+    3894       27822 :     } else if(Rname=="CYX") {
+    3895           0 :       atoi[residue_atom[i]]=CYX;
+    3896       27822 :     } else if(Rname=="GLN") {
+    3897        2584 :       atoi[residue_atom[i]]=GLN;
+    3898       25238 :     } else if(Rname=="GLU") {
+    3899        1190 :       atoi[residue_atom[i]]=GLU;
+    3900       24048 :     } else if(Rname=="GLY") {
+    3901        1548 :       atoi[residue_atom[i]]=GLY;
+    3902       22500 :     } else if(Rname=="HIS") {
+    3903           0 :       atoi[residue_atom[i]]=HIS;
+    3904       22500 :     } else if(Rname=="HID") {
+    3905           0 :       atoi[residue_atom[i]]=HIS;
+    3906       22500 :     } else if(Rname=="HIE") {
+    3907         360 :       atoi[residue_atom[i]]=HIS;
+    3908       22140 :     } else if(Rname=="HIP") {
+    3909           0 :       atoi[residue_atom[i]]=HIP;
+    3910             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    3911       22140 :     } else if(Rname=="HSD") {
+    3912           0 :       atoi[residue_atom[i]]=HIS;
+    3913       22140 :     } else if(Rname=="HSE") {
+    3914           0 :       atoi[residue_atom[i]]=HIS;
+    3915       22140 :     } else if(Rname=="HSP") {
+    3916           0 :       atoi[residue_atom[i]]=HIP;
+    3917       22140 :     } else if(Rname=="ILE") {
+    3918        2160 :       atoi[residue_atom[i]]=ILE;
+    3919       19980 :     } else if(Rname=="LEU") {
+    3920        3800 :       atoi[residue_atom[i]]=LEU;
+    3921       16180 :     } else if(Rname=="LYS") {
+    3922        2600 :       atoi[residue_atom[i]]=LYS;
+    3923       13580 :     } else if(Rname=="MET") {
+    3924        1368 :       atoi[residue_atom[i]]=MET;
+    3925       12212 :     } else if(Rname=="PHE") {
+    3926        2520 :       atoi[residue_atom[i]]=PHE;
+    3927        9692 :     } else if(Rname=="PRO") {
+    3928        1870 :       atoi[residue_atom[i]]=PRO;
+    3929        7822 :     } else if(Rname=="SER") {
+    3930        1272 :       atoi[residue_atom[i]]=SER;
+    3931        6550 :     } else if(Rname=="THR") {
+    3932        1204 :       atoi[residue_atom[i]]=THR;
+    3933        5346 :     } else if(Rname=="TRP") {
+    3934           0 :       atoi[residue_atom[i]]=TRP;
+    3935        5346 :     } else if(Rname=="TYR") {
+    3936        1320 :       atoi[residue_atom[i]]=TYR;
+    3937        4026 :     } else if(Rname=="VAL") {
+    3938        2656 :       atoi[residue_atom[i]]=VAL;
+    3939             :     }
+    3940             :     // NUCLEIC ACIDS
+    3941             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    3942             :     // RNA - G
+    3943        1370 :     else if(Rname=="G") {
+    3944           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    3945           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    3946           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3947           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3948           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3949           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3950           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3951           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3952           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3953           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3954           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3955           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3956           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3957           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3958           0 :         atoi[residue_atom[i]]=BASE_G;
+    3959           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3960             :       // RNA - G3
+    3961        1370 :     } else if(Rname=="G3") {
+    3962           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3963           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3964           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3965           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3966           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3967           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3968           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3969           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3970           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3971           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3972           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3973           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3974           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3975           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3976           0 :         atoi[residue_atom[i]]=BASE_G;
+    3977           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3978             :       // RNA - G5
+    3979        1370 :     } else if(Rname=="G5") {
+    3980           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3981           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3982           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3983           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3984           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3985           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3986           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3987           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3988           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3989           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3990           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3991           0 :         atoi[residue_atom[i]]=BASE_G;
+    3992           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3993             :       // RNA - GT
+    3994        1370 :     } else if(Rname=="GT") {
+    3995           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    3996           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    3997           0 :         atoi [residue_atom[i]]=BB_PO3;
+    3998           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3999           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4000           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4001           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4002           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4003           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4004           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4005           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4006           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4007           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4008           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4009           0 :         atoi[residue_atom[i]]=BASE_G;
+    4010           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4011             :       // RNA - U
+    4012        1370 :     } else if(Rname=="U") {
+    4013        4218 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    4014        2166 :           Aname=="O1P" || Aname=="O2P"  ) {
+    4015         114 :         atoi [residue_atom[i]]=BB_PO2;
+    4016        3724 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4017        3116 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4018        2508 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4019        1938 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4020        1748 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4021        2280 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4022         608 :         atoi[residue_atom[i]]=BB_RNA;
+    4023        1292 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    4024         684 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    4025         532 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    4026         418 :         atoi[residue_atom[i]]=BASE_U;
+    4027           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4028             :       // RNA - U3
+    4029         230 :     } else if(Rname=="U3") {
+    4030         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4031         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4032           6 :         atoi [residue_atom[i]]=BB_PO2;
+    4033         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4034         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4035         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4036         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4037          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4038          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4039          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4040          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    4041          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    4042          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    4043          22 :         atoi[residue_atom[i]]=BASE_U;
+    4044           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4045             :       // RNA - U5
+    4046         168 :     } else if(Rname=="U5") {
+    4047         612 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4048         516 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4049         420 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4050         324 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4051         264 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4052         234 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4053         102 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4054         204 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    4055         108 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    4056          84 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    4057          66 :         atoi[residue_atom[i]]=BASE_U;
+    4058           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4059             :       // RNA - UT
+    4060           0 :     } else if(Rname=="UT") {
+    4061           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    4062           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    4063           0 :         atoi [residue_atom[i]]=BB_PO3;
+    4064           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4065           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4066           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4067           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4068           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4069           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4070           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4071           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    4072           0 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    4073           0 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    4074           0 :         atoi[residue_atom[i]]=BASE_U;
+    4075           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4076             :       // RNA - A
+    4077           0 :     } else if(Rname=="A") {
+    4078           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    4079           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    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=="O2'"  || Aname=="C2'"  ||
+    4083           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4084           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4085           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4086           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4087           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4088           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4089           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4090           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4091           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4092           0 :         atoi[residue_atom[i]]=BASE_A;
+    4093           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4094             :       // RNA - A3
+    4095           0 :     } else if(Rname=="A3") {
+    4096           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4097           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4098           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4099           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4100           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4101           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4102           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4103           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4104           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4105           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4106           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4107           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4108           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4109           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4110           0 :         atoi[residue_atom[i]]=BASE_A;
+    4111           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4112             :       // RNA - A5
+    4113           0 :     } else if(Rname=="A5") {
+    4114           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4115           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4116           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4117           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4118           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4119           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4120           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4121           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4122           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4123           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4124           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4125           0 :         atoi[residue_atom[i]]=BASE_A;
+    4126           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4127             :       // RNA - AT
+    4128           0 :     } else if(Rname=="AT") {
+    4129           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    4130           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    4131           0 :         atoi [residue_atom[i]]=BB_PO3;
+    4132           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4133           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4134           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4135           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4136           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4137           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4138           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4139           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4140           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4141           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4142           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4143           0 :         atoi[residue_atom[i]]=BASE_A;
+    4144           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4145             :       // RNA - C
+    4146           0 :     } else if(Rname=="C") {
+    4147           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    4148           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    4149           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4150           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4151           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4152           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4153           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4154           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4155           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4156           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4157           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4158           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4159           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4160           0 :         atoi[residue_atom[i]]=BASE_C;
+    4161           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4162             :       // RNA - C3
+    4163           0 :     } else if(Rname=="C3") {
+    4164           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4165           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4166           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4167           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4168           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4169           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4170           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4171           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4172           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4173           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4174           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4175           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4176           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4177           0 :         atoi[residue_atom[i]]=BASE_C;
+    4178           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4179             :       // RNA - C5
+    4180           0 :     } else if(Rname=="C5") {
+    4181           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4182           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4183           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4184           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4185           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4186           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4187           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4188           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4189           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4190           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4191           0 :         atoi[residue_atom[i]]=BASE_C;
+    4192           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4193             :       // RNA - CT
+    4194           0 :     } else if(Rname=="CT") {
+    4195           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    4196           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    4197           0 :         atoi [residue_atom[i]]=BB_PO3;
+    4198           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4199           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4200           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4201           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4202           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4203           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4204           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4205           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4206           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4207           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4208           0 :         atoi[residue_atom[i]]=BASE_C;
+    4209           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4210             :       // DNA - G
+    4211           0 :     } else if(Rname=="DG") {
+    4212           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    4213           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    4214           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4215           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4216           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4217           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4218           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4219           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4220           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4221           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4222           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4223           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4224           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4225           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4226           0 :         atoi[residue_atom[i]]=BASE_G;
+    4227           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4228             :       // DNA - G3
+    4229           0 :     } else if(Rname=="DG3") {
+    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=="N2" || Aname=="N3" ||
+    4241           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4242           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4243           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4244           0 :         atoi[residue_atom[i]]=BASE_G;
+    4245           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4246             :       // DNA - G5
+    4247           0 :     } else if(Rname=="DG5") {
+    4248           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4249           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4250           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4251           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4252           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4253             :           Aname=="H5T" ) {
+    4254           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4255           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4256           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4257           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4258           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4259           0 :         atoi[residue_atom[i]]=BASE_G;
+    4260           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4261             :       // DNA - GT
+    4262           0 :     } else if(Rname=="DGT") {
+    4263           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    4264           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    4265           0 :         atoi [residue_atom[i]]=BB_PO3;
+    4266           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4267           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4268           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4269           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4270           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4271           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4272           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4273           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4274           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4275           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4276           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4277           0 :         atoi[residue_atom[i]]=BASE_G;
+    4278           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4279             :       // DNA - T
+    4280           0 :     } else if(Rname=="DT") {
+    4281           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    4282           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    4283           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4284           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4285           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4286           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4287           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4288           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4289           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4290           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4291           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4292           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4293           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4294           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4295           0 :         atoi[residue_atom[i]]=BASE_T;
+    4296           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4297             :       // DNA - T3
+    4298           0 :     } else if(Rname=="DT3") {
+    4299           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4300           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4301           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4302           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4303           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4304           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4305           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4306           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4307             :                 Aname=="H3T" ) {
+    4308           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4309           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4310           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4311           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4312           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4313           0 :         atoi[residue_atom[i]]=BASE_T;
+    4314           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4315             :       // DNA - T5
+    4316           0 :     } else if(Rname=="DT5") {
+    4317           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4318           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4319           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4320           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4321           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4322             :           Aname=="H5T" ) {
+    4323           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4324           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4325           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4326           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4327           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4328           0 :         atoi[residue_atom[i]]=BASE_T;
+    4329           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4330             :       // DNA - TT
+    4331           0 :     } else if(Rname=="DTT") {
+    4332           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    4333           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    4334           0 :         atoi [residue_atom[i]]=BB_PO3;
+    4335           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4336           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4337           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4338           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4339           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4340           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4341           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4342           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4343           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4344           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4345           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4346           0 :         atoi[residue_atom[i]]=BASE_T;
+    4347           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4348             :       // DNA - A
+    4349           0 :     } else if(Rname=="DA") {
+    4350           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    4351           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    4352           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4353           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4354           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4355           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4356           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4357           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4358           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4359           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4360           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4361           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4362           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4363           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4364           0 :         atoi[residue_atom[i]]=BASE_A;
+    4365           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4366             :       // DNA - A3
+    4367           0 :     } else if(Rname=="DA3") {
+    4368           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4369           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4370           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4371           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4372           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4373           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4374           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4375           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4376             :                 Aname=="H3T" ) {
+    4377           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4378           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4379           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4380           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4381           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4382           0 :         atoi[residue_atom[i]]=BASE_A;
+    4383           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4384             :       // DNA - A5
+    4385           0 :     } else if(Rname=="DA5") {
+    4386           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4387           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4388           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4389           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4390           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4391             :           Aname=="H5T" ) {
+    4392           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4393           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4394           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4395           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4396           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4397           0 :         atoi[residue_atom[i]]=BASE_A;
+    4398           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4399             :       // DNA - AT
+    4400           0 :     } else if(Rname=="DAT") {
+    4401           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    4402           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    4403           0 :         atoi [residue_atom[i]]=BB_PO3;
+    4404           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4405           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4406           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4407           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4408           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4409           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4410           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4411           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4412           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4413           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4414           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4415           0 :         atoi[residue_atom[i]]=BASE_A;
+    4416           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4417             :       // DNA - C
+    4418           0 :     } else if(Rname=="DC") {
+    4419           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    4420           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    4421           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4422           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4423           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4424           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4425           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4426           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4427           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4428           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4429           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4430           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4431           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4432           0 :         atoi[residue_atom[i]]=BASE_C;
+    4433           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4434             :       // DNA - C3
+    4435           0 :     } else if(Rname=="DC3") {
+    4436           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4437           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4438           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4439           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4440           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4441           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4442           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4443           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4444             :                 Aname=="H3T" ) {
+    4445           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4446           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4447           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4448           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4449           0 :         atoi[residue_atom[i]]=BASE_C;
+    4450           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4451             :       // DNA - C5
+    4452           0 :     } else if(Rname=="DC5") {
+    4453           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4454           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4455           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4456           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4457           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4458             :           Aname=="H5T" ) {
+    4459           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4460           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4461           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4462           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4463           0 :         atoi[residue_atom[i]]=BASE_C;
+    4464           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4465             :       // DNA - CT
+    4466           0 :     } else if(Rname=="DCT") {
+    4467           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    4468           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    4469           0 :         atoi [residue_atom[i]]=BB_PO3;
+    4470           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4471           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4472           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4473           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4474           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4475           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4476           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4477           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4478           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4479           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4480           0 :         atoi[residue_atom[i]]=BASE_C;
+    4481           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4482           0 :     } else error("Residue not known: "+Rname);
+    4483             :   }
+    4484          10 : }
+    4485             : 
+    4486           6 : 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)
+    4487             : {
+    4488           6 :   parameter_solv_H[TRP].push_back(60737.60249988011);
+    4489           6 :   parameter_solv_H[TRP].push_back(-77.77344118516487);
+    4490           6 :   parameter_solv_H[TRP].push_back(-205962.80436572764);
+    4491           6 :   parameter_solv_H[TRP].push_back(-62014.18523271781);
+    4492           6 :   parameter_solv_H[TRP].push_back(680712.0512548896);
+    4493           6 :   parameter_solv_H[TRP].push_back(-681337.967312983);
+    4494           6 :   parameter_solv_H[TRP].push_back(211474.00338118695);
+    4495             : 
+    4496           6 :   parameter_solv_H[TYR].push_back(46250.803599880084);
+    4497           6 :   parameter_solv_H[TYR].push_back(-45.827646837514614);
+    4498           6 :   parameter_solv_H[TYR].push_back(-143872.94597686914);
+    4499           6 :   parameter_solv_H[TYR].push_back(-39049.51580628132);
+    4500           6 :   parameter_solv_H[TYR].push_back(441321.31246635393);
+    4501           6 :   parameter_solv_H[TYR].push_back(-434477.6826175059);
+    4502           6 :   parameter_solv_H[TYR].push_back(133179.21673104732);
+    4503             : 
+    4504           6 :   parameter_solv_H[PHE].push_back(42407.164900118914);
+    4505           6 :   parameter_solv_H[PHE].push_back(-159.20054549009086);
+    4506           6 :   parameter_solv_H[PHE].push_back(-123847.83591352346);
+    4507           6 :   parameter_solv_H[PHE].push_back(-41797.78884558073);
+    4508           6 :   parameter_solv_H[PHE].push_back(380283.87543872406);
+    4509           6 :   parameter_solv_H[PHE].push_back(-361432.81356389285);
+    4510           6 :   parameter_solv_H[PHE].push_back(107750.69385054041);
+    4511             : 
+    4512           6 :   parameter_solv_H[HIP].push_back(24473.473600119047);
+    4513           6 :   parameter_solv_H[HIP].push_back(-111.6412807124612);
+    4514           6 :   parameter_solv_H[HIP].push_back(-65826.17293437096);
+    4515           6 :   parameter_solv_H[HIP].push_back(-23305.902022201855);
+    4516           6 :   parameter_solv_H[HIP].push_back(194795.09953510275);
+    4517           6 :   parameter_solv_H[HIP].push_back(-180454.47859494278);
+    4518           6 :   parameter_solv_H[HIP].push_back(52699.36922660704);
+    4519             : 
+    4520           6 :   parameter_solv_H[ARG].push_back(34106.70239988039);
+    4521           6 :   parameter_solv_H[ARG].push_back(152.74468231268114);
+    4522           6 :   parameter_solv_H[ARG].push_back(-117086.46040369231);
+    4523           6 :   parameter_solv_H[ARG].push_back(-19664.37512726012);
+    4524           6 :   parameter_solv_H[ARG].push_back(364454.3721646173);
+    4525           6 :   parameter_solv_H[ARG].push_back(-382076.05102190404);
+    4526           6 :   parameter_solv_H[ARG].push_back(122775.83306003918);
+    4527             : 
+    4528           6 :   parameter_solv_H[LYS].push_back(32292.09000011877);
+    4529           6 :   parameter_solv_H[LYS].push_back(-111.97888350941923);
+    4530           6 :   parameter_solv_H[LYS].push_back(-91953.05212591762);
+    4531           6 :   parameter_solv_H[LYS].push_back(-30691.03615444628);
+    4532           6 :   parameter_solv_H[LYS].push_back(282092.82233263896);
+    4533           6 :   parameter_solv_H[LYS].push_back(-269503.6095978623);
+    4534           6 :   parameter_solv_H[LYS].push_back(80777.92760273012);
+    4535             : 
+    4536           6 :   parameter_solv_H[CYS].push_back(11352.902500119093);
+    4537           6 :   parameter_solv_H[CYS].push_back(-45.52255488723637);
+    4538           6 :   parameter_solv_H[CYS].push_back(-20925.086525675117);
+    4539           6 :   parameter_solv_H[CYS].push_back(-5662.681335644281);
+    4540           6 :   parameter_solv_H[CYS].push_back(38559.09602816144);
+    4541           6 :   parameter_solv_H[CYS].push_back(-27885.22747486708);
+    4542           6 :   parameter_solv_H[CYS].push_back(6280.148346561226);
+    4543             : 
+    4544           6 :   parameter_solv_H[CYX].push_back(10281.960000119348);
+    4545           6 :   parameter_solv_H[CYX].push_back(-42.315998754511);
+    4546           6 :   parameter_solv_H[CYX].push_back(-19328.174487327480);
+    4547           6 :   parameter_solv_H[CYX].push_back(-5523.191775626829);
+    4548           6 :   parameter_solv_H[CYX].push_back(38185.463172673335);
+    4549           6 :   parameter_solv_H[CYX].push_back(-28940.174693042034);
+    4550           6 :   parameter_solv_H[CYX].push_back(6925.390014187676);
+    4551             : 
+    4552           6 :   parameter_solv_H[ASP].push_back(13511.73760011933);
+    4553           6 :   parameter_solv_H[ASP].push_back(-59.92934247210642);
+    4554           6 :   parameter_solv_H[ASP].push_back(-25849.867077822244);
+    4555           6 :   parameter_solv_H[ASP].push_back(-7541.679510407563);
+    4556           6 :   parameter_solv_H[ASP].push_back(50760.93853987092);
+    4557           6 :   parameter_solv_H[ASP].push_back(-37677.89102528413);
+    4558           6 :   parameter_solv_H[ASP].push_back(8745.710458140105);
+    4559             : 
+    4560           6 :   parameter_solv_H[GLU].push_back(20443.280400119456);
+    4561           6 :   parameter_solv_H[GLU].push_back(-113.77513581661388);
+    4562           6 :   parameter_solv_H[GLU].push_back(-45587.79863958479);
+    4563           6 :   parameter_solv_H[GLU].push_back(-16187.534798976243);
+    4564           6 :   parameter_solv_H[GLU].push_back(112609.61802147207);
+    4565           6 :   parameter_solv_H[GLU].push_back(-93362.01894077536);
+    4566           6 :   parameter_solv_H[GLU].push_back(24519.546829431332);
+    4567             : 
+    4568           6 :   parameter_solv_H[ILE].push_back(27858.948100119596);
+    4569           6 :   parameter_solv_H[ILE].push_back(-159.27394962770595);
+    4570           6 :   parameter_solv_H[ILE].push_back(-61571.43025249802);
+    4571           6 :   parameter_solv_H[ILE].push_back(-21324.89659912433);
+    4572           6 :   parameter_solv_H[ILE].push_back(144070.7880009225);
+    4573           6 :   parameter_solv_H[ILE].push_back(-115021.84534734003);
+    4574           6 :   parameter_solv_H[ILE].push_back(28939.093300284097);
+    4575             : 
+    4576           6 :   parameter_solv_H[LEU].push_back(27858.948100119596);
+    4577           6 :   parameter_solv_H[LEU].push_back(-165.61872365361);
+    4578           6 :   parameter_solv_H[LEU].push_back(-62564.5706162518);
+    4579           6 :   parameter_solv_H[LEU].push_back(-22465.325666767214);
+    4580           6 :   parameter_solv_H[LEU].push_back(151616.7844050042);
+    4581           6 :   parameter_solv_H[LEU].push_back(-122905.60389771541);
+    4582           6 :   parameter_solv_H[LEU].push_back(31436.66201442061);
+    4583             : 
+    4584           6 :   parameter_solv_H[MET].push_back(25609.60090011981);
+    4585           6 :   parameter_solv_H[MET].push_back(-135.38816369794569);
+    4586           6 :   parameter_solv_H[MET].push_back(-67771.01548433342);
+    4587           6 :   parameter_solv_H[MET].push_back(-25228.91756660071);
+    4588           6 :   parameter_solv_H[MET].push_back(199649.92084565928);
+    4589           6 :   parameter_solv_H[MET].push_back(-182251.9246506795);
+    4590           6 :   parameter_solv_H[MET].push_back(52502.876819125115);
+    4591             : 
+    4592           6 :   parameter_solv_H[ASN].push_back(14376.010000119095);
+    4593           6 :   parameter_solv_H[ASN].push_back(-67.65587848183215);
+    4594           6 :   parameter_solv_H[ASN].push_back(-28302.877059425664);
+    4595           6 :   parameter_solv_H[ASN].push_back(-8577.444107282141);
+    4596           6 :   parameter_solv_H[ASN].push_back(57532.88704197217);
+    4597           6 :   parameter_solv_H[ASN].push_back(-43261.79974462857);
+    4598           6 :   parameter_solv_H[ASN].push_back(10186.450874679671);
+    4599             : 
+    4600           6 :   parameter_solv_H[PRO].push_back(16866.21690011944);
+    4601           6 :   parameter_solv_H[PRO].push_back(-70.84312112734995);
+    4602           6 :   parameter_solv_H[PRO].push_back(-31465.8423531932);
+    4603           6 :   parameter_solv_H[PRO].push_back(-8653.362744540535);
+    4604           6 :   parameter_solv_H[PRO].push_back(58032.27079924916);
+    4605           6 :   parameter_solv_H[PRO].push_back(-41521.001733021694);
+    4606           6 :   parameter_solv_H[PRO].push_back(9184.527523759205);
+    4607             : 
+    4608           6 :   parameter_solv_H[GLN].push_back(21503.289600119);
+    4609           6 :   parameter_solv_H[GLN].push_back(-121.3012777474678);
+    4610           6 :   parameter_solv_H[GLN].push_back(-50468.58503443957);
+    4611           6 :   parameter_solv_H[GLN].push_back(-18462.47495329696);
+    4612           6 :   parameter_solv_H[GLN].push_back(132718.42007501892);
+    4613           6 :   parameter_solv_H[GLN].push_back(-113787.20224345029);
+    4614           6 :   parameter_solv_H[GLN].push_back(30920.340813688686);
+    4615             : 
+    4616           6 :   parameter_solv_H[SER].push_back(9181.47240011935);
+    4617           6 :   parameter_solv_H[SER].push_back(-28.775273124392083);
+    4618           6 :   parameter_solv_H[SER].push_back(-15205.54229808512);
+    4619           6 :   parameter_solv_H[SER].push_back(-3377.785599913673);
+    4620           6 :   parameter_solv_H[SER].push_back(23345.562090489493);
+    4621           6 :   parameter_solv_H[SER].push_back(-15312.699787471944);
+    4622           6 :   parameter_solv_H[SER].push_back(3013.844610647712);
+    4623             : 
+    4624           6 :   parameter_solv_H[THR].push_back(15020.953600119403);
+    4625           6 :   parameter_solv_H[THR].push_back(-61.909951810375105);
+    4626           6 :   parameter_solv_H[THR].push_back(-27814.538986050964);
+    4627           6 :   parameter_solv_H[THR].push_back(-7532.222992514079);
+    4628           6 :   parameter_solv_H[THR].push_back(50586.29804970814);
+    4629           6 :   parameter_solv_H[THR].push_back(-35943.85986777198);
+    4630           6 :   parameter_solv_H[THR].push_back(7880.091610023207);
+    4631             : 
+    4632           6 :   parameter_solv_H[VAL].push_back(19647.628900119355);
+    4633           6 :   parameter_solv_H[VAL].push_back(-89.04968136833762);
+    4634           6 :   parameter_solv_H[VAL].push_back(-38050.10118919102);
+    4635           6 :   parameter_solv_H[VAL].push_back(-10921.421066774372);
+    4636           6 :   parameter_solv_H[VAL].push_back(72774.31277743122);
+    4637           6 :   parameter_solv_H[VAL].push_back(-52689.05168504517);
+    4638           6 :   parameter_solv_H[VAL].push_back(11806.48989635518);
+    4639             : 
+    4640           6 :   parameter_solv_H[ALA].push_back(7515.156100119273);
+    4641           6 :   parameter_solv_H[ALA].push_back(-20.226317591188526);
+    4642           6 :   parameter_solv_H[ALA].push_back(-11761.841775007797);
+    4643           6 :   parameter_solv_H[ALA].push_back(-2341.4903622033885);
+    4644           6 :   parameter_solv_H[ALA].push_back(16545.381259883452);
+    4645           6 :   parameter_solv_H[ALA].push_back(-10397.171546969075);
+    4646           6 :   parameter_solv_H[ALA].push_back(1921.5253045340198);
+    4647             : 
+    4648           6 :   parameter_solv_H[GLY].push_back(3594.002500119159);
+    4649           6 :   parameter_solv_H[GLY].push_back(-6.910832388009796);
+    4650           6 :   parameter_solv_H[GLY].push_back(-4937.3542895091905);
+    4651           6 :   parameter_solv_H[GLY].push_back(-785.4545979203357);
+    4652           6 :   parameter_solv_H[GLY].push_back(5852.853693316741);
+    4653           6 :   parameter_solv_H[GLY].push_back(-3391.2920205126734);
+    4654           6 :   parameter_solv_H[GLY].push_back(552.3278183161507);
+    4655             : 
+    4656           6 :   parameter_solv_H[HIS].push_back(22888.664100119073);
+    4657           6 :   parameter_solv_H[HIS].push_back(-133.86281863999585);
+    4658           6 :   parameter_solv_H[HIS].push_back(-57533.51412287858);
+    4659           6 :   parameter_solv_H[HIS].push_back(-21767.300111408193);
+    4660           6 :   parameter_solv_H[HIS].push_back(161255.15347073504);
+    4661           6 :   parameter_solv_H[HIS].push_back(-142176.65100718598);
+    4662           6 :   parameter_solv_H[HIS].push_back(39642.61507384587);
+    4663             : 
+    4664           6 :   parameter_mix_H[TRP].push_back(2974.6515001192306);
+    4665           6 :   parameter_mix_H[TRP].push_back(-18.361939022074825);
+    4666           6 :   parameter_mix_H[TRP].push_back(-7284.637435770752);
+    4667           6 :   parameter_mix_H[TRP].push_back(-2945.7969900381895);
+    4668           6 :   parameter_mix_H[TRP].push_back(21235.01878657283);
+    4669           6 :   parameter_mix_H[TRP].push_back(-18909.7406035548);
+    4670           6 :   parameter_mix_H[TRP].push_back(5324.324204245179);
+    4671             : 
+    4672           6 :   parameter_mix_H[TYR].push_back(2029.7362801192114);
+    4673           6 :   parameter_mix_H[TYR].push_back(-6.983186065527884);
+    4674           6 :   parameter_mix_H[TYR].push_back(-5041.996113037476);
+    4675           6 :   parameter_mix_H[TYR].push_back(-1744.5213085724158);
+    4676           6 :   parameter_mix_H[TYR].push_back(15329.420227814338);
+    4677           6 :   parameter_mix_H[TYR].push_back(-14648.322529889958);
+    4678           6 :   parameter_mix_H[TYR].push_back(4405.608657083287);
+    4679             : 
+    4680           6 :   parameter_mix_H[PHE].push_back(1704.6885401192117);
+    4681           6 :   parameter_mix_H[PHE].push_back(-10.077274979133408);
+    4682           6 :   parameter_mix_H[PHE].push_back(-3769.440088334303);
+    4683           6 :   parameter_mix_H[PHE].push_back(-1574.6255694551546);
+    4684           6 :   parameter_mix_H[PHE].push_back(10996.32497868798);
+    4685           6 :   parameter_mix_H[PHE].push_back(-9840.68281283696);
+    4686           6 :   parameter_mix_H[PHE].push_back(2792.098605716682);
+    4687             : 
+    4688           6 :   parameter_mix_H[HIP].push_back(1376.0462401192394);
+    4689           6 :   parameter_mix_H[HIP].push_back(-8.576320475413144);
+    4690           6 :   parameter_mix_H[HIP].push_back(-2796.8327726392167);
+    4691           6 :   parameter_mix_H[HIP].push_back(-1165.0473128576);
+    4692           6 :   parameter_mix_H[HIP].push_back(7495.063650365717);
+    4693           6 :   parameter_mix_H[HIP].push_back(-6331.20422098132);
+    4694           6 :   parameter_mix_H[HIP].push_back(1692.637366093312);
+    4695             : 
+    4696           6 :   parameter_mix_H[ARG].push_back(1280.940480119178);
+    4697           6 :   parameter_mix_H[ARG].push_back(-7.411214928783748);
+    4698           6 :   parameter_mix_H[ARG].push_back(-3747.6200569785033);
+    4699           6 :   parameter_mix_H[ARG].push_back(-1766.5282176004569);
+    4700           6 :   parameter_mix_H[ARG].push_back(14307.817638456267);
+    4701           6 :   parameter_mix_H[ARG].push_back(-14297.104122885643);
+    4702           6 :   parameter_mix_H[ARG].push_back(4450.526244207772);
+    4703             : 
+    4704           6 :   parameter_mix_H[LYS].push_back(570.7272001192143);
+    4705           6 :   parameter_mix_H[LYS].push_back(-5.371742288956095);
+    4706           6 :   parameter_mix_H[LYS].push_back(-1255.9868267793006);
+    4707           6 :   parameter_mix_H[LYS].push_back(-748.3071074443138);
+    4708           6 :   parameter_mix_H[LYS].push_back(4534.824932304509);
+    4709           6 :   parameter_mix_H[LYS].push_back(-4125.307867230812);
+    4710           6 :   parameter_mix_H[LYS].push_back(1178.781491068295);
+    4711             : 
+    4712           6 :   parameter_mix_H[CYS].push_back(410.21750011921864);
+    4713           6 :   parameter_mix_H[CYS].push_back(-0.7655651758449595);
+    4714           6 :   parameter_mix_H[CYS].push_back(-523.8897033718782);
+    4715           6 :   parameter_mix_H[CYS].push_back(-89.88478273744425);
+    4716           6 :   parameter_mix_H[CYS].push_back(655.3313542467919);
+    4717           6 :   parameter_mix_H[CYS].push_back(-407.87897719750896);
+    4718           6 :   parameter_mix_H[CYS].push_back(76.50541508448237);
+    4719             : 
+    4720           6 :   parameter_mix_H[CYX].push_back(466.237200119199);
+    4721           6 :   parameter_mix_H[CYX].push_back(-1.302082362010);
+    4722           6 :   parameter_mix_H[CYX].push_back(-667.565738985901);
+    4723           6 :   parameter_mix_H[CYX].push_back(-159.506437978088);
+    4724           6 :   parameter_mix_H[CYX].push_back(1085.648159448292);
+    4725           6 :   parameter_mix_H[CYX].push_back(-767.622943338598);
+    4726           6 :   parameter_mix_H[CYX].push_back(170.157274620163);
+    4727             : 
+    4728           6 :   parameter_mix_H[ASP].push_back(893.6531201192147);
+    4729           6 :   parameter_mix_H[ASP].push_back(-3.0756255172248874);
+    4730           6 :   parameter_mix_H[ASP].push_back(-1453.1760425275006);
+    4731           6 :   parameter_mix_H[ASP].push_back(-365.0424824614137);
+    4732           6 :   parameter_mix_H[ASP].push_back(2443.570600976796);
+    4733           6 :   parameter_mix_H[ASP].push_back(-1679.8996339740277);
+    4734           6 :   parameter_mix_H[ASP].push_back(352.33054461512455);
+    4735             : 
+    4736           6 :   parameter_mix_H[GLU].push_back(1075.4955601191884);
+    4737           6 :   parameter_mix_H[GLU].push_back(-6.917429973203965);
+    4738           6 :   parameter_mix_H[GLU].push_back(-2262.861870389347);
+    4739           6 :   parameter_mix_H[GLU].push_back(-909.8078514527992);
+    4740           6 :   parameter_mix_H[GLU].push_back(5841.923857549836);
+    4741           6 :   parameter_mix_H[GLU].push_back(-4784.620969556751);
+    4742           6 :   parameter_mix_H[GLU].push_back(1230.873134652953);
+    4743             : 
+    4744           6 :   parameter_mix_H[ILE].push_back(466.0127201192081);
+    4745           6 :   parameter_mix_H[ILE].push_back(-0.9323443258150218);
+    4746           6 :   parameter_mix_H[ILE].push_back(-576.7178005955719);
+    4747           6 :   parameter_mix_H[ILE].push_back(-103.03003361062478);
+    4748           6 :   parameter_mix_H[ILE].push_back(706.4269951176641);
+    4749           6 :   parameter_mix_H[ILE].push_back(-420.4412859632717);
+    4750           6 :   parameter_mix_H[ILE].push_back(71.53175726608731);
+    4751             : 
+    4752           6 :   parameter_mix_H[LEU].push_back(466.0127201192081);
+    4753           6 :   parameter_mix_H[LEU].push_back(-1.9793605752606065);
+    4754           6 :   parameter_mix_H[LEU].push_back(-718.3988478701591);
+    4755           6 :   parameter_mix_H[LEU].push_back(-227.36409339012113);
+    4756           6 :   parameter_mix_H[LEU].push_back(1389.2058254917304);
+    4757           6 :   parameter_mix_H[LEU].push_back(-990.0033118748643);
+    4758           6 :   parameter_mix_H[LEU].push_back(213.15736815883042);
+    4759             : 
+    4760           6 :   parameter_mix_H[MET].push_back(562.9855401192196);
+    4761           6 :   parameter_mix_H[MET].push_back(-3.7994094933771643);
+    4762           6 :   parameter_mix_H[MET].push_back(-1139.6331862451661);
+    4763           6 :   parameter_mix_H[MET].push_back(-516.6313269725724);
+    4764           6 :   parameter_mix_H[MET].push_back(3268.957245190869);
+    4765           6 :   parameter_mix_H[MET].push_back(-2809.178864807947);
+    4766           6 :   parameter_mix_H[MET].push_back(761.4832732100416);
+    4767             : 
+    4768           6 :   parameter_mix_H[ASN].push_back(828.7488001191887);
+    4769           6 :   parameter_mix_H[ASN].push_back(-2.1275493073799625);
+    4770           6 :   parameter_mix_H[ASN].push_back(-1222.248291388804);
+    4771           6 :   parameter_mix_H[ASN].push_back(-238.94210659613537);
+    4772           6 :   parameter_mix_H[ASN].push_back(1660.8322402171973);
+    4773           6 :   parameter_mix_H[ASN].push_back(-1008.7934996077323);
+    4774           6 :   parameter_mix_H[ASN].push_back(173.6082238625797);
+    4775             : 
+    4776           6 :   parameter_mix_H[PRO].push_back(578.4409801192146);
+    4777           6 :   parameter_mix_H[PRO].push_back(-0.5379505780909722);
+    4778           6 :   parameter_mix_H[PRO].push_back(-648.146493857212);
+    4779           6 :   parameter_mix_H[PRO].push_back(-56.67223895342921);
+    4780           6 :   parameter_mix_H[PRO].push_back(509.88860586987437);
+    4781           6 :   parameter_mix_H[PRO].push_back(-214.57871784725265);
+    4782           6 :   parameter_mix_H[PRO].push_back(11.99659463759968);
+    4783             : 
+    4784           6 :   parameter_mix_H[GLN].push_back(989.2334401191976);
+    4785           6 :   parameter_mix_H[GLN].push_back(-6.307760694331967);
+    4786           6 :   parameter_mix_H[GLN].push_back(-1971.7067150503622);
+    4787           6 :   parameter_mix_H[GLN].push_back(-791.333088386235);
+    4788           6 :   parameter_mix_H[GLN].push_back(4900.009768434847);
+    4789           6 :   parameter_mix_H[GLN].push_back(-3909.7740976374153);
+    4790           6 :   parameter_mix_H[GLN].push_back(975.4952613244343);
+    4791             : 
+    4792           6 :   parameter_mix_H[SER].push_back(426.39900011920196);
+    4793           6 :   parameter_mix_H[SER].push_back(-0.42304498358319664);
+    4794           6 :   parameter_mix_H[SER].push_back(-484.2066027682147);
+    4795           6 :   parameter_mix_H[SER].push_back(-45.38968988754228);
+    4796           6 :   parameter_mix_H[SER].push_back(401.3420977115044);
+    4797           6 :   parameter_mix_H[SER].push_back(-178.0861461692512);
+    4798           6 :   parameter_mix_H[SER].push_back(13.540349238730284);
+    4799             : 
+    4800           6 :   parameter_mix_H[THR].push_back(525.0470401191992);
+    4801           6 :   parameter_mix_H[THR].push_back(-0.7419102811534484);
+    4802           6 :   parameter_mix_H[THR].push_back(-652.7134808154495);
+    4803           6 :   parameter_mix_H[THR].push_back(-80.39481224407903);
+    4804           6 :   parameter_mix_H[THR].push_back(641.5487902728123);
+    4805           6 :   parameter_mix_H[THR].push_back(-320.4227667104819);
+    4806           6 :   parameter_mix_H[THR].push_back(36.03558531183942);
+    4807             : 
+    4808           6 :   parameter_mix_H[VAL].push_back(414.6228601192123);
+    4809           6 :   parameter_mix_H[VAL].push_back(-0.35889335250521337);
+    4810           6 :   parameter_mix_H[VAL].push_back(-453.11631644097474);
+    4811           6 :   parameter_mix_H[VAL].push_back(-36.402101097644284);
+    4812           6 :   parameter_mix_H[VAL].push_back(336.24049431626804);
+    4813           6 :   parameter_mix_H[VAL].push_back(-127.42235327515239);
+    4814           6 :   parameter_mix_H[VAL].push_back(0.8013280923923705);
+    4815             : 
+    4816           6 :   parameter_mix_H[ALA].push_back(285.21010011920816);
+    4817           6 :   parameter_mix_H[ALA].push_back(-0.1573012439142169);
+    4818           6 :   parameter_mix_H[ALA].push_back(-282.8945838800694);
+    4819           6 :   parameter_mix_H[ALA].push_back(-16.32030056827785);
+    4820           6 :   parameter_mix_H[ALA].push_back(178.065895049598);
+    4821           6 :   parameter_mix_H[ALA].push_back(-60.27423229179658);
+    4822           6 :   parameter_mix_H[ALA].push_back(-1.4695219304131588);
+    4823             : 
+    4824           6 :   parameter_mix_H[GLY].push_back(207.18720011920414);
+    4825           6 :   parameter_mix_H[GLY].push_back(-0.1036587134183235);
+    4826           6 :   parameter_mix_H[GLY].push_back(-185.70794948240638);
+    4827           6 :   parameter_mix_H[GLY].push_back(-11.008101039836257);
+    4828           6 :   parameter_mix_H[GLY].push_back(115.30600405624061);
+    4829           6 :   parameter_mix_H[GLY].push_back(-42.46629718037158);
+    4830           6 :   parameter_mix_H[GLY].push_back(0.9238928987070913);
+    4831             : 
+    4832           6 :   parameter_mix_H[HIS].push_back(1443.9117601192354);
+    4833           6 :   parameter_mix_H[HIS].push_back(-7.478618745973115);
+    4834           6 :   parameter_mix_H[HIS].push_back(-2715.0835155803215);
+    4835           6 :   parameter_mix_H[HIS].push_back(-918.5243015382779);
+    4836           6 :   parameter_mix_H[HIS].push_back(5821.6258431396);
+    4837           6 :   parameter_mix_H[HIS].push_back(-4415.32722209556);
+    4838           6 :   parameter_mix_H[HIS].push_back(1044.7044029209756);
+    4839             : 
+    4840           6 :   parameter_vac_H[TRP].push_back(36.42122511920832);
+    4841           6 :   parameter_vac_H[TRP].push_back(-0.36925500341767903);
+    4842           6 :   parameter_vac_H[TRP].push_back(-51.34228792835503);
+    4843           6 :   parameter_vac_H[TRP].push_back(-34.10021080004831);
+    4844           6 :   parameter_vac_H[TRP].push_back(132.647034983933);
+    4845           6 :   parameter_vac_H[TRP].push_back(-82.89152328934257);
+    4846           6 :   parameter_vac_H[TRP].push_back(13.029994092013231);
+    4847             : 
+    4848           6 :   parameter_vac_H[TYR].push_back(22.268961119209557);
+    4849           6 :   parameter_vac_H[TYR].push_back(-0.1995573892347673);
+    4850           6 :   parameter_vac_H[TYR].push_back(-36.54202179838511);
+    4851           6 :   parameter_vac_H[TYR].push_back(-23.820801043096694);
+    4852           6 :   parameter_vac_H[TYR].push_back(127.46799692275353);
+    4853           6 :   parameter_vac_H[TYR].push_back(-107.63783234245744);
+    4854           6 :   parameter_vac_H[TYR].push_back(28.180858902960775);
+    4855             : 
+    4856           6 :   parameter_vac_H[PHE].push_back(17.131321119209627);
+    4857           6 :   parameter_vac_H[PHE].push_back(-0.15766725674246446);
+    4858           6 :   parameter_vac_H[PHE].push_back(-19.19964432024534);
+    4859           6 :   parameter_vac_H[PHE].push_back(-12.34326882843138);
+    4860           6 :   parameter_vac_H[PHE].push_back(38.17216645824474);
+    4861           6 :   parameter_vac_H[PHE].push_back(-11.245288857407298);
+    4862           6 :   parameter_vac_H[PHE].push_back(-3.8114731300899343);
+    4863             : 
+    4864           6 :   parameter_vac_H[HIP].push_back(19.34240411920875);
+    4865           6 :   parameter_vac_H[HIP].push_back(-0.13533410292592593);
+    4866           6 :   parameter_vac_H[HIP].push_back(-25.924121027387276);
+    4867           6 :   parameter_vac_H[HIP].push_back(-12.36586927492752);
+    4868           6 :   parameter_vac_H[HIP].push_back(56.75268702111191);
+    4869           6 :   parameter_vac_H[HIP].push_back(-31.126240293638094);
+    4870           6 :   parameter_vac_H[HIP].push_back(2.749811579250848);
+    4871             : 
+    4872           6 :   parameter_vac_H[ARG].push_back(12.027024119209557);
+    4873           6 :   parameter_vac_H[ARG].push_back(-0.41927538341868287);
+    4874           6 :   parameter_vac_H[ARG].push_back(-22.137566939867042);
+    4875           6 :   parameter_vac_H[ARG].push_back(-43.22615008762667);
+    4876           6 :   parameter_vac_H[ARG].push_back(165.77466655520323);
+    4877           6 :   parameter_vac_H[ARG].push_back(-140.68664871425898);
+    4878           6 :   parameter_vac_H[ARG].push_back(36.67401195170306);
+    4879             : 
+    4880           6 :   parameter_vac_H[LYS].push_back(2.5217441192093717);
+    4881           6 :   parameter_vac_H[LYS].push_back(-0.0032825476242835413);
+    4882           6 :   parameter_vac_H[LYS].push_back(14.019071697737793);
+    4883           6 :   parameter_vac_H[LYS].push_back(7.8634074595069245);
+    4884           6 :   parameter_vac_H[LYS].push_back(-82.44639716451474);
+    4885           6 :   parameter_vac_H[LYS].push_back(94.32937851921197);
+    4886           6 :   parameter_vac_H[LYS].push_back(-32.324473823417);
+    4887             : 
+    4888           6 :   parameter_vac_H[CYS].push_back(3.705624880856525);
+    4889           6 :   parameter_vac_H[CYS].push_back(0.005214780840206113);
+    4890           6 :   parameter_vac_H[CYS].push_back(1.25680902661715);
+    4891           6 :   parameter_vac_H[CYS].push_back(0.5779209425501814);
+    4892           6 :   parameter_vac_H[CYS].push_back(-3.716408071089366);
+    4893           6 :   parameter_vac_H[CYS].push_back(2.3947518943233117);
+    4894           6 :   parameter_vac_H[CYS].push_back(-0.40204949737133333);
+    4895             : 
+    4896           6 :   parameter_vac_H[CYX].push_back(5.285401118868);
+    4897           6 :   parameter_vac_H[CYX].push_back(-0.006119528779);
+    4898           6 :   parameter_vac_H[CYX].push_back(-3.091212256902);
+    4899           6 :   parameter_vac_H[CYX].push_back(-0.679948780910);
+    4900           6 :   parameter_vac_H[CYX].push_back(4.495837313271);
+    4901           6 :   parameter_vac_H[CYX].push_back(-2.827133444940);
+    4902           6 :   parameter_vac_H[CYX].push_back(0.494583310914);
+    4903             : 
+    4904           6 :   parameter_vac_H[ASP].push_back(14.776336119209605);
+    4905           6 :   parameter_vac_H[ASP].push_back(-0.037351220316916435);
+    4906           6 :   parameter_vac_H[ASP].push_back(-18.556358387626286);
+    4907           6 :   parameter_vac_H[ASP].push_back(-4.1737354794552886);
+    4908           6 :   parameter_vac_H[ASP].push_back(28.424721213037405);
+    4909           6 :   parameter_vac_H[ASP].push_back(-17.51389895324883);
+    4910           6 :   parameter_vac_H[ASP].push_back(2.9729111724708597);
+    4911             : 
+    4912           6 :   parameter_vac_H[GLU].push_back(14.145121119208973);
+    4913           6 :   parameter_vac_H[GLU].push_back(-0.11468766098213011);
+    4914           6 :   parameter_vac_H[GLU].push_back(-26.272637652294613);
+    4915           6 :   parameter_vac_H[GLU].push_back(-13.769758826440151);
+    4916           6 :   parameter_vac_H[GLU].push_back(80.4575683578491);
+    4917           6 :   parameter_vac_H[GLU].push_back(-64.19346347075);
+    4918           6 :   parameter_vac_H[GLU].push_back(15.545440117656236);
+    4919             : 
+    4920           6 :   parameter_vac_H[ILE].push_back(1.9488158808808775);
+    4921           6 :   parameter_vac_H[ILE].push_back(0.05873132133874459);
+    4922           6 :   parameter_vac_H[ILE].push_back(12.032778845884135);
+    4923           6 :   parameter_vac_H[ILE].push_back(7.148416980612881);
+    4924           6 :   parameter_vac_H[ILE].push_back(-41.87377843832961);
+    4925           6 :   parameter_vac_H[ILE].push_back(33.96120749582283);
+    4926           6 :   parameter_vac_H[ILE].push_back(-8.362535852631256);
+    4927             : 
+    4928           6 :   parameter_vac_H[LEU].push_back(1.9488158808977816);
+    4929           6 :   parameter_vac_H[LEU].push_back(0.0778305500414777);
+    4930           6 :   parameter_vac_H[LEU].push_back(12.333370614594);
+    4931           6 :   parameter_vac_H[LEU].push_back(9.449427967560764);
+    4932           6 :   parameter_vac_H[LEU].push_back(-52.65457680603262);
+    4933           6 :   parameter_vac_H[LEU].push_back(44.681877289399615);
+    4934           6 :   parameter_vac_H[LEU].push_back(-11.460498338671227);
+    4935             : 
+    4936           6 :   parameter_vac_H[MET].push_back(3.0940808808117652);
+    4937           6 :   parameter_vac_H[MET].push_back(0.04903755678213222);
+    4938           6 :   parameter_vac_H[MET].push_back(8.981927022922049);
+    4939           6 :   parameter_vac_H[MET].push_back(8.654862771879014);
+    4940           6 :   parameter_vac_H[MET].push_back(-57.09889409156816);
+    4941           6 :   parameter_vac_H[MET].push_back(58.87704775164829);
+    4942           6 :   parameter_vac_H[MET].push_back(-18.60431990258862);
+    4943             : 
+    4944           6 :   parameter_vac_H[ASN].push_back(11.943936119209074);
+    4945           6 :   parameter_vac_H[ASN].push_back(-0.0005000836239497835);
+    4946           6 :   parameter_vac_H[ASN].push_back(-9.581236453763157);
+    4947           6 :   parameter_vac_H[ASN].push_back(0.16244025786232308);
+    4948           6 :   parameter_vac_H[ASN].push_back(2.9276580099749574);
+    4949           6 :   parameter_vac_H[ASN].push_back(2.133535783835143);
+    4950           6 :   parameter_vac_H[ASN].push_back(-1.5709968820975018);
+    4951             : 
+    4952           6 :   parameter_vac_H[PRO].push_back(4.9595288808229245);
+    4953           6 :   parameter_vac_H[PRO].push_back(0.017853932680793515);
+    4954           6 :   parameter_vac_H[PRO].push_back(4.5421559293101605);
+    4955           6 :   parameter_vac_H[PRO].push_back(2.008455612787203);
+    4956           6 :   parameter_vac_H[PRO].push_back(-12.444117841318494);
+    4957           6 :   parameter_vac_H[PRO].push_back(8.511723688836447);
+    4958           6 :   parameter_vac_H[PRO].push_back(-1.6337543903496765);
+    4959             : 
+    4960           6 :   parameter_vac_H[GLN].push_back(11.377129119208574);
+    4961           6 :   parameter_vac_H[GLN].push_back(-0.0674805307761209);
+    4962           6 :   parameter_vac_H[GLN].push_back(-16.56692720411458);
+    4963           6 :   parameter_vac_H[GLN].push_back(-6.477707440126834);
+    4964           6 :   parameter_vac_H[GLN].push_back(34.78232259512621);
+    4965           6 :   parameter_vac_H[GLN].push_back(-19.450886909938312);
+    4966           6 :   parameter_vac_H[GLN].push_back(1.944286925108988);
+    4967             : 
+    4968           6 :   parameter_vac_H[SER].push_back(4.95062488096605);
+    4969           6 :   parameter_vac_H[SER].push_back(0.004676435440506079);
+    4970           6 :   parameter_vac_H[SER].push_back(-0.1896653085608564);
+    4971           6 :   parameter_vac_H[SER].push_back(0.5142284931977218);
+    4972           6 :   parameter_vac_H[SER].push_back(-2.8946087252759893);
+    4973           6 :   parameter_vac_H[SER].push_back(2.1031239401634836);
+    4974           6 :   parameter_vac_H[SER].push_back(-0.38226443516361713);
+    4975             : 
+    4976           6 :   parameter_vac_H[THR].push_back(4.588163880808971);
+    4977           6 :   parameter_vac_H[THR].push_back(0.018587905993982613);
+    4978           6 :   parameter_vac_H[THR].push_back(3.5289861308270214);
+    4979           6 :   parameter_vac_H[THR].push_back(2.0780583604591567);
+    4980           6 :   parameter_vac_H[THR].push_back(-12.3802007068414);
+    4981           6 :   parameter_vac_H[THR].push_back(8.720986674116094);
+    4982           6 :   parameter_vac_H[THR].push_back(-1.683256475122275);
+    4983             : 
+    4984           6 :   parameter_vac_H[VAL].push_back(2.187440880853519);
+    4985           6 :   parameter_vac_H[VAL].push_back(0.028351524826584255);
+    4986           6 :   parameter_vac_H[VAL].push_back(8.36584512491955);
+    4987           6 :   parameter_vac_H[VAL].push_back(3.1686206615123926);
+    4988           6 :   parameter_vac_H[VAL].push_back(-19.81959917770108);
+    4989           6 :   parameter_vac_H[VAL].push_back(13.293003038570571);
+    4990           6 :   parameter_vac_H[VAL].push_back(-2.4595257726774125);
+    4991             : 
+    4992           6 :   parameter_vac_H[ALA].push_back(2.7060248808167935);
+    4993           6 :   parameter_vac_H[ALA].push_back(0.004618897267213416);
+    4994           6 :   parameter_vac_H[ALA].push_back(2.4990261487383947);
+    4995           6 :   parameter_vac_H[ALA].push_back(0.49579332664340864);
+    4996           6 :   parameter_vac_H[ALA].push_back(-3.850400071630347);
+    4997           6 :   parameter_vac_H[ALA].push_back(1.9501161562030942);
+    4998           6 :   parameter_vac_H[ALA].push_back(-0.18332582719788362);
+    4999             : 
+    5000           6 :   parameter_vac_H[GLY].push_back(2.985983880876256);
+    5001           6 :   parameter_vac_H[GLY].push_back(0.0005033131808079042);
+    5002           6 :   parameter_vac_H[GLY].push_back(-0.42250170279962684);
+    5003           6 :   parameter_vac_H[GLY].push_back(0.05620517453257455);
+    5004           6 :   parameter_vac_H[GLY].push_back(-0.16801962822020733);
+    5005           6 :   parameter_vac_H[GLY].push_back(0.23635459648780555);
+    5006           6 :   parameter_vac_H[GLY].push_back(-0.06585244715658795);
+    5007             : 
+    5008           6 :   parameter_vac_H[HIS].push_back(22.77198411920933);
+    5009           6 :   parameter_vac_H[HIS].push_back(-0.06607491006655417);
+    5010           6 :   parameter_vac_H[HIS].push_back(-27.277710268717247);
+    5011           6 :   parameter_vac_H[HIS].push_back(-5.674444390934355);
+    5012           6 :   parameter_vac_H[HIS].push_back(33.4059567406171);
+    5013           6 :   parameter_vac_H[HIS].push_back(-11.60826210271092);
+    5014           6 :   parameter_vac_H[HIS].push_back(-1.7359607560773076);
+    5015             : 
+    5016             :   // NUCLEIC ACIDS
+    5017             : 
+    5018             :   // BB_PO2-BB_PO3 H and D parameters are identical as there is no H or D in the bead.
+    5019           6 :   parameter_solv_H[BB_PO3].push_back(1464.5929001192262);
+    5020           6 :   parameter_solv_H[BB_PO3].push_back(-2.316908934494931);
+    5021           6 :   parameter_solv_H[BB_PO3].push_back(-1882.4844584696532);
+    5022           6 :   parameter_solv_H[BB_PO3].push_back(-258.8660305554736);
+    5023           6 :   parameter_solv_H[BB_PO3].push_back(2007.5216385943972);
+    5024           6 :   parameter_solv_H[BB_PO3].push_back(-1087.6423562424877);
+    5025           6 :   parameter_solv_H[BB_PO3].push_back(154.89236486681165);
+    5026             : 
+    5027           6 :   parameter_solv_H[BB_PO2].push_back(575.5201001192197);
+    5028           6 :   parameter_solv_H[BB_PO2].push_back(-0.6126595489733864);
+    5029           6 :   parameter_solv_H[BB_PO2].push_back(-623.3371092254899);
+    5030           6 :   parameter_solv_H[BB_PO2].push_back(-68.05795957022144);
+    5031           6 :   parameter_solv_H[BB_PO2].push_back(561.8052621243661);
+    5032           6 :   parameter_solv_H[BB_PO2].push_back(-283.39573309540276);
+    5033           6 :   parameter_solv_H[BB_PO2].push_back(35.550016980100295);
+    5034             : 
+    5035           6 :   parameter_solv_H[BB_DNA].push_back(21211.009600118316);
+    5036           6 :   parameter_solv_H[BB_DNA].push_back(-90.18805990529991);
+    5037           6 :   parameter_solv_H[BB_DNA].push_back(-39731.13373512149);
+    5038           6 :   parameter_solv_H[BB_DNA].push_back(-10920.373563712872);
+    5039           6 :   parameter_solv_H[BB_DNA].push_back(72882.21702424981);
+    5040           6 :   parameter_solv_H[BB_DNA].push_back(-51747.487078112776);
+    5041           6 :   parameter_solv_H[BB_DNA].push_back(11308.678429018755);
+    5042             : 
+    5043           6 :   parameter_solv_H[BB_DNA_5].push_back(22737.624100119025);
+    5044           6 :   parameter_solv_H[BB_DNA_5].push_back(-102.72714886664161);
+    5045           6 :   parameter_solv_H[BB_DNA_5].push_back(-43685.329677789734);
+    5046           6 :   parameter_solv_H[BB_DNA_5].push_back(-12564.25937409345);
+    5047           6 :   parameter_solv_H[BB_DNA_5].push_back(83454.87540484878);
+    5048           6 :   parameter_solv_H[BB_DNA_5].push_back(-60367.15652138887);
+    5049           6 :   parameter_solv_H[BB_DNA_5].push_back(13507.333729868991);
+    5050             : 
+    5051           6 :   parameter_solv_H[BB_DNA_3].push_back(22737.62410011902);
+    5052           6 :   parameter_solv_H[BB_DNA_3].push_back(-101.57816684452251);
+    5053           6 :   parameter_solv_H[BB_DNA_3].push_back(-43488.536705576145);
+    5054           6 :   parameter_solv_H[BB_DNA_3].push_back(-12345.056184958425);
+    5055           6 :   parameter_solv_H[BB_DNA_3].push_back(81963.52364114887);
+    5056           6 :   parameter_solv_H[BB_DNA_3].push_back(-58791.59443618196);
+    5057           6 :   parameter_solv_H[BB_DNA_3].push_back(13003.199362335583);
+    5058             : 
+    5059           6 :   parameter_solv_H[BB_RNA].push_back(23953.752900120977);
+    5060           6 :   parameter_solv_H[BB_RNA].push_back(-117.35779348824417);
+    5061           6 :   parameter_solv_H[BB_RNA].push_back(-47644.41735332843);
+    5062           6 :   parameter_solv_H[BB_RNA].push_back(-14641.556643789861);
+    5063           6 :   parameter_solv_H[BB_RNA].push_back(96893.48627050371);
+    5064           6 :   parameter_solv_H[BB_RNA].push_back(-72249.62534169303);
+    5065           6 :   parameter_solv_H[BB_RNA].push_back(16792.055521055358);
+    5066             : 
+    5067           6 :   parameter_solv_H[BB_RNA_5].push_back(25574.406400119024);
+    5068           6 :   parameter_solv_H[BB_RNA_5].push_back(-131.99642772933734);
+    5069           6 :   parameter_solv_H[BB_RNA_5].push_back(-52136.51404531251);
+    5070           6 :   parameter_solv_H[BB_RNA_5].push_back(-16682.14273917604);
+    5071           6 :   parameter_solv_H[BB_RNA_5].push_back(110278.01921639398);
+    5072           6 :   parameter_solv_H[BB_RNA_5].push_back(-83715.92027818544);
+    5073           6 :   parameter_solv_H[BB_RNA_5].push_back(19875.89133770605);
+    5074             : 
+    5075           6 :   parameter_solv_H[BB_RNA_3].push_back(25574.406400119027);
+    5076           6 :   parameter_solv_H[BB_RNA_3].push_back(-127.96875237036166);
+    5077           6 :   parameter_solv_H[BB_RNA_3].push_back(-51407.18391758439);
+    5078           6 :   parameter_solv_H[BB_RNA_3].push_back(-15922.900669975606);
+    5079           6 :   parameter_solv_H[BB_RNA_3].push_back(105078.5888910626);
+    5080           6 :   parameter_solv_H[BB_RNA_3].push_back(-78289.16276190645);
+    5081           6 :   parameter_solv_H[BB_RNA_3].push_back(18156.832143441192);
+    5082             : 
+    5083           6 :   parameter_solv_H[BASE_A].push_back(13282.562500119211);
+    5084           6 :   parameter_solv_H[BASE_A].push_back(-76.45124168404048);
+    5085           6 :   parameter_solv_H[BASE_A].push_back(-28376.06994108963);
+    5086           6 :   parameter_solv_H[BASE_A].push_back(-9972.910773722022);
+    5087           6 :   parameter_solv_H[BASE_A].push_back(65873.86341939073);
+    5088           6 :   parameter_solv_H[BASE_A].push_back(-52064.33492910885);
+    5089           6 :   parameter_solv_H[BASE_A].push_back(12931.608989412513);
+    5090             : 
+    5091           6 :   parameter_solv_H[BASE_C].push_back(10600.76160011891);
+    5092           6 :   parameter_solv_H[BASE_C].push_back(-49.1670871249108);
+    5093           6 :   parameter_solv_H[BASE_C].push_back(-20239.818742072875);
+    5094           6 :   parameter_solv_H[BASE_C].push_back(-6020.278780090207);
+    5095           6 :   parameter_solv_H[BASE_C].push_back(39632.13288981881);
+    5096           6 :   parameter_solv_H[BASE_C].push_back(-28954.779736165576);
+    5097           6 :   parameter_solv_H[BASE_C].push_back(6551.541109526305);
+    5098             : 
+    5099           6 :   parameter_solv_H[BASE_G].push_back(15470.384400119934);
+    5100           6 :   parameter_solv_H[BASE_G].push_back(-93.8013620200972);
+    5101           6 :   parameter_solv_H[BASE_G].push_back(-36188.29687013545);
+    5102           6 :   parameter_solv_H[BASE_G].push_back(-13717.685098209471);
+    5103           6 :   parameter_solv_H[BASE_G].push_back(95658.18473657136);
+    5104           6 :   parameter_solv_H[BASE_G].push_back(-81262.37811451119);
+    5105           6 :   parameter_solv_H[BASE_G].push_back(21841.903930943085);
+    5106             : 
+    5107           6 :   parameter_solv_H[BASE_T].push_back(17210.81610011936);
+    5108           6 :   parameter_solv_H[BASE_T].push_back(-93.10189802920208);
+    5109           6 :   parameter_solv_H[BASE_T].push_back(-36466.51927689957);
+    5110           6 :   parameter_solv_H[BASE_T].push_back(-12425.55615716932);
+    5111           6 :   parameter_solv_H[BASE_T].push_back(83847.427808925);
+    5112           6 :   parameter_solv_H[BASE_T].push_back(-66735.64997846584);
+    5113           6 :   parameter_solv_H[BASE_T].push_back(16757.3463987507);
+    5114             : 
+    5115           6 :   parameter_solv_H[BASE_U].push_back(10909.802500119395);
+    5116           6 :   parameter_solv_H[BASE_U].push_back(-46.17712672768298);
+    5117           6 :   parameter_solv_H[BASE_U].push_back(-20149.67695512526);
+    5118           6 :   parameter_solv_H[BASE_U].push_back(-5590.242961204435);
+    5119           6 :   parameter_solv_H[BASE_U].push_back(37169.2740983132);
+    5120           6 :   parameter_solv_H[BASE_U].push_back(-26475.631627167604);
+    5121           6 :   parameter_solv_H[BASE_U].push_back(5808.201015156168);
+    5122             : 
+    5123           6 :   parameter_mix_H[BB_PO3].push_back(143.5890401192106);
+    5124           6 :   parameter_mix_H[BB_PO3].push_back(-0.0679405156108208);
+    5125           6 :   parameter_mix_H[BB_PO3].push_back(-131.78648321068806);
+    5126           6 :   parameter_mix_H[BB_PO3].push_back(-7.222980065241985);
+    5127           6 :   parameter_mix_H[BB_PO3].push_back(79.67309464590994);
+    5128           6 :   parameter_mix_H[BB_PO3].push_back(-27.950095608460042);
+    5129           6 :   parameter_mix_H[BB_PO3].push_back(0.12790403369995257);
+    5130             : 
+    5131           6 :   parameter_mix_H[BB_PO2].push_back(80.12660011920252);
+    5132           6 :   parameter_mix_H[BB_PO2].push_back(-0.0278885551982023);
+    5133           6 :   parameter_mix_H[BB_PO2].push_back(-60.532194918222984);
+    5134           6 :   parameter_mix_H[BB_PO2].push_back(-2.976882903409687);
+    5135           6 :   parameter_mix_H[BB_PO2].push_back(33.30645116638125);
+    5136           6 :   parameter_mix_H[BB_PO2].push_back(-11.601573219761374);
+    5137           6 :   parameter_mix_H[BB_PO2].push_back(0.12551046492022422);
+    5138             : 
+    5139           6 :   parameter_mix_H[BB_DNA].push_back(712.7621601191935);
+    5140           6 :   parameter_mix_H[BB_DNA].push_back(-0.3228709821198571);
+    5141           6 :   parameter_mix_H[BB_DNA].push_back(-784.5118228559945);
+    5142           6 :   parameter_mix_H[BB_DNA].push_back(-27.196125702249613);
+    5143           6 :   parameter_mix_H[BB_DNA].push_back(410.0185035102729);
+    5144           6 :   parameter_mix_H[BB_DNA].push_back(-54.453513369320355);
+    5145           6 :   parameter_mix_H[BB_DNA].push_back(-44.85506789237683);
+    5146             : 
+    5147           6 :   parameter_mix_H[BB_DNA_5].push_back(625.175339965785);
+    5148           6 :   parameter_mix_H[BB_DNA_5].push_back(0.2691706617748245);
+    5149           6 :   parameter_mix_H[BB_DNA_5].push_back(-582.8721350420001);
+    5150           6 :   parameter_mix_H[BB_DNA_5].push_back(46.512408351374326);
+    5151           6 :   parameter_mix_H[BB_DNA_5].push_back(-58.93886949899108);
+    5152           6 :   parameter_mix_H[BB_DNA_5].push_back(307.29720336085046);
+    5153           6 :   parameter_mix_H[BB_DNA_5].push_back(-131.71996309259953);
+    5154             : 
+    5155           6 :   parameter_mix_H[BB_DNA_3].push_back(625.1753399401266);
+    5156           6 :   parameter_mix_H[BB_DNA_3].push_back(0.08763234414546289);
+    5157           6 :   parameter_mix_H[BB_DNA_3].push_back(-606.8067575087485);
+    5158           6 :   parameter_mix_H[BB_DNA_3].push_back(20.84427254872218);
+    5159           6 :   parameter_mix_H[BB_DNA_3].push_back(92.53523123608991);
+    5160           6 :   parameter_mix_H[BB_DNA_3].push_back(162.04688035654937);
+    5161           6 :   parameter_mix_H[BB_DNA_3].push_back(-89.13571774638052);
+    5162             : 
+    5163           6 :   parameter_mix_H[BB_RNA].push_back(936.9775801191857);
+    5164           6 :   parameter_mix_H[BB_RNA].push_back(-1.3233686929680253);
+    5165           6 :   parameter_mix_H[BB_RNA].push_back(-1212.1627155263773);
+    5166           6 :   parameter_mix_H[BB_RNA].push_back(-141.35324744384351);
+    5167           6 :   parameter_mix_H[BB_RNA].push_back(1155.8281658363026);
+    5168           6 :   parameter_mix_H[BB_RNA].push_back(-548.9340055857343);
+    5169           6 :   parameter_mix_H[BB_RNA].push_back(50.81734777881503);
+    5170             : 
+    5171           6 :   parameter_mix_H[BB_RNA_5].push_back(848.5355201165631);
+    5172           6 :   parameter_mix_H[BB_RNA_5].push_back(-0.49570338490120175);
+    5173           6 :   parameter_mix_H[BB_RNA_5].push_back(-976.1033073783973);
+    5174           6 :   parameter_mix_H[BB_RNA_5].push_back(-32.943532187986605);
+    5175           6 :   parameter_mix_H[BB_RNA_5].push_back(475.66177061923884);
+    5176           6 :   parameter_mix_H[BB_RNA_5].push_back(17.51955845824258);
+    5177           6 :   parameter_mix_H[BB_RNA_5].push_back(-96.74451972314769);
+    5178             : 
+    5179           6 :   parameter_mix_H[BB_RNA_3].push_back(848.5355201192122);
+    5180           6 :   parameter_mix_H[BB_RNA_3].push_back(-0.8301109354355396);
+    5181           6 :   parameter_mix_H[BB_RNA_3].push_back(-1019.9524389785406);
+    5182           6 :   parameter_mix_H[BB_RNA_3].push_back(-84.1388451424885);
+    5183           6 :   parameter_mix_H[BB_RNA_3].push_back(787.1277245040931);
+    5184           6 :   parameter_mix_H[BB_RNA_3].push_back(-294.67807432795627);
+    5185           6 :   parameter_mix_H[BB_RNA_3].push_back(-1.3214626461251089);
+    5186             : 
+    5187           6 :   parameter_mix_H[BASE_A].push_back(1504.9345001191857);
+    5188           6 :   parameter_mix_H[BASE_A].push_back(-3.5306888452552663);
+    5189           6 :   parameter_mix_H[BASE_A].push_back(-2234.3933572775572);
+    5190           6 :   parameter_mix_H[BASE_A].push_back(-380.0255208494757);
+    5191           6 :   parameter_mix_H[BASE_A].push_back(2726.27802432048);
+    5192           6 :   parameter_mix_H[BASE_A].push_back(-1490.8825754968443);
+    5193           6 :   parameter_mix_H[BASE_A].push_back(199.7501110740159);
+    5194             : 
+    5195           6 :   parameter_mix_H[BASE_C].push_back(939.8188801192172);
+    5196           6 :   parameter_mix_H[BASE_C].push_back(-1.489638186262854);
+    5197           6 :   parameter_mix_H[BASE_C].push_back(-1244.5515798554075);
+    5198           6 :   parameter_mix_H[BASE_C].push_back(-161.3972705672055);
+    5199           6 :   parameter_mix_H[BASE_C].push_back(1276.3568466722545);
+    5200           6 :   parameter_mix_H[BASE_C].push_back(-643.3057776225742);
+    5201           6 :   parameter_mix_H[BASE_C].push_back(72.75963113826273);
+    5202             : 
+    5203           6 :   parameter_mix_H[BASE_G].push_back(1768.434840119199);
+    5204           6 :   parameter_mix_H[BASE_G].push_back(-6.505347007077434);
+    5205           6 :   parameter_mix_H[BASE_G].push_back(-2919.3856777898427);
+    5206           6 :   parameter_mix_H[BASE_G].push_back(-701.2456464463938);
+    5207           6 :   parameter_mix_H[BASE_G].push_back(4464.594230284102);
+    5208           6 :   parameter_mix_H[BASE_G].push_back(-2733.138521295608);
+    5209           6 :   parameter_mix_H[BASE_G].push_back(458.1177706235891);
+    5210             : 
+    5211           6 :   parameter_mix_H[BASE_T].push_back(1179.3981001192033);
+    5212           6 :   parameter_mix_H[BASE_T].push_back(-3.2037849252756527);
+    5213           6 :   parameter_mix_H[BASE_T].push_back(-1821.255498763799);
+    5214           6 :   parameter_mix_H[BASE_T].push_back(-371.01993266441303);
+    5215           6 :   parameter_mix_H[BASE_T].push_back(2604.074226688971);
+    5216           6 :   parameter_mix_H[BASE_T].push_back(-1648.1965787713084);
+    5217           6 :   parameter_mix_H[BASE_T].push_back(307.2962186436368);
+    5218             : 
+    5219           6 :   parameter_mix_H[BASE_U].push_back(956.3442001192266);
+    5220           6 :   parameter_mix_H[BASE_U].push_back(-1.724458000760567);
+    5221           6 :   parameter_mix_H[BASE_U].push_back(-1287.9746970192687);
+    5222           6 :   parameter_mix_H[BASE_U].push_back(-192.74748379510373);
+    5223           6 :   parameter_mix_H[BASE_U].push_back(1459.0789258833893);
+    5224           6 :   parameter_mix_H[BASE_U].push_back(-810.0763075080915);
+    5225           6 :   parameter_mix_H[BASE_U].push_back(119.81810290248339);
+    5226             : 
+    5227           6 :   parameter_vac_H[BB_PO3].push_back(3.519375907888525);
+    5228           6 :   parameter_vac_H[BB_PO3].push_back(7.742660056553524e-05);
+    5229           6 :   parameter_vac_H[BB_PO3].push_back(-1.3856562746347367);
+    5230           6 :   parameter_vac_H[BB_PO3].push_back(0.00821183249969174);
+    5231           6 :   parameter_vac_H[BB_PO3].push_back(0.21213096729728745);
+    5232           6 :   parameter_vac_H[BB_PO3].push_back(0.032592855104331325);
+    5233           6 :   parameter_vac_H[BB_PO3].push_back(-0.02236149538438434);
+    5234             : 
+    5235           6 :   parameter_vac_H[BB_PO2].push_back(2.7889001116093275);
+    5236           6 :   parameter_vac_H[BB_PO2].push_back(-0.00011178884266113128);
+    5237           6 :   parameter_vac_H[BB_PO2].push_back(-1.1702605818380667);
+    5238           6 :   parameter_vac_H[BB_PO2].push_back(-0.011278044036819933);
+    5239           6 :   parameter_vac_H[BB_PO2].push_back(0.3214006584089025);
+    5240           6 :   parameter_vac_H[BB_PO2].push_back(-0.04097165983591666);
+    5241           6 :   parameter_vac_H[BB_PO2].push_back(-0.017525098100539722);
+    5242             : 
+    5243           6 :   parameter_vac_H[BB_DNA].push_back(5.987809026456476);
+    5244           6 :   parameter_vac_H[BB_DNA].push_back(9.945454528827912e-05);
+    5245           6 :   parameter_vac_H[BB_DNA].push_back(-1.1884708569330031);
+    5246           6 :   parameter_vac_H[BB_DNA].push_back(-0.007457733256362841);
+    5247           6 :   parameter_vac_H[BB_DNA].push_back(0.05666858781418339);
+    5248           6 :   parameter_vac_H[BB_DNA].push_back(-0.15158797629971757);
+    5249           6 :   parameter_vac_H[BB_DNA].push_back(0.11642340861329734);
+    5250             : 
+    5251           6 :   parameter_vac_H[BB_DNA_5].push_back(4.297328944539055);
+    5252           6 :   parameter_vac_H[BB_DNA_5].push_back(0.0014793971885106831);
+    5253           6 :   parameter_vac_H[BB_DNA_5].push_back(1.3961088365255605);
+    5254           6 :   parameter_vac_H[BB_DNA_5].push_back(0.08974639858979384);
+    5255           6 :   parameter_vac_H[BB_DNA_5].push_back(-1.5198099705167643);
+    5256           6 :   parameter_vac_H[BB_DNA_5].push_back(-0.12127122359433733);
+    5257           6 :   parameter_vac_H[BB_DNA_5].push_back(0.4134601046223601);
+    5258             : 
+    5259           6 :   parameter_vac_H[BB_DNA_3].push_back(4.297328886488132);
+    5260           6 :   parameter_vac_H[BB_DNA_3].push_back(0.0041802954281271905);
+    5261           6 :   parameter_vac_H[BB_DNA_3].push_back(1.6065462295705266);
+    5262           6 :   parameter_vac_H[BB_DNA_3].push_back(0.4399805535688805);
+    5263           6 :   parameter_vac_H[BB_DNA_3].push_back(-3.3806711791929804);
+    5264           6 :   parameter_vac_H[BB_DNA_3].push_back(1.6729551563628675);
+    5265           6 :   parameter_vac_H[BB_DNA_3].push_back(-0.10911063067909885);
+    5266             : 
+    5267           6 :   parameter_vac_H[BB_RNA].push_back(9.162728984394093);
+    5268           6 :   parameter_vac_H[BB_RNA].push_back(0.00019952321584579868);
+    5269           6 :   parameter_vac_H[BB_RNA].push_back(-4.744748946331966);
+    5270           6 :   parameter_vac_H[BB_RNA].push_back(0.025106563403946364);
+    5271           6 :   parameter_vac_H[BB_RNA].push_back(1.2302956694109803);
+    5272           6 :   parameter_vac_H[BB_RNA].push_back(0.12359062278096915);
+    5273           6 :   parameter_vac_H[BB_RNA].push_back(-0.1725633367685285);
+    5274             : 
+    5275           6 :   parameter_vac_H[BB_RNA_5].push_back(7.038408898671503);
+    5276           6 :   parameter_vac_H[BB_RNA_5].push_back(0.005106788424920148);
+    5277           6 :   parameter_vac_H[BB_RNA_5].push_back(-0.8981588221803118);
+    5278           6 :   parameter_vac_H[BB_RNA_5].push_back(0.4922588155214312);
+    5279           6 :   parameter_vac_H[BB_RNA_5].push_back(-2.6667853454023644);
+    5280           6 :   parameter_vac_H[BB_RNA_5].push_back(1.533316567240718);
+    5281           6 :   parameter_vac_H[BB_RNA_5].push_back(-0.07199604869737707);
+    5282             : 
+    5283           6 :   parameter_vac_H[BB_RNA_3].push_back(7.038408892621863);
+    5284           6 :   parameter_vac_H[BB_RNA_3].push_back(0.002993083907266898);
+    5285           6 :   parameter_vac_H[BB_RNA_3].push_back(-1.3626596831098492);
+    5286           6 :   parameter_vac_H[BB_RNA_3].push_back(0.3138856961130113);
+    5287           6 :   parameter_vac_H[BB_RNA_3].push_back(-1.684185014289391);
+    5288           6 :   parameter_vac_H[BB_RNA_3].push_back(1.1862168720864616);
+    5289           6 :   parameter_vac_H[BB_RNA_3].push_back(-0.1443894172417523);
+    5290             : 
+    5291           6 :   parameter_vac_H[BASE_A].push_back(42.62784088079008);
+    5292           6 :   parameter_vac_H[BASE_A].push_back(0.02302908536431516);
+    5293           6 :   parameter_vac_H[BASE_A].push_back(-33.22707177297222);
+    5294           6 :   parameter_vac_H[BASE_A].push_back(2.6853748424439834);
+    5295           6 :   parameter_vac_H[BASE_A].push_back(-1.6632902891624768);
+    5296           6 :   parameter_vac_H[BASE_A].push_back(11.905766349515268);
+    5297           6 :   parameter_vac_H[BASE_A].push_back(-4.547083454788805);
+    5298             : 
+    5299           6 :   parameter_vac_H[BASE_C].push_back(20.83009588079022);
+    5300           6 :   parameter_vac_H[BASE_C].push_back(0.017055822321768378);
+    5301           6 :   parameter_vac_H[BASE_C].push_back(-8.349634734370916);
+    5302           6 :   parameter_vac_H[BASE_C].push_back(1.9324634367723073);
+    5303           6 :   parameter_vac_H[BASE_C].push_back(-8.435199734060882);
+    5304           6 :   parameter_vac_H[BASE_C].push_back(8.272798368731268);
+    5305           6 :   parameter_vac_H[BASE_C].push_back(-1.986671440757263);
+    5306             : 
+    5307           6 :   parameter_vac_H[BASE_G].push_back(50.53788088079374);
+    5308           6 :   parameter_vac_H[BASE_G].push_back(0.024035597617780367);
+    5309           6 :   parameter_vac_H[BASE_G].push_back(-47.94916639302998);
+    5310           6 :   parameter_vac_H[BASE_G].push_back(3.143375731466498);
+    5311           6 :   parameter_vac_H[BASE_G].push_back(4.297009866708155);
+    5312           6 :   parameter_vac_H[BASE_G].push_back(15.855448505050578);
+    5313           6 :   parameter_vac_H[BASE_G].push_back(-7.827484135873966);
+    5314             : 
+    5315           6 :   parameter_vac_H[BASE_T].push_back(20.20502488079069);
+    5316           6 :   parameter_vac_H[BASE_T].push_back(0.033659966153300002);
+    5317           6 :   parameter_vac_H[BASE_T].push_back(-6.057999187718758);
+    5318           6 :   parameter_vac_H[BASE_T].push_back(4.146969282504351);
+    5319           6 :   parameter_vac_H[BASE_T].push_back(-20.664315319574357);
+    5320           6 :   parameter_vac_H[BASE_T].push_back(19.982178623201648);
+    5321           6 :   parameter_vac_H[BASE_T].push_back(-5.440921587349456);
+    5322             : 
+    5323           6 :   parameter_vac_H[BASE_U].push_back(20.958084119209754);
+    5324           6 :   parameter_vac_H[BASE_U].push_back(-0.005164660707148803);
+    5325           6 :   parameter_vac_H[BASE_U].push_back(-14.53831312442302);
+    5326           6 :   parameter_vac_H[BASE_U].push_back(-0.5276995756310442);
+    5327           6 :   parameter_vac_H[BASE_U].push_back(7.060900707522138);
+    5328           6 :   parameter_vac_H[BASE_U].push_back(-1.8988408480951036);
+    5329           6 :   parameter_vac_H[BASE_U].push_back(-0.215000567681094);
+    5330             : 
+    5331       21340 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    5332       21334 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    5333       21334 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    5334       21334 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    5335       21334 :     if(Rname=="ALA") {
+    5336        1078 :       atoi[residue_atom[i]]=ALA;
+    5337       20256 :     } else if(Rname=="ARG") {
+    5338        1296 :       atoi[residue_atom[i]]=ARG;
+    5339       18960 :     } else if(Rname=="ASN") {
+    5340        1080 :       atoi[residue_atom[i]]=ASN;
+    5341       17880 :     } else if(Rname=="ASP") {
+    5342         936 :       atoi[residue_atom[i]]=ASP;
+    5343       16944 :     } else if(Rname=="CYS") {
+    5344          72 :       atoi[residue_atom[i]]=CYS;
+    5345       16872 :     } else if(Rname=="CYX") {
+    5346           0 :       atoi[residue_atom[i]]=CYX;
+    5347       16872 :     } else if(Rname=="GLN") {
+    5348        1558 :       atoi[residue_atom[i]]=GLN;
+    5349       15314 :     } else if(Rname=="GLU") {
+    5350         714 :       atoi[residue_atom[i]]=GLU;
+    5351       14600 :     } else if(Rname=="GLY") {
+    5352         936 :       atoi[residue_atom[i]]=GLY;
+    5353       13664 :     } else if(Rname=="HIS") {
+    5354           0 :       atoi[residue_atom[i]]=HIS;
+    5355       13664 :     } else if(Rname=="HID") {
+    5356           0 :       atoi[residue_atom[i]]=HIS;
+    5357       13664 :     } else if(Rname=="HIE") {
+    5358         216 :       atoi[residue_atom[i]]=HIS;
+    5359       13448 :     } else if(Rname=="HIP") {
+    5360           0 :       atoi[residue_atom[i]]=HIP;
+    5361             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    5362       13448 :     } else if(Rname=="HSD") {
+    5363           0 :       atoi[residue_atom[i]]=HIS;
+    5364       13448 :     } else if(Rname=="HSE") {
+    5365           0 :       atoi[residue_atom[i]]=HIS;
+    5366       13448 :     } else if(Rname=="HSP") {
+    5367           0 :       atoi[residue_atom[i]]=HIP;
+    5368       13448 :     } else if(Rname=="ILE") {
+    5369        1296 :       atoi[residue_atom[i]]=ILE;
+    5370       12152 :     } else if(Rname=="LEU") {
+    5371        2280 :       atoi[residue_atom[i]]=LEU;
+    5372        9872 :     } else if(Rname=="LYS") {
+    5373        1560 :       atoi[residue_atom[i]]=LYS;
+    5374        8312 :     } else if(Rname=="MET") {
+    5375         836 :       atoi[residue_atom[i]]=MET;
+    5376        7476 :     } else if(Rname=="PHE") {
+    5377        1512 :       atoi[residue_atom[i]]=PHE;
+    5378        5964 :     } else if(Rname=="PRO") {
+    5379        1122 :       atoi[residue_atom[i]]=PRO;
+    5380        4842 :     } else if(Rname=="SER") {
+    5381         768 :       atoi[residue_atom[i]]=SER;
+    5382        4074 :     } else if(Rname=="THR") {
+    5383         728 :       atoi[residue_atom[i]]=THR;
+    5384        3346 :     } else if(Rname=="TRP") {
+    5385           0 :       atoi[residue_atom[i]]=TRP;
+    5386        3346 :     } else if(Rname=="TYR") {
+    5387         792 :       atoi[residue_atom[i]]=TYR;
+    5388        2554 :     } else if(Rname=="VAL") {
+    5389        1600 :       atoi[residue_atom[i]]=VAL;
+    5390             :     }
+    5391             :     // NUCLEIC ACIDS
+    5392             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    5393             :     // RNA - G
+    5394         954 :     else if(Rname=="G") {
+    5395           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5396           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5397           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5398           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5399           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5400           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5401           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5402           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5403           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5404           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5405           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5406           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5407           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5408           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5409           0 :         atoi[residue_atom[i]]=BASE_G;
+    5410           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5411             :       // RNA - G3
+    5412         954 :     } else if(Rname=="G3") {
+    5413           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5414           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5415           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5416           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5417           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5418           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5419           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5420           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5421           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5422           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5423           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5424           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5425           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5426           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5427           0 :         atoi[residue_atom[i]]=BASE_G;
+    5428           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5429             :       // RNA - G5
+    5430         954 :     } else if(Rname=="G5") {
+    5431           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5432           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5433           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5434           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5435           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5436           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5437           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5438           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5439           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5440           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5441           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5442           0 :         atoi[residue_atom[i]]=BASE_G;
+    5443           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5444             :       // RNA - GT
+    5445         954 :     } else if(Rname=="GT") {
+    5446           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5447           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5448           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5449           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5450           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5451           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5452           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5453           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5454           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5455           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5456           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5457           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5458           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5459           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5460           0 :         atoi[residue_atom[i]]=BASE_G;
+    5461           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5462             :       // RNA - U
+    5463         954 :     } else if(Rname=="U") {
+    5464        2886 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5465        1482 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5466          78 :         atoi [residue_atom[i]]=BB_PO2;
+    5467        2548 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5468        2132 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5469        1716 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5470        1326 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5471        1196 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5472        1560 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5473         416 :         atoi[residue_atom[i]]=BB_RNA;
+    5474         884 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5475         468 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5476         364 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5477         286 :         atoi[residue_atom[i]]=BASE_U;
+    5478           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5479             :       // RNA - U3
+    5480         174 :     } else if(Rname=="U3") {
+    5481         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5482         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5483           6 :         atoi [residue_atom[i]]=BB_PO2;
+    5484         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5485         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5486         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5487         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5488          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5489          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5490          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5491          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5492          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5493          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5494          22 :         atoi[residue_atom[i]]=BASE_U;
+    5495           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5496             :       // RNA - U5
+    5497         112 :     } else if(Rname=="U5") {
+    5498         408 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5499         344 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5500         280 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5501         216 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5502         176 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5503         156 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5504          68 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5505         136 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5506          72 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5507          56 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5508          44 :         atoi[residue_atom[i]]=BASE_U;
+    5509           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5510             :       // RNA - UT
+    5511           0 :     } else if(Rname=="UT") {
+    5512           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5513           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5514           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5515           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5516           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5517           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5518           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5519           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5520           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5521           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5522           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5523           0 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5524           0 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5525           0 :         atoi[residue_atom[i]]=BASE_U;
+    5526           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5527             :       // RNA - A
+    5528           0 :     } else if(Rname=="A") {
+    5529           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5530           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5531           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5532           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5533           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5534           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5535           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5536           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5537           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5538           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5539           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5540           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5541           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5542           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5543           0 :         atoi[residue_atom[i]]=BASE_A;
+    5544           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5545             :       // RNA - A3
+    5546           0 :     } else if(Rname=="A3") {
+    5547           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5548           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5549           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5550           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5551           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5552           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5553           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5554           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5555           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5556           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5557           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5558           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5559           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5560           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5561           0 :         atoi[residue_atom[i]]=BASE_A;
+    5562           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5563             :       // RNA - A5
+    5564           0 :     } else if(Rname=="A5") {
+    5565           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5566           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5567           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5568           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5569           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5570           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5571           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5572           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5573           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5574           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5575           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5576           0 :         atoi[residue_atom[i]]=BASE_A;
+    5577           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5578             :       // RNA - AT
+    5579           0 :     } else if(Rname=="AT") {
+    5580           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5581           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5582           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5583           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5584           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5585           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5586           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5587           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5588           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5589           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5590           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5591           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5592           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5593           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5594           0 :         atoi[residue_atom[i]]=BASE_A;
+    5595           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5596             :       // RNA - C
+    5597           0 :     } else if(Rname=="C") {
+    5598           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5599           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5600           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5601           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5602           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5603           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5604           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5605           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5606           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5607           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5608           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5609           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5610           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5611           0 :         atoi[residue_atom[i]]=BASE_C;
+    5612           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5613             :       // RNA - C3
+    5614           0 :     } else if(Rname=="C3") {
+    5615           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5616           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5617           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5618           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5619           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5620           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5621           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5622           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5623           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5624           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5625           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5626           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5627           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5628           0 :         atoi[residue_atom[i]]=BASE_C;
+    5629           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5630             :       // RNA - C5
+    5631           0 :     } else if(Rname=="C5") {
+    5632           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5633           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5634           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5635           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5636           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5637           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5638           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5639           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5640           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5641           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5642           0 :         atoi[residue_atom[i]]=BASE_C;
+    5643           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5644             :       // RNA - CT
+    5645           0 :     } else if(Rname=="CT") {
+    5646           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5647           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5648           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5649           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5650           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5651           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5652           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5653           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5654           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5655           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5656           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5657           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5658           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5659           0 :         atoi[residue_atom[i]]=BASE_C;
+    5660           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5661             :       // DNA - G
+    5662           0 :     } else if(Rname=="DG") {
+    5663           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5664           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5665           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5666           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5667           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5668           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5669           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5670           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5671           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5672           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5673           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5674           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5675           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5676           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5677           0 :         atoi[residue_atom[i]]=BASE_G;
+    5678           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5679             :       // DNA - G3
+    5680           0 :     } else if(Rname=="DG3") {
+    5681           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5682           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5683           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5684           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5685           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5686           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5687           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5688           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5689             :                 Aname=="H3T" ) {
+    5690           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5691           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5692           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5693           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5694           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5695           0 :         atoi[residue_atom[i]]=BASE_G;
+    5696           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5697             :       // DNA - G5
+    5698           0 :     } else if(Rname=="DG5") {
+    5699           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5700           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5701           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5702           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5703           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5704             :           Aname=="H5T" ) {
+    5705           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5706           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5707           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5708           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5709           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5710           0 :         atoi[residue_atom[i]]=BASE_G;
+    5711           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5712             :       // DNA - GT
+    5713           0 :     } else if(Rname=="DGT") {
+    5714           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5715           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5716           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5717           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5718           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5719           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5720           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5721           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5722           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5723           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5724           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5725           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5726           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5727           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5728           0 :         atoi[residue_atom[i]]=BASE_G;
+    5729           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5730             :       // DNA - T
+    5731           0 :     } else if(Rname=="DT") {
+    5732           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5733           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5734           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5735           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5736           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5737           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5738           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5739           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5740           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5741           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5742           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5743           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5744           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5745           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5746           0 :         atoi[residue_atom[i]]=BASE_T;
+    5747           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5748             :       // DNA - T3
+    5749           0 :     } else if(Rname=="DT3") {
+    5750           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5751           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5752           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5753           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5754           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5755           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5756           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5757           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5758             :                 Aname=="H3T" ) {
+    5759           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5760           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5761           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5762           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5763           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5764           0 :         atoi[residue_atom[i]]=BASE_T;
+    5765           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5766             :       // DNA - T5
+    5767           0 :     } else if(Rname=="DT5") {
+    5768           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5769           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5770           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5771           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5772           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5773             :           Aname=="H5T" ) {
+    5774           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5775           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5776           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5777           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5778           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5779           0 :         atoi[residue_atom[i]]=BASE_T;
+    5780           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5781             :       // DNA - TT
+    5782           0 :     } else if(Rname=="DTT") {
+    5783           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5784           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5785           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5786           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5787           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5788           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5789           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5790           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5791           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5792           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5793           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5794           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5795           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5796           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5797           0 :         atoi[residue_atom[i]]=BASE_T;
+    5798           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5799             :       // DNA - A
+    5800           0 :     } else if(Rname=="DA") {
+    5801           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5802           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5803           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5804           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5805           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5806           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5807           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5808           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5809           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5810           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5811           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5812           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5813           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5814           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5815           0 :         atoi[residue_atom[i]]=BASE_A;
+    5816           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5817             :       // DNA - A3
+    5818           0 :     } else if(Rname=="DA3") {
+    5819           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5820           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5821           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5822           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5823           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5824           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5825           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5826           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5827             :                 Aname=="H3T" ) {
+    5828           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5829           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5830           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5831           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5832           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5833           0 :         atoi[residue_atom[i]]=BASE_A;
+    5834           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5835             :       // DNA - A5
+    5836           0 :     } else if(Rname=="DA5") {
+    5837           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5838           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5839           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5840           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5841           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5842             :           Aname=="H5T" ) {
+    5843           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5844           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5845           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5846           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5847           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5848           0 :         atoi[residue_atom[i]]=BASE_A;
+    5849           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5850             :       // DNA - AT
+    5851           0 :     } else if(Rname=="DAT") {
+    5852           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5853           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5854           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5855           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5856           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5857           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5858           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5859           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5860           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5861           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5862           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5863           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5864           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5865           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5866           0 :         atoi[residue_atom[i]]=BASE_A;
+    5867           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5868             :       // DNA - C
+    5869           0 :     } else if(Rname=="DC") {
+    5870           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    5871           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    5872           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5873           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5874           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5875           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5876           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5877           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5878           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5879           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5880           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5881           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5882           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5883           0 :         atoi[residue_atom[i]]=BASE_C;
+    5884           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5885             :       // DNA - C3
+    5886           0 :     } else if(Rname=="DC3") {
+    5887           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5888           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5889           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5890           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5891           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5892           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5893           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5894           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5895             :                 Aname=="H3T" ) {
+    5896           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5897           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5898           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5899           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5900           0 :         atoi[residue_atom[i]]=BASE_C;
+    5901           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5902             :       // DNA - C5
+    5903           0 :     } else if(Rname=="DC5") {
+    5904           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5905           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5906           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5907           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5908           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5909             :           Aname=="H5T" ) {
+    5910           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5911           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5912           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5913           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5914           0 :         atoi[residue_atom[i]]=BASE_C;
+    5915           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5916             :       // DNA - CT
+    5917           0 :     } else if(Rname=="DCT") {
+    5918           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    5919           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    5920           0 :         atoi [residue_atom[i]]=BB_PO3;
+    5921           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5922           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5923           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5924           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5925           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5926           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5927           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5928           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5929           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5930           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5931           0 :         atoi[residue_atom[i]]=BASE_C;
+    5932           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5933           0 :     } else error("Residue not known: "+Rname);
+    5934             :   }
+    5935           6 : }
+    5936             : 
+    5937           6 : 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)
+    5938             : { // 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.
+    5939           6 :   parameter_mix_D[TRP].push_back(8105.740500119327);
+    5940           6 :   parameter_mix_D[TRP].push_back(-41.785616935469804);
+    5941           6 :   parameter_mix_D[TRP].push_back(-25456.92790554363);
+    5942           6 :   parameter_mix_D[TRP].push_back(-10058.20599969184);
+    5943           6 :   parameter_mix_D[TRP].push_back(86171.76479108425);
+    5944           6 :   parameter_mix_D[TRP].push_back(-83227.63139882773);
+    5945           6 :   parameter_mix_D[TRP].push_back(25121.390436258724);
+    5946             : 
+    5947           6 :   parameter_mix_D[TYR].push_back(6059.530560118732);
+    5948           6 :   parameter_mix_D[TYR].push_back(-24.522695525705736);
+    5949           6 :   parameter_mix_D[TYR].push_back(-17180.858815360847);
+    5950           6 :   parameter_mix_D[TYR].push_back(-5990.1358528219325);
+    5951           6 :   parameter_mix_D[TYR].push_back(52936.46126637543);
+    5952           6 :   parameter_mix_D[TYR].push_back(-50150.0042622683);
+    5953           6 :   parameter_mix_D[TYR].push_back(14914.553672440441);
+    5954             : 
+    5955           6 :   parameter_mix_D[PHE].push_back(5563.404880119222);
+    5956           6 :   parameter_mix_D[PHE].push_back(-33.609784645922794);
+    5957           6 :   parameter_mix_D[PHE].push_back(-14576.935030777448);
+    5958           6 :   parameter_mix_D[PHE].push_back(-5759.170105553782);
+    5959           6 :   parameter_mix_D[PHE].push_back(43316.895956549866);
+    5960           6 :   parameter_mix_D[PHE].push_back(-39106.58694570862);
+    5961           6 :   parameter_mix_D[PHE].push_back(11143.375742877468);
+    5962             : 
+    5963           6 :   parameter_mix_D[HIP].push_back(3981.7108801192553);
+    5964           6 :   parameter_mix_D[HIP].push_back(-23.788371565946427);
+    5965           6 :   parameter_mix_D[HIP].push_back(-9471.73953776056);
+    5966           6 :   parameter_mix_D[HIP].push_back(-3690.3981577198365);
+    5967           6 :   parameter_mix_D[HIP].push_back(26365.958584217453);
+    5968           6 :   parameter_mix_D[HIP].push_back(-23067.58974902849);
+    5969           6 :   parameter_mix_D[HIP].push_back(6390.507451097114);
+    5970             : 
+    5971           6 :   parameter_mix_D[ARG].push_back(6279.489359881259);
+    5972           6 :   parameter_mix_D[ARG].push_back(1.2061878338083583);
+    5973           6 :   parameter_mix_D[ARG].push_back(-20305.413937989913);
+    5974           6 :   parameter_mix_D[ARG].push_back(-5621.666335222669);
+    5975           6 :   parameter_mix_D[ARG].push_back(67341.96785520067);
+    5976           6 :   parameter_mix_D[ARG].push_back(-68849.15464591733);
+    5977           6 :   parameter_mix_D[ARG].push_back(21773.0630363882);
+    5978             : 
+    5979           6 :   parameter_mix_D[LYS].push_back(5434.487400119193);
+    5980           6 :   parameter_mix_D[LYS].push_back(-29.32356328987909);
+    5981           6 :   parameter_mix_D[LYS].push_back(-14363.66155749977);
+    5982           6 :   parameter_mix_D[LYS].push_back(-5650.383128516514);
+    5983           6 :   parameter_mix_D[LYS].push_back(44573.73888236887);
+    5984           6 :   parameter_mix_D[LYS].push_back(-41515.980945300485);
+    5985           6 :   parameter_mix_D[LYS].push_back(12181.965046747513);
+    5986             : 
+    5987           6 :   parameter_mix_D[CYS].push_back(1519.4030001192032);
+    5988           6 :   parameter_mix_D[CYS].push_back(-3.564386334921097);
+    5989           6 :   parameter_mix_D[CYS].push_back(-2275.813167459516);
+    5990           6 :   parameter_mix_D[CYS].push_back(-409.54431591328125);
+    5991           6 :   parameter_mix_D[CYS].push_back(2969.5412742839258);
+    5992           6 :   parameter_mix_D[CYS].push_back(-1798.3157146799638);
+    5993           6 :   parameter_mix_D[CYS].push_back(314.568167888235);
+    5994             : 
+    5995           6 :   parameter_mix_D[CYX].push_back(1310.696400119220);
+    5996           6 :   parameter_mix_D[CYX].push_back(-2.919852579787);
+    5997           6 :   parameter_mix_D[CYX].push_back(-1902.283026713150);
+    5998           6 :   parameter_mix_D[CYX].push_back(-340.431267947190);
+    5999           6 :   parameter_mix_D[CYX].push_back(2480.025274590502);
+    6000           6 :   parameter_mix_D[CYX].push_back(-1529.188197179144);
+    6001           6 :   parameter_mix_D[CYX].push_back(278.926068515295);
+    6002             : 
+    6003           6 :   parameter_mix_D[ASP].push_back(1861.6998401191709);
+    6004           6 :   parameter_mix_D[ASP].push_back(-5.349780637260551);
+    6005           6 :   parameter_mix_D[ASP].push_back(-2960.36741510377);
+    6006           6 :   parameter_mix_D[ASP].push_back(-621.8270745040523);
+    6007           6 :   parameter_mix_D[ASP].push_back(4334.798300452934);
+    6008           6 :   parameter_mix_D[ASP].push_back(-2776.8560521554878);
+    6009           6 :   parameter_mix_D[ASP].push_back(527.9777182094936);
+    6010             : 
+    6011           6 :   parameter_mix_D[GLU].push_back(2861.6017201192253);
+    6012           6 :   parameter_mix_D[GLU].push_back(-13.146456903921809);
+    6013           6 :   parameter_mix_D[GLU].push_back(-5393.408563875243);
+    6014           6 :   parameter_mix_D[GLU].push_back(-1646.460570818364);
+    6015           6 :   parameter_mix_D[GLU].push_back(10884.544923253858);
+    6016           6 :   parameter_mix_D[GLU].push_back(-8159.923373048856);
+    6017           6 :   parameter_mix_D[GLU].push_back(1914.545660397314);
+    6018             : 
+    6019           6 :   parameter_mix_D[ILE].push_back(4288.585540119189);
+    6020           6 :   parameter_mix_D[ILE].push_back(-19.937215352880365);
+    6021           6 :   parameter_mix_D[ILE].push_back(-8324.540144463375);
+    6022           6 :   parameter_mix_D[ILE].push_back(-2431.835931316717);
+    6023           6 :   parameter_mix_D[ILE].push_back(16079.9912986194);
+    6024           6 :   parameter_mix_D[ILE].push_back(-11637.693060394462);
+    6025           6 :   parameter_mix_D[ILE].push_back(2600.8258068480495);
+    6026             : 
+    6027           6 :   parameter_mix_D[LEU].push_back(4288.585540119186);
+    6028           6 :   parameter_mix_D[LEU].push_back(-21.50343599461759);
+    6029           6 :   parameter_mix_D[LEU].push_back(-8479.703435720274);
+    6030           6 :   parameter_mix_D[LEU].push_back(-2647.8693829269596);
+    6031           6 :   parameter_mix_D[LEU].push_back(17297.18115838578);
+    6032           6 :   parameter_mix_D[LEU].push_back(-12826.972408323161);
+    6033           6 :   parameter_mix_D[LEU].push_back(2953.1262521615645);
+    6034             : 
+    6035           6 :   parameter_mix_D[MET].push_back(3561.6276801191552);
+    6036           6 :   parameter_mix_D[MET].push_back(-22.19323392975885);
+    6037           6 :   parameter_mix_D[MET].push_back(-8348.33907053846);
+    6038           6 :   parameter_mix_D[MET].push_back(-3323.053272414289);
+    6039           6 :   parameter_mix_D[MET].push_back(23153.238909304255);
+    6040           6 :   parameter_mix_D[MET].push_back(-20091.960440908682);
+    6041           6 :   parameter_mix_D[MET].push_back(5518.759669687693);
+    6042             : 
+    6043           6 :   parameter_mix_D[ASN].push_back(2326.5396001192003);
+    6044           6 :   parameter_mix_D[ASN].push_back(-8.634908921289112);
+    6045           6 :   parameter_mix_D[ASN].push_back(-4057.4552636749636);
+    6046           6 :   parameter_mix_D[ASN].push_back(-1032.743130124821);
+    6047           6 :   parameter_mix_D[ASN].push_back(6957.141592429445);
+    6048           6 :   parameter_mix_D[ASN].push_back(-4808.265318722317);
+    6049           6 :   parameter_mix_D[ASN].push_back(1016.3944815533755);
+    6050             : 
+    6051           6 :   parameter_mix_D[PRO].push_back(2471.1663601191985);
+    6052           6 :   parameter_mix_D[PRO].push_back(-6.360795284260088);
+    6053           6 :   parameter_mix_D[PRO].push_back(-3825.4533158429153);
+    6054           6 :   parameter_mix_D[PRO].push_back(-728.7164844824666);
+    6055           6 :   parameter_mix_D[PRO].push_back(5195.036303827973);
+    6056           6 :   parameter_mix_D[PRO].push_back(-3183.733716480742);
+    6057           6 :   parameter_mix_D[PRO].push_back(563.2376162754107);
+    6058             : 
+    6059           6 :   parameter_mix_D[GLN].push_back(3431.669280119236);
+    6060           6 :   parameter_mix_D[GLN].push_back(-19.412747205646166);
+    6061           6 :   parameter_mix_D[GLN].push_back(-7298.017973002134);
+    6062           6 :   parameter_mix_D[GLN].push_back(-2659.3014182337706);
+    6063           6 :   parameter_mix_D[GLN].push_back(17890.76595805173);
+    6064           6 :   parameter_mix_D[GLN].push_back(-14684.603067192957);
+    6065           6 :   parameter_mix_D[GLN].push_back(3814.338335151394);
+    6066             : 
+    6067           6 :   parameter_mix_D[SER].push_back(1423.885200119192);
+    6068           6 :   parameter_mix_D[SER].push_back(-2.586428606204385);
+    6069           6 :   parameter_mix_D[SER].push_back(-1966.7369507188134);
+    6070           6 :   parameter_mix_D[SER].push_back(-289.17277383434106);
+    6071           6 :   parameter_mix_D[SER].push_back(2209.478296043199);
+    6072           6 :   parameter_mix_D[SER].push_back(-1216.1521614944);
+    6073           6 :   parameter_mix_D[SER].push_back(177.0615931546754);
+    6074             : 
+    6075           6 :   parameter_mix_D[THR].push_back(2311.2364801191825);
+    6076           6 :   parameter_mix_D[THR].push_back(-6.258071321531929);
+    6077           6 :   parameter_mix_D[THR].push_back(-3656.295629081312);
+    6078           6 :   parameter_mix_D[THR].push_back(-716.4013890357804);
+    6079           6 :   parameter_mix_D[THR].push_back(5071.656317108832);
+    6080           6 :   parameter_mix_D[THR].push_back(-3125.8076789667816);
+    6081           6 :   parameter_mix_D[THR].push_back(555.9775741081131);
+    6082             : 
+    6083           6 :   parameter_mix_D[VAL].push_back(3041.128320119224);
+    6084           6 :   parameter_mix_D[VAL].push_back(-9.314034190716423);
+    6085           6 :   parameter_mix_D[VAL].push_back(-5075.684780220629);
+    6086           6 :   parameter_mix_D[VAL].push_back(-1070.7083380665008);
+    6087           6 :   parameter_mix_D[VAL].push_back(7455.654515006894);
+    6088           6 :   parameter_mix_D[VAL].push_back(-4701.19187164774);
+    6089           6 :   parameter_mix_D[VAL].push_back(863.4906179388547);
+    6090             : 
+    6091           6 :   parameter_mix_D[ALA].push_back(1187.65300011922);
+    6092           6 :   parameter_mix_D[ALA].push_back(-1.7011187932116822);
+    6093           6 :   parameter_mix_D[ALA].push_back(-1521.0113615359212);
+    6094           6 :   parameter_mix_D[ALA].push_back(-187.93745840575576);
+    6095           6 :   parameter_mix_D[ALA].push_back(1514.6745873304449);
+    6096           6 :   parameter_mix_D[ALA].push_back(-775.3890045113897);
+    6097           6 :   parameter_mix_D[ALA].push_back(96.41428177656567);
+    6098             : 
+    6099           6 :   parameter_mix_D[GLY].push_back(581.6349001192067);
+    6100           6 :   parameter_mix_D[GLY].push_back(-0.5877833598361395);
+    6101           6 :   parameter_mix_D[GLY].push_back(-640.0421286186524);
+    6102           6 :   parameter_mix_D[GLY].push_back(-64.58515074152534);
+    6103           6 :   parameter_mix_D[GLY].push_back(551.9509853583185);
+    6104           6 :   parameter_mix_D[GLY].push_back(-264.1522021146006);
+    6105           6 :   parameter_mix_D[GLY].push_back(28.36986478439301);
+    6106             : 
+    6107           6 :   parameter_mix_D[HIS].push_back(3648.812220119277);
+    6108           6 :   parameter_mix_D[HIS].push_back(-22.703075403555548);
+    6109           6 :   parameter_mix_D[HIS].push_back(-8260.235189881098);
+    6110           6 :   parameter_mix_D[HIS].push_back(-3190.3176569039265);
+    6111           6 :   parameter_mix_D[HIS].push_back(21589.074332364213);
+    6112           6 :   parameter_mix_D[HIS].push_back(-18108.640157613925);
+    6113           6 :   parameter_mix_D[HIS].push_back(4801.237639634437);
+    6114             : 
+    6115           6 :   parameter_vac_D[TRP].push_back(270.43802511921314);
+    6116           6 :   parameter_vac_D[TRP].push_back(-2.196022464340772);
+    6117           6 :   parameter_vac_D[TRP].push_back(-780.9546710244318);
+    6118           6 :   parameter_vac_D[TRP].push_back(-371.1573508312626);
+    6119           6 :   parameter_vac_D[TRP].push_back(2668.7678731652445);
+    6120           6 :   parameter_vac_D[TRP].push_back(-2478.2920954223678);
+    6121           6 :   parameter_vac_D[TRP].push_back(722.3731624901676);
+    6122             : 
+    6123           6 :   parameter_vac_D[TYR].push_back(198.471744119211);
+    6124           6 :   parameter_vac_D[TYR].push_back(-1.236792846228289);
+    6125           6 :   parameter_vac_D[TYR].push_back(-508.0448711054671);
+    6126           6 :   parameter_vac_D[TYR].push_back(-210.55908129481216);
+    6127           6 :   parameter_vac_D[TYR].push_back(1558.3884734212413);
+    6128           6 :   parameter_vac_D[TYR].push_back(-1418.36319255665);
+    6129           6 :   parameter_vac_D[TYR].push_back(407.21567613893296);
+    6130             : 
+    6131           6 :   parameter_vac_D[PHE].push_back(182.46606411921402);
+    6132           6 :   parameter_vac_D[PHE].push_back(-1.2708008333861447);
+    6133           6 :   parameter_vac_D[PHE].push_back(-424.50905926426054);
+    6134           6 :   parameter_vac_D[PHE].push_back(-177.97207825696387);
+    6135           6 :   parameter_vac_D[PHE].push_back(1180.839971941918);
+    6136           6 :   parameter_vac_D[PHE].push_back(-1004.004765231886);
+    6137           6 :   parameter_vac_D[PHE].push_back(269.34384064610344);
+    6138             : 
+    6139           6 :   parameter_vac_D[HIP].push_back(161.95107611920753);
+    6140           6 :   parameter_vac_D[HIP].push_back(-0.9661246983835707);
+    6141           6 :   parameter_vac_D[HIP].push_back(-332.04673226423995);
+    6142           6 :   parameter_vac_D[HIP].push_back(-125.41755194926544);
+    6143           6 :   parameter_vac_D[HIP].push_back(808.705672166199);
+    6144           6 :   parameter_vac_D[HIP].push_back(-648.8340711218191);
+    6145           6 :   parameter_vac_D[HIP].push_back(163.71251277400307);
+    6146             : 
+    6147           6 :   parameter_vac_D[ARG].push_back(289.0340011192071);
+    6148           6 :   parameter_vac_D[ARG].push_back(-1.4195753436279361);
+    6149           6 :   parameter_vac_D[ARG].push_back(-836.3864005546434);
+    6150           6 :   parameter_vac_D[ARG].push_back(-346.7081039129904);
+    6151           6 :   parameter_vac_D[ARG].push_back(2922.003491580559);
+    6152           6 :   parameter_vac_D[ARG].push_back(-2864.816533173085);
+    6153           6 :   parameter_vac_D[ARG].push_back(877.9525045072293);
+    6154             : 
+    6155           6 :   parameter_vac_D[LYS].push_back(228.64464111920753);
+    6156           6 :   parameter_vac_D[LYS].push_back(-1.686580749083617);
+    6157           6 :   parameter_vac_D[LYS].push_back(-544.8870548339771);
+    6158           6 :   parameter_vac_D[LYS].push_back(-252.11087773186324);
+    6159           6 :   parameter_vac_D[LYS].push_back(1693.784850493428);
+    6160           6 :   parameter_vac_D[LYS].push_back(-1514.2375008160348);
+    6161           6 :   parameter_vac_D[LYS].push_back(427.0713155512121);
+    6162             : 
+    6163           6 :   parameter_vac_D[CYS].push_back(50.836900116324315);
+    6164           6 :   parameter_vac_D[CYS].push_back(-0.040204572899665315);
+    6165           6 :   parameter_vac_D[CYS].push_back(-55.592868149339424);
+    6166           6 :   parameter_vac_D[CYS].push_back(-4.341359624977117);
+    6167           6 :   parameter_vac_D[CYS].push_back(41.55290573185214);
+    6168           6 :   parameter_vac_D[CYS].push_back(-17.248208429078456);
+    6169           6 :   parameter_vac_D[CYS].push_back(1.0736187172140528);
+    6170             : 
+    6171           6 :   parameter_vac_D[CYX].push_back(41.770369115535);
+    6172           6 :   parameter_vac_D[CYX].push_back(-0.019277246931);
+    6173           6 :   parameter_vac_D[CYX].push_back(-40.006821199463);
+    6174           6 :   parameter_vac_D[CYX].push_back(-2.056736901533);
+    6175           6 :   parameter_vac_D[CYX].push_back(23.707430747544);
+    6176           6 :   parameter_vac_D[CYX].push_back(-8.010813092204);
+    6177           6 :   parameter_vac_D[CYX].push_back(-0.023482540763);
+    6178             : 
+    6179           6 :   parameter_vac_D[ASP].push_back(64.12806411920792);
+    6180           6 :   parameter_vac_D[ASP].push_back(-0.08245818875074411);
+    6181           6 :   parameter_vac_D[ASP].push_back(-78.95500211069523);
+    6182           6 :   parameter_vac_D[ASP].push_back(-9.030157332821238);
+    6183           6 :   parameter_vac_D[ASP].push_back(74.72033164806712);
+    6184           6 :   parameter_vac_D[ASP].push_back(-36.71042192737952);
+    6185           6 :   parameter_vac_D[ASP].push_back(4.0989206257493676);
+    6186             : 
+    6187           6 :   parameter_vac_D[GLU].push_back(100.14004911920799);
+    6188           6 :   parameter_vac_D[GLU].push_back(-0.28685123265362006);
+    6189           6 :   parameter_vac_D[GLU].push_back(-152.44619103423773);
+    6190           6 :   parameter_vac_D[GLU].push_back(-32.99432901288321);
+    6191           6 :   parameter_vac_D[GLU].push_back(225.5853175183811);
+    6192           6 :   parameter_vac_D[GLU].push_back(-144.8489352831419);
+    6193           6 :   parameter_vac_D[GLU].push_back(27.49692658880534);
+    6194             : 
+    6195           6 :   parameter_vac_D[ILE].push_back(165.04540911921134);
+    6196           6 :   parameter_vac_D[ILE].push_back(-0.5061553029227089);
+    6197           6 :   parameter_vac_D[ILE].push_back(-275.1890586090823);
+    6198           6 :   parameter_vac_D[ILE].push_back(-57.288063177375356);
+    6199           6 :   parameter_vac_D[ILE].push_back(398.9780357099449);
+    6200           6 :   parameter_vac_D[ILE].push_back(-245.42678814428692);
+    6201           6 :   parameter_vac_D[ILE].push_back(42.72941025472001);
+    6202             : 
+    6203           6 :   parameter_vac_D[LEU].push_back(165.04540911921134);
+    6204           6 :   parameter_vac_D[LEU].push_back(-0.580034983510499);
+    6205           6 :   parameter_vac_D[LEU].push_back(-281.30910057877514);
+    6206           6 :   parameter_vac_D[LEU].push_back(-66.19427345166183);
+    6207           6 :   parameter_vac_D[LEU].push_back(445.19214155995115);
+    6208           6 :   parameter_vac_D[LEU].push_back(-287.0653610399624);
+    6209           6 :   parameter_vac_D[LEU].push_back(53.86626261066706);
+    6210             : 
+    6211           6 :   parameter_vac_D[MET].push_back(123.83238411920684);
+    6212           6 :   parameter_vac_D[MET].push_back(-0.7698672022751385);
+    6213           6 :   parameter_vac_D[MET].push_back(-251.2481622173618);
+    6214           6 :   parameter_vac_D[MET].push_back(-100.67742019193848);
+    6215           6 :   parameter_vac_D[MET].push_back(641.1563254731632);
+    6216           6 :   parameter_vac_D[MET].push_back(-524.8742634212379);
+    6217           6 :   parameter_vac_D[MET].push_back(135.36487813767542);
+    6218             : 
+    6219           6 :   parameter_vac_D[ASN].push_back(94.12880411921148);
+    6220           6 :   parameter_vac_D[ASN].push_back(-0.22986194121078912);
+    6221           6 :   parameter_vac_D[ASN].push_back(-138.78769705028003);
+    6222           6 :   parameter_vac_D[ASN].push_back(-25.896846049402594);
+    6223           6 :   parameter_vac_D[ASN].push_back(184.55609781654326);
+    6224           6 :   parameter_vac_D[ASN].push_back(-110.14043851975404);
+    6225           6 :   parameter_vac_D[ASN].push_back(18.388834098004153);
+    6226             : 
+    6227           6 :   parameter_vac_D[PRO].push_back(90.51619611920745);
+    6228           6 :   parameter_vac_D[PRO].push_back(-0.0977238494110807);
+    6229           6 :   parameter_vac_D[PRO].push_back(-109.43531311067846);
+    6230           6 :   parameter_vac_D[PRO].push_back(-10.592981104983805);
+    6231           6 :   parameter_vac_D[PRO].push_back(93.64863466237733);
+    6232           6 :   parameter_vac_D[PRO].push_back(-42.348197720920865);
+    6233           6 :   parameter_vac_D[PRO].push_back(3.5854078482704574);
+    6234             : 
+    6235           6 :   parameter_vac_D[GLN].push_back(136.91340111920806);
+    6236           6 :   parameter_vac_D[GLN].push_back(-0.7259026842220699);
+    6237           6 :   parameter_vac_D[GLN].push_back(-257.0347011897067);
+    6238           6 :   parameter_vac_D[GLN].push_back(-89.99600255417684);
+    6239           6 :   parameter_vac_D[GLN].push_back(570.3890595917421);
+    6240           6 :   parameter_vac_D[GLN].push_back(-438.8977029769549);
+    6241           6 :   parameter_vac_D[GLN].push_back(105.48846039376491);
+    6242             : 
+    6243           6 :   parameter_vac_D[SER].push_back(55.20490011583253);
+    6244           6 :   parameter_vac_D[SER].push_back(-0.038078030710377984);
+    6245           6 :   parameter_vac_D[SER].push_back(-58.79085960838952);
+    6246           6 :   parameter_vac_D[SER].push_back(-4.067364063406562);
+    6247           6 :   parameter_vac_D[SER].push_back(41.319899403658475);
+    6248           6 :   parameter_vac_D[SER].push_back(-15.865682241288962);
+    6249           6 :   parameter_vac_D[SER].push_back(0.5028409006168431);
+    6250             : 
+    6251           6 :   parameter_vac_D[THR].push_back(88.90604111920842);
+    6252           6 :   parameter_vac_D[THR].push_back(-0.11566717587697625);
+    6253           6 :   parameter_vac_D[THR].push_back(-114.4541243837681);
+    6254           6 :   parameter_vac_D[THR].push_back(-12.541537413808342);
+    6255           6 :   parameter_vac_D[THR].push_back(106.4974738790947);
+    6256           6 :   parameter_vac_D[THR].push_back(-50.15009912825225);
+    6257           6 :   parameter_vac_D[THR].push_back(4.719349514074467);
+    6258             : 
+    6259           6 :   parameter_vac_D[VAL].push_back(117.67910411920792);
+    6260           6 :   parameter_vac_D[VAL].push_back(-0.18187311248567883);
+    6261           6 :   parameter_vac_D[VAL].push_back(-162.8697844894754);
+    6262           6 :   parameter_vac_D[VAL].push_back(-19.769248288711825);
+    6263           6 :   parameter_vac_D[VAL].push_back(162.59270939168965);
+    6264           6 :   parameter_vac_D[VAL].push_back(-79.37261506441627);
+    6265           6 :   parameter_vac_D[VAL].push_back(8.230771959393175);
+    6266             : 
+    6267           6 :   parameter_vac_D[ALA].push_back(46.92250011448002);
+    6268           6 :   parameter_vac_D[ALA].push_back(-0.020339064649444412);
+    6269           6 :   parameter_vac_D[ALA].push_back(-44.41584945233503);
+    6270           6 :   parameter_vac_D[ALA].push_back(-2.1483754537886113);
+    6271           6 :   parameter_vac_D[ALA].push_back(25.713667829058785);
+    6272           6 :   parameter_vac_D[ALA].push_back(-8.222782061575268);
+    6273           6 :   parameter_vac_D[ALA].push_back(-0.2521732728817875);
+    6274             : 
+    6275           6 :   parameter_vac_D[GLY].push_back(23.532201119209795);
+    6276           6 :   parameter_vac_D[GLY].push_back(-0.00628609590047614);
+    6277           6 :   parameter_vac_D[GLY].push_back(-17.28421910139733);
+    6278           6 :   parameter_vac_D[GLY].push_back(-0.6641226821159686);
+    6279           6 :   parameter_vac_D[GLY].push_back(8.536119110048007);
+    6280           6 :   parameter_vac_D[GLY].push_back(-2.5438638688361466);
+    6281           6 :   parameter_vac_D[GLY].push_back(-0.11165675928832643);
+    6282             : 
+    6283           6 :   parameter_vac_D[HIS].push_back(145.41948111920982);
+    6284           6 :   parameter_vac_D[HIS].push_back(-0.8548328183368781);
+    6285           6 :   parameter_vac_D[HIS].push_back(-290.8653238004162);
+    6286           6 :   parameter_vac_D[HIS].push_back(-107.85375269366395);
+    6287           6 :   parameter_vac_D[HIS].push_back(685.7025818759361);
+    6288           6 :   parameter_vac_D[HIS].push_back(-538.2592043545858);
+    6289           6 :   parameter_vac_D[HIS].push_back(132.17357375729733);
+    6290             : 
+    6291             :   // NUCLEIC ACIDS
+    6292           6 :   parameter_mix_D[BB_PO3].push_back(223.2671801192072);
+    6293           6 :   parameter_mix_D[BB_PO3].push_back(-0.14452515213607267);
+    6294           6 :   parameter_mix_D[BB_PO3].push_back(-219.64134852678032);
+    6295           6 :   parameter_mix_D[BB_PO3].push_back(-15.527993497328728);
+    6296           6 :   parameter_mix_D[BB_PO3].push_back(153.27197635784856);
+    6297           6 :   parameter_mix_D[BB_PO3].push_back(-61.17793915482464);
+    6298           6 :   parameter_mix_D[BB_PO3].push_back(2.92608540200577);
+    6299             : 
+    6300           6 :   parameter_mix_D[BB_PO2].push_back(80.12660011920252);
+    6301           6 :   parameter_mix_D[BB_PO2].push_back(-0.02788855519820236);
+    6302           6 :   parameter_mix_D[BB_PO2].push_back(-60.53219491822279);
+    6303           6 :   parameter_mix_D[BB_PO2].push_back(-2.9768829034096806);
+    6304           6 :   parameter_mix_D[BB_PO2].push_back(33.30645116638123);
+    6305           6 :   parameter_mix_D[BB_PO2].push_back(-11.601573219761375);
+    6306           6 :   parameter_mix_D[BB_PO2].push_back(0.12551046492022438);
+    6307             : 
+    6308           6 :   parameter_mix_D[BB_DNA].push_back(2835.3195201193003);
+    6309           6 :   parameter_mix_D[BB_DNA].push_back(-7.954301723608173);
+    6310           6 :   parameter_mix_D[BB_DNA].push_back(-4509.325563460958);
+    6311           6 :   parameter_mix_D[BB_DNA].push_back(-909.1870692311344);
+    6312           6 :   parameter_mix_D[BB_DNA].push_back(6375.156903893768);
+    6313           6 :   parameter_mix_D[BB_DNA].push_back(-3956.4787847570715);
+    6314           6 :   parameter_mix_D[BB_DNA].push_back(708.9872879613656);
+    6315             : 
+    6316           6 :   parameter_mix_D[BB_DNA_5].push_back(3136.73358011921);
+    6317           6 :   parameter_mix_D[BB_DNA_5].push_back(-10.023435855160427);
+    6318           6 :   parameter_mix_D[BB_DNA_5].push_back(-5208.921666368173);
+    6319           6 :   parameter_mix_D[BB_DNA_5].push_back(-1160.4403539440214);
+    6320           6 :   parameter_mix_D[BB_DNA_5].push_back(7962.598421448727);
+    6321           6 :   parameter_mix_D[BB_DNA_5].push_back(-5149.059857691847);
+    6322           6 :   parameter_mix_D[BB_DNA_5].push_back(984.5217027570121);
+    6323             : 
+    6324           6 :   parameter_mix_D[BB_DNA_3].push_back(3136.73358011921);
+    6325           6 :   parameter_mix_D[BB_DNA_3].push_back(-9.618834865806274);
+    6326           6 :   parameter_mix_D[BB_DNA_3].push_back(-5164.249220443828);
+    6327           6 :   parameter_mix_D[BB_DNA_3].push_back(-1103.2721475326382);
+    6328           6 :   parameter_mix_D[BB_DNA_3].push_back(7633.46089052312);
+    6329           6 :   parameter_mix_D[BB_DNA_3].push_back(-4826.171688395644);
+    6330           6 :   parameter_mix_D[BB_DNA_3].push_back(888.1820863683546);
+    6331             : 
+    6332           6 :   parameter_mix_D[BB_RNA].push_back(3192.5955601188807);
+    6333           6 :   parameter_mix_D[BB_RNA].push_back(-11.475781582628308);
+    6334           6 :   parameter_mix_D[BB_RNA].push_back(-5486.264576931735);
+    6335           6 :   parameter_mix_D[BB_RNA].push_back(-1344.2878288415961);
+    6336           6 :   parameter_mix_D[BB_RNA].push_back(9035.26109892441);
+    6337           6 :   parameter_mix_D[BB_RNA].push_back(-6068.471909763036);
+    6338           6 :   parameter_mix_D[BB_RNA].push_back(1226.3696076463866);
+    6339             : 
+    6340           6 :   parameter_mix_D[BB_RNA_5].push_back(3512.1630401192215);
+    6341           6 :   parameter_mix_D[BB_RNA_5].push_back(-14.191020069433975);
+    6342           6 :   parameter_mix_D[BB_RNA_5].push_back(-6293.687102187508);
+    6343           6 :   parameter_mix_D[BB_RNA_5].push_back(-1689.3688494490984);
+    6344           6 :   parameter_mix_D[BB_RNA_5].push_back(11193.448566821942);
+    6345           6 :   parameter_mix_D[BB_RNA_5].push_back(-7806.9064399949375);
+    6346           6 :   parameter_mix_D[BB_RNA_5].push_back(1662.4594983069844);
+    6347             : 
+    6348           6 :   parameter_mix_D[BB_RNA_3].push_back(3512.1630401192215);
+    6349           6 :   parameter_mix_D[BB_RNA_3].push_back(-12.978118135595812);
+    6350           6 :   parameter_mix_D[BB_RNA_3].push_back(-6149.290195451877);
+    6351           6 :   parameter_mix_D[BB_RNA_3].push_back(-1515.8309761505627);
+    6352           6 :   parameter_mix_D[BB_RNA_3].push_back(10176.605450440278);
+    6353           6 :   parameter_mix_D[BB_RNA_3].push_back(-6813.250569884159);
+    6354           6 :   parameter_mix_D[BB_RNA_3].push_back(1366.823518955858);
+    6355             : 
+    6356           6 :   parameter_mix_D[BASE_A].push_back(2464.736500119229);
+    6357           6 :   parameter_mix_D[BASE_A].push_back(-12.127452038444783);
+    6358           6 :   parameter_mix_D[BASE_A].push_back(-4710.661256689607);
+    6359           6 :   parameter_mix_D[BASE_A].push_back(-1462.6964141954452);
+    6360           6 :   parameter_mix_D[BASE_A].push_back(9451.725575888277);
+    6361           6 :   parameter_mix_D[BASE_A].push_back(-6883.018479948857);
+    6362           6 :   parameter_mix_D[BASE_A].push_back(1540.1526599737797);
+    6363             : 
+    6364           6 :   parameter_mix_D[BASE_C].push_back(1797.2697601191685);
+    6365           6 :   parameter_mix_D[BASE_C].push_back(-5.963855532295215);
+    6366           6 :   parameter_mix_D[BASE_C].push_back(-2955.077717756034);
+    6367           6 :   parameter_mix_D[BASE_C].push_back(-689.4543508746372);
+    6368           6 :   parameter_mix_D[BASE_C].push_back(4665.914740532565);
+    6369           6 :   parameter_mix_D[BASE_C].push_back(-3051.4605913706982);
+    6370           6 :   parameter_mix_D[BASE_C].push_back(590.2201952719585);
+    6371             : 
+    6372           6 :   parameter_mix_D[BASE_G].push_back(2804.271480119049);
+    6373           6 :   parameter_mix_D[BASE_G].push_back(-16.928072935469974);
+    6374           6 :   parameter_mix_D[BASE_G].push_back(-5989.82519987899);
+    6375           6 :   parameter_mix_D[BASE_G].push_back(-2275.490326521775);
+    6376           6 :   parameter_mix_D[BASE_G].push_back(15007.832401865428);
+    6377           6 :   parameter_mix_D[BASE_G].push_back(-12287.520690325606);
+    6378           6 :   parameter_mix_D[BASE_G].push_back(3172.98306575258);
+    6379             : 
+    6380           6 :   parameter_mix_D[BASE_T].push_back(2545.0860001192113);
+    6381           6 :   parameter_mix_D[BASE_T].push_back(-10.975141620541738);
+    6382           6 :   parameter_mix_D[BASE_T].push_back(-4636.058358764447);
+    6383           6 :   parameter_mix_D[BASE_T].push_back(-1340.3746388296138);
+    6384           6 :   parameter_mix_D[BASE_T].push_back(8850.604320505428);
+    6385           6 :   parameter_mix_D[BASE_T].push_back(-6421.852532013674);
+    6386           6 :   parameter_mix_D[BASE_T].push_back(1443.371517335904);
+    6387             : 
+    6388           6 :   parameter_mix_D[BASE_U].push_back(1608.7389001192062);
+    6389           6 :   parameter_mix_D[BASE_U].push_back(-3.9816849036181434);
+    6390           6 :   parameter_mix_D[BASE_U].push_back(-2411.056432130769);
+    6391           6 :   parameter_mix_D[BASE_U].push_back(-451.8236361945487);
+    6392           6 :   parameter_mix_D[BASE_U].push_back(3220.4418252803644);
+    6393           6 :   parameter_mix_D[BASE_U].push_back(-1944.2515577994325);
+    6394           6 :   parameter_mix_D[BASE_U].push_back(332.9259542628691);
+    6395             : 
+    6396           6 :   parameter_vac_D[BB_PO3].push_back(8.508889119209273);
+    6397           6 :   parameter_vac_D[BB_PO3].push_back(-0.0010408625482164885);
+    6398           6 :   parameter_vac_D[BB_PO3].push_back(-5.656130990440752);
+    6399           6 :   parameter_vac_D[BB_PO3].push_back(-0.10748040057053611);
+    6400           6 :   parameter_vac_D[BB_PO3].push_back(2.1441246977168227);
+    6401           6 :   parameter_vac_D[BB_PO3].push_back(-0.3967083127147655);
+    6402           6 :   parameter_vac_D[BB_PO3].push_back(-0.10110003105909898);
+    6403             : 
+    6404           6 :   parameter_vac_D[BB_PO2].push_back(2.7889001116093284);
+    6405           6 :   parameter_vac_D[BB_PO2].push_back(-0.00011178884266113128);
+    6406           6 :   parameter_vac_D[BB_PO2].push_back(-1.1702605818380654);
+    6407           6 :   parameter_vac_D[BB_PO2].push_back(-0.011278044036819927);
+    6408           6 :   parameter_vac_D[BB_PO2].push_back(0.3214006584089024);
+    6409           6 :   parameter_vac_D[BB_PO2].push_back(-0.04097165983591666);
+    6410           6 :   parameter_vac_D[BB_PO2].push_back(-0.017525098100539684);
+    6411             : 
+    6412           6 :   parameter_vac_D[BB_DNA].push_back(94.75075611920529);
+    6413           6 :   parameter_vac_D[BB_DNA].push_back(-0.13973533952241124);
+    6414           6 :   parameter_vac_D[BB_DNA].push_back(-123.45402430039046);
+    6415           6 :   parameter_vac_D[BB_DNA].push_back(-15.19494522082691);
+    6416           6 :   parameter_vac_D[BB_DNA].push_back(123.34749914811465);
+    6417           6 :   parameter_vac_D[BB_DNA].push_back(-61.038507985345504);
+    6418           6 :   parameter_vac_D[BB_DNA].push_back(6.601587478585944);
+    6419             : 
+    6420           6 :   parameter_vac_D[BB_DNA_5].push_back(108.18080111920679);
+    6421           6 :   parameter_vac_D[BB_DNA_5].push_back(-0.2055953690887981);
+    6422           6 :   parameter_vac_D[BB_DNA_5].push_back(-150.7924892157235);
+    6423           6 :   parameter_vac_D[BB_DNA_5].push_back(-22.700459516383198);
+    6424           6 :   parameter_vac_D[BB_DNA_5].push_back(172.2599851655527);
+    6425           6 :   parameter_vac_D[BB_DNA_5].push_back(-93.4983124807692);
+    6426           6 :   parameter_vac_D[BB_DNA_5].push_back(12.867661230942868);
+    6427             : 
+    6428           6 :   parameter_vac_D[BB_DNA_3].push_back(108.18080111920537);
+    6429           6 :   parameter_vac_D[BB_DNA_3].push_back(-0.18263717534168372);
+    6430           6 :   parameter_vac_D[BB_DNA_3].push_back(-148.5918817744255);
+    6431           6 :   parameter_vac_D[BB_DNA_3].push_back(-19.90799847398835);
+    6432           6 :   parameter_vac_D[BB_DNA_3].push_back(157.55184203379557);
+    6433           6 :   parameter_vac_D[BB_DNA_3].push_back(-80.28471270058103);
+    6434           6 :   parameter_vac_D[BB_DNA_3].push_back(9.313712500298278);
+    6435             : 
+    6436           6 :   parameter_vac_D[BB_RNA].push_back(106.37859611922117);
+    6437           6 :   parameter_vac_D[BB_RNA].push_back(-0.2380766148121975);
+    6438           6 :   parameter_vac_D[BB_RNA].push_back(-153.74131338570024);
+    6439           6 :   parameter_vac_D[BB_RNA].push_back(-26.415436217574932);
+    6440           6 :   parameter_vac_D[BB_RNA].push_back(191.90585451112776);
+    6441           6 :   parameter_vac_D[BB_RNA].push_back(-109.61737794316868);
+    6442           6 :   parameter_vac_D[BB_RNA].push_back(16.663804191332204);
+    6443             : 
+    6444           6 :   parameter_vac_D[BB_RNA_5].push_back(120.58236111920618);
+    6445           6 :   parameter_vac_D[BB_RNA_5].push_back(-0.340258533619014);
+    6446           6 :   parameter_vac_D[BB_RNA_5].push_back(-186.08333929996334);
+    6447           6 :   parameter_vac_D[BB_RNA_5].push_back(-38.493337147644795);
+    6448           6 :   parameter_vac_D[BB_RNA_5].push_back(266.2262415641144);
+    6449           6 :   parameter_vac_D[BB_RNA_5].push_back(-164.73088478359585);
+    6450           6 :   parameter_vac_D[BB_RNA_5].push_back(29.07014157680879);
+    6451             : 
+    6452           6 :   parameter_vac_D[BB_RNA_3].push_back(120.5823611192099);
+    6453           6 :   parameter_vac_D[BB_RNA_3].push_back(-0.274146129206928);
+    6454           6 :   parameter_vac_D[BB_RNA_3].push_back(-179.24499182395388);
+    6455           6 :   parameter_vac_D[BB_RNA_3].push_back(-30.315729372259426);
+    6456           6 :   parameter_vac_D[BB_RNA_3].push_back(222.2645581367648);
+    6457           6 :   parameter_vac_D[BB_RNA_3].push_back(-125.13581171514033);
+    6458           6 :   parameter_vac_D[BB_RNA_3].push_back(18.350308154920107);
+    6459             : 
+    6460           6 :   parameter_vac_D[BASE_A].push_back(114.34024911921);
+    6461           6 :   parameter_vac_D[BASE_A].push_back(-0.4136665918383359);
+    6462           6 :   parameter_vac_D[BASE_A].push_back(-192.33138384655922);
+    6463           6 :   parameter_vac_D[BASE_A].push_back(-46.74428306691412);
+    6464           6 :   parameter_vac_D[BASE_A].push_back(312.9511030981905);
+    6465           6 :   parameter_vac_D[BASE_A].push_back(-199.6349962647333);
+    6466           6 :   parameter_vac_D[BASE_A].push_back(36.15938693202153);
+    6467             : 
+    6468           6 :   parameter_vac_D[BASE_C].push_back(76.17798411921166);
+    6469           6 :   parameter_vac_D[BASE_C].push_back(-0.1444475142707445);
+    6470           6 :   parameter_vac_D[BASE_C].push_back(-102.66873668949485);
+    6471           6 :   parameter_vac_D[BASE_C].push_back(-15.813768367725821);
+    6472           6 :   parameter_vac_D[BASE_C].push_back(119.63436338715553);
+    6473           6 :   parameter_vac_D[BASE_C].push_back(-64.22251971660583);
+    6474           6 :   parameter_vac_D[BASE_C].push_back(8.351952332828862);
+    6475             : 
+    6476           6 :   parameter_vac_D[BASE_G].push_back(127.08052911921965);
+    6477           6 :   parameter_vac_D[BASE_G].push_back(-0.7137457014712297);
+    6478           6 :   parameter_vac_D[BASE_G].push_back(-239.67686838772786);
+    6479           6 :   parameter_vac_D[BASE_G].push_back(-88.53661981200943);
+    6480           6 :   parameter_vac_D[BASE_G].push_back(556.7254485453866);
+    6481           6 :   parameter_vac_D[BASE_G].push_back(-432.0234649577737);
+    6482           6 :   parameter_vac_D[BASE_G].push_back(104.407200463848);
+    6483             : 
+    6484           6 :   parameter_vac_D[BASE_T].push_back(94.09000011920868);
+    6485           6 :   parameter_vac_D[BASE_T].push_back(-0.27147149980458524);
+    6486           6 :   parameter_vac_D[BASE_T].push_back(-143.65649702254174);
+    6487           6 :   parameter_vac_D[BASE_T].push_back(-30.861235738371892);
+    6488           6 :   parameter_vac_D[BASE_T].push_back(212.3643014774958);
+    6489           6 :   parameter_vac_D[BASE_T].push_back(-133.06675501066275);
+    6490           6 :   parameter_vac_D[BASE_T].push_back(23.951588200687073);
+    6491             : 
+    6492           6 :   parameter_vac_D[BASE_U].push_back(59.30540111665979);
+    6493           6 :   parameter_vac_D[BASE_U].push_back(-0.06146929846591808);
+    6494           6 :   parameter_vac_D[BASE_U].push_back(-67.43680950211682);
+    6495           6 :   parameter_vac_D[BASE_U].push_back(-6.625289749170134);
+    6496           6 :   parameter_vac_D[BASE_U].push_back(58.37012229348065);
+    6497           6 :   parameter_vac_D[BASE_U].push_back(-26.23044613101723);
+    6498           6 :   parameter_vac_D[BASE_U].push_back(2.061238351422343);
+    6499             : 
+    6500       21340 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    6501       21334 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    6502       21334 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    6503       21334 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    6504       21334 :     if(Rname=="ALA") {
+    6505        1078 :       atoi[residue_atom[i]]=ALA;
+    6506       20256 :     } else if(Rname=="ARG") {
+    6507        1296 :       atoi[residue_atom[i]]=ARG;
+    6508       18960 :     } else if(Rname=="ASN") {
+    6509        1080 :       atoi[residue_atom[i]]=ASN;
+    6510       17880 :     } else if(Rname=="ASP") {
+    6511         936 :       atoi[residue_atom[i]]=ASP;
+    6512       16944 :     } else if(Rname=="CYS") {
+    6513          72 :       atoi[residue_atom[i]]=CYS;
+    6514       16872 :     } else if(Rname=="CYX") {
+    6515           0 :       atoi[residue_atom[i]]=CYX;
+    6516       16872 :     } else if(Rname=="GLN") {
+    6517        1558 :       atoi[residue_atom[i]]=GLN;
+    6518       15314 :     } else if(Rname=="GLU") {
+    6519         714 :       atoi[residue_atom[i]]=GLU;
+    6520       14600 :     } else if(Rname=="GLY") {
+    6521         936 :       atoi[residue_atom[i]]=GLY;
+    6522       13664 :     } else if(Rname=="HIS") {
+    6523           0 :       atoi[residue_atom[i]]=HIS;
+    6524       13664 :     } else if(Rname=="HID") {
+    6525           0 :       atoi[residue_atom[i]]=HIS;
+    6526       13664 :     } else if(Rname=="HIE") {
+    6527         216 :       atoi[residue_atom[i]]=HIS;
+    6528       13448 :     } else if(Rname=="HIP") {
+    6529           0 :       atoi[residue_atom[i]]=HIP;
+    6530             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    6531       13448 :     } else if(Rname=="HSD") {
+    6532           0 :       atoi[residue_atom[i]]=HIS;
+    6533       13448 :     } else if(Rname=="HSE") {
+    6534           0 :       atoi[residue_atom[i]]=HIS;
+    6535       13448 :     } else if(Rname=="HSP") {
+    6536           0 :       atoi[residue_atom[i]]=HIP;
+    6537       13448 :     } else if(Rname=="ILE") {
+    6538        1296 :       atoi[residue_atom[i]]=ILE;
+    6539       12152 :     } else if(Rname=="LEU") {
+    6540        2280 :       atoi[residue_atom[i]]=LEU;
+    6541        9872 :     } else if(Rname=="LYS") {
+    6542        1560 :       atoi[residue_atom[i]]=LYS;
+    6543        8312 :     } else if(Rname=="MET") {
+    6544         836 :       atoi[residue_atom[i]]=MET;
+    6545        7476 :     } else if(Rname=="PHE") {
+    6546        1512 :       atoi[residue_atom[i]]=PHE;
+    6547        5964 :     } else if(Rname=="PRO") {
+    6548        1122 :       atoi[residue_atom[i]]=PRO;
+    6549        4842 :     } else if(Rname=="SER") {
+    6550         768 :       atoi[residue_atom[i]]=SER;
+    6551        4074 :     } else if(Rname=="THR") {
+    6552         728 :       atoi[residue_atom[i]]=THR;
+    6553        3346 :     } else if(Rname=="TRP") {
+    6554           0 :       atoi[residue_atom[i]]=TRP;
+    6555        3346 :     } else if(Rname=="TYR") {
+    6556         792 :       atoi[residue_atom[i]]=TYR;
+    6557        2554 :     } else if(Rname=="VAL") {
+    6558        1600 :       atoi[residue_atom[i]]=VAL;
+    6559             :     }
+    6560             :     // NUCLEIC ACIDS
+    6561             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    6562             :     // RNA - G
+    6563         954 :     else if(Rname=="G") {
+    6564           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    6565           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    6566           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6567           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6568           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6569           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6570           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6571           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6572           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6573           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6574           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6575           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6576           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6577           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6578           0 :         atoi[residue_atom[i]]=BASE_G;
+    6579           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6580             :       // RNA - G3
+    6581         954 :     } else if(Rname=="G3") {
+    6582           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6583           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6584           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6585           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6586           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6587           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6588           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6589           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6590           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6591           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6592           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6593           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6594           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6595           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6596           0 :         atoi[residue_atom[i]]=BASE_G;
+    6597           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6598             :       // RNA - G5
+    6599         954 :     } else if(Rname=="G5") {
+    6600           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6601           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6602           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6603           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6604           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6605           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6606           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6607           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6608           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6609           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6610           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6611           0 :         atoi[residue_atom[i]]=BASE_G;
+    6612           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6613             :       // RNA - GT
+    6614         954 :     } else if(Rname=="GT") {
+    6615           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    6616           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    6617           0 :         atoi [residue_atom[i]]=BB_PO3;
+    6618           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6619           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6620           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6621           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6622           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6623           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6624           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6625           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6626           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6627           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6628           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6629           0 :         atoi[residue_atom[i]]=BASE_G;
+    6630           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6631             :       // RNA - U
+    6632         954 :     } else if(Rname=="U") {
+    6633        2886 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    6634        1482 :           Aname=="O1P" || Aname=="O2P"  ) {
+    6635          78 :         atoi [residue_atom[i]]=BB_PO2;
+    6636        2548 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6637        2132 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6638        1716 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6639        1326 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6640        1196 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6641        1560 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6642         416 :         atoi[residue_atom[i]]=BB_RNA;
+    6643         884 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6644         468 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6645         364 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6646         286 :         atoi[residue_atom[i]]=BASE_U;
+    6647           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6648             :       // RNA - U3
+    6649         174 :     } else if(Rname=="U3") {
+    6650         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6651         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6652           6 :         atoi [residue_atom[i]]=BB_PO2;
+    6653         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6654         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6655         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6656         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6657          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6658          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6659          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6660          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6661          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6662          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6663          22 :         atoi[residue_atom[i]]=BASE_U;
+    6664           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6665             :       // RNA - U5
+    6666         112 :     } else if(Rname=="U5") {
+    6667         408 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6668         344 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6669         280 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6670         216 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6671         176 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6672         156 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6673          68 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6674         136 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6675          72 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6676          56 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6677          44 :         atoi[residue_atom[i]]=BASE_U;
+    6678           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6679             :       // RNA - UT
+    6680           0 :     } else if(Rname=="UT") {
+    6681           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    6682           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    6683           0 :         atoi [residue_atom[i]]=BB_PO3;
+    6684           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6685           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6686           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6687           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6688           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6689           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6690           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6691           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6692           0 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6693           0 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6694           0 :         atoi[residue_atom[i]]=BASE_U;
+    6695           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6696             :       // RNA - A
+    6697           0 :     } else if(Rname=="A") {
+    6698           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    6699           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    6700           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6701           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6702           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6703           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6704           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6705           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6706           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6707           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6708           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6709           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6710           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6711           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6712           0 :         atoi[residue_atom[i]]=BASE_A;
+    6713           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6714             :       // RNA - A3
+    6715           0 :     } else if(Rname=="A3") {
+    6716           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6717           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6718           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6719           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6720           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6721           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6722           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6723           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6724           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6725           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6726           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6727           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6728           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6729           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6730           0 :         atoi[residue_atom[i]]=BASE_A;
+    6731           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6732             :       // RNA - A5
+    6733           0 :     } else if(Rname=="A5") {
+    6734           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6735           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6736           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6737           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6738           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6739           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6740           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6741           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6742           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6743           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6744           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6745           0 :         atoi[residue_atom[i]]=BASE_A;
+    6746           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6747             :       // RNA - AT
+    6748           0 :     } else if(Rname=="AT") {
+    6749           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    6750           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    6751           0 :         atoi [residue_atom[i]]=BB_PO3;
+    6752           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6753           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6754           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6755           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6756           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6757           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6758           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6759           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6760           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6761           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6762           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6763           0 :         atoi[residue_atom[i]]=BASE_A;
+    6764           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6765             :       // RNA - C
+    6766           0 :     } else if(Rname=="C") {
+    6767           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    6768           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    6769           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6770           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6771           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6772           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6773           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6774           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6775           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6776           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6777           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6778           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6779           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6780           0 :         atoi[residue_atom[i]]=BASE_C;
+    6781           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6782             :       // RNA - C3
+    6783           0 :     } else if(Rname=="C3") {
+    6784           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6785           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6786           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6787           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6788           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6789           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6790           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6791           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6792           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6793           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6794           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6795           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6796           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6797           0 :         atoi[residue_atom[i]]=BASE_C;
+    6798           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6799             :       // RNA - C5
+    6800           0 :     } else if(Rname=="C5") {
+    6801           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6802           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6803           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6804           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6805           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6806           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6807           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6808           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6809           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6810           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6811           0 :         atoi[residue_atom[i]]=BASE_C;
+    6812           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6813             :       // RNA - CT
+    6814           0 :     } else if(Rname=="CT") {
+    6815           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    6816           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    6817           0 :         atoi [residue_atom[i]]=BB_PO3;
+    6818           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6819           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6820           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6821           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6822           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6823           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6824           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6825           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6826           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6827           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6828           0 :         atoi[residue_atom[i]]=BASE_C;
+    6829           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6830             :       // DNA - G
+    6831           0 :     } else if(Rname=="DG") {
+    6832           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    6833           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    6834           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6835           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6836           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6837           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6838           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6839           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6840           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6841           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6842           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6843           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6844           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6845           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6846           0 :         atoi[residue_atom[i]]=BASE_G;
+    6847           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6848             :       // DNA - G3
+    6849           0 :     } else if(Rname=="DG3") {
+    6850           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6851           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6852           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6853           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6854           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6855           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6856           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6857           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6858             :                 Aname=="H3T" ) {
+    6859           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6860           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6861           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6862           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6863           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6864           0 :         atoi[residue_atom[i]]=BASE_G;
+    6865           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6866             :       // DNA - G5
+    6867           0 :     } else if(Rname=="DG5") {
+    6868           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6869           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6870           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6871           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6872           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6873             :           Aname=="H5T" ) {
+    6874           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6875           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6876           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6877           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6878           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6879           0 :         atoi[residue_atom[i]]=BASE_G;
+    6880           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6881             :       // DNA - GT
+    6882           0 :     } else if(Rname=="DGT") {
+    6883           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    6884           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    6885           0 :         atoi [residue_atom[i]]=BB_PO3;
+    6886           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6887           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6888           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6889           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6890           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6891           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6892           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6893           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6894           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6895           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6896           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6897           0 :         atoi[residue_atom[i]]=BASE_G;
+    6898           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6899             :       // DNA - T
+    6900           0 :     } else if(Rname=="DT") {
+    6901           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    6902           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    6903           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6904           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6905           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6906           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6907           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6908           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6909           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6910           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6911           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6912           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6913           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6914           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6915           0 :         atoi[residue_atom[i]]=BASE_T;
+    6916           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6917             :       // DNA - T3
+    6918           0 :     } else if(Rname=="DT3") {
+    6919           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6920           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6921           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6922           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6923           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6924           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6925           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6926           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6927             :                 Aname=="H3T" ) {
+    6928           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6929           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6930           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6931           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6932           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6933           0 :         atoi[residue_atom[i]]=BASE_T;
+    6934           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6935             :       // DNA - T5
+    6936           0 :     } else if(Rname=="DT5") {
+    6937           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6938           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6939           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6940           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6941           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6942             :           Aname=="H5T" ) {
+    6943           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6944           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6945           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6946           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6947           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6948           0 :         atoi[residue_atom[i]]=BASE_T;
+    6949           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6950             :       // DNA - TT
+    6951           0 :     } else if(Rname=="DTT") {
+    6952           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    6953           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    6954           0 :         atoi [residue_atom[i]]=BB_PO3;
+    6955           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6956           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6957           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6958           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6959           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6960           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6961           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6962           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6963           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6964           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6965           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6966           0 :         atoi[residue_atom[i]]=BASE_T;
+    6967           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6968             :       // DNA - A
+    6969           0 :     } else if(Rname=="DA") {
+    6970           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    6971           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    6972           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6973           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6974           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6975           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6976           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6977           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6978           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6979           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6980           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6981           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6982           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6983           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6984           0 :         atoi[residue_atom[i]]=BASE_A;
+    6985           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6986             :       // DNA - A3
+    6987           0 :     } else if(Rname=="DA3") {
+    6988           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6989           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6990           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6991           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6992           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6993           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6994           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6995           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6996             :                 Aname=="H3T" ) {
+    6997           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6998           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6999           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    7000           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    7001           0 :                 Aname=="H61" || Aname=="H62" ) {
+    7002           0 :         atoi[residue_atom[i]]=BASE_A;
+    7003           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    7004             :       // DNA - A5
+    7005           0 :     } else if(Rname=="DA5") {
+    7006           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    7007           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    7008           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    7009           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    7010           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    7011             :           Aname=="H5T" ) {
+    7012           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    7013           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    7014           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    7015           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    7016           0 :                 Aname=="H61" || Aname=="H62" ) {
+    7017           0 :         atoi[residue_atom[i]]=BASE_A;
+    7018           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    7019             :       // DNA - AT
+    7020           0 :     } else if(Rname=="DAT") {
+    7021           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    7022           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    7023           0 :         atoi [residue_atom[i]]=BB_PO3;
+    7024           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    7025           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    7026           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    7027           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    7028           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    7029           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    7030           0 :         atoi[residue_atom[i]]=BB_DNA;
+    7031           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    7032           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    7033           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    7034           0 :                 Aname=="H61" || Aname=="H62" ) {
+    7035           0 :         atoi[residue_atom[i]]=BASE_A;
+    7036           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    7037             :       // DNA - C
+    7038           0 :     } else if(Rname=="DC") {
+    7039           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="HP" ||
+    7040           0 :           Aname=="O1P" || Aname=="O2P"  ) {
+    7041           0 :         atoi [residue_atom[i]]=BB_PO2;
+    7042           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    7043           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    7044           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    7045           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    7046           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    7047           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    7048           0 :         atoi[residue_atom[i]]=BB_DNA;
+    7049           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    7050           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    7051           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    7052           0 :         atoi[residue_atom[i]]=BASE_C;
+    7053           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    7054             :       // DNA - C3
+    7055           0 :     } else if(Rname=="DC3") {
+    7056           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    7057           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    7058           0 :         atoi [residue_atom[i]]=BB_PO2;
+    7059           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    7060           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    7061           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    7062           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    7063           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    7064             :                 Aname=="H3T" ) {
+    7065           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    7066           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    7067           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    7068           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    7069           0 :         atoi[residue_atom[i]]=BASE_C;
+    7070           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    7071             :       // DNA - C5
+    7072           0 :     } else if(Rname=="DC5") {
+    7073           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    7074           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    7075           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    7076           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    7077           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    7078             :           Aname=="H5T" ) {
+    7079           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    7080           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    7081           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    7082           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    7083           0 :         atoi[residue_atom[i]]=BASE_C;
+    7084           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    7085             :       // DNA - CT
+    7086           0 :     } else if(Rname=="DCT") {
+    7087           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3"  ||
+    7088           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" || Aname=="HOP3" ) {
+    7089           0 :         atoi [residue_atom[i]]=BB_PO3;
+    7090           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    7091           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    7092           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    7093           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    7094           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    7095           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    7096           0 :         atoi[residue_atom[i]]=BB_DNA;
+    7097           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    7098           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    7099           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    7100           0 :         atoi[residue_atom[i]]=BASE_C;
+    7101           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    7102           0 :     } else error("Residue not known: "+Rname);
+    7103             :   }
+    7104           6 : }
+    7105             : 
+    7106           8 : double SAXS::calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho)
+    7107             : {
+    7108             :   std::map<std::string, unsigned> AA_map;
+    7109           8 :   AA_map["H"] = H;
+    7110           8 :   AA_map["C"] = C;
+    7111           8 :   AA_map["N"] = N;
+    7112           8 :   AA_map["O"] = O;
+    7113           8 :   AA_map["P"] = P;
+    7114           8 :   AA_map["S"] = S;
+    7115             : 
+    7116             :   std::vector<std::vector<double> > param_a;
+    7117             :   std::vector<std::vector<double> > param_b;
+    7118             :   std::vector<double> param_c;
+    7119             :   std::vector<double> param_v;
+    7120             : 
+    7121           8 :   param_a.resize(NTT, std::vector<double>(5));
+    7122           8 :   param_b.resize(NTT, std::vector<double>(5));
+    7123           8 :   param_c.resize(NTT);
+    7124           8 :   param_v.resize(NTT);
+    7125             : 
+    7126           8 :   param_a[H][0] = 0.493002; param_b[H][0] = 10.5109; param_c[H] = 0.003038;
+    7127           8 :   param_a[H][1] = 0.322912; param_b[H][1] = 26.1257; param_v[H] = 5.15;
+    7128           8 :   param_a[H][2] = 0.140191; param_b[H][2] = 3.14236;
+    7129           8 :   param_a[H][3] = 0.040810; param_b[H][3] = 57.7997;
+    7130           8 :   param_a[H][4] = 0.0;      param_b[H][4] = 1.0;
+    7131             : 
+    7132           8 :   param_a[C][0] = 2.31000; param_b[C][0] = 20.8439; param_c[C] = 0.215600;
+    7133           8 :   param_a[C][1] = 1.02000; param_b[C][1] = 10.2075; param_v[C] = 16.44;
+    7134           8 :   param_a[C][2] = 1.58860; param_b[C][2] = 0.56870;
+    7135           8 :   param_a[C][3] = 0.86500; param_b[C][3] = 51.6512;
+    7136           8 :   param_a[C][4] = 0.0;     param_b[C][4] = 1.0;
+    7137             : 
+    7138           8 :   param_a[N][0] = 12.2126; param_b[N][0] = 0.00570; param_c[N] = -11.529;
+    7139           8 :   param_a[N][1] = 3.13220; param_b[N][1] = 9.89330; param_v[N] = 2.49;
+    7140           8 :   param_a[N][2] = 2.01250; param_b[N][2] = 28.9975;
+    7141           8 :   param_a[N][3] = 1.16630; param_b[N][3] = 0.58260;
+    7142           8 :   param_a[N][4] = 0.0;     param_b[N][4] = 1.0;
+    7143             : 
+    7144           8 :   param_a[O][0] = 3.04850; param_b[O][0] = 13.2771; param_c[O] = 0.250800 ;
+    7145           8 :   param_a[O][1] = 2.28680; param_b[O][1] = 5.70110; param_v[O] = 9.13;
+    7146           8 :   param_a[O][2] = 1.54630; param_b[O][2] = 0.32390;
+    7147           8 :   param_a[O][3] = 0.86700; param_b[O][3] = 32.9089;
+    7148           8 :   param_a[O][4] = 0.0;     param_b[O][4] = 1.0;
+    7149             : 
+    7150           8 :   param_a[P][0] = 6.43450; param_b[P][0] = 1.90670; param_c[P] = 1.11490;
+    7151           8 :   param_a[P][1] = 4.17910; param_b[P][1] = 27.1570; param_v[P] = 5.73;
+    7152           8 :   param_a[P][2] = 1.78000; param_b[P][2] = 0.52600;
+    7153           8 :   param_a[P][3] = 1.49080; param_b[P][3] = 68.1645;
+    7154           8 :   param_a[P][4] = 0.0;     param_b[P][4] = 1.0;
+    7155             : 
+    7156           8 :   param_a[S][0] = 6.90530; param_b[S][0] = 1.46790; param_c[S] = 0.866900;
+    7157           8 :   param_a[S][1] = 5.20340; param_b[S][1] = 22.2151; param_v[S] = 19.86;
+    7158           8 :   param_a[S][2] = 1.43790; param_b[S][2] = 0.25360;
+    7159           8 :   param_a[S][3] = 1.58630; param_b[S][3] = 56.1720;
+    7160           8 :   param_a[S][4] = 0.0;     param_b[S][4] = 1.0;
+    7161             : 
+    7162           8 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    7163             : 
+    7164             :   double Iq0=0.;
+    7165           8 :   if( moldat ) {
+    7166             :     // cycle over the atom types
+    7167          56 :     for(unsigned i=0; i<NTT; ++i) {
+    7168          48 :       const double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    7169             :       // cycle over q
+    7170         480 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    7171         432 :         const double q = q_list[k];
+    7172         432 :         const double s = q / (4. * M_PI);
+    7173         432 :         FF_tmp[k][i] = param_c[i];
+    7174             :         // SUM [a_i * EXP( - b_i * (q/4pi)^2 )] Waasmaier and Kirfel (1995)
+    7175        2160 :         for(unsigned j=0; j<4; ++j) {
+    7176        1728 :           FF_tmp[k][i] += param_a[i][j]*std::exp(-param_b[i][j]*s*s);
+    7177             :         }
+    7178             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    7179         432 :         FF_tmp[k][i] -= rho*param_v[i]*std::exp(-volr*q*q);
+    7180             :       }
+    7181             :     }
+    7182             :     // cycle over the atoms to assign the atom type and calculate I0
+    7183       28382 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    7184             :       // get atom name
+    7185       28374 :       std::string name = moldat->getAtomName(atoms[i]);
+    7186             :       char type;
+    7187             :       // get atom type
+    7188       28374 :       char first = name.at(0);
+    7189             :       // GOLDEN RULE: type is first letter, if not a number
+    7190       28374 :       if (!isdigit(first)) {
+    7191             :         type = first;
+    7192             :         // otherwise is the second
+    7193             :       } else {
+    7194           0 :         type = name.at(1);
+    7195             :       }
+    7196       28374 :       std::string type_s = std::string(1,type);
+    7197       28374 :       if(AA_map.find(type_s) != AA_map.end()) {
+    7198       28374 :         const unsigned index=AA_map[type_s];
+    7199       28374 :         atoi[i] = AA_map[type_s];
+    7200      141870 :         for(unsigned j=0; j<4; ++j) Iq0 += param_a[index][j];
+    7201       28374 :         Iq0 = Iq0 -rho*param_v[index] + param_c[index];
+    7202             :       } else {
+    7203           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    7204             :       }
+    7205             :     }
+    7206             :   } else {
+    7207           0 :     error("MOLINFO DATA not found\n");
+    7208             :   }
+    7209           8 :   if(absolute) Iq0 = 1;
+    7210             : 
+    7211           8 :   return Iq0;
+    7212           8 : }
+    7213             : 
+    7214           4 : double SAXS::calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc)
+    7215             : {
+    7216             :   std::map<std::string, unsigned> AA_map;
+    7217           4 :   AA_map["H"] = H;
+    7218           4 :   AA_map["C"] = C;
+    7219           4 :   AA_map["N"] = N;
+    7220           4 :   AA_map["O"] = O;
+    7221           4 :   AA_map["P"] = P;
+    7222           4 :   AA_map["S"] = S;
+    7223             : 
+    7224             :   std::vector<double> param_b;
+    7225             :   std::vector<double> param_v;
+    7226             : 
+    7227           4 :   param_b.resize(NTT);
+    7228           4 :   param_v.resize(NTT);
+    7229             : 
+    7230           4 :   param_b[H] = -0.374; param_v[H] = 5.15;
+    7231             :   // param_b[D] = 0.667;
+    7232           4 :   param_b[C] =  0.665;  param_v[C] = 16.44;
+    7233           4 :   param_b[N] =  0.94;   param_v[N] = 2.49;
+    7234           4 :   param_b[O] =  0.580;  param_v[O] = 9.13;
+    7235           4 :   param_b[P] =  0.51;   param_v[P] = 5.73;
+    7236           4 :   param_b[S] =  0.28;   param_v[S] = 19.86;
+    7237             : 
+    7238           4 :   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)
+    7239             : 
+    7240           4 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    7241             : 
+    7242             :   double Iq0=0.;
+    7243           4 :   if( moldat ) {
+    7244             :     // cycle over the atom types
+    7245          28 :     for(unsigned i=0; i<NTT; ++i) {
+    7246          24 :       double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    7247             :       // cycle over q
+    7248         240 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    7249         216 :         const double q = q_list[k];
+    7250         216 :         FF_tmp[k][i] = param_b[i];
+    7251             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    7252         216 :         FF_tmp[k][i] -= solv_sc_length*rho*param_v[i]*std::exp(-volr*q*q);
+    7253             :       }
+    7254             :     }
+    7255             :     // cycle over the atoms to assign the atom type and calculate I0
+    7256       13922 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    7257             :       // get atom name
+    7258       13918 :       std::string name = moldat->getAtomName(atoms[i]);
+    7259             :       char type;
+    7260             :       // get atom type
+    7261       13918 :       char first = name.at(0);
+    7262             :       // GOLDEN RULE: type is first letter, if not a number
+    7263       13918 :       if (!isdigit(first)) {
+    7264             :         type = first;
+    7265             :         // otherwise is the second
+    7266             :       } else {
+    7267           0 :         type = name.at(1);
+    7268             :       }
+    7269       13918 :       std::string type_s = std::string(1,type);
+    7270       13918 :       if(AA_map.find(type_s) != AA_map.end()) {
+    7271       13918 :         const unsigned index=AA_map[type_s];
+    7272       13918 :         atoi[i] = AA_map[type_s];
+    7273       13918 :         Iq0 += param_b[index]-solv_sc_length*rho*param_v[index];
+    7274             :       } else {
+    7275           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    7276             :       }
+    7277             :     }
+    7278             :   } else {
+    7279           0 :     error("MOLINFO DATA not found\n");
+    7280             :   }
+    7281           4 :   if(absolute) Iq0 = 1;
+    7282             : 
+    7283           4 :   return Iq0;
+    7284             : }
+    7285             : 
+    7286          16 : std::map<std::string, std::vector<double> > SAXS::setupLCPOparam() {
+    7287             :   std::map<std::string, std::vector<double> > lcpomap;
+    7288             : 
+    7289             :   // We arbitrarily set OC1/OT1 as the charged oxygen.
+    7290             : 
+    7291          16 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7292          16 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7293          16 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7294          16 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7295          16 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7296          16 :   lcpomap["ALA_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7297          16 :   lcpomap["ALA_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7298          16 :   lcpomap["ALA_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7299          16 :   lcpomap["ALA_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7300          16 :   lcpomap["ALA_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7301             : 
+    7302          16 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7303          16 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7304          16 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7305          16 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7306          16 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7307          16 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7308          16 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7309          16 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7310          16 :   lcpomap["ASP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7311          16 :   lcpomap["ASP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7312          16 :   lcpomap["ASP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7313          16 :   lcpomap["ASP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7314          16 :   lcpomap["ASP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7315             : 
+    7316          16 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7317          16 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7318          16 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7319          16 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7320          16 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7321          16 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7322          16 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7323          16 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    7324          16 :   lcpomap["ASN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7325          16 :   lcpomap["ASN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7326          16 :   lcpomap["ASN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7327          16 :   lcpomap["ASN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7328          16 :   lcpomap["ASN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7329             : 
+    7330          16 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7331          16 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7332          16 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7333          16 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7334          16 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7335          16 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7336          16 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7337          16 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7338          16 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    7339          16 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    7340          16 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7341          16 :   lcpomap["ARG_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7342          16 :   lcpomap["ARG_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7343          16 :   lcpomap["ARG_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7344          16 :   lcpomap["ARG_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7345          16 :   lcpomap["ARG_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7346             : 
+    7347          16 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7348          16 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7349          16 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7350          16 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7351          16 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7352          16 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    7353          16 :   lcpomap["CYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7354          16 :   lcpomap["CYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7355          16 :   lcpomap["CYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7356          16 :   lcpomap["CYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7357          16 :   lcpomap["CYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7358             : 
+    7359          16 :   lcpomap["CYX_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7360          16 :   lcpomap["CYX_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7361          16 :   lcpomap["CYX_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7362          16 :   lcpomap["CYX_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7363          16 :   lcpomap["CYX_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7364          16 :   lcpomap["CYX_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    7365          16 :   lcpomap["CYX_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7366          16 :   lcpomap["CYX_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7367          16 :   lcpomap["CYX_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7368          16 :   lcpomap["CYX_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7369          16 :   lcpomap["CYX_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7370             : 
+    7371          16 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7372          16 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7373          16 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7374          16 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7375          16 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7376          16 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7377          16 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7378          16 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7379          16 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7380          16 :   lcpomap["GLU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7381          16 :   lcpomap["GLU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7382          16 :   lcpomap["GLU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7383          16 :   lcpomap["GLU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7384          16 :   lcpomap["GLU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7385             : 
+    7386          16 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7387          16 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7388          16 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7389          16 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7390          16 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7391          16 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7392          16 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7393          16 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7394          16 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    7395          16 :   lcpomap["GLN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7396          16 :   lcpomap["GLN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7397          16 :   lcpomap["GLN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7398          16 :   lcpomap["GLN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7399          16 :   lcpomap["GLN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7400             : 
+    7401          16 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7402          16 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7403          16 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7404          16 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7405          16 :   lcpomap["GLY_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7406          16 :   lcpomap["GLY_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7407          16 :   lcpomap["GLY_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7408          16 :   lcpomap["GLY_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7409          16 :   lcpomap["GLY_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7410             : 
+    7411          16 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7412          16 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7413          16 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7414          16 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7415          16 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7416          16 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7417          16 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7418          16 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7419          16 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7420          16 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7421          16 :   lcpomap["HIS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7422          16 :   lcpomap["HIS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7423          16 :   lcpomap["HIS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7424             : 
+    7425          16 :   lcpomap["HIE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7426          16 :   lcpomap["HIE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7427          16 :   lcpomap["HIE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7428          16 :   lcpomap["HIE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7429          16 :   lcpomap["HIE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7430          16 :   lcpomap["HIE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7431          16 :   lcpomap["HIE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7432          16 :   lcpomap["HIE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7433          16 :   lcpomap["HIE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7434          16 :   lcpomap["HIE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7435          16 :   lcpomap["HIE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7436          16 :   lcpomap["HIE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7437          16 :   lcpomap["HIE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7438             : 
+    7439          16 :   lcpomap["HSE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7440          16 :   lcpomap["HSE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7441          16 :   lcpomap["HSE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7442          16 :   lcpomap["HSE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7443          16 :   lcpomap["HSE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7444          16 :   lcpomap["HSE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7445          16 :   lcpomap["HSE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7446          16 :   lcpomap["HSE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7447          16 :   lcpomap["HSE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7448          16 :   lcpomap["HSE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7449          16 :   lcpomap["HSE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7450          16 :   lcpomap["HSE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7451          16 :   lcpomap["HSE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7452             : 
+    7453          16 :   lcpomap["HID_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7454          16 :   lcpomap["HID_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7455          16 :   lcpomap["HID_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7456          16 :   lcpomap["HID_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7457          16 :   lcpomap["HID_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7458          16 :   lcpomap["HID_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7459          16 :   lcpomap["HID_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7460          16 :   lcpomap["HID_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7461          16 :   lcpomap["HID_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7462          16 :   lcpomap["HID_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7463          16 :   lcpomap["HID_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7464          16 :   lcpomap["HID_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7465          16 :   lcpomap["HID_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7466             : 
+    7467          16 :   lcpomap["HSD_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7468          16 :   lcpomap["HSD_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7469          16 :   lcpomap["HSD_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7470          16 :   lcpomap["HSD_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7471          16 :   lcpomap["HSD_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7472          16 :   lcpomap["HSD_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7473          16 :   lcpomap["HSD_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7474          16 :   lcpomap["HSD_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7475          16 :   lcpomap["HSD_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7476          16 :   lcpomap["HSD_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7477          16 :   lcpomap["HSD_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7478          16 :   lcpomap["HSD_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7479          16 :   lcpomap["HSD_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7480             : 
+    7481          16 :   lcpomap["HIP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7482          16 :   lcpomap["HIP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7483          16 :   lcpomap["HIP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7484          16 :   lcpomap["HIP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7485          16 :   lcpomap["HIP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7486          16 :   lcpomap["HIP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7487          16 :   lcpomap["HIP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7488          16 :   lcpomap["HIP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7489          16 :   lcpomap["HIP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7490          16 :   lcpomap["HIP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7491          16 :   lcpomap["HIP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7492          16 :   lcpomap["HIP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7493          16 :   lcpomap["HIP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7494             : 
+    7495          16 :   lcpomap["HSP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7496          16 :   lcpomap["HSP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7497          16 :   lcpomap["HSP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7498          16 :   lcpomap["HSP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7499          16 :   lcpomap["HSP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7500          16 :   lcpomap["HSP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7501          16 :   lcpomap["HSP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7502          16 :   lcpomap["HSP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7503          16 :   lcpomap["HSP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7504          16 :   lcpomap["HSP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7505          16 :   lcpomap["HSP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7506          16 :   lcpomap["HSP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7507          16 :   lcpomap["HSP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7508             : 
+    7509          16 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7510          16 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7511          16 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7512          16 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7513          16 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7514          16 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7515          16 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7516          16 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7517          16 :   lcpomap["ILE_CD"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7518          16 :   lcpomap["ILE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7519          16 :   lcpomap["ILE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7520          16 :   lcpomap["ILE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7521          16 :   lcpomap["ILE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7522          16 :   lcpomap["ILE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7523             : 
+    7524          16 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7525          16 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7526          16 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7527          16 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7528          16 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7529          16 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7530          16 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7531          16 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7532          16 :   lcpomap["LEU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7533          16 :   lcpomap["LEU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7534          16 :   lcpomap["LEU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7535          16 :   lcpomap["LEU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7536          16 :   lcpomap["LEU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7537             : 
+    7538          16 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7539          16 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7540          16 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7541          16 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7542          16 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7543          16 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7544          16 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7545          16 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7546          16 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    7547          16 :   lcpomap["LYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7548          16 :   lcpomap["LYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7549          16 :   lcpomap["LYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7550          16 :   lcpomap["LYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7551          16 :   lcpomap["LYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7552             : 
+    7553          16 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7554          16 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7555          16 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7556          16 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7557          16 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7558          16 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7559          16 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    7560          16 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7561          16 :   lcpomap["MET_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7562          16 :   lcpomap["MET_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7563          16 :   lcpomap["MET_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7564          16 :   lcpomap["MET_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7565          16 :   lcpomap["MET_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7566             : 
+    7567          16 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7568          16 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7569          16 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7570          16 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7571          16 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7572          16 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7573          16 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7574          16 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7575          16 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7576          16 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7577          16 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7578          16 :   lcpomap["PHE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7579          16 :   lcpomap["PHE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7580          16 :   lcpomap["PHE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7581          16 :   lcpomap["PHE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7582          16 :   lcpomap["PHE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7583             : 
+    7584          16 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7585          16 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7586          16 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7587          16 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7588          16 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7589          16 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7590          16 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7591          16 :   lcpomap["PRO_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7592          16 :   lcpomap["PRO_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7593          16 :   lcpomap["PRO_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7594          16 :   lcpomap["PRO_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7595          16 :   lcpomap["PRO_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7596             : 
+    7597          16 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7598          16 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7599          16 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7600          16 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7601          16 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7602          16 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7603          16 :   lcpomap["SER_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7604          16 :   lcpomap["SER_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7605          16 :   lcpomap["SER_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7606          16 :   lcpomap["SER_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7607          16 :   lcpomap["SER_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7608             : 
+    7609          16 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7610          16 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7611          16 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7612          16 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7613          16 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7614          16 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7615          16 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7616          16 :   lcpomap["THR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7617          16 :   lcpomap["THR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7618          16 :   lcpomap["THR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7619          16 :   lcpomap["THR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7620          16 :   lcpomap["THR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7621             : 
+    7622          16 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7623          16 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7624          16 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7625          16 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7626          16 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7627          16 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7628          16 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7629          16 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7630          16 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7631          16 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7632          16 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7633          16 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7634          16 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7635          16 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7636          16 :   lcpomap["TRP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7637          16 :   lcpomap["TRP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7638          16 :   lcpomap["TRP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7639          16 :   lcpomap["TRP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7640          16 :   lcpomap["TRP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7641             : 
+    7642          16 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    7643          16 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7644          16 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7645          16 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7646          16 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7647          16 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7648          16 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7649          16 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7650          16 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7651          16 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7652          16 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7653          16 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7654          16 :   lcpomap["TYR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7655          16 :   lcpomap["TYR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7656          16 :   lcpomap["TYR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7657          16 :   lcpomap["TYR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7658          16 :   lcpomap["TYR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7659             : 
+    7660          16 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    7661          16 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7662          16 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7663          16 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7664          16 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7665          16 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7666          16 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7667          16 :   lcpomap["VAL_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7668          16 :   lcpomap["VAL_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7669          16 :   lcpomap["VAL_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7670          16 :   lcpomap["VAL_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7671          16 :   lcpomap["VAL_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7672             : 
+    7673             :   // nucleic acids - WARNING: ONLY AMBER (OL3-rna/OL15-dna) FORMAT
+    7674             : 
+    7675          16 :   lcpomap["A3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7676          16 :   lcpomap["A3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7677          16 :   lcpomap["A3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7678          16 :   lcpomap["A3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7679          16 :   lcpomap["A3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7680          16 :   lcpomap["A3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7681          16 :   lcpomap["A3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7682          16 :   lcpomap["A3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7683          16 :   lcpomap["A3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7684          16 :   lcpomap["A3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7685          16 :   lcpomap["A3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7686          16 :   lcpomap["A3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7687          16 :   lcpomap["A3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7688          16 :   lcpomap["A3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7689          16 :   lcpomap["A3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7690          16 :   lcpomap["A3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7691          16 :   lcpomap["A3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7692          16 :   lcpomap["A3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7693          16 :   lcpomap["A3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7694          16 :   lcpomap["A3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7695          16 :   lcpomap["A3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7696          16 :   lcpomap["A3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7697          16 :   lcpomap["A3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7698          16 :   lcpomap["A3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7699          16 :   lcpomap["A3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7700          16 :   lcpomap["A3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7701             : 
+    7702          16 :   lcpomap["A5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7703          16 :   lcpomap["A5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7704          16 :   lcpomap["A5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7705          16 :   lcpomap["A5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7706          16 :   lcpomap["A5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7707          16 :   lcpomap["A5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7708          16 :   lcpomap["A5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7709          16 :   lcpomap["A5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7710          16 :   lcpomap["A5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7711          16 :   lcpomap["A5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7712          16 :   lcpomap["A5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7713          16 :   lcpomap["A5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7714          16 :   lcpomap["A5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7715          16 :   lcpomap["A5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7716          16 :   lcpomap["A5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7717          16 :   lcpomap["A5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7718          16 :   lcpomap["A5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7719          16 :   lcpomap["A5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7720          16 :   lcpomap["A5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7721          16 :   lcpomap["A5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7722          16 :   lcpomap["A5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7723          16 :   lcpomap["A5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7724          16 :   lcpomap["A5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7725          16 :   lcpomap["A5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7726             : 
+    7727          16 :   lcpomap["AT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7728          16 :   lcpomap["AT_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7729          16 :   lcpomap["AT_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7730          16 :   lcpomap["AT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7731          16 :   lcpomap["AT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7732          16 :   lcpomap["AT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7733          16 :   lcpomap["AT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7734          16 :   lcpomap["AT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7735          16 :   lcpomap["AT_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7736          16 :   lcpomap["AT_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7737          16 :   lcpomap["AT_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7738          16 :   lcpomap["AT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7739          16 :   lcpomap["AT_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7740          16 :   lcpomap["AT_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7741          16 :   lcpomap["AT_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7742          16 :   lcpomap["AT_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7743          16 :   lcpomap["AT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7744          16 :   lcpomap["AT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7745          16 :   lcpomap["AT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7746          16 :   lcpomap["AT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7747          16 :   lcpomap["AT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7748          16 :   lcpomap["AT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7749          16 :   lcpomap["AT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7750          16 :   lcpomap["AT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7751          16 :   lcpomap["AT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7752          16 :   lcpomap["AT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7753             : 
+    7754          16 :   lcpomap["A_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7755          16 :   lcpomap["A_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7756          16 :   lcpomap["A_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7757          16 :   lcpomap["A_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7758          16 :   lcpomap["A_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7759          16 :   lcpomap["A_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7760          16 :   lcpomap["A_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7761          16 :   lcpomap["A_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7762          16 :   lcpomap["A_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7763          16 :   lcpomap["A_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7764          16 :   lcpomap["A_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7765          16 :   lcpomap["A_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7766          16 :   lcpomap["A_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7767          16 :   lcpomap["A_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7768          16 :   lcpomap["A_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7769          16 :   lcpomap["A_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7770          16 :   lcpomap["A_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7771          16 :   lcpomap["A_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7772          16 :   lcpomap["A_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7773          16 :   lcpomap["A_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7774          16 :   lcpomap["A_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7775          16 :   lcpomap["A_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7776          16 :   lcpomap["A_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7777          16 :   lcpomap["A_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7778          16 :   lcpomap["A_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7779          16 :   lcpomap["A_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7780             : 
+    7781          16 :   lcpomap["C3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7782          16 :   lcpomap["C3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7783          16 :   lcpomap["C3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7784          16 :   lcpomap["C3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7785          16 :   lcpomap["C3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7786          16 :   lcpomap["C3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7787          16 :   lcpomap["C3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7788          16 :   lcpomap["C3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7789          16 :   lcpomap["C3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7790          16 :   lcpomap["C3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7791          16 :   lcpomap["C3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7792          16 :   lcpomap["C3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7793          16 :   lcpomap["C3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7794          16 :   lcpomap["C3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7795          16 :   lcpomap["C3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7796          16 :   lcpomap["C3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7797          16 :   lcpomap["C3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7798          16 :   lcpomap["C3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7799          16 :   lcpomap["C3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7800          16 :   lcpomap["C3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7801          16 :   lcpomap["C3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7802          16 :   lcpomap["C3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7803          16 :   lcpomap["C3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7804          16 :   lcpomap["C3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7805             : 
+    7806          16 :   lcpomap["C5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7807          16 :   lcpomap["C5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7808          16 :   lcpomap["C5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7809          16 :   lcpomap["C5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7810          16 :   lcpomap["C5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7811          16 :   lcpomap["C5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7812          16 :   lcpomap["C5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7813          16 :   lcpomap["C5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7814          16 :   lcpomap["C5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7815          16 :   lcpomap["C5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7816          16 :   lcpomap["C5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7817          16 :   lcpomap["C5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7818          16 :   lcpomap["C5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7819          16 :   lcpomap["C5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7820          16 :   lcpomap["C5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7821          16 :   lcpomap["C5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7822          16 :   lcpomap["C5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7823          16 :   lcpomap["C5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7824          16 :   lcpomap["C5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7825          16 :   lcpomap["C5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7826          16 :   lcpomap["C5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7827          16 :   lcpomap["C5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7828             : 
+    7829          16 :   lcpomap["CT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7830          16 :   lcpomap["CT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7831          16 :   lcpomap["CT_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7832          16 :   lcpomap["CT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7833          16 :   lcpomap["CT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7834          16 :   lcpomap["CT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7835          16 :   lcpomap["CT_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7836          16 :   lcpomap["CT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7837          16 :   lcpomap["CT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7838          16 :   lcpomap["CT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7839          16 :   lcpomap["CT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7840          16 :   lcpomap["CT_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7841          16 :   lcpomap["CT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7842          16 :   lcpomap["CT_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7843          16 :   lcpomap["CT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7844          16 :   lcpomap["CT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7845          16 :   lcpomap["CT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7846          16 :   lcpomap["CT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7847          16 :   lcpomap["CT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7848          16 :   lcpomap["CT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7849          16 :   lcpomap["CT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7850          16 :   lcpomap["CT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7851          16 :   lcpomap["CT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7852          16 :   lcpomap["CT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7853             : 
+    7854          16 :   lcpomap["C_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7855          16 :   lcpomap["C_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7856          16 :   lcpomap["C_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7857          16 :   lcpomap["C_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7858          16 :   lcpomap["C_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7859          16 :   lcpomap["C_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7860          16 :   lcpomap["C_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7861          16 :   lcpomap["C_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7862          16 :   lcpomap["C_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7863          16 :   lcpomap["C_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7864          16 :   lcpomap["C_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7865          16 :   lcpomap["C_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7866          16 :   lcpomap["C_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7867          16 :   lcpomap["C_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7868          16 :   lcpomap["C_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7869          16 :   lcpomap["C_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7870          16 :   lcpomap["C_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7871          16 :   lcpomap["C_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7872          16 :   lcpomap["C_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7873          16 :   lcpomap["C_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7874          16 :   lcpomap["C_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7875          16 :   lcpomap["C_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7876          16 :   lcpomap["C_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7877          16 :   lcpomap["C_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7878             : 
+    7879          16 :   lcpomap["DA3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7880          16 :   lcpomap["DA3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7881          16 :   lcpomap["DA3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7882          16 :   lcpomap["DA3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7883          16 :   lcpomap["DA3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7884          16 :   lcpomap["DA3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7885          16 :   lcpomap["DA3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7886          16 :   lcpomap["DA3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7887          16 :   lcpomap["DA3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7888          16 :   lcpomap["DA3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7889          16 :   lcpomap["DA3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7890          16 :   lcpomap["DA3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7891          16 :   lcpomap["DA3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7892          16 :   lcpomap["DA3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7893          16 :   lcpomap["DA3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7894          16 :   lcpomap["DA3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7895          16 :   lcpomap["DA3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7896          16 :   lcpomap["DA3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7897          16 :   lcpomap["DA3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7898          16 :   lcpomap["DA3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7899          16 :   lcpomap["DA3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7900          16 :   lcpomap["DA3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7901          16 :   lcpomap["DA3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7902          16 :   lcpomap["DA3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7903          16 :   lcpomap["DA3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7904             : 
+    7905          16 :   lcpomap["DA5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7906          16 :   lcpomap["DA5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7907          16 :   lcpomap["DA5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7908          16 :   lcpomap["DA5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7909          16 :   lcpomap["DA5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7910          16 :   lcpomap["DA5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7911          16 :   lcpomap["DA5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7912          16 :   lcpomap["DA5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7913          16 :   lcpomap["DA5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7914          16 :   lcpomap["DA5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7915          16 :   lcpomap["DA5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7916          16 :   lcpomap["DA5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7917          16 :   lcpomap["DA5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7918          16 :   lcpomap["DA5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7919          16 :   lcpomap["DA5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7920          16 :   lcpomap["DA5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7921          16 :   lcpomap["DA5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7922          16 :   lcpomap["DA5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7923          16 :   lcpomap["DA5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7924          16 :   lcpomap["DA5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7925          16 :   lcpomap["DA5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7926          16 :   lcpomap["DA5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7927          16 :   lcpomap["DA5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7928             : 
+    7929          16 :   lcpomap["DAT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7930          16 :   lcpomap["DAT_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7931          16 :   lcpomap["DAT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7932          16 :   lcpomap["DAT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7933          16 :   lcpomap["DAT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7934          16 :   lcpomap["DAT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7935          16 :   lcpomap["DAT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7936          16 :   lcpomap["DAT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7937          16 :   lcpomap["DAT_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7938          16 :   lcpomap["DAT_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7939          16 :   lcpomap["DAT_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7940          16 :   lcpomap["DAT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7941          16 :   lcpomap["DAT_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7942          16 :   lcpomap["DAT_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7943          16 :   lcpomap["DAT_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7944          16 :   lcpomap["DAT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7945          16 :   lcpomap["DAT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7946          16 :   lcpomap["DAT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7947          16 :   lcpomap["DAT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7948          16 :   lcpomap["DAT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7949          16 :   lcpomap["DAT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7950          16 :   lcpomap["DAT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7951          16 :   lcpomap["DAT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7952          16 :   lcpomap["DAT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7953          16 :   lcpomap["DAT_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7954             : 
+    7955          16 :   lcpomap["DA_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7956          16 :   lcpomap["DA_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7957          16 :   lcpomap["DA_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7958          16 :   lcpomap["DA_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7959          16 :   lcpomap["DA_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7960          16 :   lcpomap["DA_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7961          16 :   lcpomap["DA_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7962          16 :   lcpomap["DA_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7963          16 :   lcpomap["DA_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7964          16 :   lcpomap["DA_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7965          16 :   lcpomap["DA_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7966          16 :   lcpomap["DA_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7967          16 :   lcpomap["DA_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7968          16 :   lcpomap["DA_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7969          16 :   lcpomap["DA_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7970          16 :   lcpomap["DA_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7971          16 :   lcpomap["DA_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7972          16 :   lcpomap["DA_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7973          16 :   lcpomap["DA_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7974          16 :   lcpomap["DA_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7975          16 :   lcpomap["DA_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7976          16 :   lcpomap["DA_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7977          16 :   lcpomap["DA_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7978          16 :   lcpomap["DA_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7979          16 :   lcpomap["DA_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7980             : 
+    7981          16 :   lcpomap["DC3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7982          16 :   lcpomap["DC3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7983          16 :   lcpomap["DC3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7984          16 :   lcpomap["DC3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7985          16 :   lcpomap["DC3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7986          16 :   lcpomap["DC3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7987          16 :   lcpomap["DC3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7988          16 :   lcpomap["DC3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7989          16 :   lcpomap["DC3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7990          16 :   lcpomap["DC3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7991          16 :   lcpomap["DC3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7992          16 :   lcpomap["DC3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7993          16 :   lcpomap["DC3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7994          16 :   lcpomap["DC3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7995          16 :   lcpomap["DC3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7996          16 :   lcpomap["DC3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7997          16 :   lcpomap["DC3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7998          16 :   lcpomap["DC3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7999          16 :   lcpomap["DC3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8000          16 :   lcpomap["DC3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8001          16 :   lcpomap["DC3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8002          16 :   lcpomap["DC3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8003          16 :   lcpomap["DC3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8004             : 
+    8005          16 :   lcpomap["DC5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8006          16 :   lcpomap["DC5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8007          16 :   lcpomap["DC5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8008          16 :   lcpomap["DC5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8009          16 :   lcpomap["DC5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8010          16 :   lcpomap["DC5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8011          16 :   lcpomap["DC5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8012          16 :   lcpomap["DC5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8013          16 :   lcpomap["DC5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8014          16 :   lcpomap["DC5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8015          16 :   lcpomap["DC5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8016          16 :   lcpomap["DC5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8017          16 :   lcpomap["DC5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8018          16 :   lcpomap["DC5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8019          16 :   lcpomap["DC5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8020          16 :   lcpomap["DC5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8021          16 :   lcpomap["DC5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8022          16 :   lcpomap["DC5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8023          16 :   lcpomap["DC5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8024          16 :   lcpomap["DC5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8025          16 :   lcpomap["DC5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8026             : 
+    8027          16 :   lcpomap["DCT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8028          16 :   lcpomap["DCT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05};
+    8029          16 :   lcpomap["DCT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8030          16 :   lcpomap["DCT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8031          16 :   lcpomap["DCT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05};
+    8032          16 :   lcpomap["DCT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8033          16 :   lcpomap["DCT_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8034          16 :   lcpomap["DCT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8035          16 :   lcpomap["DCT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8036          16 :   lcpomap["DCT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05};
+    8037          16 :   lcpomap["DCT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8038          16 :   lcpomap["DCT_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8039          16 :   lcpomap["DCT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8040          16 :   lcpomap["DCT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8041          16 :   lcpomap["DCT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8042          16 :   lcpomap["DCT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8043          16 :   lcpomap["DCT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8044          16 :   lcpomap["DCT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8045          16 :   lcpomap["DCT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8046          16 :   lcpomap["DCT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8047          16 :   lcpomap["DCT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8048          16 :   lcpomap["DCT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8049          16 :   lcpomap["DCT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8050             : 
+    8051          16 :   lcpomap["DC_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8052          16 :   lcpomap["DC_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8053          16 :   lcpomap["DC_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8054          16 :   lcpomap["DC_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8055          16 :   lcpomap["DC_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8056          16 :   lcpomap["DC_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8057          16 :   lcpomap["DC_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8058          16 :   lcpomap["DC_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8059          16 :   lcpomap["DC_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8060          16 :   lcpomap["DC_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8061          16 :   lcpomap["DC_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8062          16 :   lcpomap["DC_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8063          16 :   lcpomap["DC_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8064          16 :   lcpomap["DC_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8065          16 :   lcpomap["DC_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8066          16 :   lcpomap["DC_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8067          16 :   lcpomap["DC_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8068          16 :   lcpomap["DC_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8069          16 :   lcpomap["DC_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8070          16 :   lcpomap["DC_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8071          16 :   lcpomap["DC_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8072          16 :   lcpomap["DC_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8073          16 :   lcpomap["DC_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8074             : 
+    8075          16 :   lcpomap["DG3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8076          16 :   lcpomap["DG3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8077          16 :   lcpomap["DG3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8078          16 :   lcpomap["DG3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8079          16 :   lcpomap["DG3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8080          16 :   lcpomap["DG3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8081          16 :   lcpomap["DG3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8082          16 :   lcpomap["DG3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8083          16 :   lcpomap["DG3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8084          16 :   lcpomap["DG3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8085          16 :   lcpomap["DG3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8086          16 :   lcpomap["DG3_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8087          16 :   lcpomap["DG3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8088          16 :   lcpomap["DG3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8089          16 :   lcpomap["DG3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8090          16 :   lcpomap["DG3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8091          16 :   lcpomap["DG3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8092          16 :   lcpomap["DG3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8093          16 :   lcpomap["DG3_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8094          16 :   lcpomap["DG3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8095          16 :   lcpomap["DG3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8096          16 :   lcpomap["DG3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8097          16 :   lcpomap["DG3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8098          16 :   lcpomap["DG3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8099          16 :   lcpomap["DG3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8100          16 :   lcpomap["DG3_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8101             : 
+    8102          16 :   lcpomap["DG5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8103          16 :   lcpomap["DG5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8104          16 :   lcpomap["DG5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8105          16 :   lcpomap["DG5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8106          16 :   lcpomap["DG5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8107          16 :   lcpomap["DG5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8108          16 :   lcpomap["DG5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8109          16 :   lcpomap["DG5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8110          16 :   lcpomap["DG5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8111          16 :   lcpomap["DG5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8112          16 :   lcpomap["DG5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8113          16 :   lcpomap["DG5_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8114          16 :   lcpomap["DG5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8115          16 :   lcpomap["DG5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8116          16 :   lcpomap["DG5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8117          16 :   lcpomap["DG5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8118          16 :   lcpomap["DG5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8119          16 :   lcpomap["DG5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8120          16 :   lcpomap["DG5_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8121          16 :   lcpomap["DG5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8122          16 :   lcpomap["DG5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8123          16 :   lcpomap["DG5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8124          16 :   lcpomap["DG5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8125          16 :   lcpomap["DG5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8126             : 
+    8127          16 :   lcpomap["DGT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8128          16 :   lcpomap["DGT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8129          16 :   lcpomap["DGT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8130          16 :   lcpomap["DGT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8131          16 :   lcpomap["DGT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8132          16 :   lcpomap["DGT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8133          16 :   lcpomap["DGT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8134          16 :   lcpomap["DGT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8135          16 :   lcpomap["DGT_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8136          16 :   lcpomap["DGT_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8137          16 :   lcpomap["DGT_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8138          16 :   lcpomap["DGT_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8139          16 :   lcpomap["DGT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8140          16 :   lcpomap["DGT_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8141          16 :   lcpomap["DGT_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8142          16 :   lcpomap["DGT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8143          16 :   lcpomap["DGT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8144          16 :   lcpomap["DGT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8145          16 :   lcpomap["DGT_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8146          16 :   lcpomap["DGT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8147          16 :   lcpomap["DGT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8148          16 :   lcpomap["DGT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8149          16 :   lcpomap["DGT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8150          16 :   lcpomap["DGT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8151          16 :   lcpomap["DGT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8152          16 :   lcpomap["DGT_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8153             : 
+    8154          16 :   lcpomap["DG_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8155          16 :   lcpomap["DG_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8156          16 :   lcpomap["DG_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8157          16 :   lcpomap["DG_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8158          16 :   lcpomap["DG_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8159          16 :   lcpomap["DG_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8160          16 :   lcpomap["DG_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8161          16 :   lcpomap["DG_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8162          16 :   lcpomap["DG_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8163          16 :   lcpomap["DG_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8164          16 :   lcpomap["DG_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8165          16 :   lcpomap["DG_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8166          16 :   lcpomap["DG_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8167          16 :   lcpomap["DG_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8168          16 :   lcpomap["DG_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8169          16 :   lcpomap["DG_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8170          16 :   lcpomap["DG_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8171          16 :   lcpomap["DG_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8172          16 :   lcpomap["DG_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8173          16 :   lcpomap["DG_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8174          16 :   lcpomap["DG_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8175          16 :   lcpomap["DG_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8176          16 :   lcpomap["DG_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8177          16 :   lcpomap["DG_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8178          16 :   lcpomap["DG_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8179          16 :   lcpomap["DG_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8180             : 
+    8181          16 :   lcpomap["DT3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8182          16 :   lcpomap["DT3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8183          16 :   lcpomap["DT3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8184          16 :   lcpomap["DT3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8185          16 :   lcpomap["DT3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8186          16 :   lcpomap["DT3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8187          16 :   lcpomap["DT3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8188          16 :   lcpomap["DT3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8189          16 :   lcpomap["DT3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8190          16 :   lcpomap["DT3_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    8191          16 :   lcpomap["DT3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8192          16 :   lcpomap["DT3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8193          16 :   lcpomap["DT3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8194          16 :   lcpomap["DT3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8195          16 :   lcpomap["DT3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8196          16 :   lcpomap["DT3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8197          16 :   lcpomap["DT3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8198          16 :   lcpomap["DT3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8199          16 :   lcpomap["DT3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8200          16 :   lcpomap["DT3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8201          16 :   lcpomap["DT3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8202          16 :   lcpomap["DT3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8203          16 :   lcpomap["DT3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8204          16 :   lcpomap["DT3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8205             : 
+    8206          16 :   lcpomap["DT5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8207          16 :   lcpomap["DT5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8208          16 :   lcpomap["DT5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8209          16 :   lcpomap["DT5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8210          16 :   lcpomap["DT5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8211          16 :   lcpomap["DT5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8212          16 :   lcpomap["DT5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8213          16 :   lcpomap["DT5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8214          16 :   lcpomap["DT5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8215          16 :   lcpomap["DT5_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    8216          16 :   lcpomap["DT5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8217          16 :   lcpomap["DT5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8218          16 :   lcpomap["DT5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8219          16 :   lcpomap["DT5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8220          16 :   lcpomap["DT5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8221          16 :   lcpomap["DT5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8222          16 :   lcpomap["DT5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8223          16 :   lcpomap["DT5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8224          16 :   lcpomap["DT5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8225          16 :   lcpomap["DT5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8226          16 :   lcpomap["DT5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8227          16 :   lcpomap["DT5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8228             : 
+    8229          16 :   lcpomap["DTT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8230          16 :   lcpomap["DTT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8231          16 :   lcpomap["DTT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8232          16 :   lcpomap["DTT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8233          16 :   lcpomap["DTT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8234          16 :   lcpomap["DTT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8235          16 :   lcpomap["DTT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8236          16 :   lcpomap["DTT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8237          16 :   lcpomap["DTT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8238          16 :   lcpomap["DTT_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    8239          16 :   lcpomap["DTT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8240          16 :   lcpomap["DTT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8241          16 :   lcpomap["DTT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8242          16 :   lcpomap["DTT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8243          16 :   lcpomap["DTT_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8244          16 :   lcpomap["DTT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8245          16 :   lcpomap["DTT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8246          16 :   lcpomap["DTT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8247          16 :   lcpomap["DTT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8248          16 :   lcpomap["DTT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8249          16 :   lcpomap["DTT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8250          16 :   lcpomap["DTT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8251          16 :   lcpomap["DTT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8252          16 :   lcpomap["DTT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8253             : 
+    8254          16 :   lcpomap["DT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8255          16 :   lcpomap["DT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8256          16 :   lcpomap["DT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8257          16 :   lcpomap["DT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8258          16 :   lcpomap["DT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8259          16 :   lcpomap["DT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8260          16 :   lcpomap["DT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8261          16 :   lcpomap["DT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8262          16 :   lcpomap["DT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8263          16 :   lcpomap["DT_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    8264          16 :   lcpomap["DT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8265          16 :   lcpomap["DT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8266          16 :   lcpomap["DT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8267          16 :   lcpomap["DT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8268          16 :   lcpomap["DT_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8269          16 :   lcpomap["DT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8270          16 :   lcpomap["DT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8271          16 :   lcpomap["DT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8272          16 :   lcpomap["DT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8273          16 :   lcpomap["DT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8274          16 :   lcpomap["DT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8275          16 :   lcpomap["DT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8276          16 :   lcpomap["DT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8277          16 :   lcpomap["DT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8278             : 
+    8279          16 :   lcpomap["G3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8280          16 :   lcpomap["G3_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8281          16 :   lcpomap["G3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8282          16 :   lcpomap["G3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8283          16 :   lcpomap["G3_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8284          16 :   lcpomap["G3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8285          16 :   lcpomap["G3_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8286          16 :   lcpomap["G3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8287          16 :   lcpomap["G3_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8288          16 :   lcpomap["G3_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8289          16 :   lcpomap["G3_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8290          16 :   lcpomap["G3_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8291          16 :   lcpomap["G3_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8292          16 :   lcpomap["G3_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8293          16 :   lcpomap["G3_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8294          16 :   lcpomap["G3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8295          16 :   lcpomap["G3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8296          16 :   lcpomap["G3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8297          16 :   lcpomap["G3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8298          16 :   lcpomap["G3_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8299          16 :   lcpomap["G3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8300          16 :   lcpomap["G3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8301          16 :   lcpomap["G3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8302          16 :   lcpomap["G3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8303          16 :   lcpomap["G3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8304          16 :   lcpomap["G3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8305          16 :   lcpomap["G3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8306             : 
+    8307          16 :   lcpomap["G5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8308          16 :   lcpomap["G5_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8309          16 :   lcpomap["G5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8310          16 :   lcpomap["G5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8311          16 :   lcpomap["G5_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8312          16 :   lcpomap["G5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8313          16 :   lcpomap["G5_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8314          16 :   lcpomap["G5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8315          16 :   lcpomap["G5_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8316          16 :   lcpomap["G5_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8317          16 :   lcpomap["G5_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8318          16 :   lcpomap["G5_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8319          16 :   lcpomap["G5_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8320          16 :   lcpomap["G5_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8321          16 :   lcpomap["G5_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8322          16 :   lcpomap["G5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8323          16 :   lcpomap["G5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8324          16 :   lcpomap["G5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8325          16 :   lcpomap["G5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8326          16 :   lcpomap["G5_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8327          16 :   lcpomap["G5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8328          16 :   lcpomap["G5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8329          16 :   lcpomap["G5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8330          16 :   lcpomap["G5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8331          16 :   lcpomap["G5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8332             : 
+    8333          16 :   lcpomap["GT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8334          16 :   lcpomap["GT_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8335          16 :   lcpomap["GT_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8336          16 :   lcpomap["GT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8337          16 :   lcpomap["GT_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8338          16 :   lcpomap["GT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8339          16 :   lcpomap["GT_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8340          16 :   lcpomap["GT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8341          16 :   lcpomap["GT_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8342          16 :   lcpomap["GT_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8343          16 :   lcpomap["GT_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8344          16 :   lcpomap["GT_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8345          16 :   lcpomap["GT_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8346          16 :   lcpomap["GT_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8347          16 :   lcpomap["GT_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8348          16 :   lcpomap["GT_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8349          16 :   lcpomap["GT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8350          16 :   lcpomap["GT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8351          16 :   lcpomap["GT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8352          16 :   lcpomap["GT_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8353          16 :   lcpomap["GT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8354          16 :   lcpomap["GT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8355          16 :   lcpomap["GT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8356          16 :   lcpomap["GT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8357          16 :   lcpomap["GT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8358          16 :   lcpomap["GT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8359          16 :   lcpomap["GT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8360             : 
+    8361          16 :   lcpomap["G_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8362          16 :   lcpomap["G_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8363          16 :   lcpomap["G_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8364          16 :   lcpomap["G_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8365          16 :   lcpomap["G_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8366          16 :   lcpomap["G_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8367          16 :   lcpomap["G_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8368          16 :   lcpomap["G_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8369          16 :   lcpomap["G_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8370          16 :   lcpomap["G_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8371          16 :   lcpomap["G_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8372          16 :   lcpomap["G_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    8373          16 :   lcpomap["G_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8374          16 :   lcpomap["G_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8375          16 :   lcpomap["G_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8376          16 :   lcpomap["G_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8377          16 :   lcpomap["G_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8378          16 :   lcpomap["G_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8379          16 :   lcpomap["G_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8380          16 :   lcpomap["G_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8381          16 :   lcpomap["G_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8382          16 :   lcpomap["G_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8383          16 :   lcpomap["G_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8384          16 :   lcpomap["G_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8385          16 :   lcpomap["G_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8386          16 :   lcpomap["G_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8387          16 :   lcpomap["G_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8388             : 
+    8389          16 :   lcpomap["U3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8390          16 :   lcpomap["U3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8391          16 :   lcpomap["U3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8392          16 :   lcpomap["U3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8393          16 :   lcpomap["U3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8394          16 :   lcpomap["U3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8395          16 :   lcpomap["U3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8396          16 :   lcpomap["U3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8397          16 :   lcpomap["U3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8398          16 :   lcpomap["U3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8399          16 :   lcpomap["U3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8400          16 :   lcpomap["U3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8401          16 :   lcpomap["U3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8402          16 :   lcpomap["U3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8403          16 :   lcpomap["U3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8404          16 :   lcpomap["U3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8405          16 :   lcpomap["U3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8406          16 :   lcpomap["U3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8407          16 :   lcpomap["U3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8408          16 :   lcpomap["U3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8409          16 :   lcpomap["U3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8410          16 :   lcpomap["U3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8411          16 :   lcpomap["U3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8412          16 :   lcpomap["U3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8413             : 
+    8414          16 :   lcpomap["U5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8415          16 :   lcpomap["U5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8416          16 :   lcpomap["U5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8417          16 :   lcpomap["U5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8418          16 :   lcpomap["U5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8419          16 :   lcpomap["U5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8420          16 :   lcpomap["U5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8421          16 :   lcpomap["U5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8422          16 :   lcpomap["U5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8423          16 :   lcpomap["U5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8424          16 :   lcpomap["U5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8425          16 :   lcpomap["U5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8426          16 :   lcpomap["U5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8427          16 :   lcpomap["U5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8428          16 :   lcpomap["U5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8429          16 :   lcpomap["U5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8430          16 :   lcpomap["U5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8431          16 :   lcpomap["U5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8432          16 :   lcpomap["U5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8433          16 :   lcpomap["U5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8434          16 :   lcpomap["U5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8435          16 :   lcpomap["U5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8436             : 
+    8437          16 :   lcpomap["UT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8438          16 :   lcpomap["UT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8439          16 :   lcpomap["UT_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8440          16 :   lcpomap["UT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8441          16 :   lcpomap["UT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8442          16 :   lcpomap["UT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8443          16 :   lcpomap["UT_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8444          16 :   lcpomap["UT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8445          16 :   lcpomap["UT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8446          16 :   lcpomap["UT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8447          16 :   lcpomap["UT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8448          16 :   lcpomap["UT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8449          16 :   lcpomap["UT_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8450          16 :   lcpomap["UT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8451          16 :   lcpomap["UT_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8452          16 :   lcpomap["UT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8453          16 :   lcpomap["UT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8454          16 :   lcpomap["UT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8455          16 :   lcpomap["UT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8456          16 :   lcpomap["UT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8457          16 :   lcpomap["UT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8458          16 :   lcpomap["UT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8459          16 :   lcpomap["UT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8460          16 :   lcpomap["UT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8461             : 
+    8462          16 :   lcpomap["U_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8463          16 :   lcpomap["U_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8464          16 :   lcpomap["U_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8465          16 :   lcpomap["U_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8466          16 :   lcpomap["U_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    8467          16 :   lcpomap["U_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    8468          16 :   lcpomap["U_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8469          16 :   lcpomap["U_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    8470          16 :   lcpomap["U_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    8471          16 :   lcpomap["U_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    8472          16 :   lcpomap["U_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    8473          16 :   lcpomap["U_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8474          16 :   lcpomap["U_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8475          16 :   lcpomap["U_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8476          16 :   lcpomap["U_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    8477          16 :   lcpomap["U_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8478          16 :   lcpomap["U_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    8479          16 :   lcpomap["U_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8480          16 :   lcpomap["U_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8481          16 :   lcpomap["U_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8482          16 :   lcpomap["U_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    8483          16 :   lcpomap["U_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8484          16 :   lcpomap["U_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    8485          16 :   lcpomap["U_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    8486             : 
+    8487          16 :   return lcpomap;
+    8488             : }
+    8489             : 
+    8490             : // assigns LCPO parameters to each atom reading from database
+    8491          16 : void SAXS::readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms)
+    8492             : {
+    8493          16 :   std::map<std::string, std::vector<double> > lcpomap = setupLCPOparam();
+    8494             : 
+    8495       56602 :   for(unsigned i=0; i<natoms; ++i)
+    8496             :   {
+    8497       56586 :     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'))) {
+    8498       26526 :       std::string identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+    8499       26526 :       std::vector<double> LCPOparamVector = lcpomap.at(identifier);
+    8500             :       double rs = 0.14;
+    8501       26526 :       LCPOparam[i].push_back(LCPOparamVector[0]+rs*10.);
+    8502       26526 :       LCPOparam[i].push_back(LCPOparamVector[1]);
+    8503       26526 :       LCPOparam[i].push_back(LCPOparamVector[2]);
+    8504       26526 :       LCPOparam[i].push_back(LCPOparamVector[3]);
+    8505       26526 :       LCPOparam[i].push_back(LCPOparamVector[4]);
+    8506             :     }
+    8507             :   }
+    8508             : 
+    8509       56602 :   for(unsigned i=0; i<natoms; ++i) {
+    8510       56586 :     if (LCPOparam[i].size()==0 ) {
+    8511       30060 :       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')) {
+    8512           0 :         std::cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << std::endl;
+    8513           0 :         error ("missing LCPO parameters\n");
+    8514             :       }
+    8515             :     }
+    8516             :   }
+    8517             : 
+    8518          16 :   if (AtomResidueName[0][0] == "N") {
+    8519          16 :     LCPOparam[0][1] = 7.3511e-01;
+    8520          16 :     LCPOparam[0][2] = -2.2116e-01;
+    8521          16 :     LCPOparam[0][3] = -8.9148e-04;
+    8522          16 :     LCPOparam[0][4] = 2.5230e-04;
+    8523             :   }
+    8524             : 
+    8525          16 :   if (AtomResidueName[0][natoms-1] == "O") {
+    8526           0 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+    8527           0 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+    8528           0 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+    8529           0 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+    8530             :   }
+    8531          16 : }
+    8532             : 
+    8533           4 : void SAXS::resolution_function()
+    8534             : {
+    8535           4 :   const unsigned numq = q_list.size();
+    8536             : 
+    8537             :   // only OpenMP because numq might be smaller than the number of ranks
+    8538           4 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    8539             :   for (unsigned i=0; i<numq; i++) {
+    8540             :     double qi = q_list[i];
+    8541             :     double dq = 6*sigma_res[i]/(Nj-1);
+    8542             :     double sigma_sq = sigma_res[i]*sigma_res[i];
+    8543             :     double qstart = qi - 3*sigma_res[i];
+    8544             :     for (unsigned j=0; j<Nj; j++) {
+    8545             :       double qj = qstart + j*dq;
+    8546             :       double I0exp = i0e(qj*qi/sigma_sq);
+    8547             : 
+    8548             :       qj_list[i][j] = qj;
+    8549             :       Rij[i][j] = (qj/sigma_sq)*std::exp(-0.5*(qj - qi)*(qj - qi)/sigma_sq)*I0exp;
+    8550             :     }
+    8551             :   }
+    8552           4 : }
+    8553             : 
+    8554             : // i0e function from cephes
+    8555             : // compute I0(x) * exp (-x), with I0 being the modified Bessel function
+    8556             : // of first kind and zeroth order.
+    8557         660 : inline double SAXS::i0e(double x)
+    8558             : {
+    8559             :   double y = 0.0;
+    8560             : 
+    8561         660 :   if (x < 0)
+    8562           0 :     x = -x;
+    8563         660 :   if (x <= 8.0) {
+    8564           0 :     y = (x/2.0) - 2.0;
+    8565           0 :     return chbevl(y, A);
+    8566             :   }
+    8567             : 
+    8568         660 :   return chbevl(32.0/x - 2.0, B) / sqrt(x);
+    8569             : }
+    8570             : 
+    8571         660 : double SAXS::chbevl(double x, const std::vector<double> &coeffs)
+    8572             : {
+    8573             :   double b0, b1, b2;
+    8574         660 :   unsigned n = coeffs.size();
+    8575             : 
+    8576         660 :   b0 = coeffs[0];
+    8577             :   b1 = 0.0;
+    8578             :   b2 = 0.0;
+    8579             : 
+    8580       16500 :   for (unsigned i = 1; i < n; i++) {
+    8581             :     b2 = b1;
+    8582             :     b1 = b0;
+    8583       15840 :     b0 = x * b1 - b2 + coeffs[i];
+    8584             :   }
+    8585         660 :   return 0.5 * (b0 - b2);
+    8586             : }
+    8587             : 
+    8588      134310 : inline double SAXS::interpolation(std::vector<SplineCoeffs> &coeffs, double x)
+    8589             : {
+    8590             :   unsigned s = 0;
+    8591     1002034 :   while ((x >= q_list[s+1]) && (s+1 < q_list.size()-1)) s++;
+    8592             : 
+    8593      134310 :   double dx = x - coeffs[s].x;
+    8594      134310 :   return coeffs[s].a + coeffs[s].b*dx + coeffs[s].c*dx*dx + coeffs[s].d*dx*dx*dx;
+    8595             : }
+    8596             : 
+    8597             : // natural bc cubic spline implementation from the Wikipedia algorithm
+    8598             : // modified from https://stackoverflow.com/a/19216702/3254658
+    8599         814 : std::vector<SAXS::SplineCoeffs> SAXS::spline_coeffs(std::vector<double> &x, std::vector<double> &y)
+    8600             : {
+    8601         814 :   unsigned n = x.size()-1;
+    8602             :   std::vector<double> a;
+    8603         814 :   a.insert(a.begin(), y.begin(), y.end());
+    8604         814 :   std::vector<double> b(n);
+    8605         814 :   std::vector<double> d(n);
+    8606             :   std::vector<double> h;
+    8607             : 
+    8608       12210 :   for(unsigned i=0; i<n; i++)
+    8609       11396 :     h.push_back(x[i+1]-x[i]);
+    8610             : 
+    8611             :   std::vector<double> alpha;
+    8612         814 :   alpha.push_back(0);
+    8613       11396 :   for(unsigned i=1; i<n; i++)
+    8614       10582 :     alpha.push_back( 3*(a[i+1]-a[i])/h[i] - 3*(a[i]-a[i-1])/h[i-1]  );
+    8615             : 
+    8616         814 :   std::vector<double> c(n+1);
+    8617         814 :   std::vector<double> l(n+1);
+    8618         814 :   std::vector<double> mu(n+1);
+    8619         814 :   std::vector<double> z(n+1);
+    8620         814 :   l[0] = 1;
+    8621         814 :   mu[0] = 0;
+    8622         814 :   z[0] = 0;
+    8623             : 
+    8624       11396 :   for(unsigned i=1; i<n; i++) {
+    8625       10582 :     l[i] = 2 *(x[i+1]-x[i-1])-h[i-1]*mu[i-1];
+    8626       10582 :     mu[i] = h[i]/l[i];
+    8627       10582 :     z[i] = (alpha[i]-h[i-1]*z[i-1])/l[i];
+    8628             :   }
+    8629             : 
+    8630         814 :   l[n] = 1;
+    8631         814 :   z[n] = 0;
+    8632         814 :   c[n] = 0;
+    8633             : 
+    8634       12210 :   for(int j=n-1; j>=0; j--) {
+    8635       11396 :     c[j] = z[j] - mu[j] * c[j+1];
+    8636       11396 :     b[j] = (a[j+1]-a[j])/h[j]-h[j]*(c[j+1]+2*c[j])/3;
+    8637       11396 :     d[j] = (c[j+1]-c[j])/3/h[j];
+    8638             :   }
+    8639             : 
+    8640         814 :   std::vector<SplineCoeffs> output_set(n);
+    8641       12210 :   for(unsigned i=0; i<n; i++) {
+    8642       11396 :     output_set[i].a = a[i];
+    8643       11396 :     output_set[i].b = b[i];
+    8644       11396 :     output_set[i].c = c[i];
+    8645       11396 :     output_set[i].d = d[i];
+    8646       11396 :     output_set[i].x = x[i];
+    8647             :   }
+    8648             : 
+    8649         814 :   return output_set;
+    8650             : }
+    8651             : 
+    8652             : 
+    8653             : }//namespace isdb
+    8654             : }//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 000000000..6007f738d --- /dev/null +++ b/coverage/isdb/Select.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..71f8b2187 --- /dev/null +++ b/coverage/isdb/Select.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..1ae24dc07 --- /dev/null +++ b/coverage/isdb/Select.cpp.gcov.html @@ -0,0 +1,195 @@ + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-10-17 16:45:00Functions: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 SELECTOR.
+      35             : 
+      36             : You should read the documentation for \ref SELECTOR to understand this action better.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : In this example we use a simulated-tempering like approach activated by the \ref RESCALE action.
+      41             : For each value of the scale parameter, we perform an independent Parallel Bias Metadynamics
+      42             : simulation (see \ref PBMETAD). At each moment of the simulation, only one of the \ref PBMETAD
+      43             : actions is activated, based on the current value of the associated \ref SELECTOR.
+      44             : The \ref SELECT action can then be used to print out the value of the (active) \ref PBMETAD bias potential.
+      45             : 
+      46             : \plumedfile
+      47             : ene:  ENERGY
+      48             : d: DISTANCE ATOMS=1,2
+      49             : 
+      50             : SELECTOR NAME=GAMMA VALUE=0
+      51             : 
+      52             : pbmetad0: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=0 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.0
+      53             : pbmetad1: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=1 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.1
+      54             : 
+      55             : RESCALE ...
+      56             : LABEL=res ARG=ene,pbmetad0.bias,pbmetad1.bias TEMP=300
+      57             : SELECTOR=GAMMA MAX_RESCALE=1.2 NOT_RESCALED=2 NBIN=2
+      58             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      59             : ...
+      60             : 
+      61             : pbactive: SELECT ARG=pbmetad0.bias,pbmetad1.bias SELECTOR=GAMMA
+      62             : 
+      63             : PRINT ARG=pbactive STRIDE=100 FILE=COLVAR
+      64             : \endplumedfile
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : class Select : public function::Function
+      70             : {
+      71             :   std::string selector_;
+      72             : 
+      73             : public:
+      74             :   explicit Select(const ActionOptions&);
+      75             :   void calculate();
+      76             :   static void registerKeywords(Keywords& keys);
+      77             : };
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(Select,"SELECT")
+      80             : 
+      81           4 : void Select::registerKeywords(Keywords& keys) {
+      82           4 :   Function::registerKeywords(keys);
+      83           4 :   keys.use("ARG");
+      84           8 :   keys.add("compulsory","SELECTOR","name of the variable used to select");
+      85           4 :   keys.setValueDescription("the value of the selected argument");
+      86           4 : }
+      87             : 
+      88           2 : Select::Select(const ActionOptions&ao):
+      89           2 :   Action(ao), Function(ao)
+      90             : {
+      91             :   // name of selector
+      92           2 :   parse("SELECTOR", selector_);
+      93             : 
+      94           2 :   addValueWithDerivatives(); setNotPeriodic();
+      95           2 :   checkRead();
+      96             : 
+      97           2 :   log.printf("  select based on %s\n",selector_.c_str());
+      98           4 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+      99             : 
+     100           2 : }
+     101             : 
+     102           8 : void Select::calculate()
+     103             : {
+     104           8 :   unsigned iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+     105             : 
+     106             :   // check if iselect is smaller than the number of arguments
+     107           8 :   if(iselect>=getNumberOfArguments()) error("the value of the SELECTOR is greater than the number of arguments!");
+     108             : 
+     109             :   // put all the derivatives to zero
+     110          24 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) setDerivative(i, 0.0);
+     111             : 
+     112             :   // set value and derivative for selected argument
+     113           8 :   setValue(getArgument(iselect));
+     114           8 :   setDerivative(iselect, 1.0);
+     115           8 : }
+     116             : 
+     117             : }
+     118             : }
+     119             : 
+
+
+
+ + + + +
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 000000000..242f5cfbe --- /dev/null +++ b/coverage/isdb/Selector.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f69bc9a65 --- /dev/null +++ b/coverage/isdb/Selector.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..46c0bac50 --- /dev/null +++ b/coverage/isdb/Selector.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + LCOV - plumed test coverage - isdb/Selector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Selector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111384.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..0a14c4e94 --- /dev/null +++ b/coverage/isdb/Shadow.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:75812.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..629c9b210 --- /dev/null +++ b/coverage/isdb/Shadow.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:75812.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..9b5e1fd09 --- /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:75812.1 %
Date:2024-10-17 16:45:00Functions: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 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 :   keys.setValueDescription("the value of the shadow RMSD");
+     119           2 : }
+     120             : 
+     121           0 : Shadow::Shadow(const ActionOptions&ao):
+     122             :   PLUMED_COLVAR_INIT(ao),
+     123           0 :   isreference_(false), nupdate_(1), pbc_(true), first_time_(true)
+     124             : {
+     125             :   // list of atoms
+     126             :   std::vector<AtomNumber> atoms;
+     127           0 :   parseAtomList("ATOMS",atoms);
+     128             :   // update stride
+     129           0 :   parse("UPDATE",nupdate_);
+     130             : 
+     131             :   // is this the reference replica
+     132           0 :   parseFlag("REFERENCE",isreference_);
+     133             : 
+     134             :   // periodic boundary conditions
+     135           0 :   bool nopbc=!pbc_;
+     136           0 :   parseFlag("NOPBC",nopbc);
+     137           0 :   pbc_=!nopbc;
+     138             : 
+     139             :   // set intra-replica (openmp) parallel stuff
+     140           0 :   size_ = comm.Get_size();
+     141           0 :   rank_ = comm.Get_rank();
+     142             : 
+     143             :   // get number of (MPI) replicas
+     144           0 :   int nrep = 0;
+     145           0 :   int replica = 0;
+     146             :   // only if openmp master
+     147           0 :   if(rank_==0) {
+     148           0 :     nrep    = multi_sim_comm.Get_size();
+     149           0 :     replica = multi_sim_comm.Get_rank();
+     150             :   }
+     151           0 :   comm.Sum(&nrep,1);
+     152           0 :   comm.Sum(&replica,1);
+     153             :   // check number of replicas
+     154             :   //if(nrep<2) error("SHADOW must be used with at least two replicas");
+     155             : 
+     156           0 :   checkRead();
+     157             : 
+     158           0 :   log.printf("  atoms involved : ");
+     159           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     160           0 :   log.printf("\n");
+     161           0 :   log.printf("  stride for updating reference coordinates : %d\n", nupdate_);
+     162           0 :   log.printf("  number of replicas : %d\n", nrep);
+     163           0 :   log.printf("  replica id : %d\n", replica);
+     164           0 :   if(isreference_) log.printf("  this is the reference replica\n");
+     165             : 
+     166             :   // add value and set periodicity
+     167           0 :   addValueWithDerivatives(); setNotPeriodic();
+     168             : 
+     169             :   // request atoms
+     170           0 :   requestAtoms(atoms);
+     171           0 : }
+     172             : 
+     173           0 : void Shadow::update_reference()
+     174             : {
+     175             : // number of atoms
+     176             :   unsigned natoms = getNumberOfAtoms();
+     177             : // initialize rmsd variables
+     178           0 :   std::vector<double> align(natoms,1.0);
+     179           0 :   std::vector<double> displace(natoms,1.0);
+     180           0 :   std::vector<Vector> reference(natoms);
+     181             : 
+     182             : // first get the reference coordinates
+     183             : // if master openmp task
+     184           0 :   if(rank_==0) {
+     185             :     // if reference replica
+     186           0 :     if(isreference_) reference = getPositions();
+     187             :     // share coordinates
+     188           0 :     multi_sim_comm.Sum(&reference[0][0], 3*natoms);
+     189             :   }
+     190             : // now intra replica (openmp) communication
+     191           0 :   if(size_>1) comm.Sum(&reference[0][0], 3*natoms);
+     192             : 
+     193             : // clear the rmsd object
+     194           0 :   rmsd_.clear();
+     195             : // and initialize it
+     196           0 :   rmsd_.set(align,displace,reference,"OPTIMAL");
+     197           0 : }
+     198             : 
+     199           0 : void Shadow::calculate()
+     200             : {
+     201             :   // make whole
+     202           0 :   if(pbc_) makeWhole();
+     203             : 
+     204             :   // if it is time, update reference coordinates
+     205           0 :   if(first_time_ || getStep()%nupdate_==0) {
+     206           0 :     update_reference();
+     207           0 :     first_time_ = false;
+     208             :   }
+     209             : 
+     210             :   // calculate RMSD and derivatives
+     211           0 :   std::vector<Vector> derivatives(getNumberOfAtoms());
+     212           0 :   double rmsd = rmsd_.calculate(getPositions(), derivatives);
+     213             : 
+     214             :   // set RMSD value
+     215           0 :   setValue(rmsd);
+     216             :   // if this is not the reference replica, add derivatives
+     217           0 :   if(!isreference_) {
+     218           0 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) setAtomsDerivatives(i, derivatives[i]);
+     219             :   }
+     220             :   // set virial
+     221           0 :   setBoxDerivativesNoPbc();
+     222           0 : }
+     223             : 
+     224             : }
+     225             : }
+
+
+
+ + + + +
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 000000000..b668464c7 --- /dev/null +++ b/coverage/isdb/index-sort-f.html @@ -0,0 +1,253 @@ + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:90861213074.9 %
Date:2024-10-17 16:45:00Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EMMIVox.cpp +
5.4%5.4%
+
5.4 %35 / 6473.8 %1 / 26
Rescale.cpp +
10.8%10.8%
+
10.8 %20 / 1858.3 %1 / 12
Shadow.cpp +
12.1%12.1%
+
12.1 %7 / 5820.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 %588 / 77874.4 %29 / 39
FretEfficiency.cpp +
94.6%94.6%
+
94.6 %35 / 3775.0 %3 / 4
Select.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
Jcoupling.cpp +
93.0%93.0%
+
93.0 %159 / 17180.0 %4 / 5
NOE.cpp +
98.1%98.1%
+
98.1 %101 / 10380.0 %4 / 5
PRE.cpp +
92.2%92.2%
+
92.2 %118 / 12880.0 %4 / 5
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %753 / 88482.1 %23 / 28
RDC.cpp +
93.9%93.9%
+
93.9 %169 / 18083.3 %5 / 6
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
SAXS.cpp +
76.2%76.2%
+
76.2 %5227 / 686191.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 000000000..b13cbf936 --- /dev/null +++ b/coverage/isdb/index-sort-l.html @@ -0,0 +1,253 @@ + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:90861213074.9 %
Date:2024-10-17 16:45:00Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EMMIVox.cpp +
5.4%5.4%
+
5.4 %35 / 6473.8 %1 / 26
Rescale.cpp +
10.8%10.8%
+
10.8 %20 / 1858.3 %1 / 12
Shadow.cpp +
12.1%12.1%
+
12.1 %7 / 5820.0 %1 / 5
EMMI.cpp +
75.6%75.6%
+
75.6 %588 / 77874.4 %29 / 39
SAXS.cpp +
76.2%76.2%
+
76.2 %5227 / 686191.3 %21 / 23
Caliber.cpp +
78.9%78.9%
+
78.9 %116 / 14762.5 %5 / 8
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 %753 / 88482.1 %23 / 28
PRE.cpp +
92.2%92.2%
+
92.2 %118 / 12880.0 %4 / 5
Jcoupling.cpp +
93.0%93.0%
+
93.0 %159 / 17180.0 %4 / 5
RDC.cpp +
93.9%93.9%
+
93.9 %169 / 18083.3 %5 / 6
FretEfficiency.cpp +
94.6%94.6%
+
94.6 %35 / 3775.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 %101 / 10380.0 %4 / 5
Select.cpp +
100.0%
+
100.0 %21 / 2175.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 000000000..e9edd436f --- /dev/null +++ b/coverage/isdb/index.html @@ -0,0 +1,253 @@ + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:90861213074.9 %
Date:2024-10-17 16:45:00Functions: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 %588 / 77874.4 %29 / 39
EMMIVox.cpp +
5.4%5.4%
+
5.4 %35 / 6473.8 %1 / 26
FretEfficiency.cpp +
94.6%94.6%
+
94.6 %35 / 3775.0 %3 / 4
Jcoupling.cpp +
93.0%93.0%
+
93.0 %159 / 17180.0 %4 / 5
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %753 / 88482.1 %23 / 28
MetainferenceBase.h +
97.3%97.3%
+
97.3 %71 / 73100.0 %11 / 11
NOE.cpp +
98.1%98.1%
+
98.1 %101 / 10380.0 %4 / 5
PRE.cpp +
92.2%92.2%
+
92.2 %118 / 12880.0 %4 / 5
RDC.cpp +
93.9%93.9%
+
93.9 %169 / 18083.3 %5 / 6
Rescale.cpp +
10.8%10.8%
+
10.8 %20 / 1858.3 %1 / 12
SAXS.cpp +
76.2%76.2%
+
76.2 %5227 / 686191.3 %21 / 23
Select.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
Selector.cpp +
84.6%84.6%
+
84.6 %11 / 1350.0 %2 / 4
Shadow.cpp +
12.1%12.1%
+
12.1 %7 / 5820.0 %1 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/CollectFrames.cpp.func-sort-c.html b/coverage/landmarks/CollectFrames.cpp.func-sort-c.html new file mode 100644 index 000000000..f8245afea --- /dev/null +++ b/coverage/landmarks/CollectFrames.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - landmarks/CollectFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - CollectFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606296.8 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks13CollectFramesC2ERKNS_13ActionOptionsE0
_ZN4PLMD9landmarks13CollectFramesC1ERKNS_13ActionOptionsE19
_ZN4PLMD9landmarks13CollectFrames16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD9landmarks13CollectFrames15fixArgumentNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/CollectFrames.cpp.func.html b/coverage/landmarks/CollectFrames.cpp.func.html new file mode 100644 index 000000000..c43a1f393 --- /dev/null +++ b/coverage/landmarks/CollectFrames.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - landmarks/CollectFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - CollectFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606296.8 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks13CollectFrames15fixArgumentNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48
_ZN4PLMD9landmarks13CollectFrames16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD9landmarks13CollectFramesC1ERKNS_13ActionOptionsE19
_ZN4PLMD9landmarks13CollectFramesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/CollectFrames.cpp.gcov.html b/coverage/landmarks/CollectFrames.cpp.gcov.html new file mode 100644 index 000000000..e4bc0cfc2 --- /dev/null +++ b/coverage/landmarks/CollectFrames.cpp.gcov.html @@ -0,0 +1,218 @@ + + + + + + + LCOV - plumed test coverage - landmarks/CollectFrames.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - CollectFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606296.8 %
Date:2024-10-17 16:45:00Functions: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 landmarks {
+      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/landmarks/FarthestPointSampling.cpp.func-sort-c.html b/coverage/landmarks/FarthestPointSampling.cpp.func-sort-c.html new file mode 100644 index 000000000..827cb8f3d --- /dev/null +++ b/coverage/landmarks/FarthestPointSampling.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - landmarks/FarthestPointSampling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - FarthestPointSampling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384192.7 %
Date:2024-10-17 16:45:00Functions:4850.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks21FarthestPointSampling22getNumberOfDerivativesEv0
_ZN4PLMD9landmarks21FarthestPointSampling5applyEv0
_ZN4PLMD9landmarks21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9landmarks21FarthestPointSampling23getForceOnMatrixElementERKjS3_0
_ZN4PLMD9landmarks21FarthestPointSampling7prepareEv1
_ZN4PLMD9landmarks21FarthestPointSampling9calculateEv1
_ZN4PLMD9landmarks21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD9landmarks21FarthestPointSampling16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/FarthestPointSampling.cpp.func.html b/coverage/landmarks/FarthestPointSampling.cpp.func.html new file mode 100644 index 000000000..256e51dee --- /dev/null +++ b/coverage/landmarks/FarthestPointSampling.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - landmarks/FarthestPointSampling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - FarthestPointSampling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384192.7 %
Date:2024-10-17 16:45:00Functions:4850.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks21FarthestPointSampling16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD9landmarks21FarthestPointSampling22getNumberOfDerivativesEv0
_ZN4PLMD9landmarks21FarthestPointSampling5applyEv0
_ZN4PLMD9landmarks21FarthestPointSampling7prepareEv1
_ZN4PLMD9landmarks21FarthestPointSampling9calculateEv1
_ZN4PLMD9landmarks21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD9landmarks21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9landmarks21FarthestPointSampling23getForceOnMatrixElementERKjS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/FarthestPointSampling.cpp.gcov.html b/coverage/landmarks/FarthestPointSampling.cpp.gcov.html new file mode 100644 index 000000000..b1c63e6eb --- /dev/null +++ b/coverage/landmarks/FarthestPointSampling.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + LCOV - plumed test coverage - landmarks/FarthestPointSampling.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - FarthestPointSampling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384192.7 %
Date:2024-10-17 16:45:00Functions: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 "matrixtools/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 landmarks {
+      37             : 
+      38             : class FarthestPointSampling : public matrixtools::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           4 : void FarthestPointSampling::registerKeywords( Keywords& keys ) {
+      55           4 :   matrixtools::MatrixOperationBase::registerKeywords( keys );
+      56           8 :   keys.add("compulsory","NZEROS","the number of landmark points that you want to select");
+      57           8 :   keys.add("compulsory","SEED","1234","a random number seed");
+      58           4 :   keys.setValueDescription("a vector which has as many elements as there are rows in the input matrix of dissimilarities. NZEROS of the elements in this vector are equal to one, the rest of the elements are equal to zero.  The nodes that have elements equal to one are the NZEROS points that are farthest appart according to the input dissimilarities");
+      59           4 : }
+      60             : 
+      61           1 : FarthestPointSampling::FarthestPointSampling( const ActionOptions& ao ):
+      62             :   Action(ao),
+      63           1 :   MatrixOperationBase(ao)
+      64             : {
+      65           1 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) error("input to this argument should be a square matrix of dissimilarities");
+      66           2 :   parse("NZEROS",nlandmarks); parse("SEED",seed);
+      67           1 :   log.printf("  selecting %d landmark points \n", nlandmarks );
+      68             : 
+      69           1 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0];
+      70           1 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      71           1 : }
+      72             : 
+      73           1 : void FarthestPointSampling::prepare() {
+      74           1 :   Value* myval = getPntrToComponent(0);
+      75           1 :   if( myval->getShape()[0]!=getPntrToArgument(0)->getShape()[0] ) {
+      76           1 :     std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0]; myval->setShape(shape);
+      77             :   }
+      78           4 :   for(unsigned i=0; i<nlandmarks; ++i) myval->set( i, 0.0 );
+      79          11 :   for(unsigned i=nlandmarks; i<myval->getShape()[0]; ++i) myval->set( i, 1.0 );
+      80           1 : }
+      81             : 
+      82           1 : void FarthestPointSampling::calculate() {
+      83           1 :   Value* myval=getPntrToComponent(0); unsigned npoints = getPntrToArgument(0)->getShape()[0];
+      84          14 :   for(unsigned i=0; i<npoints; ++i) myval->set( i, 1.0 );
+      85           1 :   std::vector<unsigned> landmarks( nlandmarks );
+      86             : 
+      87             :   // Select first point at random
+      88           1 :   Random random; random.setSeed(-seed); double rand=random.RandU01();
+      89           1 :   landmarks[0] = std::floor( npoints*rand ); myval->set( landmarks[0], 0 );
+      90             : 
+      91             :   // Now find distance to all other points (N.B. We can use squared distances here for speed)
+      92           1 :   Matrix<double> distances( nlandmarks, npoints ); Value* myarg = getPntrToArgument(0);
+      93          14 :   for(unsigned i=0; i<npoints; ++i) distances(0,i) = myarg->get( landmarks[0]*npoints + i );
+      94             : 
+      95             :   // Now find all other landmarks
+      96           3 :   for(unsigned i=1; i<nlandmarks; ++i) {
+      97             :     // Find point that has the largest minimum distance from the landmarks selected thus far
+      98             :     double maxd=0;
+      99          28 :     for(unsigned j=0; j<npoints; ++j) {
+     100          26 :       double mind=distances(0,j);
+     101          39 :       for(unsigned k=1; k<i; ++k) {
+     102          13 :         if( distances(k,j)<mind ) { mind=distances(k,j); }
+     103             :       }
+     104          26 :       if( mind>maxd ) { maxd=mind; landmarks[i]=j; }
+     105             :     }
+     106           2 :     myval->set( landmarks[i], 0 );
+     107          28 :     for(unsigned k=0; k<npoints; ++k) distances(i,k) = myarg->get( landmarks[i]*npoints + k );
+     108             :   }
+     109           1 : }
+     110             : 
+     111             : }
+     112             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/LandmarkSelection.cpp.func-sort-c.html b/coverage/landmarks/LandmarkSelection.cpp.func-sort-c.html new file mode 100644 index 000000000..3a3548d83 --- /dev/null +++ b/coverage/landmarks/LandmarkSelection.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - landmarks/LandmarkSelection.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - LandmarkSelection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6868100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks17LandmarkSelectionC2ERKNS_13ActionOptionsE0
_ZN4PLMD9landmarks17LandmarkSelectionC1ERKNS_13ActionOptionsE8
_ZN4PLMD9landmarks17LandmarkSelection16registerKeywordsERNS_8KeywordsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/LandmarkSelection.cpp.func.html b/coverage/landmarks/LandmarkSelection.cpp.func.html new file mode 100644 index 000000000..8953608fe --- /dev/null +++ b/coverage/landmarks/LandmarkSelection.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - landmarks/LandmarkSelection.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - LandmarkSelection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6868100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks17LandmarkSelection16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD9landmarks17LandmarkSelectionC1ERKNS_13ActionOptionsE8
_ZN4PLMD9landmarks17LandmarkSelectionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/LandmarkSelection.cpp.gcov.html b/coverage/landmarks/LandmarkSelection.cpp.gcov.html new file mode 100644 index 000000000..cf7b90ac5 --- /dev/null +++ b/coverage/landmarks/LandmarkSelection.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + LCOV - plumed test coverage - landmarks/LandmarkSelection.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - LandmarkSelection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6868100.0 %
Date:2024-10-17 16:45:00Functions: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 landmarks {
+      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/landmarks/LogSumExp.cpp.func-sort-c.html b/coverage/landmarks/LogSumExp.cpp.func-sort-c.html new file mode 100644 index 000000000..6293e8e79 --- /dev/null +++ b/coverage/landmarks/LogSumExp.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - landmarks/LogSumExp.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - LogSumExp.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks9LogSumExpC2ERKNS_13ActionOptionsE0
_ZN4PLMD9landmarks9LogSumExpC1ERKNS_13ActionOptionsE9
_ZN4PLMD9landmarks9LogSumExp16registerKeywordsERNS_8KeywordsE20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/LogSumExp.cpp.func.html b/coverage/landmarks/LogSumExp.cpp.func.html new file mode 100644 index 000000000..37df3bf01 --- /dev/null +++ b/coverage/landmarks/LogSumExp.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - landmarks/LogSumExp.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - LogSumExp.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9landmarks9LogSumExp16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD9landmarks9LogSumExpC1ERKNS_13ActionOptionsE9
_ZN4PLMD9landmarks9LogSumExpC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/LogSumExp.cpp.gcov.html b/coverage/landmarks/LogSumExp.cpp.gcov.html new file mode 100644 index 000000000..4b856d74b --- /dev/null +++ b/coverage/landmarks/LogSumExp.cpp.gcov.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - landmarks/LogSumExp.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarks - LogSumExp.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions: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 landmarks {
+      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          20 : void LogSumExp::registerKeywords( Keywords& keys ) {
+      50          20 :   ActionShortcut::registerKeywords( keys );
+      51          40 :   keys.add("compulsory","ARG","the vector of logweights that you would like to normalise using the logsumexp trick");
+      52          20 :   keys.setValueDescription("the logarithms of the input weights logweights that are computed with the log-sum weights formula");
+      53          60 :   keys.needsAction("HIGHEST"); keys.needsAction("CUSTOM"); keys.needsAction("SUM");
+      54          20 : }
+      55             : 
+      56             : 
+      57           9 : LogSumExp::LogSumExp( const ActionOptions& ao ):
+      58             :   Action(ao),
+      59           9 :   ActionShortcut(ao)
+      60             : {
+      61             :   // Find the argument name
+      62           9 :   std::string argn; parse("ARG",argn);
+      63             :   // Find the maximum weight
+      64          18 :   readInputLine( getShortcutLabel() + "_maxlogweight: HIGHEST ARG=" + argn );
+      65          18 :   readInputLine( getShortcutLabel() + "_maxweight: CUSTOM ARG=" + getShortcutLabel() + "_maxlogweight FUNC=exp(x) PERIODIC=NO");
+      66             :   // Calculate the maximum
+      67          18 :   readInputLine( getShortcutLabel() + "_shiftw: CUSTOM ARG=" + argn + "," + getShortcutLabel() + "_maxlogweight FUNC=exp(x-y) PERIODIC=NO");
+      68             :   // compute the sum of all the exponentials
+      69          18 :   readInputLine( getShortcutLabel() + "_sumw: SUM ARG=" + getShortcutLabel() + "_shiftw PERIODIC=NO");
+      70             :   // and the logsum
+      71          18 :   readInputLine( getShortcutLabel() + "_logsum: CUSTOM ARG=" + getShortcutLabel() + "_sumw," + getShortcutLabel() + "_maxlogweight FUNC=y+log(x) PERIODIC=NO");
+      72             :   // And the final weights
+      73          18 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + argn + "," +  getShortcutLabel() + "_logsum FUNC=exp(x-y) PERIODIC=NO");
+      74           9 : }
+      75             : 
+      76             : }
+      77             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/index-sort-f.html b/coverage/landmarks/index-sort-f.html new file mode 100644 index 000000000..8b83d9f1d --- /dev/null +++ b/coverage/landmarks/index-sort-f.html @@ -0,0 +1,123 @@ + + + + + + + LCOV - plumed test coverage - landmarks + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarksHitTotalCoverage
Test:plumed test coverageLines:18218797.3 %
Date:2024-10-17 16:45:00Functions:111861.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FarthestPointSampling.cpp +
92.7%92.7%
+
92.7 %38 / 4150.0 %4 / 8
LogSumExp.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
LandmarkSelection.cpp +
100.0%
+
100.0 %68 / 6866.7 %2 / 3
CollectFrames.cpp +
96.8%96.8%
+
96.8 %60 / 6275.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/index-sort-l.html b/coverage/landmarks/index-sort-l.html new file mode 100644 index 000000000..0798fd032 --- /dev/null +++ b/coverage/landmarks/index-sort-l.html @@ -0,0 +1,123 @@ + + + + + + + LCOV - plumed test coverage - landmarks + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarksHitTotalCoverage
Test:plumed test coverageLines:18218797.3 %
Date:2024-10-17 16:45:00Functions:111861.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FarthestPointSampling.cpp +
92.7%92.7%
+
92.7 %38 / 4150.0 %4 / 8
CollectFrames.cpp +
96.8%96.8%
+
96.8 %60 / 6275.0 %3 / 4
LogSumExp.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
LandmarkSelection.cpp +
100.0%
+
100.0 %68 / 6866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/landmarks/index.html b/coverage/landmarks/index.html new file mode 100644 index 000000000..2961b8c6a --- /dev/null +++ b/coverage/landmarks/index.html @@ -0,0 +1,123 @@ + + + + + + + LCOV - plumed test coverage - landmarks + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - landmarksHitTotalCoverage
Test:plumed test coverageLines:18218797.3 %
Date:2024-10-17 16:45:00Functions:111861.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CollectFrames.cpp +
96.8%96.8%
+
96.8 %60 / 6275.0 %3 / 4
FarthestPointSampling.cpp +
92.7%92.7%
+
92.7 %38 / 4150.0 %4 / 8
LandmarkSelection.cpp +
100.0%
+
100.0 %68 / 6866.7 %2 / 3
LogSumExp.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
+
+
+ + + + +
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 000000000..71fb25114 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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:32537087.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..d51cf8bbd --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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:32537087.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..9327f4c35 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.gcov.html @@ -0,0 +1,1315 @@ + + + + + + + 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:32537087.8 %
Date:2024-10-17 16:45:00Functions: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 (N_m) 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 N*kb*T*100*100." );
+     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({X}(t)) > 0 at any X(t), "
+     522             :            "resulting in enhanced barrier-crossing. "
+     523             :            "(The value of H_log is automatically "
+     524             :            "set according to FLOG). "
+     525             :            "In fact, F({X}(t)) is correctly "
+     526             :            "estimated in PLUMED even when F({X}(t)) < 0 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          10 :   keys.addOutputComponent("_fict","default",
+     541             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     542             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, "
+     543             :                           "the associated fictitious dynamical variable can be specified as "
+     544             :                           "PRINT ARG=dist12,logmfd.dist12_fict FILE=COLVAR");
+     545          10 :   keys.addOutputComponent("_vfict","default",
+     546             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     547             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, the "
+     548             :                           "velocity of the associated fictitious dynamical variable can be specified as "
+     549             :                           "PRINT ARG=dist12,logmfd.dist12_vfict FILE=COLVAR");
+     550           5 : }
+     551             : 
+     552             : 
+     553             : /**
+     554             :    \brief constructor of LogMFD class
+     555             :    \details This constructor initializes all parameters and variables,
+     556             :    reads input file and set value of parameters and initial value of variables,
+     557             :    and writes messages as Plumed log.
+     558             : */
+     559           3 : LogMFD::LogMFD( const ActionOptions& ao ):
+     560             :   PLUMED_BIAS_INIT(ao),
+     561           3 :   firsttime(true),
+     562           3 :   step_initial(0),
+     563           3 :   interval(10),
+     564           3 :   delta_t(1.0),
+     565           6 :   thermostat("NVE"),
+     566           3 :   kbt(-1.0),
+     567           3 :   kbtpd(-1.0),
+     568           3 :   TAMD(0),
+     569           3 :   alpha(0.0),
+     570           3 :   gamma(0.0),
+     571           3 :   kappa(getNumberOfArguments(),0.0),
+     572           3 :   fict_max(getNumberOfArguments(),0.0),
+     573           3 :   fict_min(getNumberOfArguments(),0.0),
+     574           3 :   fict (getNumberOfArguments(),-999.0), // -999 means no initial values given in plumed.dat
+     575           3 :   vfict(getNumberOfArguments(),0.0),
+     576           3 :   mfict(getNumberOfArguments(),10000.0),
+     577           3 :   xeta(0.0),
+     578           3 :   veta(0.0),
+     579           3 :   meta(0.0),
+     580           3 :   flog(0.0),
+     581           3 :   hlog(0.0),
+     582           3 :   phivs(0.0),
+     583           3 :   work(0.0),
+     584           3 :   weight(0.0),
+     585           3 :   ffict(getNumberOfArguments(),0.0),
+     586           3 :   fict_ave(getNumberOfArguments(),0.0),
+     587           3 :   fictValue(getNumberOfArguments(),NULL),
+     588           9 :   vfictValue(getNumberOfArguments(),NULL)
+     589             : {
+     590           3 :   backup.fict.resize(getNumberOfArguments(),0.0);
+     591           3 :   backup.vfict.resize(getNumberOfArguments(),0.0);
+     592           3 :   backup.ffict.resize(getNumberOfArguments(),0.0);
+     593           3 :   backup.xeta = 0.0;
+     594           3 :   backup.veta = 0.0;
+     595           3 :   backup.phivs = 0.0;
+     596           3 :   backup.work = 0.0;
+     597           3 :   backup.weight = 0.0;
+     598             : 
+     599           3 :   parse("INTERVAL",interval);
+     600           3 :   parse("DELTA_T",delta_t);
+     601           3 :   parse("THERMOSTAT",thermostat);
+     602           3 :   kbt = getkBT(); // read as temperature
+     603           3 :   parse("TEMPPD",kbtpd); // read as temperature
+     604             : 
+     605           3 :   parse("TAMD",TAMD);
+     606           3 :   parse("ALPHA",alpha);
+     607           3 :   parse("GAMMA",gamma);
+     608           3 :   parseVector("KAPPA",kappa);
+     609             : 
+     610           3 :   parseVector("FICT_MAX",fict_max);
+     611           3 :   parseVector("FICT_MIN",fict_min);
+     612             : 
+     613           3 :   parseVector("FICT",fict);
+     614           3 :   parseVector("VFICT",vfict);
+     615           3 :   parseVector("MFICT",mfict);
+     616             : 
+     617           3 :   parse("XETA",xeta);
+     618           3 :   parse("VETA",veta);
+     619           3 :   parse("META",meta);
+     620             : 
+     621           3 :   parse("FLOG",flog);
+     622             : 
+     623             :   // read initial value of work for each replica of LogPD
+     624           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     625           0 :     vector<double> vwork(multi_sim_comm.Get_size(),0.0);
+     626           0 :     parseVector("WORK",vwork);
+     627             :     // initial work of this replica
+     628           0 :     work = vwork[multi_sim_comm.Get_rank()];
+     629             :   }
+     630             :   else {
+     631           3 :     work = 0.0;
+     632             :   }
+     633             : 
+     634           3 :   if( kbtpd>=0.0 ) {
+     635           0 :     kbtpd *= getKBoltzmann();
+     636             :   }
+     637             :   else {
+     638           3 :     kbtpd = kbt;
+     639             :   }
+     640             : 
+     641           3 :   if( meta == 0.0 ) {
+     642           2 :     const double nkt = getNumberOfArguments()*kbt;
+     643           2 :     meta = nkt*100.0*100.0;
+     644             :   }
+     645             : 
+     646           3 :   if(alpha == 0.0 && gamma == 0.0) {
+     647           0 :     alpha = 4.0;
+     648           0 :     gamma = 1 / alpha;
+     649             :   }
+     650           3 :   else if(alpha != 0.0 && gamma == 0.0) {
+     651           3 :     gamma = 1 / alpha;
+     652             :   }
+     653           0 :   else if(alpha == 0.0 && gamma != 0.0) {
+     654           0 :     alpha = 1 / gamma;
+     655             :   }
+     656             : 
+     657           3 :   checkRead();
+     658             : 
+     659             :   // output messaages to Plumed's log file
+     660           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     661           0 :     if( TAMD ) {
+     662           0 :       log.printf("TAMD-PD, replica parallel of TAMD, no logarithmic flattening.\n");
+     663             :     }
+     664             :     else {
+     665           0 :       log.printf("LogPD, replica parallel of LogMFD.\n");
+     666             :     }
+     667           0 :     log.printf("number of replica : %d.\n", multi_sim_comm.Get_size() );
+     668             :   }
+     669             :   else {
+     670           3 :     if( TAMD ) {
+     671           0 :       log.printf("TAMD, no logarithmic flattening.\n");
+     672             :     }
+     673             :     else {
+     674           3 :       log.printf("LogMFD, logarithmic flattening.\n");
+     675             :     }
+     676             :   }
+     677             : 
+     678           3 :   log.printf("  with harmonic force constant      ");
+     679           6 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     680           3 :   log.printf("\n");
+     681             : 
+     682           3 :   log.printf("  with interval of cv(ideal) update ");
+     683           3 :   log.printf(" %d", interval);
+     684           3 :   log.printf("\n");
+     685             : 
+     686           3 :   log.printf("  with time step of cv(ideal) update ");
+     687           3 :   log.printf(" %f", delta_t);
+     688           3 :   log.printf("\n");
+     689             : 
+     690           3 :   if( !TAMD ) {
+     691           3 :     log.printf("  with alpha, gamma                 ");
+     692           3 :     log.printf(" %f %f", alpha, gamma);
+     693           3 :     log.printf("\n");
+     694             :   }
+     695             : 
+     696           3 :   log.printf("  with Thermostat for cv(ideal)     ");
+     697           3 :   log.printf(" %s", thermostat.c_str());
+     698           3 :   log.printf("\n");
+     699             : 
+     700           3 :   log.printf("  with initial free energy          ");
+     701           3 :   log.printf(" %f", flog);
+     702           3 :   log.printf("\n");
+     703             : 
+     704           3 :   log.printf("  with mass of cv(ideal)");
+     705           6 :   for(unsigned i=0; i<mfict.size(); i++) log.printf(" %f", mfict[i]);
+     706           3 :   log.printf("\n");
+     707             : 
+     708           3 :   log.printf("  with initial value of cv(ideal)");
+     709           6 :   for(unsigned i=0; i<fict.size(); i++) log.printf(" %f", fict[i]);
+     710           3 :   log.printf("\n");
+     711             : 
+     712           3 :   log.printf("  with initial velocity of cv(ideal)");
+     713           6 :   for(unsigned i=0; i<vfict.size(); i++) log.printf(" %f", vfict[i]);
+     714           3 :   log.printf("\n");
+     715             : 
+     716           3 :   log.printf("  with maximum value of cv(ideal)    ");
+     717           6 :   for(unsigned i=0; i<fict_max.size(); i++) log.printf(" %f",fict_max[i]);
+     718           3 :   log.printf("\n");
+     719             : 
+     720           3 :   log.printf("  with minimum value of cv(ideal)    ");
+     721           6 :   for(unsigned i=0; i<fict_min.size(); i++) log.printf(" %f",fict_min[i]);
+     722           3 :   log.printf("\n");
+     723             : 
+     724           3 :   log.printf("  and kbt                           ");
+     725           3 :   log.printf(" %f\n",kbt);
+     726           3 :   log.printf(" kbt for PD %f\n",kbtpd);
+     727             : 
+     728             :   // setup Value* variables
+     729           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     730           3 :     std::string comp = getPntrToArgument(i)->getName()+"_fict";
+     731           6 :     addComponentWithDerivatives(comp);
+     732             : 
+     733           3 :     if(getPntrToArgument(i)->isPeriodic()) {
+     734             :       std::string a,b;
+     735           0 :       getPntrToArgument(i)->getDomain(a,b);
+     736           0 :       componentIsPeriodic(comp,a,b);
+     737             :     }
+     738             :     else {
+     739           3 :       componentIsNotPeriodic(comp);
+     740             :     }
+     741           3 :     fictValue[i] = getPntrToComponent(comp);
+     742             : 
+     743           6 :     comp = getPntrToArgument(i)->getName()+"_vfict";
+     744           3 :     addComponent(comp);
+     745             : 
+     746           3 :     componentIsNotPeriodic(comp);
+     747           3 :     vfictValue[i] = getPntrToComponent(comp);
+     748             :   }
+     749           3 : }
+     750             : 
+     751             : /**
+     752             :    \brief calculate forces for fictitious variables at every MD steps.
+     753             :    \details This function calculates initial values of fictitious variables
+     754             :    and write header messages to LogMFD log files at the first MFD step,
+     755             :    calculates restraining fources comes from difference between the fictitious variable
+     756             :    and collective variable at every MD steps.
+     757             : */
+     758        1500 : void LogMFD::calculate() {
+     759        1500 :   if( firsttime ) {
+     760           3 :     firsttime = false;
+     761             : 
+     762           3 :     step_initial = getStep();
+     763             : 
+     764             :     // set initial values of fictitious variables if they were not specified.
+     765           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     766           3 :       if( fict[i] != -999.0 ) continue; // -999 means no initial values given in plumed.dat
+     767             : 
+     768             :       // use the collective variables as the initial of the fictitious variable.
+     769           0 :       fict[i] = getArgument(i);
+     770             : 
+     771             :       // average values of fictitious variables by all replica.
+     772           0 :       if( multi_sim_comm.Get_size()>1 ) {
+     773           0 :         multi_sim_comm.Sum(fict[i]);
+     774           0 :         fict[i] /= multi_sim_comm.Get_size();
+     775             :       }
+     776             :     }
+     777             : 
+     778             :     // initialize accumulation value to zero
+     779           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     780           3 :       fict_ave[i] = 0.0;
+     781             :     }
+     782             : 
+     783             :     // calculate invariant for NVE
+     784           3 :     if(thermostat == "NVE") {
+     785             :       // kinetic energy
+     786           1 :       const double ekin = calcEkin();
+     787             :       // potential energy
+     788           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     789             :       // invariant
+     790           1 :       hlog = pot + ekin;
+     791             :     }
+     792           2 :     else if(thermostat == "NVT") {
+     793           1 :       const double nkt = getNumberOfArguments()*kbt;
+     794             :       // kinetic energy
+     795           1 :       const double ekin = calcEkin();
+     796             :       // bath energy
+     797           1 :       const double ekin_bath = 0.5*veta*veta*meta + xeta*nkt;
+     798             :       // potential energy
+     799           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     800             :       // invariant
+     801           1 :       hlog = pot + ekin + ekin_bath;
+     802             :     }
+     803           1 :     else if(thermostat == "VS") {
+     804             :       // kinetic energy
+     805           1 :       const double ekin = calcEkin();
+     806           1 :       if( ekin == 0.0 ) { // this means VFICT is not given.
+     807             :         // initial velocities
+     808           2 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     809           1 :           vfict[i] = sqrt(kbt/mfict[i]);
+     810             :         }
+     811             :       }
+     812             :       else {
+     813           0 :         const double nkt = getNumberOfArguments()*kbt;
+     814           0 :         const double svs = sqrt(nkt/ekin/2);
+     815           0 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     816           0 :           vfict[i] *= svs; // scale velocities
+     817             :         }
+     818             :       }
+     819             :       // initial VS potential
+     820           1 :       phivs = TAMD ? flog : sgn(flog)* gamma*std::log1p( alpha*fabs(flog) );
+     821             : 
+     822             :       // invariant
+     823           1 :       hlog = 0.0;
+     824             :     }
+     825             : 
+     826           3 :     weight = 1.0; // for replica parallel
+     827             : 
+     828             :     // open LogMFD's log file
+     829           3 :     if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     830           3 :       FILE *outlog = std::fopen("logmfd.out", "w");
+     831             : 
+     832             :       // output messages to LogMFD's log file
+     833           3 :       if( multi_sim_comm.Get_size()>1 ) {
+     834             :         fprintf(outlog, "# LogPD, replica parallel of LogMFD\n");
+     835           0 :         fprintf(outlog, "# number of replica : %d\n", multi_sim_comm.Get_size() );
+     836             :       }
+     837             :       else {
+     838             :         fprintf(outlog, "# LogMFD\n");
+     839             :       }
+     840             : 
+     841             :       fprintf(outlog, "# CVs :");
+     842           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     843             :         fprintf(outlog, " %s",  getPntrToArgument(i)->getName().c_str() );
+     844             :       }
+     845             :       fprintf(outlog, "\n");
+     846             : 
+     847             :       fprintf(outlog, "# Mass for CV particles :");
+     848           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     849           3 :         fprintf(outlog, "%15.6f", mfict[i]);
+     850             :       }
+     851             :       fprintf(outlog, "\n");
+     852             : 
+     853             :       fprintf(outlog, "# Mass for thermostat   :");
+     854           3 :       fprintf(outlog, "%15.6f", meta);
+     855             :       fprintf(outlog, "\n");
+     856             :       fprintf(outlog, "# 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,\n");
+     857             : 
+     858           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     859           3 :         fprintf(outlog, "# %u:%s_fict(t), %u:%s_vfict(t), %u:%s_force(t),\n",
+     860             :                 6+i*3, getPntrToArgument(i)->getName().c_str(),
+     861             :                 7+i*3, getPntrToArgument(i)->getName().c_str(),
+     862           3 :                 8+i*3, getPntrToArgument(i)->getName().c_str() );
+     863             :       }
+     864           3 :       fclose(outlog);
+     865             :     }
+     866             : 
+     867           3 :     if( comm.Get_rank()==0 ) {
+     868             :       // the number of replica is added to file name to distingwish replica.
+     869           3 :       FILE *outlog2 = fopen("replica.out", "w");
+     870           6 :       fprintf(outlog2, "# Replica No. %d of %d.\n",
+     871           3 :               multi_sim_comm.Get_rank(), multi_sim_comm.Get_size() );
+     872             : 
+     873             :       fprintf(outlog2, "# 1:iter_mfd, 2:work, 3:weight,\n");
+     874           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     875           3 :         fprintf(outlog2, "# %u:%s(q)\n",
+     876             :                 4+i, getPntrToArgument(i)->getName().c_str() );
+     877             :       }
+     878           3 :       fclose(outlog2);
+     879             :     }
+     880             : 
+     881             :     // output messages to Plumed's log file
+     882             :     //    log.printf("LOGMFD thermostat parameters Xeta Veta Meta");
+     883             :     //    log.printf(" %f %f %f", xeta, veta, meta);
+     884             :     //    log.printf("\n");
+     885             :     //    log.printf("# 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,");
+     886             :     //    log.printf("# 6:X1(t), 7:V1(t), 8:F1(t), 9:X2(t), 10:V2(t), 11:F2(t), ...");
+     887             : 
+     888             :   } // firsttime
+     889             : 
+     890             :   // calculate force for fictitious variable
+     891             :   double ene=0.0;
+     892        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     893             :     // difference between fictitious variable and collective variable.
+     894        1500 :     const double diff = difference(i,fict[i],getArgument(i));
+     895             :     // restraining force.
+     896        1500 :     const double f = -kappa[i]*diff;
+     897        1500 :     setOutputForce(i,f);
+     898             : 
+     899             :     // restraining energy.
+     900        1500 :     ene += 0.5*kappa[i]*diff*diff;
+     901             : 
+     902             :     // accumulate force, later it will be averaged.
+     903        1500 :     ffict[i] += -f;
+     904             : 
+     905             :     // accumulate varience of collective variable, later it will be averaged.
+     906        1500 :     fict_ave[i] += diff;
+     907             :   }
+     908             : 
+     909        1500 :   setBias(ene);
+     910        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     911             :     // correct fict so that it is inside [min:max].
+     912        1500 :     double tmp = fict[i];
+     913        1500 :     fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
+     914        1500 :     fictValue[i]->set(fict[i]);
+     915        1500 :     vfictValue[i]->set(vfict[i]);
+     916             :   }
+     917        1500 : } // calculate
+     918             : 
+     919             : /**
+     920             :    \brief update fictitious variables.
+     921             :    \details This function manages evolution of fictitious variables.
+     922             :    This function calculates mean force, updates fictitious variables by one MFD step,
+     923             :    bounces back variables, updates free energy, and record logs.
+     924             : */
+     925        1500 : void LogMFD::update() {
+     926        1500 :   if( (getStep()-step_initial)%interval != interval-1 ) return;
+     927             : 
+     928          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     929          15 :     backup.fict[i]  =  fict[i];
+     930          15 :     backup.vfict[i] = vfict[i];
+     931             :   }
+     932          15 :   backup.xeta = xeta;
+     933          15 :   backup.veta = veta;
+     934          15 :   backup.phivs = phivs;
+     935          15 :   backup.work = work;
+     936          15 :   backup.weight = weight;
+     937             : 
+     938             :   // calc mean force for fictitious variables
+     939          15 :   calcMeanForce();
+     940             : 
+     941             :   // record log for fictitious variables
+     942          15 :   if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     943          15 :     const double ekin = calcEkin();
+     944          15 :     const double temp = 2.0*ekin/getNumberOfArguments()/getKBoltzmann();
+     945             : 
+     946          15 :     FILE *outlog = std::fopen("logmfd.out", "a");
+     947          15 :     fprintf(outlog, "%*d", 8, (int)(getStep()-step_initial)/interval);
+     948          15 :     fprintf(outlog, "%15.6f", flog);
+     949             :     fprintf(outlog, "%15.6f", temp);
+     950          15 :     fprintf(outlog, "%15.6f", xeta);
+     951          15 :     fprintf(outlog, "%15.6f", veta);
+     952          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     953          15 :       fprintf(outlog, "%15.6f", fict[i]);
+     954          15 :       fprintf(outlog, "%15.6f", vfict[i]);
+     955          15 :       fprintf(outlog, "%15.6f", ffict[i]);
+     956             :     }
+     957             :     fprintf(outlog," \n");
+     958          15 :     fclose(outlog);
+     959             :   }
+     960             : 
+     961             :   // record log for collective variables
+     962          15 :   if( comm.Get_rank()==0 ) {
+     963             :     // the number of replica is added to file name to distingwish replica.
+     964          15 :     FILE *outlog2 = fopen("replica.out", "a");
+     965          15 :     fprintf(outlog2, "%*d", 8, (int)(getStep()-step_initial)/interval);
+     966          15 :     fprintf(outlog2, "%16.6e ", work);
+     967          15 :     fprintf(outlog2, "%16.6e ", weight);
+     968          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     969          15 :       fprintf(outlog2, "%15.6f", fict_ave[i]);
+     970             :     }
+     971             :     fprintf(outlog2," \n");
+     972          15 :     fclose(outlog2);
+     973             :   }
+     974             : 
+     975             :   // update fictitious variables
+     976          15 :   if(thermostat == "NVE") {
+     977           5 :     updateNVE();
+     978             :   }
+     979          10 :   else if(thermostat == "NVT") {
+     980           5 :     updateNVT();
+     981             :   }
+     982           5 :   else if(thermostat == "VS") {
+     983           5 :     updateVS();
+     984             :   }
+     985             : 
+     986             :   // update work done by fictitious dynamical variables
+     987          15 :   updateWork();
+     988             : 
+     989             :   // check boundary
+     990             :   bool reject = false;
+     991          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     992          15 :     if( fict[i] < fict_min[i] || fict_max[i] < fict[i] ) {
+     993             :       reject = true;
+     994           0 :       backup.vfict[i] *= -1.0;
+     995             :     }
+     996             :   }
+     997          15 :   if( reject ) {
+     998           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     999           0 :       fict[i] = backup.fict[i];
+    1000           0 :       vfict[i] = backup.vfict[i];
+    1001             :     }
+    1002           0 :     xeta = backup.xeta;
+    1003           0 :     veta = backup.veta;
+    1004           0 :     phivs = backup.phivs;
+    1005           0 :     work = backup.work;
+    1006           0 :     weight = backup.weight;
+    1007             :   }
+    1008             : 
+    1009             :   // update free energy
+    1010          15 :   flog = calcFlog();
+    1011             : 
+    1012             :   // reset mean force
+    1013          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1014          15 :     ffict[i] = 0.0;
+    1015          15 :     fict_ave[i] = 0.0;
+    1016             :   }
+    1017             : 
+    1018             : } // update
+    1019             : 
+    1020             : /**
+    1021             :    \brief update fictitious variables by NVE mechanics.
+    1022             :    \details This function updates ficitious variables by one NVE-MFD step using mean forces
+    1023             :    and flattening coefficient and free energy.
+    1024             :  */
+    1025           5 : void LogMFD::updateNVE() {
+    1026           5 :   const double dt = delta_t;
+    1027             : 
+    1028             :   // get latest free energy and flattening coefficient
+    1029           5 :   flog = calcFlog();
+    1030           5 :   const double clog = calcClog();
+    1031             : 
+    1032             :   // update all ficitious variables by one MFD step
+    1033          10 :   for( unsigned i=0; i<getNumberOfArguments(); ++i ) {
+    1034             :     // update velocity (full step)
+    1035           5 :     vfict[i]+=clog*ffict[i]*dt/mfict[i];
+    1036             :     // update position (full step)
+    1037           5 :     fict[i]+=vfict[i]*dt;
+    1038             :   }
+    1039           5 : } // updateNVE
+    1040             : 
+    1041             : /**
+    1042             :    \brief update fictitious variables by NVT mechanics.
+    1043             :    \details This function updates ficitious variables by one NVT-MFD step using mean forces
+    1044             :    and flattening coefficient and free energy.
+    1045             :  */
+    1046           5 : void LogMFD::updateNVT() {
+    1047           5 :   const double dt = delta_t;
+    1048           5 :   const double nkt = getNumberOfArguments()*kbt;
+    1049             : 
+    1050             :   // backup vfict
+    1051          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1052           5 :     backup.vfict[i] = vfict[i];
+    1053             :   }
+    1054             : 
+    1055             :   const int niter=5;
+    1056          30 :   for(unsigned j=0; j<niter; ++j) {
+    1057             :     // get latest free energy and flattening coefficient
+    1058          25 :     flog = calcFlog();
+    1059          25 :     const double clog = calcClog();
+    1060             : 
+    1061             :     // restore vfict from backup.vfict
+    1062          50 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1063          25 :       vfict[i] = backup.vfict[i];
+    1064             :     }
+    1065             : 
+    1066             :     // evolve vfict from backup.vfict by dt/2
+    1067          50 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1068          25 :       vfict[i] *= exp(-0.25*dt*veta);
+    1069          25 :       vfict[i] += 0.5*dt*clog*ffict[i]/mfict[i];
+    1070          25 :       vfict[i] *= exp(-0.25*dt*veta);
+    1071             :     }
+    1072             :   }
+    1073             : 
+    1074             :   // get latest free energy and flattening coefficient
+    1075           5 :   flog = calcFlog();
+    1076           5 :   const double clog = calcClog();
+    1077             : 
+    1078             :   // evolve vfict by dt/2, and evolve fict by dt
+    1079          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1080           5 :     vfict[i] *= exp(-0.25*dt*veta);
+    1081           5 :     vfict[i] += 0.5*dt*clog*ffict[i]/mfict[i];
+    1082           5 :     vfict[i] *= exp(-0.25*dt*veta);
+    1083           5 :     fict[i]  += dt*vfict[i];
+    1084             :   }
+    1085             : 
+    1086             :   // evolve xeta and veta by dt
+    1087           5 :   xeta += 0.5*dt*veta;
+    1088           5 :   const double ekin = calcEkin();
+    1089           5 :   veta += dt*(2.0*ekin-nkt)/meta;
+    1090           5 :   xeta += 0.5*dt*veta;
+    1091           5 : } // updateNVT
+    1092             : 
+    1093             : /**
+    1094             :    \brief update fictitious variables by VS mechanics.
+    1095             :    \details This function updates ficitious variables by one VS-MFD step using mean forces
+    1096             :    and flattening coefficient and free energy.
+    1097             :  */
+    1098           5 : void LogMFD::updateVS() {
+    1099           5 :   const double dt = delta_t;
+    1100           5 :   const double nkt = getNumberOfArguments()*kbt;
+    1101             : 
+    1102             :   // get latest free energy and flattening coefficient
+    1103           5 :   flog = calcFlog();
+    1104           5 :   const double clog = calcClog();
+    1105             : 
+    1106          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1107             :     // update velocity (full step)
+    1108           5 :     vfict[i] += clog*ffict[i]*dt/mfict[i];
+    1109             :   }
+    1110             : 
+    1111           5 :   const double ekin = calcEkin();
+    1112           5 :   const double svs = sqrt(nkt/ekin/2);
+    1113             : 
+    1114          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1115             :     // update position (full step)
+    1116           5 :     vfict[i] *= svs;
+    1117           5 :     fict[i] += vfict[i]*dt;
+    1118             :   }
+    1119             : 
+    1120             :   // evolve VS potential
+    1121           5 :   phivs += nkt*std::log(svs);
+    1122           5 : } // updateVS
+    1123             : 
+    1124             : /**
+    1125             :    \brief update work done by fictious variables.
+    1126             :    \details This function updates work done by ficitious variables.
+    1127             :  */
+    1128          15 : void LogMFD::updateWork() {
+    1129             :   // accumulate work, it was initialized as 0.0
+    1130          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1131          15 :     work -= backup.ffict[i] * vfict[i] * delta_t;
+    1132             :   }
+    1133          15 : } // updateWork
+    1134             : 
+    1135             : /**
+    1136             :    \brief calculate mean force for fictitious variables.
+    1137             :    \details This function calculates mean forces by averaging forces accumulated during one MFD step,
+    1138             :    update work variables done by fictitious variables by one MFD step,
+    1139             :    calculate weight variable of this replica for LogPD.
+    1140             : */
+    1141          15 : void LogMFD::calcMeanForce() {
+    1142             :   // cale temporal mean force for each CV
+    1143          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1144          15 :     ffict[i] /= interval;
+    1145             :     // backup force of replica
+    1146          15 :     backup.ffict[i] = ffict[i];
+    1147             :     // average of diff (getArgument(i)-fict[i])
+    1148          15 :     fict_ave[i] /= interval;
+    1149             :     // average of getArgument(i)
+    1150          15 :     fict_ave[i] += fict[i];
+    1151             : 
+    1152             :     // correct fict_ave so that it is inside [min:max].
+    1153          15 :     fict_ave[i] = fictValue[i]->bringBackInPbc(fict_ave[i]);
+    1154             :   }
+    1155             : 
+    1156             :   // for replica parallel
+    1157          15 :   if( multi_sim_comm.Get_size()>1 ) {
+    1158             :     // find the minimum work among all replicas
+    1159           0 :     double work_min = work;
+    1160           0 :     multi_sim_comm.Min(work_min);
+    1161             : 
+    1162             :     // weight of this replica.
+    1163             :     // here, work is reduced by work_min to avoid all exp(-work/kbt)s disconverge
+    1164           0 :     if( kbtpd == 0.0 ) {
+    1165           0 :       weight = work==work_min ? 1.0 : 0.0;
+    1166             :     }
+    1167             :     else {
+    1168           0 :       weight = exp(-(work-work_min)/kbtpd);
+    1169             :     }
+    1170             : 
+    1171             :     // normalize the weight
+    1172           0 :     double sum_weight = weight;
+    1173           0 :     multi_sim_comm.Sum(sum_weight);
+    1174           0 :     weight /= sum_weight;
+    1175             : 
+    1176             :     // weighting force of this replica
+    1177           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1178           0 :       ffict[i] *= weight;
+    1179             :     }
+    1180             : 
+    1181             :     // averaged mean forces of all replica.
+    1182           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1183           0 :       multi_sim_comm.Sum(ffict[i]);
+    1184             :     }
+    1185             :     // now, mean force is obtained.
+    1186             :   }
+    1187          15 : } // calcMeanForce
+    1188             : 
+    1189             : /**
+    1190             :    \brief calculate kinetic energy of fictitious variables.
+    1191             :    \retval kinetic energy.
+    1192             :    \details This function calculates sum of kinetic energy of all fictitious variables.
+    1193             :  */
+    1194          83 : double LogMFD::calcEkin() {
+    1195             :   double ekin=0.0;
+    1196         166 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1197          83 :     ekin += mfict[i]*vfict[i]*vfict[i]*0.5;
+    1198             :   }
+    1199          83 :   return ekin;
+    1200             : } // calcEkin
+    1201             : 
+    1202             : /**
+    1203             :    \brief calculate free energy of fictitious variables.
+    1204             :    \retval free energy.
+    1205             :    \details This function calculates free energy by using invariant of canonical mechanics.
+    1206             :  */
+    1207          55 : double LogMFD::calcFlog() {
+    1208          55 :   const double nkt = getNumberOfArguments()*kbt;
+    1209          55 :   const double ekin = calcEkin();
+    1210             :   double pot;
+    1211             : 
+    1212          55 :   if (thermostat == "NVE") {
+    1213          10 :     pot = hlog - ekin;
+    1214             :   }
+    1215          45 :   else if (thermostat == "NVT") {
+    1216          35 :     const double ekin_bath = 0.5*veta*veta*meta+xeta*nkt;
+    1217          35 :     pot = hlog - ekin - ekin_bath;
+    1218             :   }
+    1219          10 :   else if (thermostat == "VS") {
+    1220          10 :     pot = phivs;
+    1221             :   }
+    1222             :   else {
+    1223             :     pot = 0.0; // never occurs
+    1224             :   }
+    1225             : 
+    1226         110 :   return TAMD ? pot : sgn(pot)*expm1(fabs(pot)/gamma)/alpha;
+    1227             : } // calcFlog
+    1228             : 
+    1229             : /**
+    1230             :    \brief calculate coefficient for flattening.
+    1231             :    \retval flattering coefficient.
+    1232             :    \details This function returns 1.0 for TAMD, flattening coefficient for LogMFD.
+    1233             :  */
+    1234          40 : double LogMFD::calcClog() {
+    1235          40 :   return TAMD ? 1.0 : alpha*gamma/(alpha*fabs(flog)+1.0);
+    1236             : } // calcClog
+    1237             : 
+    1238             : } // logmfd
+    1239             : } // 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 000000000..b64981a88 --- /dev/null +++ b/coverage/logmfd/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32537087.8 %
Date:2024-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.8%87.8%
+
87.8 %325 / 37092.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 000000000..1a608eb5d --- /dev/null +++ b/coverage/logmfd/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32537087.8 %
Date:2024-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.8%87.8%
+
87.8 %325 / 37092.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 000000000..cc2551d0e --- /dev/null +++ b/coverage/logmfd/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32537087.8 %
Date:2024-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.8%87.8%
+
87.8 %325 / 37092.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 000000000..26c884479 --- /dev/null +++ b/coverage/main/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:151883.3 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
83.3%83.3%
+
83.3 %15 / 18100.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 000000000..02e8c1fd5 --- /dev/null +++ b/coverage/main/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:151883.3 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
83.3%83.3%
+
83.3 %15 / 18100.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 000000000..763b1cae3 --- /dev/null +++ b/coverage/main/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:151883.3 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
83.3%83.3%
+
83.3 %15 / 18100.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 000000000..b806878e7 --- /dev/null +++ b/coverage/main/main.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - main/main.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151883.3 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main5248
+
+
+ + + +
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 000000000..f6dc062d5 --- /dev/null +++ b/coverage/main/main.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - main/main.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151883.3 %
Date:2024-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main5248
+
+
+ + + +
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 000000000..f7f2646c5 --- /dev/null +++ b/coverage/main/main.cpp.gcov.html @@ -0,0 +1,147 @@ + + + + + + + LCOV - plumed test coverage - main/main.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151883.3 %
Date:2024-10-17 16:45:00Functions: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        5248 : int main(int argc,char**argv) {
+      37             : #ifdef __PLUMED_HAS_MPI
+      38             :   bool nompi=false;
+      39       10935 :   for(unsigned iarg=1; iarg<argc; iarg++) {
+      40       10144 :     if(!std::strcmp(argv[iarg],"--no-mpi")) nompi=true;
+      41       10144 :     if(!std::strcmp(argv[iarg],"--mpi"))    nompi=false;
+      42             : // stop at first non-option
+      43       10144 :     if(argv[iarg] && argv[iarg][0]!='-') break;
+      44             :   }
+      45        5248 :   if(!nompi) MPI_Init(&argc,&argv);
+      46             : #endif
+      47        5248 :   int ret=0;
+      48             : 
+      49             :   try {
+      50             :     PLMD::Plumed p;
+      51        5248 :     p.cmd("CLTool setArgc",&argc);
+      52        5248 :     p.cmd("CLTool setArgv",argv, {argc});
+      53             : #ifdef __PLUMED_HAS_MPI
+      54        5248 :     if(!nompi) {
+      55             :       MPI_Comm comm;
+      56         352 :       MPI_Comm_dup(MPI_COMM_WORLD,&comm);
+      57         704 :       p.cmd("CLTool setMPIComm",&comm);
+      58             :     }
+      59             : #endif
+      60       10496 :     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        5248 :   if(!nompi) MPI_Finalize();
+      69             : #endif
+      70        5248 :   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 000000000..797a8df4b --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:505198.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..ccce41d8a --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:505198.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..646dddb23 --- /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:505198.0 %
Date:2024-10-17 16:45:00Functions: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           6 :   keys.setValueDescription("the position along and from the adaptive path");
+     108          12 :   keys.needsAction("GEOMETRIC_PATH"); keys.needsAction("AVERAGE_PATH_DISPLACEMENT");
+     109          12 :   keys.needsAction("REPARAMETERIZE_PATH"); keys.needsAction("DUMPPDB");
+     110          18 :   keys.needsAction("PDB2CONSTANT"); keys.needsAction("DISPLACEMENT"); keys.needsAction("CONSTANT");
+     111           6 : }
+     112             : 
+     113           2 : AdaptivePath::AdaptivePath(const ActionOptions& ao):
+     114             :   Action(ao),
+     115           2 :   ActionShortcut(ao)
+     116             : {
+     117             :   // Read in the arguments
+     118           4 :   std::vector<std::string> argnames; parseVector("ARG",argnames);
+     119           4 :   std::string reference_data, metric, mtype; parse("TYPE", mtype);
+     120           4 :   std::string reference; parse("REFERENCE",reference);
+     121           2 :   FILE* fp=std::fopen(reference.c_str(),"r"); PDB mypdb; if(!fp) error("could not open reference file " + reference );
+     122           2 :   bool do_read=mypdb.readFromFilepointer(fp,false,0.1); if( !do_read ) error("missing file " + reference );
+     123             :   // Create list of reference configurations that PLUMED will use
+     124           2 :   Path::readInputFrames( reference, mtype, argnames, true, this, reference_data );
+     125             :   // Now get coordinates on spath
+     126           4 :   std::vector<std::string> pnames; parseVector("PROPERTY",pnames); Path::readPropertyInformation( pnames, getShortcutLabel(), reference, this );
+     127             :   // Create action that computes the geometric path variablesa
+     128           3 :   std::string propstr = getShortcutLabel() + "_ind"; if( pnames.size()>0 ) propstr = pnames[0] + "_ref";
+     129           3 :   if( argnames.size()>0 ) readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data " + " PROPERTY=" + propstr + " REFERENCE=" + reference_data + " METRIC={DIFFERENCE}");
+     130             :   else {
+     131           1 :     std::string num, align_str, displace_str; Tools::convert( mypdb.getOccupancy()[0], align_str ); Tools::convert( mypdb.getBeta()[0], displace_str );
+     132          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; }
+     133           2 :     metric = "RMSD_VECTOR DISPLACEMENT TYPE=" + mtype + " ALIGN=" + align_str + " DISPLACE=" + displace_str;
+     134           2 :     readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data.disp " + " PROPERTY=" +  propstr + " REFERENCE=" + reference_data + " METRIC={" + metric + "} METRIC_COMPONENT=disp");
+     135             :   }
+     136             :   // Create the object to accumulate the average path displacements
+     137           8 :   std::string update, halflife; parse("HALFLIFE",halflife); parse("UPDATE",update); std::string refframes = " REFERENCE=" + getShortcutLabel() + "_pos";
+     138           3 :   if( argnames.size()>0 ) readInputLine( getShortcutLabel() + "_disp: AVERAGE_PATH_DISPLACEMENT ARG=" + getShortcutLabel() + "_data HALFLIFE=" + halflife + " CLEAR=" + update + " METRIC={DIFFERENCE} REFERENCE=" + reference_data );
+     139           2 :   else readInputLine( getShortcutLabel() + "_disp: AVERAGE_PATH_DISPLACEMENT ARG=" + getShortcutLabel() + "_data.disp HALFLIFE=" + halflife + " CLEAR=" + update + " METRIC={" + metric + "} METRIC_COMPONENT=disp REFERENCE=" + reference_data );
+     140             : 
+     141             :   // Create the object to update the path
+     142           4 :   std::string fixedn; parse("FIXED",fixedn); std::string component="METRIC_COMPONENT=disp"; if( argnames.size()>0 ) { metric="DIFFERENCE"; component=""; }
+     143           4 :   if( fixedn.length()>0 ) readInputLine("REPARAMETERIZE_PATH DISPLACE_FRAMES=" + getShortcutLabel() + "_disp FIXED=" + fixedn + " STRIDE=" + update + " METRIC={" + metric + "} " + component + " REFERENCE=" + reference_data );
+     144           0 :   else readInputLine("REPARAMETERIZE_PATH DISPLACE_FRAMES=" + getShortcutLabel() + "_disp STRIDE=" + update + " METRIC={" + metric + "} " + component + " REFERENCE=" + reference_data );
+     145             : 
+     146             :   // Information for write out
+     147           4 :   std::string wfilename; parse("WFILE",wfilename);
+     148           2 :   if( wfilename.length()>0 ) {
+     149             :     // This just gets the atom numbers for output
+     150             :     std::string atomstr;
+     151           2 :     if( argnames.size()==0 ) {
+     152           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);
+     153           1 :       std::string num; Tools::convert( mypdb.getAtomNumbers()[0].serial(), atomstr );
+     154          13 :       for(unsigned j=1; j<mypdb.getAtomNumbers().size(); ++j ) { Tools::convert( mypdb.getAtomNumbers()[j].serial(), num ); atomstr += "," + num; }
+     155           1 :     }
+     156             : 
+     157           2 :     if( wfilename.find(".pdb")==std::string::npos ) error("output must be to a pdb file");
+     158           6 :     std::string ofmt, pframes, wstride; parse("WSTRIDE",wstride); parse("FMT",ofmt);
+     159           2 :     if( argnames.size()>0 ) {
+     160           3 :       std::string argstr = argnames[0]; for(unsigned i=1; i<argnames.size(); ++i) argstr += "," + argnames[i];
+     161           2 :       readInputLine("DUMPPDB DESCRIPTION=PATH STRIDE=" + wstride + " FMT=" + ofmt + " FILE=" + wfilename + " ARG=" + reference_data );
+     162           2 :     } else readInputLine("DUMPPDB DESCRIPTION=PATH STRIDE=" + wstride + " FMT=" + ofmt + " FILE=" + wfilename + " ATOMS=" + reference_data + " ATOM_INDICES=" + atomstr );
+     163             :   }
+     164           4 :   log<<"  Bibliography "<<plumed.cite("Diaz Leines and Ensing, Phys. Rev. Lett. 109, 020601 (2012)")<<"\n";
+     165           4 : }
+     166             : 
+     167             : }
+     168             : }
+
+
+
+ + + + +
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 000000000..c480f4294 --- /dev/null +++ b/coverage/mapping/GeometricPath.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:606198.4 %
Date:2024-10-17 16:45:00Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping13GeometricPathC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7mapping13GeometricPath11performTaskERKjRNS_10MultiValueE0
_ZN4PLMD7mapping13GeometricPathC1ERKNS_13ActionOptionsE4
_ZN4PLMD7mapping13GeometricPath16registerKeywordsERNS_8KeywordsE10
_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 000000000..c1df43143 --- /dev/null +++ b/coverage/mapping/GeometricPath.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:606198.4 %
Date:2024-10-17 16:45:00Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping13GeometricPath16registerKeywordsERNS_8KeywordsE10
_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 000000000..f03d79453 --- /dev/null +++ b/coverage/mapping/GeometricPath.cpp.gcov.html @@ -0,0 +1,214 @@ + + + + + + + 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:606198.4 %
Date:2024-10-17 16:45:00Functions: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          10 : void GeometricPath::registerKeywords(Keywords& keys) {
+      53          10 :   ActionWithVector::registerKeywords(keys); keys.use("ARG");
+      54          10 :   PathProjectionCalculator::registerKeywords(keys);
+      55          20 :   keys.add("compulsory","PROPERTY","the coordinates we are projecting these points onto");
+      56          20 :   keys.addOutputComponent("s","default","the position on the path");
+      57          20 :   keys.addOutputComponent("z","default","the distance from the path");
+      58          20 :   keys.needsAction("GEOMETRIC_PATH"); keys.needsAction("PDB2CONSTANT");
+      59          10 : }
+      60             : 
+      61           4 : GeometricPath::GeometricPath(const ActionOptions&ao):
+      62             :   Action(ao),
+      63             :   ActionWithVector(ao),
+      64           4 :   path_projector(this)
+      65             : {
+      66           4 :   plumed_assert( !actionInChain() );
+      67             :   // Get the coordinates in the low dimensional space
+      68           8 :   std::vector<std::string> pcoord; parseVector("PROPERTY", pcoord ); std::vector<Value*> theprop;
+      69           4 :   ActionWithArguments::interpretArgumentList( pcoord, plumed.getActionSet(), this, theprop );
+      70           4 :   if( theprop.size()!=1 ) error("did not find property to project on");
+      71           4 :   if( theprop[0]->getNumberOfValues()!=getPntrToArgument(0)->getShape()[0] ) error("mismatch between number of frames and property of interest");
+      72           4 :   log.printf("  projecting onto : %s \n", theprop[0]->getName().c_str() );
+      73           4 :   std::vector<Value*> args( getArguments() ); args.push_back( theprop[0] ); requestArguments( args );
+      74             :   // Create the values to store the output
+      75          12 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+      76          12 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+      77           4 : }
+      78             : 
+      79        1677 : unsigned GeometricPath::getNumberOfDerivatives() {
+      80        1677 :   return getPntrToArgument(0)->getShape()[0]*getPntrToArgument(0)->getShape()[1] + getPntrToArgument(1)->getShape()[0];
+      81             : }
+      82             : 
+      83        1665 : void GeometricPath::calculate() {
+      84        1665 :   unsigned k=0, iclose1=0, iclose2=0; double v1v1=0, v3v3=0;
+      85        1665 :   unsigned nrows = getPntrToArgument(0)->getShape()[0];
+      86        1665 :   unsigned ncols = getPntrToArgument(0)->getShape()[1];
+      87       79201 :   for(unsigned i=0; i<nrows; ++i) {
+      88             :     double dist = 0;
+      89     1814580 :     for(unsigned j=0; j<ncols; ++j) {
+      90     1737044 :       double tmp = getPntrToArgument(0)->get(k);
+      91     1737044 :       dist += tmp*tmp; k++;
+      92             :     }
+      93       77536 :     if( i==0 ) { v1v1 = dist; iclose1 = 0; }
+      94       75871 :     else if( dist<v1v1 ) { v3v3=v1v1; v1v1=dist; iclose2=iclose1; iclose1=i; }
+      95       45571 :     else if( i==1 ) { v3v3=dist; iclose2=1; }
+      96       45244 :     else if( dist<v3v3 ) { v3v3=dist; iclose2=i; }
+      97             :   }
+      98             :   // And find third closest point
+      99        1665 :   int isign = iclose1 - iclose2;
+     100             :   if( isign>1 ) isign=1; else if( isign<-1 ) isign=-1;
+     101        1665 :   int iclose3 = iclose1 + isign;
+     102        1665 :   unsigned ifrom=iclose1, ito=iclose3; if( iclose3<0 || iclose3>=nrows ) { ifrom=iclose2; ito=iclose1; }
+     103             : 
+     104             :   // And calculate projection of vector connecting current point to closest frame on vector connecting nearest two frames
+     105        1665 :   std::vector<double> displace; path_projector.getDisplaceVector( ifrom, ito, displace );
+     106        1665 :   double v2v2=0, v1v2=0; k=ncols*iclose1;
+     107       42661 :   for(unsigned i=0; i<displace.size(); ++i) { v2v2 += displace[i]*displace[i]; v1v2 += displace[i]*getPntrToArgument(0)->get(k+i); }
+     108             : 
+     109             :   // This computes s value
+     110        1665 :   double spacing = getPntrToArgument(1)->get(iclose1) - getPntrToArgument(1)->get(iclose2);
+     111        1665 :   double root = sqrt( v1v2*v1v2 - v2v2 * ( v1v1 - v3v3) );
+     112        1665 :   double dx = 0.5 * ( (root + v1v2) / v2v2 - 1.);
+     113        1665 :   double path_s = getPntrToArgument(1)->get(iclose1) + spacing * dx;
+     114        1665 :   Value* sp = getPntrToComponent(0); sp->set( path_s );
+     115        1665 :   if( !doNotCalculateDerivatives() ) {
+     116       23478 :     for(unsigned i=0; i<ncols; ++i) {
+     117       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 );
+     118       22386 :       sp->addDerivative( ncols*iclose2 + i, 0.5*spacing*getPntrToArgument(0)->get(ncols*iclose2 + i)/root );
+     119             :     }
+     120             :   }
+     121             : 
+     122             :   // This computes z value
+     123        1665 :   path_projector.getDisplaceVector( iclose2, iclose1, displace ); double v4v4=0, proj=0; k=ncols*iclose1;
+     124       42661 :   for(unsigned i=0; i<displace.size(); ++i) { v4v4 += displace[i]*displace[i]; proj += displace[i]*getPntrToArgument(0)->get(k+i); }
+     125        1665 :   double path_z = v1v1 + dx*dx*v4v4 - 2*dx*proj; path_z = sqrt(path_z);
+     126        1665 :   Value* zp = getPntrToComponent(1); zp->set( path_z );
+     127        1665 :   if( !doNotCalculateDerivatives() ) {
+     128       23478 :     for(unsigned i=0; i<ncols; ++i) {
+     129       22386 :       zp->addDerivative( ncols*iclose1 + i, (1/path_z)*(getPntrToArgument(0)->get(ncols*iclose1 + i) +
+     130       22386 :                          (v4v4*dx-proj)*sp->getDerivative(ncols*iclose1 + i)/spacing -
+     131       22386 :                          dx*displace[i]) );
+     132       22386 :       zp->addDerivative( ncols*iclose2 + i, (v4v4*dx-proj)*sp->getDerivative(ncols*iclose2 + i)/(path_z*spacing) );
+     133             :     }
+     134             :   }
+     135        1665 : }
+     136             : 
+     137             : }
+     138             : }
+
+
+
+ + + + +
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 000000000..a050c8058 --- /dev/null +++ b/coverage/mapping/GeometricPathShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..7bbd6e2a6 --- /dev/null +++ b/coverage/mapping/GeometricPathShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..b46e942ad --- /dev/null +++ b/coverage/mapping/GeometricPathShortcut.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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:2222100.0 %
Date:2024-10-17 16:45:00Functions: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          16 :   keys.addOutputComponent("s","default","the position on the path");
+      51          16 :   keys.addOutputComponent("z","default","the distance from the path");
+      52          32 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("GEOMETRIC_PATH"); keys.needsAction("PDB2CONSTANT"); keys.needsAction("CONSTANT");
+      53           8 : }
+      54             : 
+      55           2 : GeometricPathShortcut::GeometricPathShortcut( const ActionOptions& ao ):
+      56             :   Action(ao),
+      57           2 :   ActionShortcut(ao)
+      58             : {
+      59           6 :   std::string mtype, reference_data; std::vector<std::string> argnames; parseVector("ARG",argnames); parse("TYPE", mtype);
+      60             :   // Create list of reference configurations that PLUMED will use
+      61           4 :   std::string reference; parse("REFERENCE",reference);
+      62           2 :   FILE* fp=std::fopen(reference.c_str(),"r"); PDB mypdb; if(!fp) error("could not open reference file " + reference );
+      63           2 :   bool do_read=mypdb.readFromFilepointer(fp,false,0.1); if( !do_read ) error("missing file " + reference );
+      64           2 :   Path::readInputFrames( reference, mtype, argnames, true, this, reference_data );
+      65             :   // Now get coordinates on spath
+      66           4 :   std::vector<std::string> pnames; parseVector("PROPERTY",pnames); Path::readPropertyInformation( pnames, getShortcutLabel(), reference, this );
+      67             :   // Create action that computes the geometric path variablesa
+      68           2 :   std::string propstr = getShortcutLabel() + "_ind"; if( pnames.size()>0 ) propstr = pnames[0] + "_ref";
+      69           3 :   if( argnames.size()>0 ) readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data " + " PROPERTY=" + propstr + " REFERENCE=" + reference_data + " METRIC={DIFFERENCE}");
+      70             :   else {
+      71           1 :     std::string num, align_str, displace_str; Tools::convert( mypdb.getOccupancy()[0], align_str ); Tools::convert( mypdb.getBeta()[0], displace_str );
+      72          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; }
+      73           2 :     std::string metric = "RMSD_VECTOR DISPLACEMENT TYPE=" + mtype + " ALIGN=" + align_str + " DISPLACE=" + displace_str;
+      74           2 :     readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data.disp " + " PROPERTY=" +  propstr + " REFERENCE=" + reference_data + " METRIC={" + metric + "} METRIC_COMPONENT=disp");
+      75             :   }
+      76           6 : }
+      77             : 
+      78             : 
+      79             : }
+      80             : }
+      81             : 
+      82             : 
+
+
+
+ + + + +
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 000000000..766e872d5 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8c26eedca --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d1feaec78 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.gcov.html @@ -0,0 +1,376 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..15e936733 --- /dev/null +++ b/coverage/mapping/Path.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..28898e4c3 --- /dev/null +++ b/coverage/mapping/Path.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..cbda088f5 --- /dev/null +++ b/coverage/mapping/Path.cpp.gcov.html @@ -0,0 +1,423 @@ + + + + + + + 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-10-17 16:45:00Functions: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          28 :   keys.addOutputComponent("gspath","GPATH","the position along the path calculated using the geometric formula");
+     216          28 :   keys.addOutputComponent("gzpath","GPATH","the distance from the path calculated using the geometric formula");
+     217          28 :   keys.addOutputComponent("spath","default","the position along the path calculated");
+     218          28 :   keys.addOutputComponent("zpath","default","the distance from the path calculated");
+     219          14 : }
+     220             : 
+     221          32 : void Path::registerInputFileKeywords( Keywords& keys ) {
+     222          64 :   keys.add("compulsory","REFERENCE","a pdb file containing the set of reference configurations");
+     223          64 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
+     224             :            "metrics that are available in PLUMED can be found in the section of the manual on "
+     225             :            "\\ref dists");
+     226          64 :   keys.add("optional","ARG","the list of arguments you would like to use in your definition of the path");
+     227          64 :   keys.add("optional","COEFFICIENTS","the coefficients of the displacements along each argument that should be used when calculating the euclidean distance");
+     228          64 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     229          64 :   keys.addFlag("NOSPATH",false,"do not calculate the spath CV");
+     230          64 :   keys.addFlag("NOZPATH",false,"do not calculate the zpath CV");
+     231          64 :   keys.addFlag("GPATH",false,"calculate the trigonometric path");
+     232         128 :   keys.needsAction("DRMSD"); keys.needsAction("RMSD"); keys.needsAction("LOWEST"); keys.needsAction("GPATH");
+     233         128 :   keys.needsAction("EUCLIDEAN_DISTANCE"); keys.needsAction("CUSTOM"); keys.needsAction("SUM"); keys.needsAction("COMBINE");
+     234          96 :   keys.needsAction("NORMALIZED_EUCLIDEAN_DISTANCE"); keys.needsAction("PDB2CONSTANT"); keys.needsAction("CONSTANT");
+     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: GPATH " + convertInputLineToString() );
+     244           0 :     readInputLine( getShortcutLabel() + "_gspath: COMBINE ARG=" + getShortcutLabel() + "_gpath.s PERIODIC=NO");
+     245           0 :     readInputLine( getShortcutLabel() + "_gzpath: COMBINE ARG=" + getShortcutLabel() + "_gpath.z 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 000000000..37febb6d5 --- /dev/null +++ b/coverage/mapping/PathDisplacements.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:707395.9 %
Date:2024-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping17PathDisplacements22getNumberOfDerivativesEv0
_ZN4PLMD7mapping17PathDisplacementsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping17PathDisplacementsC1ERKNS_13ActionOptionsE2
_ZN4PLMD7mapping17PathDisplacements16registerKeywordsERNS_8KeywordsE6
_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 000000000..2ec1d5d08 --- /dev/null +++ b/coverage/mapping/PathDisplacements.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:707395.9 %
Date:2024-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping17PathDisplacements16clearDerivativesERKb573
_ZN4PLMD7mapping17PathDisplacements16registerKeywordsERNS_8KeywordsE6
_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 000000000..1a121d3bf --- /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:707395.9 %
Date:2024-10-17 16:45:00Functions: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           6 : void PathDisplacements::registerKeywords( Keywords& keys ) {
+      62           6 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      63          12 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG"); PathProjectionCalculator::registerKeywords( keys );
+      64          12 :   keys.add("compulsory","STRIDE","1","the frequency with which the average displacements should be collected and added to the average displacements");
+      65          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");
+      66          12 :   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           6 :   keys.setValueDescription("vector containing the average displacement between the trajectory and each of the landmarks that makes up the path");
+      69           6 : }
+      70             : 
+      71           2 : PathDisplacements::PathDisplacements(const ActionOptions& ao):
+      72             :   Action(ao),
+      73             :   ActionWithValue(ao),
+      74             :   ActionPilot(ao),
+      75             :   ActionWithArguments(ao),
+      76           2 :   clearnextstep(false),
+      77           2 :   path_projector(this)
+      78             : {
+      79             :   // Read in clear instructions
+      80           2 :   parse("CLEAR",clearstride);
+      81           2 :   if( clearstride>0 ) {
+      82           2 :     if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE");
+      83           2 :     log.printf("  clearing average every %u steps \n",clearstride);
+      84             :   }
+      85           2 :   double halflife; parse("HALFLIFE",halflife);
+      86           2 :   log.printf("  weight of contribution to frame halves every %f steps \n",halflife);
+      87           2 :   if( halflife<0 ) fadefact=1.0;
+      88           0 :   else fadefact = exp( -0.693147180559945 / static_cast<double>(halflife) );
+      89             :   // Now create the weights vector and displacements matrix
+      90           2 :   unsigned nrows = getPntrToArgument(0)->getShape()[0];
+      91           2 :   unsigned ncols = getPntrToArgument(0)->getShape()[1];
+      92           2 :   wsum.resize( nrows ); displacements.resize( nrows, ncols );
+      93          64 :   for(unsigned i=0; i<nrows; ++i) {
+      94        1740 :     wsum[i]=0; for(unsigned j=0; j<ncols; ++j) displacements(i,j)=0;
+      95             :   }
+      96             :   // Add bibliography
+      97           4 :   log<<"  Bibliography "<<plumed.cite("Diaz Leines and Ensing, Phys. Rev. Lett. 109, 020601 (2012)")<<"\n";
+      98             :   // And create a value to hold the displacements
+      99           2 :   std::vector<unsigned> shape(2); shape[0]=nrows; shape[1]=ncols;
+     100           2 :   addValue( shape ); setNotPeriodic();
+     101           2 :   getPntrToComponent(0)->buildDataStore();
+     102           2 :   getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     103           2 : }
+     104             : 
+     105           0 : unsigned PathDisplacements::getNumberOfDerivatives() {
+     106           0 :   return 0;
+     107             : }
+     108             : 
+     109         573 : void PathDisplacements::update() {
+     110         573 :   unsigned nrows = getPntrToArgument(0)->getShape()[0];
+     111         573 :   unsigned ncols = getPntrToArgument(0)->getShape()[1];
+     112             : 
+     113         573 :   if( clearnextstep ) {
+     114             :     unsigned k=0;
+     115        1010 :     for(unsigned i=0; i<nrows; ++i) {
+     116       38700 :       for(unsigned j=0; j<ncols; ++j) { displacements(i,j)=0; getPntrToComponent(0)->set(k,0); k++; }
+     117             :     }
+     118          24 :     clearnextstep=false;
+     119             :   }
+     120             : 
+     121             :   unsigned k=0, iclose1=0, iclose2=0; double v1v1=0, v3v3=0;
+     122       22417 :   for(unsigned i=0; i<nrows; ++i) {
+     123             :     double dist = 0;
+     124      799020 :     for(unsigned j=0; j<ncols; ++j) {
+     125      777176 :       double tmp = getPntrToArgument(0)->get(k);
+     126      777176 :       dist += tmp*tmp; k++;
+     127             :     }
+     128       21844 :     if( i==0 ) { v1v1 = dist; iclose1 = 0; }
+     129       21271 :     else if( dist<v1v1 ) { v3v3=v1v1; v1v1=dist; iclose2=iclose1; iclose1=i; }
+     130       10991 :     else if( i==1 ) { v3v3=dist; iclose2=1; }
+     131       10991 :     else if( dist<v3v3 ) { v3v3=dist; iclose2=i; }
+     132             :   }
+     133             :   // And find third closest point
+     134         573 :   int isign = iclose1 - iclose2;
+     135             :   if( isign>1 ) isign=1; else if( isign<-1 ) isign=-1;
+     136         573 :   int iclose3 = iclose1 + isign;
+     137         573 :   unsigned ifrom=iclose1, ito=iclose3; if( iclose3<0 || iclose3>=nrows ) { ifrom=iclose2; ito=iclose1; }
+     138             : 
+     139             :   // Calculate the dot product of v1 with v2
+     140         573 :   path_projector.getDisplaceVector( ifrom, ito, displace_v );
+     141         573 :   double v2v2=0, v1v2=0; unsigned kclose1 = iclose1*ncols;
+     142       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); }
+     143             : 
+     144         573 :   double root = sqrt( v1v2*v1v2 - v2v2 * ( v1v1 - v3v3) );
+     145         573 :   double dx = 0.5 * ( (root + v1v2) / v2v2 - 1.);
+     146         573 :   double weight2 = -1.* dx; double weight1 = 1.0 + dx;
+     147         573 :   if( weight1>1.0 ) {
+     148             :     weight1=1.0; weight2=0.0;
+     149         573 :   } else if( weight2>1.0 ) {
+     150             :     weight1=0.0; weight2=1.0;
+     151             :   }
+     152             : 
+     153             :   // Accumulate displacements for path
+     154       19183 :   for(unsigned i=0; i<ncols; ++i) {
+     155       18610 :     double displace = getPntrToArgument(0)->get(kclose1+i) - dx*displace_v[i];
+     156       18610 :     displacements(iclose1,i) += weight1 * displace; displacements(iclose2,i) += weight2 * displace;
+     157             :   }
+     158             : 
+     159             :   // Update weight accumulators
+     160         573 :   wsum[iclose1] *= fadefact; wsum[iclose2] *= fadefact;
+     161         573 :   wsum[iclose1] += weight1; wsum[iclose2] += weight2;
+     162             : 
+     163             :   // Update numbers in values
+     164         573 :   if( wsum[iclose1] > epsilon ) {
+     165       19183 :     for(unsigned i=0; i<ncols; ++i) getPntrToComponent(0)->set( kclose1+i, displacements(iclose1,i) / wsum[iclose1] );
+     166             :   }
+     167         573 :   if( wsum[iclose2] > epsilon ) {
+     168         573 :     unsigned kclose2 = iclose2*ncols;
+     169       19183 :     for(unsigned i=0; i<ncols; ++i) getPntrToComponent(0)->set( kclose2+i, displacements(iclose2,i) / wsum[iclose2] );
+     170             :   }
+     171             : 
+     172             :   // Clear if required
+     173         573 :   if( (getStep()>0 && clearstride>0 && getStep()%clearstride==0) ) clearnextstep=true;
+     174         573 : }
+     175             : 
+     176             : }
+     177             : }
+
+
+
+ + + + +
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 000000000..e4bac368a --- /dev/null +++ b/coverage/mapping/PathProjectionCalculator.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping24PathProjectionCalculatorC2EPNS_6ActionE10
_ZN4PLMD7mapping24PathProjectionCalculator16registerKeywordsERNS_8KeywordsE24
_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 000000000..8bba488a2 --- /dev/null +++ b/coverage/mapping/PathProjectionCalculator.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping24PathProjectionCalculator16registerKeywordsERNS_8KeywordsE24
_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 000000000..c66bd14d0 --- /dev/null +++ b/coverage/mapping/PathProjectionCalculator.cpp.gcov.html @@ -0,0 +1,219 @@ + + + + + + + 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-10-17 16:45:00Functions: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          24 : void PathProjectionCalculator::registerKeywords(Keywords& keys) {
+      33          48 :   keys.add("compulsory","METRIC","the method to use for computing the displacement vectors between the reference frames");
+      34          48 :   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          48 :   keys.add("compulsory","REFERENCE","labels for actions that contain reference coordinates for each point on the path");
+      36          24 : }
+      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 000000000..d1bc08865 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping22PathReparameterizationC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping22PathReparameterizationC1ERKNS_13ActionOptionsE4
_ZN4PLMD7mapping22PathReparameterization16registerKeywordsERNS_8KeywordsE8
_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 000000000..1b45075e5 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping22PathReparameterization14computeSpacingERKjS3_4459
_ZN4PLMD7mapping22PathReparameterization16registerKeywordsERNS_8KeywordsE8
_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 000000000..c4d85aa77 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.gcov.html @@ -0,0 +1,305 @@ + + + + + + + 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-10-17 16:45:00Functions: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           8 : void PathReparameterization::registerKeywords( Keywords& keys ) {
+      76           8 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      77           8 :   PathProjectionCalculator::registerKeywords(keys);
+      78          16 :   keys.add("compulsory","STRIDE","1","the frequency with which to reparameterize the path");
+      79          16 :   keys.add("compulsory","FIXED","0","the frames in the path to fix");
+      80          16 :   keys.add("compulsory","MAXCYLES","100","number of cycles of the algorithm to run");
+      81          16 :   keys.add("compulsory","TOL","1E-4","the tolerance to use for the path reparameterization algorithm");
+      82          16 :   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           8 : }
+      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 000000000..9acf34158 --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:24124698.0 %
Date:2024-10-17 16:45:00Functions: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_119PathToolsRegisterMeC2Ev5301
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev5301
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..a0fc498c7 --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:24124698.0 %
Date:2024-10-17 16:45:00Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMe6createERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeC2Ev5301
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev5301
_ZN4PLMD7mapping9PathTools11printLambdaERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EES9_4
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE5301
_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 000000000..174dde21b --- /dev/null +++ b/coverage/mapping/PathTools.cpp.gcov.html @@ -0,0 +1,536 @@ + + + + + + + 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:24124698.0 %
Date:2024-10-17 16:45:00Functions: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       15911 : PLUMED_REGISTER_CLTOOL(PathTools,"pathtools")
+     121             : 
+     122        5301 : void PathTools::registerKeywords( Keywords& keys ) {
+     123        5301 :   CLTool::registerKeywords( keys );
+     124       10602 :   keys.add("atoms","--start","a pdb file that contains the structure for the initial frame of your path");
+     125       10602 :   keys.add("atoms","--end","a pdb file that contains the structure for the final frame of your path");
+     126       10602 :   keys.add("atoms-1","--path","a pdb file that contains an initial path in which the frames are not equally spaced");
+     127       10602 :   keys.add("optional","--arg","the arguments that should be read in from the pdb files");
+     128       10602 :   keys.add("compulsory","--fixed","0","the frames to fix when constructing the path using --path");
+     129       10602 :   keys.add("compulsory","--metric","the measure to use to calculate the distance between frames");
+     130       10602 :   keys.add("compulsory","--out","the name of the file on which to output your path");
+     131       10602 :   keys.add("compulsory","--arg-fmt","%f","the format to use for argument values in your frames");
+     132       10602 :   keys.add("compulsory","--tolerance","1E-4","the tolerance to use for the algorithm that is used to re-parameterize the path");
+     133       10602 :   keys.add("compulsory","--nframes-before-start","1","the number of frames to include in the path before the first frame");
+     134       10602 :   keys.add("compulsory","--nframes","1","the number of frames between the start and end frames in your path");
+     135       10602 :   keys.add("compulsory","--nframes-after-end","1","the number of frames to put after the last frame of your path");
+     136        5301 : }
+     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          15 :     std::vector<unsigned> residue_indices( indices.size() ); for(unsigned i=0; i<residue_indices.size(); ++i) residue_indices[i] = mypdb.getResidueNumber( indices[i] );
+     164             :     // Count the number of frames in the input file
+     165          20 :     unsigned nfram=1; while ( do_read ) { if( !mypdb.readFromFilepointer(fp,false,0.1) ) break; nfram++; }
+     166           2 :     if( argstr.size()>0 ) {
+     167           3 :       for(unsigned i=0; i<argstr.size(); ++i ) {
+     168           4 :         std::string input = argstr[i] + ": PDB2CONSTANT NOARGS REFERENCE=" + ifilename + " ARG=" + argstr[i];
+     169           2 :         const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt);
+     170             :       }
+     171             :     } else {
+     172           1 :       std::string input = "data: PDB2CONSTANT REFERENCE=" + ifilename;
+     173           1 :       const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     174             :     }
+     175           2 :     std::string reparam_str = "REPARAMETERIZE_PATH REFERENCE=";
+     176           5 :     if( argstr.size()>0 ) { reparam_str += argstr[0]; for(unsigned i=0; i<argstr.size(); ++i ) reparam_str += "," + argstr[i]; }
+     177           4 :     else { reparam_str += "data"; } std::vector<unsigned> fixed; parseVector("--fixed",fixed);
+     178           2 :     if( fixed.size()==1 ) {
+     179           1 :       if( fixed[0]!=0 ) error("input to --fixed should be two integers");
+     180           1 :       fixed.resize(2); fixed[0]=1; fixed[1]=nfram;
+     181           1 :     } else if( fixed.size()==2 ) {
+     182           1 :       if( fixed[0]<1 || fixed[1]<1 || fixed[0]>nfram || fixed[1]>nfram ) {
+     183           0 :         error("input to --fixed should be two numbers between 0 and the number of frames-1");
+     184             :       }
+     185           0 :     } else error("input to --fixed should be two integers");
+     186           2 :     std::string fix1, fix2; Tools::convert( fixed[0], fix1 ); Tools::convert( fixed[1], fix2 );
+     187           4 :     reparam_str += " FIXED=" + fix1 + "," + fix2;
+     188           6 :     std::string tol; parse("--tolerance",tol); reparam_str += " TOL=" + tol;
+     189             : // Now create the metric object
+     190             :     reparam_str += " METRIC=";
+     191           5 :     if( mtype=="OPTIMAL-FAST" || mtype=="OPTIMAL" || mtype=="SIMPLE" ) {
+     192           2 :       reparam_str += "{RMSD_VECTOR DISPLACEMENT SQUARED UNORMALIZED TYPE=" + mtype;
+     193             :       // Get the align values
+     194           1 :       std::string anum; Tools::convert( alig[0], anum ); reparam_str += " ALIGN=" + anum;
+     195          13 :       for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); reparam_str += "," + anum; }
+     196             :       // Get the displace values
+     197           1 :       std::string dnum; Tools::convert( disp[0], dnum ); reparam_str += " DISPLACE=" + dnum;
+     198          13 :       for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); reparam_str += "," + dnum; }
+     199             :       reparam_str += "} METRIC_COMPONENT=disp";
+     200           1 :     } else if( mtype=="EUCLIDEAN" ) {
+     201             :       reparam_str += "DIFFERENCE";
+     202             :     } else {
+     203             :       // Add functionality to read plumed input here
+     204           0 :       plumed_merror("metric type " + mtype + " has not been implemented");
+     205             :     }
+     206             : 
+     207             :     // Now do the reparameterization
+     208           2 :     const char* icinp= reparam_str.c_str(); plmd.cmd("readInputLine",icinp);
+     209             :     Action* raction = plmd.getActionSet()[plmd.getActionSet().size()-1].get();
+     210           2 :     raction->update();
+     211             : 
+     212             :     // And print the final reference configurations
+     213           4 :     std::string pinput="DUMPPDB STRIDE=1 DESCRIPTION=PATH FILE=" + ofilename + " FMT=" + ofmt;
+     214           2 :     if( argstr.size()>0 ) {
+     215           3 :       pinput += " ARG=" + argstr[0]; for(unsigned i=1; i<argstr.size(); ++i ) pinput += "," + argstr[i];
+     216             :     } else {
+     217          14 :       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; }
+     218          14 :       Tools::convert( residue_indices[0], num ); pinput += " RESIDUE_INDICES=" + num; for(unsigned i=1; i<residue_indices.size(); ++i ) { Tools::convert( residue_indices[i], num ); pinput += "," + num; }
+     219           1 :       std::string anum, dnum; Tools::convert( alig[0], anum ); Tools::convert( disp[0], dnum );
+     220          14 :       pinput += " OCCUPANCY=" + anum; for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); pinput += "," + anum; }
+     221          14 :       pinput += " BETA=" + dnum; for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); pinput += "," + dnum; }
+     222             :     }
+     223           2 :     const char* pcinp=pinput.c_str(); plmd.cmd("readInputLine",pcinp);
+     224             :     Action* paction = plmd.getActionSet()[plmd.getActionSet().size()-1].get();
+     225           2 :     paction->update();
+     226             : 
+     227             :     // Ouput data on spacings
+     228           2 :     printLambda( mtype, argstr, ofilename );
+     229             :     return 0;
+     230           2 :   }
+     231           4 :   for(unsigned i=0; i<argstr.size(); ++i) {
+     232           2 :     std::string input = argstr[i] + ": CONSTANT VALUE=1";
+     233           2 :     const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt);
+     234             :   }
+     235             : 
+     236             : // Read in the instructions
+     237             :   unsigned nbefore, nbetween, nafter;
+     238           4 :   std::string istart; parse("--start",istart); std::string iend; parse("--end",iend);
+     239           6 :   parse("--nframes-before-start",nbefore); parse("--nframes",nbetween); parse("--nframes-after-end",nafter);
+     240           2 :   nbetween++;
+     241             :   fprintf(out,"Generating linear path connecting structure in file named %s to structure in file named %s \n",istart.c_str(),iend.c_str() );
+     242           2 :   fprintf(out,"A path consisting of %u equally-spaced frames before the initial structure, %u frames between the initial and final structures "
+     243             :           "and %u frames after the final structure will be created \n",nbefore,nbetween,nafter);
+     244             : 
+     245           2 :   std::vector<double> start_pos( argstr.size() ), end_pos( argstr.size() ); std::vector<AtomNumber> indices;
+     246           2 :   if( argstr.size()>0 ) {
+     247           3 :     for(unsigned i=0; i<argstr.size(); ++i ) {
+     248           4 :       std::string input = argstr[i] + "_start: PDB2CONSTANT REFERENCE=" + istart + " ARG=" + argstr[i];
+     249           2 :       const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     250           4 :       long srank; plmd.cmd("getDataRank " + argstr[i] + "_start", &srank );
+     251           2 :       if( srank!=1 ) error("should only be one frame in input pdb");
+     252           4 :       std::vector<long> sshape( 1 ); plmd.cmd("getDataShape " + argstr[i] + "_start", &sshape[0] );
+     253           2 :       if( sshape[0]!=1 ) error("should only be one frame in input pdb");
+     254           4 :       plmd.cmd("setMemoryForData " + argstr[i] + "_start", &start_pos[i] );
+     255           4 :       std::string input2 = argstr[i] + "_end: PDB2CONSTANT REFERENCE=" + iend + " ARG=" + argstr[i];
+     256           2 :       const char* inpt2 = input2.c_str(); plmd.cmd("readInputLine", inpt2 );
+     257           4 :       long erank; plmd.cmd("getDataRank " + argstr[i] + "_end", &erank );
+     258           2 :       if( erank!=1 ) error("should only be one frame in input pdb");
+     259           4 :       std::vector<long> eshape( 1 ); plmd.cmd("getDataShape " + argstr[i] + "_end", &eshape[0] );
+     260           2 :       if( eshape[0]!=1 ) error("should only be one frame in input pdb");
+     261           4 :       plmd.cmd("setMemoryForData " + argstr[i] + "_end", &end_pos[i] );
+     262             :     }
+     263             :   } else {
+     264           1 :     std::string input = "start: PDB2CONSTANT REFERENCE=" + istart;
+     265           1 :     const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     266           1 :     FILE* fp=fopen(istart.c_str(),"r"); PDB mypdb; bool do_read=mypdb.readFromFilepointer(fp,false,0.1);
+     267          14 :     indices.resize( mypdb.getAtomNumbers().size() ); for(unsigned i=0; i<indices.size(); ++i) indices[i] = mypdb.getAtomNumbers()[i];
+     268           1 :     long srank; plmd.cmd("getDataRank start", &srank ); if( srank!=2 ) error("should only be one frame in input pdb:" + istart);
+     269           1 :     std::vector<long> sshape( srank ); plmd.cmd("getDataShape start", &sshape[0] ); start_pos.resize( sshape[0]*sshape[1] );
+     270           1 :     if( sshape[0]!=1 ) error("should only be one frame in input pdb: " + istart);
+     271           1 :     plmd.cmd("setMemoryForData start", &start_pos[0] );
+     272           1 :     std::string input2 = "end: PDB2CONSTANT REFERENCE=" + iend;
+     273           1 :     const char* inpt2 = input2.c_str(); plmd.cmd("readInputLine", inpt2 );
+     274           1 :     long erank; plmd.cmd("getDataRank end", &erank ); if( erank!=2 ) error("should only be one frame in input pdb: " + iend);
+     275           1 :     std::vector<long> eshape( erank ); plmd.cmd("getDataShape end", &eshape[0] ); end_pos.resize( eshape[0]*eshape[1] );
+     276           1 :     if( eshape[0]!=1 ) error("should only be one frame in input pdb: " + iend );
+     277           1 :     plmd.cmd("setMemoryForData end", &end_pos[0] );
+     278           1 :   }
+     279             : 
+     280             : // Now create the metric object
+     281             :   std::vector<double> alig, disp; std::vector<unsigned> residue_indices;
+     282           5 :   if( mtype=="OPTIMAL-FAST" || mtype=="OPTIMAL" || mtype=="SIMPLE" ) {
+     283           1 :     std::string trinput = "endT: TRANSPOSE ARG=end";
+     284           1 :     const char* tinp=trinput.c_str(); plmd.cmd("readInputLine",tinp);
+     285           1 :     PDB pdb; pdb.read(istart,false,0.1);
+     286           1 :     alig.resize( pdb.getOccupancy().size() ); disp.resize( pdb.getBeta().size() );
+     287          14 :     for(unsigned i=0; i<alig.size(); ++i) { alig[i] = pdb.getOccupancy()[i]; disp[i]= pdb.getBeta()[i]; }
+     288           2 :     std::string minput = "d: RMSD_VECTOR DISPLACEMENT SQUARED UNORMALIZED TYPE=" + mtype + " ARG=endT,start";
+     289             :     // Get the align values
+     290           1 :     std::string anum; Tools::convert( alig[0], anum ); minput += " ALIGN=" + anum;
+     291          13 :     for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); minput += "," + anum; }
+     292             :     // Get the displace values
+     293           1 :     std::string dnum; Tools::convert( disp[0], dnum ); minput += " DISPLACE=" + dnum;
+     294          13 :     for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); minput += "," + dnum; }
+     295           1 :     const char* mcinp=minput.c_str(); plmd.cmd("readInputLine",mcinp);
+     296           1 :     std::string tinput = "CUSTOM ARG=d.disp FUNC=x PERIODIC=NO"; const char* tcinp=tinput.c_str(); plmd.cmd("readInputLine",tcinp);
+     297             :     // Get the residue numbers
+     298           1 :     residue_indices.resize( pdb.size() );
+     299          14 :     for(unsigned i=0; i<residue_indices.size(); ++i) residue_indices[i] = pdb.getResidueNumber( indices[i] );
+     300           2 :   } else if( mtype=="EUCLIDEAN" ) {
+     301           2 :     std::string end_args="ARG1=" + argstr[0] + "_end", start_args="ARG2=" + argstr[0] + "_start";
+     302           3 :     for(unsigned i=1; i<argstr.size(); ++i ) { end_args += "," + argstr[i] + "_end"; start_args += "," + argstr[i] + "_start"; }
+     303           2 :     std::string minput = "d: DISPLACEMENT " + end_args + " " + start_args; const char* mcinp=minput.c_str(); plmd.cmd("readInputLine",mcinp);
+     304           1 :     std::string tinput = "TRANSPOSE ARG=d"; const char* tcinp=tinput.c_str(); plmd.cmd("readInputLine",tcinp);
+     305             :   } else {
+     306             :     // Add functionality to read plumed input here
+     307           0 :     plumed_merror("metric type " + mtype + " has not been implemented");
+     308             :   }
+     309             : 
+     310             : // Retrieve final displacement vector
+     311           2 :   unsigned aind = plmd.getActionSet().size()-1;
+     312             :   while( true ) {
+     313           3 :     const ActionShortcut* as=dynamic_cast<const ActionShortcut*>( plmd.getActionSet()[aind].get() );
+     314           3 :     if( !as ) break ; aind = aind - 1; plumed_assert( aind>=0 );
+     315           1 :   }
+     316           2 :   ActionWithValue* av = dynamic_cast<ActionWithValue*>( plmd.getActionSet()[aind].get() );
+     317           2 :   if( !av ) error("invalid input for metric" );
+     318           2 :   if( av->getNumberOfComponents()!=1 && av->getName()!="RMSD_VECTOR" ) error("cannot use multi component actions as metric");
+     319           2 :   std::string mydisp = av->copyOutput(0)->getName();
+     320             : // Now add calls so we can grab the data from plumed
+     321           4 :   long rank; plmd.cmd("getDataRank " + mydisp, &rank );
+     322           2 :   if( rank!=1 ) error("displacement must be a vector quantity");
+     323           4 :   std::vector<long> ishape( rank ); plmd.cmd("getDataShape " + mydisp, &ishape[0] );
+     324           4 :   std::vector<double> displacement( ishape[0] ); plmd.cmd("setMemoryForData " + mydisp, &displacement[0] );
+     325             : // And calculate the displacement
+     326           2 :   plmd.cmd("calc");
+     327             : 
+     328             :   // Now read in the initial frame
+     329             : 
+     330             :   // Now create frames
+     331           2 :   double delr = 1.0 / static_cast<double>( nbetween ); std::vector<std::vector<double> > allframes; std::vector<double> frame( displacement.size() );
+     332           4 :   for(int i=0; i<nbefore; ++i) {
+     333          43 :     for(unsigned j=0; j<frame.size(); ++j) frame[j] = start_pos[j] - i*delr*displacement[j];
+     334           2 :     allframes.push_back( frame );
+     335             :   }
+     336           8 :   for(unsigned i=1; i<nbetween; ++i) {
+     337          55 :     for(unsigned j=0; j<frame.size(); ++j) frame[j] = start_pos[j] + i*delr*displacement[j];
+     338           6 :     allframes.push_back( frame );
+     339             :   }
+     340           7 :   for(unsigned i=0; i<nafter; ++i) {
+     341          52 :     for(unsigned j=0; j<frame.size(); ++j) frame[j] = end_pos[j] + i*delr*displacement[j];
+     342           5 :     allframes.push_back( frame );
+     343             :   }
+     344             :   // This prints out our final reference configurations
+     345           4 :   plmd.cmd("clear"); plmd.readInputLine("timestep: PUT UNIT=time PERIODIC=NO CONSTANT");
+     346           2 :   ActionToPutData* ts = plmd.getActionSet().selectWithLabel<ActionToPutData*>("timestep");
+     347           4 :   ts->setValuePointer("timestep", &tstep );
+     348           4 :   std::string pinput="DUMPPDB STRIDE=1 DESCRIPTION=PATH FILE=" + ofilename + " FMT=" + ofmt;
+     349           2 :   if( argstr.size()>0 ) {
+     350           3 :     for(unsigned i=0; i<argstr.size(); ++i) {
+     351           2 :       std::string rnum; Tools::convert( allframes[0][i], rnum );
+     352           2 :       std::string inpt = argstr[i] + ": CONSTANT VALUES=" + rnum;
+     353          20 :       for(unsigned j=1; j<allframes.size(); ++j) { Tools::convert( allframes[j][i], rnum ); inpt += "," + rnum; }
+     354           2 :       const char* icinp=inpt.c_str(); plmd.cmd("readInputLine",icinp);
+     355           4 :       if( i==0 ) pinput += " ARG=" + argstr[i]; else pinput += "," + argstr[i];
+     356             :     }
+     357             :   } else {
+     358           1 :     std::string nc; Tools::convert( frame.size(), nc );
+     359           1 :     std::string nr; Tools::convert( allframes.size(), nr );
+     360           1 :     std::string rnum; Tools::convert( allframes[0][0], rnum );
+     361           2 :     std::string inpt = "atom_data: CONSTANT NROWS=" + nr + " NCOLS=" + nc + " VALUES=" + rnum;
+     362           4 :     for(unsigned i=0; i<allframes.size(); ++i) {
+     363         120 :       for(unsigned j=0; j<allframes[i].size(); ++j) {
+     364         233 :         if( i==0 && j==0 ) continue; Tools::convert( allframes[i][j], rnum ); inpt += "," + rnum;
+     365             :       }
+     366             :     }
+     367           1 :     const char* icinp=inpt.c_str(); plmd.cmd("readInputLine",icinp); std::string num; Tools::convert( indices[0].serial(), num );
+     368          14 :     pinput += " ATOMS=atom_data ATOM_INDICES=" + num; for(unsigned i=1; i<indices.size(); ++i ) { Tools::convert( indices[i].serial(), num ); pinput += "," + num; }
+     369          14 :     Tools::convert( residue_indices[0], num ); pinput += " RESIDUE_INDICES=" + num; for(unsigned i=1; i<residue_indices.size(); ++i ) { Tools::convert( residue_indices[i], num ); pinput += "," + num; }
+     370           1 :     std::string anum, dnum; Tools::convert( alig[0], anum ); Tools::convert( disp[0], dnum );
+     371          14 :     pinput += " OCCUPANCY=" + anum; for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); pinput += "," + anum; }
+     372          14 :     pinput += " BETA=" + dnum; for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); pinput += "," + dnum; }
+     373             :   }
+     374           2 :   const char* pcinp=pinput.c_str(); plmd.cmd("readInputLine",pcinp);
+     375             :   Action* paction = plmd.getActionSet()[plmd.getActionSet().size()-1].get();
+     376           2 :   paction->update();
+     377             :   // And output suggestions on the value of Lambda
+     378           2 :   printLambda( mtype, argstr, ofilename );
+     379             :   return 0;
+     380          10 : }
+     381             : 
+     382           4 : void PathTools::printLambda( const std::string& mtype, const std::vector<std::string>& argstr, const std::string& ofile ) {
+     383             :   // Create a PLUMED object
+     384           4 :   PlumedMain plmd; int s=sizeof(double);
+     385           4 :   plmd.cmd("setRealPrecision",&s);
+     386           4 :   plmd.cmd("setMDEngine","pathtools");
+     387           4 :   double tstep=1.0; plmd.cmd("setTimestep",&tstep);
+     388           4 :   plmd.cmd("init");
+     389           4 :   int step=1; plmd.cmd("setStep",&step);
+     390             : 
+     391           4 :   FILE* fp=fopen(ofile.c_str(),"r");
+     392             :   bool do_read=true; unsigned nfram=0;
+     393             :   std::vector<double> alig, disp;
+     394             :   // Read in the argument names
+     395           8 :   for(unsigned i=0; i<argstr.size(); ++i ) {
+     396           4 :     std::string input2 = argstr[i] + ": CONSTANT VALUE=1";
+     397           4 :     const char* inpt2 = input2.c_str(); plmd.cmd("readInputLine", inpt2);
+     398             :   }
+     399          37 :   while (do_read ) {
+     400          37 :     PDB mypdb;
+     401             :     // Read the pdb file
+     402          37 :     do_read=mypdb.readFromFilepointer(fp,false,0.1); if( !do_read ) break;
+     403          33 :     std::string num; Tools::convert( nfram+1, num ); nfram++; std::string iinput;
+     404          33 :     if( argstr.size()>0 ) {
+     405          60 :       for(unsigned i=0; i<argstr.size(); ++i ) {
+     406          80 :         std::string input = "ref_" + num + "_" + argstr[i] + ": PDB2CONSTANT REFERENCE=" + ofile + " ARG=" + argstr[i] + " NUMBER=" + num;
+     407          40 :         const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     408             :       }
+     409             :     } else {
+     410          26 :       std::string input = "ref_" + num + ": PDB2CONSTANT REFERENCE=" + ofile + " NUMBER=" + num;
+     411          13 :       const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     412             :     }
+     413             : 
+     414          33 :     if( nfram==1 ) {
+     415           4 :       alig.resize( mypdb.getOccupancy().size() );
+     416          30 :       for(unsigned i=0; i<alig.size(); ++i) alig[i]=mypdb.getOccupancy()[i];
+     417           4 :       disp.resize( mypdb.getBeta().size() );
+     418          30 :       for(unsigned i=0; i<disp.size(); ++i) disp[i]=mypdb.getBeta()[i];
+     419             :     }
+     420          37 :   }
+     421             :   // Now create the objects to measure the distances between the frames
+     422           4 :   std::vector<double> data( nfram );
+     423          33 :   for(unsigned j=1; j<nfram; ++j) {
+     424          29 :     std::string istr, jstr; Tools::convert( j, istr); Tools::convert( j+1, jstr );
+     425          76 :     if( mtype=="OPTIMAL-FAST" || mtype=="OPTIMAL" || mtype=="SIMPLE" ) {
+     426          22 :       std::string strv = "ref_" + jstr + "T: TRANSPOSE ARG=ref_" + jstr;
+     427          11 :       const char* cstrv = strv.c_str(); plmd.cmd("readInputLine",cstrv);
+     428          22 :       std::string dstring = "d" + istr + ": RMSD_VECTOR TYPE=" + mtype + " ARG=ref_" + jstr + "T,ref_" + istr;
+     429             :       // Get the align values
+     430          11 :       std::string anum; Tools::convert( alig[0], anum ); dstring += " ALIGN=" + anum;
+     431         143 :       for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); dstring += "," + anum; }
+     432             :       // Get the displace values
+     433          11 :       std::string dnum; Tools::convert( disp[0], dnum ); dstring += " DISPLACE=" + dnum;
+     434         143 :       for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); dstring += "," + dnum; }
+     435          11 :       const char* icinp=dstring.c_str(); plmd.cmd("readInputLine",icinp);
+     436          18 :     } else if( mtype=="EUCLIDEAN" ) {
+     437          54 :       std::string end_args="ARG1=ref_" + istr + "_" + argstr[0], start_args="ARG2=ref_" + jstr + "_" + argstr[0];
+     438          54 :       for(unsigned i=1; i<argstr.size(); ++i ) { end_args += ",ref_" + istr + "_" + argstr[i]; start_args += ",ref_" + jstr + "_" + argstr[i]; }
+     439          36 :       std::string fstr = "d" + istr + ": EUCLIDEAN_DISTANCE " + end_args + " " + start_args;
+     440          18 :       const char* icinp=fstr.c_str(); plmd.cmd("readInputLine",icinp);
+     441             :     } else {
+     442           0 :       plumed_merror("metric type " + mtype + " has not been implemented");
+     443             :     }
+     444          58 :     long rank; plmd.cmd("getDataRank d" + istr, &rank );
+     445          29 :     if( rank!=1 ) error("distance should be of rank 1");
+     446          58 :     std::vector<long> ishape(1); plmd.cmd("getDataShape d" + istr, &ishape[0] );
+     447          29 :     if( ishape[0]!=1 ) error("distance should be of rank 1");
+     448          58 :     plmd.cmd("setMemoryForData d" + istr, &data[j-1] );
+     449             :   }
+     450           4 :   plmd.cmd("calc"); double mean=0;
+     451             :   printf("N.B. THIS CODE ALWAYS AIMS TO CREATE EQUALLY SPACED FRAMES \n");
+     452             :   printf("THERE MAY BE SMALL DESCREPENCIES IN THE NUMBERS BELOW, HOWEVER, BECAUSE OF ROUNDING ERRORS \n");
+     453          33 :   for(unsigned i=1; i<nfram; ++i) {
+     454          29 :     printf("FINAL DISTANCE BETWEEN FRAME %u AND %u IS %f \n",i-1,i,data[i-1]); mean += data[i-1];
+     455             :   }
+     456           4 :   printf("SUGGESTED LAMBDA PARAMETER IS THUS %f \n",2.3/mean/static_cast<double>( nfram-1 ) );
+     457           4 : }
+     458             : 
+     459             : } // End of namespace
+     460             : }
+
+
+
+ + + + +
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 000000000..2039e6a75 --- /dev/null +++ b/coverage/mapping/index-sort-f.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:79281996.7 %
Date:2024-10-17 16:45:00Functions:475683.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PCAVars.cpp +
96.6%96.6%
+
96.6 %86 / 8966.7 %2 / 3
AdaptivePath.cpp +
98.0%98.0%
+
98.0 %50 / 5166.7 %2 / 3
GeometricPathShortcut.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
GeometricPath.cpp +
98.4%98.4%
+
98.4 %60 / 6166.7 %4 / 6
PathDisplacements.cpp +
95.9%95.9%
+
95.9 %70 / 7375.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
PathTools.cpp +
98.0%98.0%
+
98.0 %241 / 246100.0 %8 / 8
PathProjectionCalculator.cpp +
98.8%98.8%
+
98.8 %80 / 81100.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 000000000..dc636d1a1 --- /dev/null +++ b/coverage/mapping/index-sort-l.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:79281996.7 %
Date:2024-10-17 16:45:00Functions: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.9%95.9%
+
95.9 %70 / 7375.0 %6 / 8
PCAVars.cpp +
96.6%96.6%
+
96.6 %86 / 8966.7 %2 / 3
PathTools.cpp +
98.0%98.0%
+
98.0 %241 / 246100.0 %8 / 8
AdaptivePath.cpp +
98.0%98.0%
+
98.0 %50 / 5166.7 %2 / 3
GeometricPath.cpp +
98.4%98.4%
+
98.4 %60 / 6166.7 %4 / 6
PathProjectionCalculator.cpp +
98.8%98.8%
+
98.8 %80 / 81100.0 %8 / 8
GeometricPathShortcut.cpp +
100.0%
+
100.0 %22 / 2266.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 000000000..f2dc3e37c --- /dev/null +++ b/coverage/mapping/index.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:79281996.7 %
Date:2024-10-17 16:45:00Functions:475683.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AdaptivePath.cpp +
98.0%98.0%
+
98.0 %50 / 5166.7 %2 / 3
GeometricPath.cpp +
98.4%98.4%
+
98.4 %60 / 6166.7 %4 / 6
GeometricPathShortcut.cpp +
100.0%
+
100.0 %22 / 2266.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.9%95.9%
+
95.9 %70 / 7375.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 +
98.0%98.0%
+
98.0 %241 / 246100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/CovarianceMatrix.cpp.func-sort-c.html b/coverage/matrixtools/CovarianceMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000..57be2cdf4 --- /dev/null +++ b/coverage/matrixtools/CovarianceMatrix.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/CovarianceMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - CovarianceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools16CovarianceMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools16CovarianceMatrixC1ERKNS_13ActionOptionsE4
_ZN4PLMD11matrixtools16CovarianceMatrix16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/CovarianceMatrix.cpp.func.html b/coverage/matrixtools/CovarianceMatrix.cpp.func.html new file mode 100644 index 000000000..e4f6bd2f2 --- /dev/null +++ b/coverage/matrixtools/CovarianceMatrix.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/CovarianceMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - CovarianceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools16CovarianceMatrix16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD11matrixtools16CovarianceMatrixC1ERKNS_13ActionOptionsE4
_ZN4PLMD11matrixtools16CovarianceMatrixC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/CovarianceMatrix.cpp.gcov.html b/coverage/matrixtools/CovarianceMatrix.cpp.gcov.html new file mode 100644 index 000000000..47b829903 --- /dev/null +++ b/coverage/matrixtools/CovarianceMatrix.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/CovarianceMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - CovarianceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-10-17 16:45:00Functions: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 matrixtools {
+      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          10 : void CovarianceMatrix::registerKeywords(Keywords& keys ) {
+      46          10 :   ActionShortcut::registerKeywords( keys );
+      47          20 :   keys.add("numbered","ARG","the vectors of data from which we are calculating the covariance");
+      48          20 :   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          20 :   keys.addFlag("UNORMALIZED",false,"do not divide by the sum of the weights");
+      51          10 :   keys.setValueDescription("the covariance matrix");
+      52          40 :   keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("VSTACK"); keys.needsAction("TRANSPOSE");
+      53          30 :   keys.needsAction("ONES"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("MATRIX_PRODUCT");
+      54          10 : }
+      55             : 
+      56           4 : CovarianceMatrix::CovarianceMatrix(const ActionOptions&ao):
+      57             :   Action(ao),
+      58           4 :   ActionShortcut(ao)
+      59             : {
+      60           8 :   std::vector<std::string> args; parseVector("ARG",args);
+      61           4 :   unsigned nargs=args.size(); std::string argstr="ARG=" + args[0];
+      62          12 :   for(unsigned i=1; i<args.size(); ++i) argstr += "," + args[i];
+      63             : 
+      64           8 :   bool unorm; parseFlag("UNORMALIZED",unorm); std::string wstr; parse("WEIGHTS",wstr);
+      65           4 :   if( !unorm ) {
+      66             :     // Normalize the weights
+      67           8 :     readInputLine( getShortcutLabel() + "_wsum: SUM ARG=" + wstr + " PERIODIC=NO");
+      68           8 :     readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + wstr + "," + getShortcutLabel() + "_wsum FUNC=x/y PERIODIC=NO");
+      69           8 :     wstr = getShortcutLabel() + "_weights";
+      70             :   }
+      71             :   // Make a stack of all the data
+      72           8 :   readInputLine( getShortcutLabel() + "_stack: VSTACK " + argstr );
+      73             :   // And calculate the covariance matrix by first transposing the stack
+      74           8 :   readInputLine( getShortcutLabel() + "_stackT: TRANSPOSE ARG=" + getShortcutLabel() + "_stack");
+      75             :   // Create a matrix that holds all the weights
+      76           4 :   std::string str_nargs; Tools::convert( nargs, str_nargs );
+      77           8 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + str_nargs );
+      78             :   // Now create a matrix that holds all the weights
+      79           8 :   readInputLine( getShortcutLabel() + "_matweights: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_ones," + wstr );
+      80             :   // And multiply the weights by the transpose to get the weighted transpose
+      81           8 :   readInputLine( getShortcutLabel() + "_wT: CUSTOM ARG=" + getShortcutLabel() + "_matweights," + getShortcutLabel() + "_stackT FUNC=x*y PERIODIC=NO");
+      82             :   // And now calculate the covariance by doing a suitable matrix product
+      83           8 :   readInputLine( getShortcutLabel() + ": MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_wT," + getShortcutLabel() + "_stack");
+      84           4 : }
+      85             : 
+      86             : }
+      87             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/Determinent.cpp.func-sort-c.html b/coverage/matrixtools/Determinent.cpp.func-sort-c.html new file mode 100644 index 000000000..6fcde528f --- /dev/null +++ b/coverage/matrixtools/Determinent.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/Determinent.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - Determinent.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51145.5 %
Date:2024-10-17 16:45:00Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools11DeterminantC1ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools11DeterminantC2ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools11Determinant16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/Determinent.cpp.func.html b/coverage/matrixtools/Determinent.cpp.func.html new file mode 100644 index 000000000..d4b78becd --- /dev/null +++ b/coverage/matrixtools/Determinent.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/Determinent.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - Determinent.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51145.5 %
Date:2024-10-17 16:45:00Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools11Determinant16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11matrixtools11DeterminantC1ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools11DeterminantC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/Determinent.cpp.gcov.html b/coverage/matrixtools/Determinent.cpp.gcov.html new file mode 100644 index 000000000..7fd6ad217 --- /dev/null +++ b/coverage/matrixtools/Determinent.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/Determinent.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - Determinent.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51145.5 %
Date:2024-10-17 16:45:00Functions: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 matrixtools {
+      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 :   keys.setValueDescription("the determinant of the matrix");
+      49           2 : }
+      50             : 
+      51           0 : Determinant::Determinant( const ActionOptions& ao):
+      52             :   Action(ao),
+      53           0 :   ActionShortcut(ao)
+      54             : {
+      55           0 :   std::string arg; parse("ARG",arg);
+      56             :   // Compose a vector from the args
+      57           0 :   readInputLine( getShortcutLabel() + "_diag: DIAGONALIZE ARG=" + arg + " VECTORS=all");
+      58             :   // Not sure about the regexp here - check with matrix with more than 10 rows
+      59           0 :   readInputLine( getShortcutLabel() + ": PRODUCT ARG=(" + getShortcutLabel() + "_diag\.vals-[0-9])");
+      60           0 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/DiagonalizeMatrix.cpp.func-sort-c.html b/coverage/matrixtools/DiagonalizeMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000..2e524266e --- /dev/null +++ b/coverage/matrixtools/DiagonalizeMatrix.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/DiagonalizeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - DiagonalizeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5757100.0 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools17DiagonalizeMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools17DiagonalizeMatrixC1ERKNS_13ActionOptionsE22
_ZN4PLMD11matrixtools17DiagonalizeMatrix16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD11matrixtools17DiagonalizeMatrix9calculateEv122
_ZN4PLMD11matrixtools17DiagonalizeMatrix7prepareEv124
_ZN4PLMD11matrixtools17DiagonalizeMatrix22getNumberOfDerivativesEv276
_ZNK4PLMD11matrixtools17DiagonalizeMatrix23getForceOnMatrixElementERKjS3_12495
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/DiagonalizeMatrix.cpp.func.html b/coverage/matrixtools/DiagonalizeMatrix.cpp.func.html new file mode 100644 index 000000000..16ac74c56 --- /dev/null +++ b/coverage/matrixtools/DiagonalizeMatrix.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/DiagonalizeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - DiagonalizeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5757100.0 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools17DiagonalizeMatrix16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD11matrixtools17DiagonalizeMatrix22getNumberOfDerivativesEv276
_ZN4PLMD11matrixtools17DiagonalizeMatrix7prepareEv124
_ZN4PLMD11matrixtools17DiagonalizeMatrix9calculateEv122
_ZN4PLMD11matrixtools17DiagonalizeMatrixC1ERKNS_13ActionOptionsE22
_ZN4PLMD11matrixtools17DiagonalizeMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools17DiagonalizeMatrix23getForceOnMatrixElementERKjS3_12495
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/DiagonalizeMatrix.cpp.gcov.html b/coverage/matrixtools/DiagonalizeMatrix.cpp.gcov.html new file mode 100644 index 000000000..9cff9c12c --- /dev/null +++ b/coverage/matrixtools/DiagonalizeMatrix.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/DiagonalizeMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - DiagonalizeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5757100.0 %
Date:2024-10-17 16:45:00Functions: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 matrixtools {
+      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          41 : void DiagonalizeMatrix::registerKeywords( Keywords& keys ) {
+      60          41 :   MatrixOperationBase::registerKeywords( keys );
+      61          82 :   keys.add("compulsory","VECTORS","all","the eigenvalues and vectors that you would like to calculate.  1=largest, 2=second largest and so on");
+      62          82 :   keys.addOutputComponent("vals","default","the eigevalues of the input matrix");
+      63          82 :   keys.addOutputComponent("vecs","default","the eigenvectors of the input matrix");
+      64          41 : }
+      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/matrixtools/InvertMatrix.cpp.func-sort-c.html b/coverage/matrixtools/InvertMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000..716786fa8 --- /dev/null +++ b/coverage/matrixtools/InvertMatrix.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/InvertMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - InvertMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232785.2 %
Date:2024-10-17 16:45:00Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools12InvertMatrix5applyEv0
_ZN4PLMD11matrixtools12InvertMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools12InvertMatrix23getForceOnMatrixElementERKjS3_0
_ZN4PLMD11matrixtools12InvertMatrix22getNumberOfDerivativesEv6
_ZN4PLMD11matrixtools12InvertMatrix9calculateEv9
_ZN4PLMD11matrixtools12InvertMatrixC1ERKNS_13ActionOptionsE9
_ZN4PLMD11matrixtools12InvertMatrix16registerKeywordsERNS_8KeywordsE18
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/InvertMatrix.cpp.func.html b/coverage/matrixtools/InvertMatrix.cpp.func.html new file mode 100644 index 000000000..45196a30e --- /dev/null +++ b/coverage/matrixtools/InvertMatrix.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/InvertMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - InvertMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232785.2 %
Date:2024-10-17 16:45:00Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools12InvertMatrix16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD11matrixtools12InvertMatrix22getNumberOfDerivativesEv6
_ZN4PLMD11matrixtools12InvertMatrix5applyEv0
_ZN4PLMD11matrixtools12InvertMatrix9calculateEv9
_ZN4PLMD11matrixtools12InvertMatrixC1ERKNS_13ActionOptionsE9
_ZN4PLMD11matrixtools12InvertMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools12InvertMatrix23getForceOnMatrixElementERKjS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/InvertMatrix.cpp.gcov.html b/coverage/matrixtools/InvertMatrix.cpp.gcov.html new file mode 100644 index 000000000..5580920b6 --- /dev/null +++ b/coverage/matrixtools/InvertMatrix.cpp.gcov.html @@ -0,0 +1,176 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/InvertMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - InvertMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232785.2 %
Date:2024-10-17 16:45:00Functions: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 matrixtools {
+      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          18 : void InvertMatrix::registerKeywords( Keywords& keys ) {
+      59          18 :   MatrixOperationBase::registerKeywords( keys );
+      60          18 :   keys.setValueDescription("the inverse of the input matrix");
+      61          18 : }
+      62             : 
+      63           9 : InvertMatrix::InvertMatrix(const ActionOptions& ao):
+      64             :   Action(ao),
+      65             :   MatrixOperationBase(ao),
+      66           9 :   input_is_constant(false)
+      67             : {
+      68           9 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) error("input matrix should be square");
+      69             : 
+      70           9 :   ActionSetup* as = dynamic_cast<ActionSetup*>( getPntrToArgument(0)->getPntrToAction() );
+      71           9 :   if(as) input_is_constant=true;
+      72             : 
+      73           9 :   std::vector<unsigned> shape(2); shape[0]=shape[1]=getPntrToArgument(0)->getShape()[0]; addValue( shape );
+      74           9 :   setNotPeriodic(); getPntrToComponent(0)->buildDataStore(); getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      75           9 :   mymatrix.resize( shape[0], shape[1] ); inverse.resize( shape[0], shape[1] );
+      76           9 : }
+      77             : 
+      78           9 : void InvertMatrix::calculate() {
+      79             :   // Retrieve the matrix from input
+      80           9 :   retrieveFullMatrix( mymatrix );
+      81             :   // Now invert the matrix
+      82           9 :   Invert( mymatrix, inverse );
+      83             :   // And set the inverse
+      84           9 :   unsigned k = 0; Value* myval=getPntrToComponent(0);
+      85          30 :   for(unsigned i=0; i<mymatrix.nrows(); ++i) {
+      86          78 :     for(unsigned j=0; j<mymatrix.ncols(); ++j) {
+      87          57 :       myval->set( k, inverse(i,j) ); k++;
+      88             :     }
+      89             :   }
+      90             : 
+      91           9 :   if( !doNotCalculateDerivatives() && !input_is_constant ) error("derivatives of inverse matrix have not been implemented");
+      92           9 : }
+      93             : 
+      94           0 : void InvertMatrix::apply() {
+      95           0 :   if( doNotCalculateDerivatives() || input_is_constant ) return;
+      96           0 :   error("derivatives of inverse matrix have not been implemented");
+      97             : }
+      98             : 
+      99             : }
+     100             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/MatrixOperationBase.cpp.func-sort-c.html b/coverage/matrixtools/MatrixOperationBase.cpp.func-sort-c.html new file mode 100644 index 000000000..0c25066e1 --- /dev/null +++ b/coverage/matrixtools/MatrixOperationBase.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixOperationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixOperationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools19MatrixOperationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools19MatrixOperationBase18retrieveFullMatrixERNS_6MatrixIdEE131
_ZN4PLMD11matrixtools19MatrixOperationBaseC2ERKNS_13ActionOptionsE211
_ZN4PLMD11matrixtools19MatrixOperationBase16registerKeywordsERNS_8KeywordsE363
_ZN4PLMD11matrixtools19MatrixOperationBase5applyEv1448
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/MatrixOperationBase.cpp.func.html b/coverage/matrixtools/MatrixOperationBase.cpp.func.html new file mode 100644 index 000000000..a25d87e74 --- /dev/null +++ b/coverage/matrixtools/MatrixOperationBase.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixOperationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixOperationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools19MatrixOperationBase16registerKeywordsERNS_8KeywordsE363
_ZN4PLMD11matrixtools19MatrixOperationBase18retrieveFullMatrixERNS_6MatrixIdEE131
_ZN4PLMD11matrixtools19MatrixOperationBase5applyEv1448
_ZN4PLMD11matrixtools19MatrixOperationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools19MatrixOperationBaseC2ERKNS_13ActionOptionsE211
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/MatrixOperationBase.cpp.gcov.html b/coverage/matrixtools/MatrixOperationBase.cpp.gcov.html new file mode 100644 index 000000000..5ac554a96 --- /dev/null +++ b/coverage/matrixtools/MatrixOperationBase.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixOperationBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixOperationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-10-17 16:45:00Functions: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 matrixtools {
+      26             : 
+      27         363 : void MatrixOperationBase::registerKeywords( Keywords& keys ) {
+      28         363 :   Action::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      29         726 :   keys.use("ARG"); keys.remove("NUMERICAL_DERIVATIVES");
+      30         726 :   keys.add("optional","MATRIX","the input matrix (can use ARG instead)");
+      31         363 : }
+      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/matrixtools/MatrixTimesMatrix.cpp.func-sort-c.html b/coverage/matrixtools/MatrixTimesMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000..b17b3dd57 --- /dev/null +++ b/coverage/matrixtools/MatrixTimesMatrix.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixTimesMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixTimesMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:647288.9 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools17MatrixTimesMatrix26getAdditionalTasksRequiredEPNS_16ActionWithVectorERSt6vectorIjSaIjEE0
_ZN4PLMD11matrixtools17MatrixTimesMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools17MatrixTimesMatrixC1ERKNS_13ActionOptionsE57
_ZN4PLMD11matrixtools17MatrixTimesMatrix22getNumberOfDerivativesEv65
_ZN4PLMD11matrixtools17MatrixTimesMatrix16registerKeywordsERNS_8KeywordsE96
_ZN4PLMD11matrixtools17MatrixTimesMatrix7prepareEv172
_ZNK4PLMD11matrixtools17MatrixTimesMatrix18getNumberOfColumnsEv1297
_ZNK4PLMD11matrixtools17MatrixTimesMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3233
_ZNK4PLMD11matrixtools17MatrixTimesMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8116
_ZNK4PLMD11matrixtools17MatrixTimesMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE926514
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/MatrixTimesMatrix.cpp.func.html b/coverage/matrixtools/MatrixTimesMatrix.cpp.func.html new file mode 100644 index 000000000..5452cd90f --- /dev/null +++ b/coverage/matrixtools/MatrixTimesMatrix.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixTimesMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixTimesMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:647288.9 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools17MatrixTimesMatrix16registerKeywordsERNS_8KeywordsE96
_ZN4PLMD11matrixtools17MatrixTimesMatrix22getNumberOfDerivativesEv65
_ZN4PLMD11matrixtools17MatrixTimesMatrix26getAdditionalTasksRequiredEPNS_16ActionWithVectorERSt6vectorIjSaIjEE0
_ZN4PLMD11matrixtools17MatrixTimesMatrix7prepareEv172
_ZN4PLMD11matrixtools17MatrixTimesMatrixC1ERKNS_13ActionOptionsE57
_ZN4PLMD11matrixtools17MatrixTimesMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools17MatrixTimesMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE926514
_ZNK4PLMD11matrixtools17MatrixTimesMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3233
_ZNK4PLMD11matrixtools17MatrixTimesMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8116
_ZNK4PLMD11matrixtools17MatrixTimesMatrix18getNumberOfColumnsEv1297
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/MatrixTimesMatrix.cpp.gcov.html b/coverage/matrixtools/MatrixTimesMatrix.cpp.gcov.html new file mode 100644 index 000000000..1173fc9d9 --- /dev/null +++ b/coverage/matrixtools/MatrixTimesMatrix.cpp.gcov.html @@ -0,0 +1,245 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixTimesMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixTimesMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:647288.9 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools17MatrixTimesVectorC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools17MatrixTimesVector18getNumberOfColumnsEv0
_ZNK4PLMD11matrixtools17MatrixTimesVector29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE6
_ZN4PLMD11matrixtools17MatrixTimesVectorC1ERKNS_13ActionOptionsE352
_ZN4PLMD11matrixtools17MatrixTimesVector16registerKeywordsERNS_8KeywordsE629
_ZN4PLMD11matrixtools17MatrixTimesVector12isInSubChainERj2151
_ZNK4PLMD11matrixtools17MatrixTimesVector12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE6574
_ZN4PLMD11matrixtools17MatrixTimesVector7prepareEv13575
_ZN4PLMD11matrixtools17MatrixTimesVector22getNumberOfDerivativesEv31643
_ZNK4PLMD11matrixtools17MatrixTimesVector23updateAdditionalIndicesERKjRNS_10MultiValueE372677
_ZNK4PLMD11matrixtools17MatrixTimesVector15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE472445
_ZNK4PLMD11matrixtools17MatrixTimesVector11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE23970940
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/MatrixTimesVector.cpp.func.html b/coverage/matrixtools/MatrixTimesVector.cpp.func.html new file mode 100644 index 000000000..a7a1f580c --- /dev/null +++ b/coverage/matrixtools/MatrixTimesVector.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixTimesVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixTimesVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10712486.3 %
Date:2024-10-17 16:45:00Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools17MatrixTimesVector12isInSubChainERj2151
_ZN4PLMD11matrixtools17MatrixTimesVector16registerKeywordsERNS_8KeywordsE629
_ZN4PLMD11matrixtools17MatrixTimesVector22getNumberOfDerivativesEv31643
_ZN4PLMD11matrixtools17MatrixTimesVector7prepareEv13575
_ZN4PLMD11matrixtools17MatrixTimesVectorC1ERKNS_13ActionOptionsE352
_ZN4PLMD11matrixtools17MatrixTimesVectorC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools17MatrixTimesVector11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE23970940
_ZNK4PLMD11matrixtools17MatrixTimesVector12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE6574
_ZNK4PLMD11matrixtools17MatrixTimesVector15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE472445
_ZNK4PLMD11matrixtools17MatrixTimesVector18getNumberOfColumnsEv0
_ZNK4PLMD11matrixtools17MatrixTimesVector23updateAdditionalIndicesERKjRNS_10MultiValueE372677
_ZNK4PLMD11matrixtools17MatrixTimesVector29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/MatrixTimesVector.cpp.gcov.html b/coverage/matrixtools/MatrixTimesVector.cpp.gcov.html new file mode 100644 index 000000000..98abcd4e6 --- /dev/null +++ b/coverage/matrixtools/MatrixTimesVector.cpp.gcov.html @@ -0,0 +1,323 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/MatrixTimesVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - MatrixTimesVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10712486.3 %
Date:2024-10-17 16:45:00Functions:101283.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/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 matrixtools {
+      36             : 
+      37             : class MatrixTimesVector : public ActionWithMatrix {
+      38             : private:
+      39             :   bool sumrows;
+      40             :   unsigned nderivatives;
+      41             :   std::vector<bool> stored_arg;
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             :   explicit MatrixTimesVector(const ActionOptions&);
+      45             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      46           0 :   unsigned getNumberOfColumns() const override { plumed_error(); }
+      47             :   unsigned getNumberOfDerivatives();
+      48             :   void prepare() override ;
+      49        2151 :   bool isInSubChain( unsigned& nder ) override { nder = arg_deriv_starts[0]; return true; }
+      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& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      53             :   void updateAdditionalIndices( const unsigned& ostrn, MultiValue& myvals ) const override ;
+      54             : };
+      55             : 
+      56             : PLUMED_REGISTER_ACTION(MatrixTimesVector,"MATRIX_VECTOR_PRODUCT")
+      57             : 
+      58         629 : void MatrixTimesVector::registerKeywords( Keywords& keys ) {
+      59         629 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      60         629 :   keys.setValueDescription("the vector that is obtained by taking the product between the matrix and the vector that were input");
+      61         629 :   ActionWithValue::useCustomisableComponents(keys);
+      62         629 : }
+      63             : 
+      64           6 : std::string MatrixTimesVector::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+      65           6 :   if( getPntrToArgument(1)->getRank()==1 ) {
+      66           0 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+      67           0 :       if( getPntrToArgument(i)->getName().find(cname)!=std::string::npos ) {
+      68           0 :         return "the product of the matrix " + getPntrToArgument(0)->getName() + " and the vector " + getPntrToArgument(i)->getName();
+      69             :       }
+      70             :     }
+      71             :   }
+      72          21 :   for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+      73          21 :     if( getPntrToArgument(i)->getName().find(cname)!=std::string::npos ) {
+      74          12 :       return "the product of the matrix " + getPntrToArgument(i)->getName() + " and the vector " + getPntrToArgument(getNumberOfArguments()-1)->getName();
+      75             :     }
+      76             :   }
+      77           0 :   plumed_merror( "could not understand request for component " + cname ); return "";
+      78             : }
+      79             : 
+      80         352 : MatrixTimesVector::MatrixTimesVector(const ActionOptions&ao):
+      81             :   Action(ao),
+      82             :   ActionWithMatrix(ao),
+      83         352 :   sumrows(false)
+      84             : {
+      85         352 :   if( getNumberOfArguments()<2 ) error("Not enough arguments specified");
+      86             :   unsigned nvectors=0, nmatrices=0;
+      87        1875 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      88        1523 :     if( getPntrToArgument(i)->hasDerivatives() ) error("arguments should be vectors or matrices");
+      89        1523 :     if( getPntrToArgument(i)->getRank()<=1 ) nvectors++;
+      90        1523 :     if( getPntrToArgument(i)->getRank()==2 ) nmatrices++;
+      91             :   }
+      92             : 
+      93         352 :   std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getShape()[0];
+      94         352 :   if( nvectors==1 ) {
+      95         343 :     unsigned n = getNumberOfArguments()-1;
+      96        1320 :     for(unsigned i=0; i<n; ++i) {
+      97         977 :       if( getPntrToArgument(i)->getRank()!=2 || getPntrToArgument(i)->hasDerivatives() ) error("all arguments other than last argument should be matrices");
+      98         977 :       if( getPntrToArgument(n)->getRank()==0 ) {
+      99           1 :         if( getPntrToArgument(i)->getShape()[1]!=1 ) error("number of columns in input matrix does not equal number of elements in vector");
+     100         976 :       } 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");
+     101             :     }
+     102         343 :     if( getPntrToArgument(n)->getRank()>0 ) {
+     103         342 :       if( getPntrToArgument(n)->getRank()!=1 || getPntrToArgument(n)->hasDerivatives() ) error("last argument to this action should be a vector");
+     104             :     }
+     105         343 :     getPntrToArgument(n)->buildDataStore();
+     106             : 
+     107         343 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(0)->getPntrToAction() );
+     108         343 :     if( av ) done_in_chain=canBeAfterInChain( av );
+     109             : 
+     110         343 :     if( getNumberOfArguments()==2 ) {
+     111         301 :       addValue( shape ); setNotPeriodic();
+     112             :     } else {
+     113         718 :       for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+     114         676 :         std::string name = getPntrToArgument(i)->getName();
+     115        1352 :         if( name.find_first_of(".")!=std::string::npos ) { std::size_t dot=name.find_first_of("."); name = name.substr(dot+1); }
+     116         676 :         addComponent( name, shape ); componentIsNotPeriodic( name );
+     117             :       }
+     118             :     }
+     119         343 :     if( (getPntrToArgument(n)->getPntrToAction())->getName()=="CONSTANT" ) {
+     120         306 :       sumrows=true;
+     121         306 :       if( getPntrToArgument(n)->getRank()==0 ) {
+     122           1 :         if( fabs( getPntrToArgument(n)->get() - 1.0 )>epsilon ) sumrows = false;
+     123             :       } else {
+     124      180438 :         for(unsigned i=0; i<getPntrToArgument(n)->getShape()[0]; ++i) {
+     125      180141 :           if( fabs( getPntrToArgument(n)->get(i) - 1.0 )>epsilon ) { sumrows=false; break; }
+     126             :         }
+     127             :       }
+     128             :     }
+     129           9 :   } else if( nmatrices==1 ) {
+     130           9 :     if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a matrix");
+     131         203 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+     132         194 :       if( getPntrToArgument(i)->getRank()>1 || getPntrToArgument(i)->hasDerivatives() ) error("all arguments other than first argument should be vectors");
+     133         194 :       if( getPntrToArgument(i)->getRank()==0 ) {
+     134           0 :         if( getPntrToArgument(0)->getShape()[1]!=1 ) error("number of columns in input matrix does not equal number of elements in vector");
+     135         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");
+     136         194 :       getPntrToArgument(i)->buildDataStore();
+     137             :     }
+     138             : 
+     139           9 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(0)->getPntrToAction() );
+     140           9 :     if( av ) done_in_chain=canBeAfterInChain( av );
+     141             : 
+     142         203 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+     143         194 :       std::string name = getPntrToArgument(i)->getName();
+     144         194 :       if( name.find_first_of(".")!=std::string::npos ) { std::size_t dot=name.find_first_of("."); name = name.substr(dot+1); }
+     145         194 :       addComponent( name, shape ); componentIsNotPeriodic( name );
+     146             :     }
+     147           0 :   } else error("You should either have one vector or one matrix in input");
+     148             : 
+     149         352 :   nderivatives = buildArgumentStore(0);
+     150         352 :   std::string headstr=getFirstActionInChain()->getLabel(); stored_arg.resize( getNumberOfArguments() );
+     151        1875 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) stored_arg[i] = getPntrToArgument(i)->ignoreStoredValue( headstr );
+     152         352 : }
+     153             : 
+     154       31643 : unsigned MatrixTimesVector::getNumberOfDerivatives() {
+     155       31643 :   return nderivatives;
+     156             : }
+     157             : 
+     158       13575 : void MatrixTimesVector::prepare() {
+     159       13575 :   ActionWithVector::prepare(); Value* myval = getPntrToComponent(0);
+     160       13575 :   if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] ) return;
+     161          10 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0]; myval->setShape(shape);
+     162             : }
+     163             : 
+     164        6574 : void MatrixTimesVector::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     165        6574 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(0)->getRowLength(task_index);
+     166        6574 :   if( indices.size()!=size_v+1 ) indices.resize( size_v + 1 );
+     167      842762 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     168             :   myvals.setSplitIndex( size_v + 1 );
+     169        6574 : }
+     170             : 
+     171    23970940 : void MatrixTimesVector::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     172    23970940 :   unsigned ind2 = index2; if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     173    23970940 :   if( sumrows ) {
+     174    22303792 :     unsigned n=getNumberOfArguments()-1; double matval = 0;
+     175    87441027 :     for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+     176    65137235 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     177             :       Value* myarg = getPntrToArgument(i);
+     178    65137235 :       if( !myarg->valueHasBeenSet() ) myvals.addValue( ostrn, myvals.get( myarg->getPositionInStream() ) );
+     179       14718 :       else myvals.addValue( ostrn, myarg->get( index1*myarg->getNumberOfColumns() + ind2, false ) );
+     180             :       // Now lets work out the derivatives
+     181    65137235 :       if( doNotCalculateDerivatives() ) continue;
+     182    32823346 :       addDerivativeOnMatrixArgument( stored_arg[i], i, i, index1, ind2, 1.0, myvals );
+     183             :     }
+     184     1667148 :   } else if( getPntrToArgument(1)->getRank()==1 ) {
+     185     1667148 :     double matval = 0; Value* myarg = getPntrToArgument(0); unsigned vcol = ind2;
+     186     1667148 :     if( !myarg->valueHasBeenSet() ) matval = myvals.get( myarg->getPositionInStream() );
+     187             :     else {
+     188      827038 :       matval = myarg->get( index1*myarg->getNumberOfColumns() + ind2, false );
+     189      827038 :       vcol = getPntrToArgument(0)->getRowIndex( index1, ind2 );
+     190             :     }
+     191    18356786 :     for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+     192    16689638 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     193    16689638 :       double vecval=getArgumentElement( i+1, vcol, myvals );
+     194             :       // And add this part of the product
+     195    16689638 :       myvals.addValue( ostrn, matval*vecval );
+     196             :       // Now lets work out the derivatives
+     197    16689638 :       if( doNotCalculateDerivatives() ) continue;
+     198    15688768 :       addDerivativeOnMatrixArgument( stored_arg[0], i, 0, index1, ind2, vecval, myvals ); addDerivativeOnVectorArgument( stored_arg[i+1], i, i+1, vcol, matval, myvals );
+     199             :     }
+     200             :   } else {
+     201           0 :     unsigned n=getNumberOfArguments()-1; double matval = 0; unsigned vcol = ind2;
+     202           0 :     for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+     203           0 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     204             :       Value* myarg = getPntrToArgument(i);
+     205           0 :       if( !myarg->valueHasBeenSet() ) matval = myvals.get( myarg->getPositionInStream() );
+     206             :       else {
+     207           0 :         matval = myarg->get( index1*myarg->getNumberOfColumns() + ind2, false );
+     208           0 :         vcol = getPntrToArgument(i)->getRowIndex( index1, ind2 );
+     209             :       }
+     210           0 :       double vecval=getArgumentElement( n, vcol, myvals );
+     211             :       // And add this part of the product
+     212           0 :       myvals.addValue( ostrn, matval*vecval );
+     213             :       // Now lets work out the derivatives
+     214           0 :       if( doNotCalculateDerivatives() ) continue;
+     215           0 :       addDerivativeOnMatrixArgument( stored_arg[i], i, i, index1, ind2, vecval, myvals ); addDerivativeOnVectorArgument( stored_arg[n], i, n, vcol, matval, myvals );
+     216             :     }
+     217             :   }
+     218    23970940 : }
+     219             : 
+     220      472445 : void MatrixTimesVector::runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     221      472445 :   if( doNotCalculateDerivatives() || !actionInChain() ) return ;
+     222             : 
+     223      358714 :   if( getPntrToArgument(1)->getRank()==1 ) {
+     224             :     unsigned istrn = getPntrToArgument(0)->getPositionInMatrixStash();
+     225             :     std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     226     1010565 :     for(unsigned j=0; j<getNumberOfComponents(); ++j) {
+     227      671975 :       unsigned ostrn = getConstPntrToComponent(j)->getPositionInStream();
+     228    40971258 :       for(unsigned i=0; i<myvals.getNumberOfMatrixRowDerivatives(istrn); ++i) myvals.updateIndex( ostrn, mat_indices[i] );
+     229             :     }
+     230             :   } else {
+     231      530036 :     for(unsigned j=0; j<getNumberOfComponents(); ++j) {
+     232             :       unsigned istrn = getPntrToArgument(j)->getPositionInMatrixStash();
+     233      509912 :       unsigned ostrn = getConstPntrToComponent(j)->getPositionInStream();
+     234             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     235    17456348 :       for(unsigned i=0; i<myvals.getNumberOfMatrixRowDerivatives(istrn); ++i) myvals.updateIndex( ostrn, mat_indices[i] );
+     236             :     }
+     237             :   }
+     238             : }
+     239             : 
+     240      372677 : void MatrixTimesVector::updateAdditionalIndices( const unsigned& ostrn, MultiValue& myvals ) const {
+     241      372677 :   unsigned n = getNumberOfArguments()-1; if( getPntrToArgument(1)->getRank()==1 ) n = 1;
+     242      372677 :   unsigned nvals = getPntrToArgument(n)->getNumberOfValues();
+     243  1387754027 :   for(unsigned i=0; i<nvals; ++i) myvals.updateIndex( ostrn, arg_deriv_starts[n] + i );
+     244      372677 : }
+     245             : 
+     246             : }
+     247             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/OuterProduct.cpp.func-sort-c.html b/coverage/matrixtools/OuterProduct.cpp.func-sort-c.html new file mode 100644 index 000000000..3e8f5d25c --- /dev/null +++ b/coverage/matrixtools/OuterProduct.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/OuterProduct.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - OuterProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:727694.7 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools12OuterProductC2ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools12OuterProductC1ERKNS_13ActionOptionsE77
_ZN4PLMD11matrixtools12OuterProduct22getNumberOfDerivativesEv96
_ZN4PLMD11matrixtools12OuterProduct16registerKeywordsERNS_8KeywordsE137
_ZN4PLMD11matrixtools12OuterProduct7prepareEv158
_ZNK4PLMD11matrixtools12OuterProduct18getNumberOfColumnsEv2298
_ZNK4PLMD11matrixtools12OuterProduct12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE27151
_ZNK4PLMD11matrixtools12OuterProduct15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE39963
_ZNK4PLMD11matrixtools12OuterProduct11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE6874326
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/OuterProduct.cpp.func.html b/coverage/matrixtools/OuterProduct.cpp.func.html new file mode 100644 index 000000000..c2d5ddbe4 --- /dev/null +++ b/coverage/matrixtools/OuterProduct.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/OuterProduct.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - OuterProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:727694.7 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools12OuterProduct16registerKeywordsERNS_8KeywordsE137
_ZN4PLMD11matrixtools12OuterProduct22getNumberOfDerivativesEv96
_ZN4PLMD11matrixtools12OuterProduct7prepareEv158
_ZN4PLMD11matrixtools12OuterProductC1ERKNS_13ActionOptionsE77
_ZN4PLMD11matrixtools12OuterProductC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools12OuterProduct11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE6874326
_ZNK4PLMD11matrixtools12OuterProduct12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE27151
_ZNK4PLMD11matrixtools12OuterProduct15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE39963
_ZNK4PLMD11matrixtools12OuterProduct18getNumberOfColumnsEv2298
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/OuterProduct.cpp.gcov.html b/coverage/matrixtools/OuterProduct.cpp.gcov.html new file mode 100644 index 000000000..b035bfdb9 --- /dev/null +++ b/coverage/matrixtools/OuterProduct.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/OuterProduct.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - OuterProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:727694.7 %
Date:2024-10-17 16:45:00Functions: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 "core/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 matrixtools {
+      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         137 : void OuterProduct::registerKeywords( Keywords& keys ) {
+      58         137 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      59         274 :   keys.add("compulsory","FUNC","x*y","the function of the input vectors that should be put in the elements of the outer product");
+      60         274 :   keys.addFlag("ELEMENTS_ON_DIAGONAL_ARE_ZERO",false,"set all diagonal elements to zero");
+      61         137 :   keys.setValueDescription("a matrix containing the outer product of the two input vectors that was obtained using the function that was input");
+      62         137 : }
+      63             : 
+      64          77 : OuterProduct::OuterProduct(const ActionOptions&ao):
+      65             :   Action(ao),
+      66             :   ActionWithMatrix(ao),
+      67          77 :   domin(false),
+      68          77 :   domax(false)
+      69             : {
+      70          77 :   if( getNumberOfArguments()!=2 ) error("should be two arguments to this action, a matrix and a vector");
+      71          77 :   if( getPntrToArgument(0)->getRank()!=1 || getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a vector");
+      72          77 :   if( getPntrToArgument(1)->getRank()!=1 || getPntrToArgument(1)->hasDerivatives() ) error("first argument to this action should be a vector");
+      73             : 
+      74         154 :   std::string func; parse("FUNC",func);
+      75          77 :   if( func=="min") {
+      76           0 :     domin=true;
+      77           0 :     log.printf("  taking minimum of two input vectors \n");
+      78          77 :   } else if( func=="max" ) {
+      79           2 :     domax=true;
+      80           2 :     log.printf("  taking maximum of two input vectors \n");
+      81             :   } else {
+      82          75 :     log.printf("  with function : %s \n", func.c_str() );
+      83          75 :     std::vector<std::string> var(2); var[0]="x"; var[1]="y";
+      84          75 :     function.set( func, var, this );
+      85          75 :   }
+      86          77 :   parseFlag("ELEMENTS_ON_DIAGONAL_ARE_ZERO",diagzero);
+      87          77 :   if( diagzero ) log.printf("  setting diagonal elements equal to zero\n");
+      88             : 
+      89          77 :   std::vector<unsigned> shape(2); shape[0]=getPntrToArgument(0)->getShape()[0]; shape[1]=getPntrToArgument(1)->getShape()[0];
+      90          77 :   addValue( shape ); setNotPeriodic(); nderivatives = buildArgumentStore(0);
+      91          77 :   std::string headstr=getFirstActionInChain()->getLabel();
+      92          77 :   stored_vector1 = getPntrToArgument(0)->ignoreStoredValue( headstr );
+      93          77 :   stored_vector2 = getPntrToArgument(1)->ignoreStoredValue( headstr );
+      94          77 :   if( getPntrToArgument(0)->isDerivativeZeroWhenValueIsZero() || getPntrToArgument(1)->isDerivativeZeroWhenValueIsZero() ) getPntrToComponent(0)->setDerivativeIsZeroWhenValueIsZero();
+      95          77 : }
+      96             : 
+      97          96 : unsigned OuterProduct::getNumberOfDerivatives() {
+      98          96 :   return nderivatives;
+      99             : }
+     100             : 
+     101         158 : void OuterProduct::prepare() {
+     102         158 :   ActionWithVector::prepare(); Value* myval=getPntrToComponent(0);
+     103         158 :   if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] && myval->getShape()[1]==getPntrToArgument(1)->getShape()[0] ) return;
+     104          17 :   std::vector<unsigned> shape(2); shape[0] = getPntrToArgument(0)->getShape()[0]; shape[1] = getPntrToArgument(1)->getShape()[0];
+     105          17 :   myval->setShape( shape );
+     106             : }
+     107             : 
+     108       27151 : void OuterProduct::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     109       27151 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[0];
+     110       27151 :   if( diagzero ) {
+     111         990 :     if( indices.size()!=size_v ) indices.resize( size_v );
+     112             :     unsigned k=1;
+     113       99000 :     for(unsigned i=0; i<size_v; ++i) {
+     114       98010 :       if( task_index==i ) continue ;
+     115       97020 :       indices[k] = size_v + i; k++;
+     116             :     }
+     117             :     myvals.setSplitIndex( size_v );
+     118             :   } else {
+     119       26161 :     if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+     120     1690193 :     for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     121             :     myvals.setSplitIndex( size_v + 1 );
+     122             :   }
+     123       27151 : }
+     124             : 
+     125     6874326 : void OuterProduct::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     126     6874326 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream(), ind2=index2;
+     127     6874326 :   if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     128    13385626 :   if( diagzero && index1==ind2 ) return;
+     129             : 
+     130     6874326 :   double fval; unsigned jarg = 0, kelem = index1; bool jstore=stored_vector1;
+     131     6874326 :   std::vector<double> args(2);
+     132     6874326 :   args[0] = getArgumentElement( 0, index1, myvals );
+     133     6874326 :   args[1] = getArgumentElement( 1, ind2, myvals );
+     134     6874326 :   if( domin ) {
+     135           0 :     fval=args[0]; if( args[1]<args[0] ) { fval=args[1]; jarg=1; kelem=ind2; jstore=stored_vector2; }
+     136     6874326 :   } else if( domax ) {
+     137      315192 :     fval=args[0]; if( args[1]>args[0] ) { fval=args[1]; jarg=1; kelem=ind2; jstore=stored_vector2; }
+     138     6559134 :   } else { fval=function.evaluate( args ); }
+     139             : 
+     140     6874326 :   myvals.addValue( ostrn, fval );
+     141     6874326 :   if( doNotCalculateDerivatives() ) return ;
+     142             : 
+     143      366326 :   if( domin || domax ) {
+     144           0 :     addDerivativeOnVectorArgument( jstore, 0, jarg, kelem, 1.0, myvals );
+     145             :   } else {
+     146      366326 :     addDerivativeOnVectorArgument( stored_vector1, 0, 0, index1, function.evaluateDeriv( 0, args ), myvals );
+     147      366326 :     addDerivativeOnVectorArgument( stored_vector2, 0, 1, ind2, function.evaluateDeriv( 1, args ), myvals );
+     148             :   }
+     149      366326 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     150      363026 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     151      363026 :   myvals.getMatrixRowDerivativeIndices( nmat )[nmat_ind] = arg_deriv_starts[1] + ind2; myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind+1 );
+     152             : }
+     153             : 
+     154       39963 : void OuterProduct::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     155       39963 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     156       11402 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     157       11402 :   myvals.getMatrixRowDerivativeIndices( nmat )[nmat_ind] = ival; myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind+1 );
+     158             : }
+     159             : 
+     160             : }
+     161             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/TransposeMatrix.cpp.func-sort-c.html b/coverage/matrixtools/TransposeMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000..0396d6792 --- /dev/null +++ b/coverage/matrixtools/TransposeMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/TransposeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - TransposeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485488.9 %
Date:2024-10-17 16:45:00Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools15TransposeMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD11matrixtools15TransposeMatrixC1ERKNS_13ActionOptionsE162
_ZN4PLMD11matrixtools15TransposeMatrix22getNumberOfDerivativesEv256
_ZN4PLMD11matrixtools15TransposeMatrix16registerKeywordsERNS_8KeywordsE279
_ZN4PLMD11matrixtools15TransposeMatrix5applyEv4144
_ZN4PLMD11matrixtools15TransposeMatrix9calculateEv4225
_ZN4PLMD11matrixtools15TransposeMatrix7prepareEv4821
_ZNK4PLMD11matrixtools15TransposeMatrix23getForceOnMatrixElementERKjS3_4124572
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/TransposeMatrix.cpp.func.html b/coverage/matrixtools/TransposeMatrix.cpp.func.html new file mode 100644 index 000000000..94204beaf --- /dev/null +++ b/coverage/matrixtools/TransposeMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/TransposeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - TransposeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485488.9 %
Date:2024-10-17 16:45:00Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools15TransposeMatrix16registerKeywordsERNS_8KeywordsE279
_ZN4PLMD11matrixtools15TransposeMatrix22getNumberOfDerivativesEv256
_ZN4PLMD11matrixtools15TransposeMatrix5applyEv4144
_ZN4PLMD11matrixtools15TransposeMatrix7prepareEv4821
_ZN4PLMD11matrixtools15TransposeMatrix9calculateEv4225
_ZN4PLMD11matrixtools15TransposeMatrixC1ERKNS_13ActionOptionsE162
_ZN4PLMD11matrixtools15TransposeMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools15TransposeMatrix23getForceOnMatrixElementERKjS3_4124572
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/TransposeMatrix.cpp.gcov.html b/coverage/matrixtools/TransposeMatrix.cpp.gcov.html new file mode 100644 index 000000000..6c239a0be --- /dev/null +++ b/coverage/matrixtools/TransposeMatrix.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/TransposeMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - TransposeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485488.9 %
Date:2024-10-17 16:45:00Functions: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 matrixtools {
+      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         279 : void TransposeMatrix::registerKeywords( Keywords& keys ) {
+      57         279 :   MatrixOperationBase::registerKeywords( keys );
+      58         279 :   keys.setValueDescription("the transpose of the input matrix");
+      59         279 : }
+      60             : 
+      61         162 : TransposeMatrix::TransposeMatrix(const ActionOptions& ao):
+      62             :   Action(ao),
+      63         162 :   MatrixOperationBase(ao)
+      64             : {
+      65         162 :   if( getPntrToArgument(0)->isSymmetric() ) error("input matrix is symmetric.  Transposing will achieve nothing!");
+      66             :   std::vector<unsigned> shape;
+      67         162 :   if( getPntrToArgument(0)->getRank()==0 ) error("transposing a scalar?");
+      68         162 :   else if( getPntrToArgument(0)->getRank()==1 ) { shape.resize(2); shape[0]=1; shape[1]=getPntrToArgument(0)->getShape()[0]; }
+      69         145 :   else if( getPntrToArgument(0)->getShape()[0]==1 ) { shape.resize(1); shape[0] = getPntrToArgument(0)->getShape()[1]; }
+      70          84 :   else { shape.resize(2); shape[0]=getPntrToArgument(0)->getShape()[1]; shape[1]=getPntrToArgument(0)->getShape()[0]; }
+      71         162 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      72         162 :   if( shape.size()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      73         162 : }
+      74             : 
+      75        4821 : void TransposeMatrix::prepare() {
+      76        4821 :   Value* myval = getPntrToComponent(0); Value* myarg = getPntrToArgument(0);
+      77        4821 :   if( myarg->getRank()==1 ) {
+      78         586 :     if( myval->getShape()[0]!=1 || myval->getShape()[1]!=myarg->getShape()[0] ) {
+      79           6 :       std::vector<unsigned> shape(2); shape[0] = 1; shape[1] = myarg->getShape()[0];
+      80           6 :       myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+      81             :     }
+      82        4235 :   } else if( myarg->getShape()[0]==1 ) {
+      83        2392 :     if( myval->getShape()[0]!=myarg->getShape()[1] ) { std::vector<unsigned> shape(1); shape[0] = myarg->getShape()[1]; myval->setShape( shape ); }
+      84        1843 :   } else if( myarg->getShape()[0]!=myval->getShape()[1] || myarg->getShape()[1]!=myval->getShape()[0] ) {
+      85          19 :     std::vector<unsigned> shape(2); shape[0] = myarg->getShape()[1]; shape[1] = myarg->getShape()[0];
+      86          19 :     myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+      87             :   }
+      88        4821 : }
+      89             : 
+      90        4225 : void TransposeMatrix::calculate() {
+      91             :   // Retrieve the non-zero pairs
+      92        4225 :   Value* myarg=getPntrToArgument(0); Value* myval=getPntrToComponent(0);
+      93        4225 :   if( myarg->getRank()<=1 || myval->getRank()==1 ) {
+      94        2389 :     if( myarg->getRank()<=1 && myval->getShape()[1]!=myarg->getShape()[0] ) {
+      95           0 :       std::vector<unsigned> shape( 2 ); shape[0] = 1; shape[1] = myarg->getShape()[0];
+      96           0 :       myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+      97        2389 :     } else if( myval->getRank()==1 && myval->getShape()[0]!=myarg->getShape()[1] ) {
+      98           0 :       std::vector<unsigned> shape( 1 ); shape[0] = myarg->getShape()[1];
+      99           0 :       myval->setShape( shape );
+     100             :     }
+     101        2389 :     unsigned nv=myarg->getNumberOfValues();
+     102       49015 :     for(unsigned i=0; i<nv; ++i) myval->set( i, myarg->get(i) );
+     103             :   } else {
+     104        1836 :     if( myarg->getShape()[0]!=myval->getShape()[1] || myarg->getShape()[1]!=myval->getShape()[0] ) {
+     105           0 :       std::vector<unsigned> shape( 2 ); shape[0] = myarg->getShape()[1]; shape[1] = myarg->getShape()[0];
+     106           0 :       myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+     107             :     }
+     108             :     std::vector<double> vals; std::vector<std::pair<unsigned,unsigned> > pairs;
+     109        1836 :     std::vector<unsigned> shape( myval->getShape() ); unsigned nedge=0; myarg->retrieveEdgeList( nedge, pairs, vals );
+     110     2758860 :     for(unsigned i=0; i<nedge; ++i) myval->set( pairs[i].second*shape[1] + pairs[i].first, vals[i] );
+     111             :   }
+     112        4225 : }
+     113             : 
+     114        4144 : void TransposeMatrix::apply() {
+     115        4144 :   if( doNotCalculateDerivatives() ) return;
+     116             : 
+     117             :   // Apply force on the matrix
+     118        1930 :   if( getPntrToComponent(0)->forcesWereAdded() ) {
+     119        1930 :     Value* myarg=getPntrToArgument(0); Value* myval=getPntrToComponent(0);
+     120        1930 :     if( myarg->getRank()<=1 || myval->getRank()==1 ) {
+     121         588 :       unsigned nv=myarg->getNumberOfValues();
+     122        2408 :       for(unsigned i=0; i<nv; ++i) myarg->addForce( i, myval->getForce(i) );
+     123        1342 :     } else MatrixOperationBase::apply();
+     124             :   }
+     125             : }
+     126             : 
+     127     4124572 : double TransposeMatrix::getForceOnMatrixElement( const unsigned& jrow, const unsigned& kcol ) const {
+     128     4124572 :   return getConstPntrToComponent(0)->getForce(kcol*getConstPntrToComponent(0)->getShape()[1]+jrow);
+     129             : }
+     130             : 
+     131             : 
+     132             : }
+     133             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/Voronoi.cpp.func-sort-c.html b/coverage/matrixtools/Voronoi.cpp.func-sort-c.html new file mode 100644 index 000000000..c530e87a7 --- /dev/null +++ b/coverage/matrixtools/Voronoi.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/Voronoi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - Voronoi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-10-17 16:45:00Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools7Voronoi22getNumberOfDerivativesEv0
_ZN4PLMD11matrixtools7VoronoiC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools7Voronoi11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE0
_ZN4PLMD11matrixtools7Voronoi7prepareEv6
_ZN4PLMD11matrixtools7VoronoiC1ERKNS_13ActionOptionsE6
_ZN4PLMD11matrixtools7Voronoi16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD11matrixtools7Voronoi18getNumberOfColumnsEv12
_ZNK4PLMD11matrixtools7Voronoi12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD11matrixtools7Voronoi15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD11matrixtools7Voronoi17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE1036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/Voronoi.cpp.func.html b/coverage/matrixtools/Voronoi.cpp.func.html new file mode 100644 index 000000000..3bd3b011f --- /dev/null +++ b/coverage/matrixtools/Voronoi.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/Voronoi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - Voronoi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-10-17 16:45:00Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11matrixtools7Voronoi16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD11matrixtools7Voronoi22getNumberOfDerivativesEv0
_ZN4PLMD11matrixtools7Voronoi7prepareEv6
_ZN4PLMD11matrixtools7VoronoiC1ERKNS_13ActionOptionsE6
_ZN4PLMD11matrixtools7VoronoiC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11matrixtools7Voronoi11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE0
_ZNK4PLMD11matrixtools7Voronoi12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD11matrixtools7Voronoi15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD11matrixtools7Voronoi17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE1036
_ZNK4PLMD11matrixtools7Voronoi18getNumberOfColumnsEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/Voronoi.cpp.gcov.html b/coverage/matrixtools/Voronoi.cpp.gcov.html new file mode 100644 index 000000000..b3e13c3b5 --- /dev/null +++ b/coverage/matrixtools/Voronoi.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + LCOV - plumed test coverage - matrixtools/Voronoi.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtools - Voronoi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-10-17 16:45:00Functions: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 "core/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 matrixtools {
+      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          11 : void Voronoi::registerKeywords( Keywords& keys ) {
+      54          11 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      55          11 :   keys.setValueDescription("a matrix in which element ij is equal to one if the ij component of the input matrix is lower than all the ik elements of the matrix where k is not j and zero otherwise");
+      56          11 : }
+      57             : 
+      58           6 : Voronoi::Voronoi(const ActionOptions&ao):
+      59             :   Action(ao),
+      60           6 :   ActionWithMatrix(ao)
+      61             : {
+      62           6 :   if( getNumberOfArguments()!=1 ) error("should be one arguments to this action, a matrix");
+      63           6 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("argument to this action should be a matrix");
+      64           6 :   if( getPntrToArgument(0)->getShape()[1]>getPntrToArgument(0)->getShape()[0] ) warning("would expect number of columns in matrix to exceed number of rows");
+      65           6 :   getPntrToArgument(0)->buildDataStore(); std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      66           6 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      67           6 : }
+      68             : 
+      69           6 : void Voronoi::prepare() {
+      70           6 :   Value* myval = getPntrToComponent(0);
+      71           6 :   if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] && myval->getShape()[1]==getPntrToArgument(0)->getShape()[1] ) return;
+      72           6 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() ); myval->setShape(shape);
+      73             : }
+      74             : 
+      75        1036 : void Voronoi::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+      76             :                                  const unsigned& bufstart, std::vector<double>& buffer ) const {
+      77        1036 :   Value* arg0 = getPntrToArgument(0); unsigned nv = 0; std::size_t cc=code; double minmax = arg0->get( cc*arg0->getShape()[1] );
+      78      251175 :   for(unsigned i=0; i<arg0->getShape()[1]; ++i) {
+      79      250139 :     double value = arg0->get( code*arg0->getShape()[1] + i );
+      80      250139 :     if( value<minmax ) { minmax = value; nv = i; }
+      81             :   }
+      82        1036 :   buffer[bufstart + code*arg0->getShape()[1] + nv] = 1;
+      83        1036 : }
+      84             : 
+      85             : }
+      86             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/index-sort-f.html b/coverage/matrixtools/index-sort-f.html new file mode 100644 index 000000000..2fbee9a8b --- /dev/null +++ b/coverage/matrixtools/index-sort-f.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - matrixtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtoolsHitTotalCoverage
Test:plumed test coverageLines:45750790.1 %
Date:2024-10-17 16:45:00Functions:577477.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Determinent.cpp +
45.5%45.5%
+
45.5 %5 / 1133.3 %1 / 3
InvertMatrix.cpp +
85.2%85.2%
+
85.2 %23 / 2757.1 %4 / 7
CovarianceMatrix.cpp +
100.0%
+
100.0 %27 / 2766.7 %2 / 3
Voronoi.cpp +
92.9%92.9%
+
92.9 %26 / 2870.0 %7 / 10
MatrixOperationBase.cpp +
90.3%90.3%
+
90.3 %28 / 3180.0 %4 / 5
MatrixTimesMatrix.cpp +
88.9%88.9%
+
88.9 %64 / 7280.0 %8 / 10
MatrixTimesVector.cpp +
86.3%86.3%
+
86.3 %107 / 12483.3 %10 / 12
DiagonalizeMatrix.cpp +
100.0%
+
100.0 %57 / 5785.7 %6 / 7
TransposeMatrix.cpp +
88.9%88.9%
+
88.9 %48 / 5487.5 %7 / 8
OuterProduct.cpp +
94.7%94.7%
+
94.7 %72 / 7688.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/index-sort-l.html b/coverage/matrixtools/index-sort-l.html new file mode 100644 index 000000000..d9ee0c098 --- /dev/null +++ b/coverage/matrixtools/index-sort-l.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - matrixtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtoolsHitTotalCoverage
Test:plumed test coverageLines:45750790.1 %
Date:2024-10-17 16:45:00Functions:577477.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Determinent.cpp +
45.5%45.5%
+
45.5 %5 / 1133.3 %1 / 3
InvertMatrix.cpp +
85.2%85.2%
+
85.2 %23 / 2757.1 %4 / 7
MatrixTimesVector.cpp +
86.3%86.3%
+
86.3 %107 / 12483.3 %10 / 12
TransposeMatrix.cpp +
88.9%88.9%
+
88.9 %48 / 5487.5 %7 / 8
MatrixTimesMatrix.cpp +
88.9%88.9%
+
88.9 %64 / 7280.0 %8 / 10
MatrixOperationBase.cpp +
90.3%90.3%
+
90.3 %28 / 3180.0 %4 / 5
Voronoi.cpp +
92.9%92.9%
+
92.9 %26 / 2870.0 %7 / 10
OuterProduct.cpp +
94.7%94.7%
+
94.7 %72 / 7688.9 %8 / 9
CovarianceMatrix.cpp +
100.0%
+
100.0 %27 / 2766.7 %2 / 3
DiagonalizeMatrix.cpp +
100.0%
+
100.0 %57 / 5785.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/matrixtools/index.html b/coverage/matrixtools/index.html new file mode 100644 index 000000000..6fb519cf1 --- /dev/null +++ b/coverage/matrixtools/index.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - matrixtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - matrixtoolsHitTotalCoverage
Test:plumed test coverageLines:45750790.1 %
Date:2024-10-17 16:45:00Functions:577477.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CovarianceMatrix.cpp +
100.0%
+
100.0 %27 / 2766.7 %2 / 3
Determinent.cpp +
45.5%45.5%
+
45.5 %5 / 1133.3 %1 / 3
DiagonalizeMatrix.cpp +
100.0%
+
100.0 %57 / 5785.7 %6 / 7
InvertMatrix.cpp +
85.2%85.2%
+
85.2 %23 / 2757.1 %4 / 7
MatrixOperationBase.cpp +
90.3%90.3%
+
90.3 %28 / 3180.0 %4 / 5
MatrixTimesMatrix.cpp +
88.9%88.9%
+
88.9 %64 / 7280.0 %8 / 10
MatrixTimesVector.cpp +
86.3%86.3%
+
86.3 %107 / 12483.3 %10 / 12
OuterProduct.cpp +
94.7%94.7%
+
94.7 %72 / 7688.9 %8 / 9
TransposeMatrix.cpp +
88.9%88.9%
+
88.9 %48 / 5487.5 %7 / 8
Voronoi.cpp +
92.9%92.9%
+
92.9 %26 / 2870.0 %7 / 10
+
+
+ + + + +
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 000000000..bb5298086 --- /dev/null +++ b/coverage/maze/Loss.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4maze4Loss7pairingEd15923130
+
+
+ + + +
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 000000000..ed527e6e6 --- /dev/null +++ b/coverage/maze/Loss.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4maze4Loss7pairingEd15923130
_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 000000000..1e364a89a --- /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:2424100.0 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the loss function");
+      74          10 : }
+      75             : 
+      76           8 : Loss::Loss(const ActionOptions& ao)
+      77           8 :   : PLUMED_COLVAR_INIT(ao)
+      78             : {
+      79          16 :   if (keywords.exists("PARAMS")) {
+      80          16 :     parseVector("PARAMS", params_);
+      81             : 
+      82           8 :     plumed_massert(
+      83             :       params_.size() == 3,
+      84             :       "maze> PARAMS should be of size 3: alpha, beta, gamma\n"
+      85             :     );
+      86             : 
+      87           8 :     plumed_massert(
+      88             :       params_[0] > 0 && params_[1] > 0 && params_[2] > 0,
+      89             :       "maze> Each parameter should be positive\n"
+      90             :     );
+      91             : 
+      92           8 :     log.printf("maze> \t Loss parsed with parameters: ");
+      93          32 :     for (size_t i = 0; i < params_.size(); ++i) {
+      94          24 :       log.printf("%f ", params_[i]);
+      95             :     }
+      96           8 :     log.printf("\n");
+      97             :   }
+      98             : 
+      99           8 :   checkRead();
+     100           8 : }
+     101             : 
+     102    15923130 : double Loss::pairing(double distance) {
+     103    15923130 :   double alpha = params_[0];
+     104    15923130 :   double beta = params_[1];
+     105    15923130 :   double gamma = params_[2];
+     106             : 
+     107    31846260 :   if (getUnits().getLengthString() == "nm") {
+     108    15804000 :     distance *= 10.0;
+     109             :   }
+     110             : 
+     111    15923130 :   return pow(distance, -alpha) * exp(-beta * pow(distance, gamma));
+     112             : }
+     113             : 
+     114             : } // namespace maze
+     115             : } // 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 000000000..1e18ae57e --- /dev/null +++ b/coverage/maze/Loss.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - maze/Loss.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..cfd92b5db --- /dev/null +++ b/coverage/maze/Loss.h.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - maze/Loss.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..2bb790d8e --- /dev/null +++ b/coverage/maze/Loss.h.gcov.html @@ -0,0 +1,162 @@ + + + + + + + LCOV - plumed test coverage - maze/Loss.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..e622c35e7 --- /dev/null +++ b/coverage/maze/Member.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - maze/Member.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev354
_ZN4PLMD4maze7compareERNS0_6MemberES2_407
+
+
+ + + +
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 000000000..4f7cccd7c --- /dev/null +++ b/coverage/maze/Member.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - maze/Member.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev354
_ZN4PLMD4maze7compareERNS0_6MemberES2_407
+
+
+ + + +
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 000000000..f33179600 --- /dev/null +++ b/coverage/maze/Member.h.gcov.html @@ -0,0 +1,142 @@ + + + + + + + LCOV - plumed test coverage - maze/Member.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-10-17 16:45:00Functions: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         354 :   Member()
+      49         354 :     : score(-1),
+      50         354 :       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         407 : inline bool compare(Member& m, Member& n) {
+      60         407 :   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 000000000..5ca42c4fa --- /dev/null +++ b/coverage/maze/Memetic.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3314099a2 --- /dev/null +++ b/coverage/maze/Memetic.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..add2c305c --- /dev/null +++ b/coverage/maze/Memetic.cpp.gcov.html @@ -0,0 +1,358 @@ + + + + + + + LCOV - plumed test coverage - maze/Memetic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..1044f1708 --- /dev/null +++ b/coverage/maze/Memetic.h.func-sort-c.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-10-17 16:45:00Functions: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_6MemberERKSt6vectorIdSaIdEE10
_ZN4PLMD4maze7Memetic12local_searchERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic12sort_membersEv30
_ZN4PLMD4maze7Memetic13score_membersEv30
_ZN4PLMD4maze7Memetic18selection_rouletteEv30
_ZN4PLMD4maze7Memetic6matingERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic8mutationERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic13create_codingEv36
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE104
_ZN4PLMD4maze7Memetic13out_of_boundsEd106
_ZN4PLMD4maze7Memetic12score_memberERKNS_13VectorGenericILj3EEE280
+
+
+ + + +
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 000000000..ff20e5d18 --- /dev/null +++ b/coverage/maze/Memetic.h.func.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-10-17 16:45:00Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7Memetic10score_meanEv0
_ZN4PLMD4maze7Memetic12local_searchERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic12luus_jaakolaERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic12score_memberERKNS_13VectorGenericILj3EEE280
_ZN4PLMD4maze7Memetic12sort_membersEv30
_ZN4PLMD4maze7Memetic13create_codingEv36
_ZN4PLMD4maze7Memetic13out_of_boundsEd106
_ZN4PLMD4maze7Memetic13score_membersEv30
_ZN4PLMD4maze7Memetic18initialize_membersEv6
_ZN4PLMD4maze7Memetic18selection_rouletteEv30
_ZN4PLMD4maze7Memetic22adaptive_random_searchERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic24stochastic_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE10
_ZN4PLMD4maze7Memetic28random_restart_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic5solveEv6
_ZN4PLMD4maze7Memetic6matingERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE104
_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 000000000..e4d73dc27 --- /dev/null +++ b/coverage/maze/Memetic.h.gcov.html @@ -0,0 +1,882 @@ + + + + + + + LCOV - plumed test coverage - maze/Memetic.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-10-17 16:45:00Functions: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         665 :     for (size_t i = 0; i < cum_sum.size(); ++i) {
+     394         665 :       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         104 : void Memetic::mutation(Member& m) {
+     424         104 :   int which = rnd::next_int(coding_len_);
+     425         104 :   double v = rnd::next_cauchy(cauchy_mean_alpha_, cauchy_mean_beta_);
+     426         104 :   m.translation[which] += v;
+     427         104 :   if (out_of_bounds(m.translation.modulo())) {
+     428          33 :     m.translation[which] -= v;
+     429             :   }
+     430         104 : }
+     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          10 : void Memetic::stochastic_hill_climbing(
+     442             :   Member& m,
+     443             :   const std::vector<double>& params)
+     444             : {
+     445         110 :   for (std::size_t i = 0; i < n_local_iterations_; ++i) {
+     446         100 :     Member n;
+     447         100 :     n.translation = m.translation;
+     448         100 :     mutation(n);
+     449         100 :     double score_n = score_member(n.translation);
+     450             : 
+     451         100 :     if (m.score > score_n) {
+     452          46 :       m.translation = n.translation;
+     453             :     }
+     454             :   }
+     455          10 : }
+     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          10 :         if (local_search_type_ == "stochastic_hill_climbing")
+     595          20 :           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         149 :     while (i == j) {
+     615          59 :       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          42 :     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         106 : bool Memetic::out_of_bounds(double v) {
+     651         106 :   double s = sampling_radius();
+     652             : 
+     653         106 :   return v > s;
+     654             : }
+     655             : 
+     656         280 : double Memetic::score_member(const Vector& coding) {
+     657             :   double action = 0;
+     658         280 :   Vector distance;
+     659         280 :   const unsigned nl_size = neighbor_list_->size();
+     660         280 :   Vector dev = coding;
+     661             : 
+     662         280 :   #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         280 :   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 000000000..a09e92a12 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16117989.9 %
Date:2024-10-17 16:45:00Functions: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_radiusEv355
_ZNK4PLMD4maze9Optimizer7pairingEd15923130
+
+
+ + + +
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 000000000..8aaa1858d --- /dev/null +++ b/coverage/maze/Optimizer.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16117989.9 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9Optimizer15sampling_radiusEv355
_ZN4PLMD4maze9Optimizer16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD4maze9Optimizer5scoreEv226
_ZN4PLMD4maze9Optimizer7prepareEv210
_ZN4PLMD4maze9Optimizer9calculateEv210
_ZN4PLMD4maze9Optimizer9update_nlEv210
_ZN4PLMD4maze9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD4maze9OptimizerC2ERKNS_13ActionOptionsE7
_ZNK4PLMD4maze9Optimizer14center_of_massEv6
_ZNK4PLMD4maze9Optimizer7pairingEd15923130
+
+
+ + + +
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 000000000..8e9808feb --- /dev/null +++ b/coverage/maze/Optimizer.cpp.gcov.html @@ -0,0 +1,584 @@ + + + + + + + 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:16117989.9 %
Date:2024-10-17 16:45:00Functions: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          34 :   keys.addOutputComponent(
+     107             :     "x",
+     108             :     "default",
+     109             :     "Optimal biasing direction; x component."
+     110             :   );
+     111             : 
+     112          34 :   keys.addOutputComponent(
+     113             :     "y",
+     114             :     "default",
+     115             :     "Optimal biasing direction; y component."
+     116             :   );
+     117             : 
+     118          34 :   keys.addOutputComponent(
+     119             :     "z",
+     120             :     "default",
+     121             :     "Optimal biasing direction; z component."
+     122             :   );
+     123             : 
+     124          34 :   keys.addOutputComponent(
+     125             :     "loss",
+     126             :     "default",
+     127             :     "Loss function value defined by the provided pairing function."
+     128             :   );
+     129             : 
+     130          34 :   keys.addOutputComponent(
+     131             :     "sr",
+     132             :     "default",
+     133             :     "Sampling radius. Reduces sampling to the local proximity of the ligand "
+     134             :     "position."
+     135             :   );
+     136          17 : }
+     137             : 
+     138           7 : Optimizer::Optimizer(const ActionOptions& ao)
+     139             :   : PLUMED_COLVAR_INIT(ao),
+     140           7 :     first_step_(true),
+     141           7 :     opt_value_(0.0),
+     142           7 :     pbc_(true),
+     143           7 :     sampling_r_(0.0),
+     144           7 :     serial_(false),
+     145           7 :     validate_list_(true),
+     146           7 :     first_time_(true)
+     147             : {
+     148           7 :   parseFlag("SERIAL", serial_);
+     149             : 
+     150          14 :   if (keywords.exists("LOSS")) {
+     151           7 :     std::vector<std::string> loss_labels(0);
+     152          14 :     parseVector("LOSS", loss_labels);
+     153             : 
+     154           7 :     plumed_massert(
+     155             :       loss_labels.size() > 0,
+     156             :       "maze> Something went wrong with the LOSS keyword.\n"
+     157             :     );
+     158             : 
+     159           7 :     std::string error_msg = "";
+     160           7 :     vec_loss_ = tls::get_pointers_labels<Loss*>(
+     161             :                   loss_labels,
+     162           7 :                   plumed.getActionSet(),
+     163             :                   error_msg
+     164             :                 );
+     165             : 
+     166           7 :     if (error_msg.size() > 0) {
+     167           0 :       plumed_merror(
+     168             :         "maze> Error in the LOSS keyword " + getName() + ": " + error_msg
+     169             :       );
+     170             :     }
+     171             : 
+     172           7 :     loss_ = vec_loss_[0];
+     173           7 :     log.printf("maze> Loss function linked to the optimizer.\n");
+     174           7 :   }
+     175             : 
+     176          14 :   if (keywords.exists("N_ITER")) {
+     177           3 :     parse("N_ITER", n_iter_);
+     178             : 
+     179           3 :     plumed_massert(
+     180             :       n_iter_ > 0,
+     181             :       "maze> N_ITER should be explicitly specified and positive.\n"
+     182             :     );
+     183             : 
+     184           3 :     log.printf(
+     185             :       "maze> Optimizer will run %u iterations once launched.\n",
+     186             :       n_iter_
+     187             :     );
+     188             :   }
+     189             : 
+     190             :   std::vector<AtomNumber> ga_list, gb_list;
+     191           7 :   parseAtomList("LIGAND", ga_list);
+     192           7 :   parseAtomList("PROTEIN", gb_list);
+     193             : 
+     194           7 :   bool nopbc = !pbc_;
+     195           7 :   parseFlag("NOPBC", nopbc);
+     196             : 
+     197           7 :   bool do_pair = false;
+     198           7 :   parseFlag("PAIR", do_pair);
+     199             : 
+     200           7 :   nl_stride_ = 0;
+     201           7 :   bool do_neigh = false;
+     202           7 :   parseFlag("NLIST", do_neigh);
+     203             : 
+     204           7 :   if (do_neigh) {
+     205          14 :     if (keywords.exists("NL_CUTOFF")) {
+     206           7 :       parse("NL_CUTOFF", nl_cutoff_);
+     207             : 
+     208           7 :       plumed_massert(
+     209             :         nl_cutoff_ > 0,
+     210             :         "maze> NL_CUTOFF should be explicitly specified and positive.\n"
+     211             :       );
+     212             :     }
+     213             : 
+     214          14 :     if (keywords.exists("NL_STRIDE")) {
+     215           7 :       parse("NL_STRIDE", nl_stride_);
+     216             : 
+     217           7 :       plumed_massert(
+     218             :         nl_stride_ > 0,
+     219             :         "maze> NL_STRIDE should be explicitly specified and positive.\n"
+     220             :       );
+     221             :     }
+     222             :   }
+     223             : 
+     224           7 :   if (gb_list.size() > 0) {
+     225           7 :     if (do_neigh) {
+     226           7 :       neighbor_list_ = Tools::make_unique<NeighborList>(
+     227             :                          ga_list,
+     228             :                          gb_list,
+     229             :                          serial_,
+     230             :                          do_pair,
+     231           7 :                          pbc_,
+     232             :                          getPbc(),
+     233             :                          comm,
+     234           7 :                          nl_cutoff_,
+     235           7 :                          nl_stride_
+     236             :                        );
+     237             :     }
+     238             :     else {
+     239           0 :       neighbor_list_=Tools::make_unique<NeighborList>(
+     240             :                        ga_list,
+     241             :                        gb_list,
+     242             :                        serial_,
+     243             :                        do_pair,
+     244           0 :                        pbc_,
+     245             :                        getPbc(),
+     246             :                        comm
+     247             :                      );
+     248             :     }
+     249             :   }
+     250             :   else {
+     251           0 :     if (do_neigh) {
+     252           0 :       neighbor_list_ = Tools::make_unique<NeighborList>(
+     253             :                          ga_list,
+     254             :                          serial_,
+     255           0 :                          pbc_,
+     256             :                          getPbc(),
+     257             :                          comm,
+     258           0 :                          nl_cutoff_,
+     259           0 :                          nl_stride_
+     260             :                        );
+     261             :     }
+     262             :     else {
+     263           0 :       neighbor_list_=Tools::make_unique<NeighborList>(
+     264             :                        ga_list,
+     265             :                        serial_,
+     266           0 :                        pbc_,
+     267             :                        getPbc(),
+     268             :                        comm
+     269             :                      );
+     270             :     }
+     271             :   }
+     272             : 
+     273           7 :   requestAtoms(neighbor_list_->getFullAtomList());
+     274             : 
+     275           7 :   log.printf(
+     276             :     "maze> Loss will be calculated between two groups of %u and %u atoms.\n",
+     277             :     static_cast<unsigned>(ga_list.size()),
+     278             :     static_cast<unsigned>(gb_list.size())
+     279             :   );
+     280             : 
+     281           7 :   log.printf(
+     282             :     "maze> First group (LIGAND): from %d to %d.\n",
+     283             :     ga_list[0].serial(),
+     284             :     ga_list[ga_list.size()-1].serial()
+     285             :   );
+     286             : 
+     287           7 :   if (gb_list.size() > 0) {
+     288           7 :     log.printf(
+     289             :       "maze> Second group (PROTEIN): from %d to %d.\n",
+     290             :       gb_list[0].serial(),
+     291             :       gb_list[gb_list.size()-1].serial()
+     292             :     );
+     293             :   }
+     294             : 
+     295           7 :   if (pbc_) {
+     296           7 :     log.printf("maze> Using periodic boundary conditions.\n");
+     297             :   }
+     298             :   else {
+     299           0 :     log.printf("maze> Without periodic boundary conditions.\n");
+     300             :   }
+     301             : 
+     302           7 :   if (do_pair) {
+     303           0 :     log.printf("maze> With PAIR option.\n");
+     304             :   }
+     305             : 
+     306           7 :   if (do_neigh) {
+     307           7 :     log.printf(
+     308             :       "maze> Using neighbor lists updated every %d steps and cutoff %f.\n",
+     309             :       nl_stride_,
+     310             :       nl_cutoff_
+     311             :     );
+     312             :   }
+     313             : 
+     314             :   // OpenMP
+     315           7 :   stride_ = comm.Get_size();
+     316           7 :   rank_ = comm.Get_rank();
+     317             : 
+     318           7 :   n_threads_ = OpenMP::getNumThreads();
+     319           7 :   unsigned int nn = neighbor_list_->size();
+     320             : 
+     321           7 :   if (n_threads_ * stride_ * 10 > nn) {
+     322           0 :     n_threads_ = nn / stride_ / 10;
+     323             :   }
+     324             : 
+     325           7 :   if (n_threads_ == 0) {
+     326           0 :     n_threads_ = 1;
+     327             :   }
+     328             : 
+     329          14 :   if (keywords.exists("OPTIMIZER_STRIDE")) {
+     330           7 :     parse("OPTIMIZER_STRIDE", optimizer_stride_);
+     331             : 
+     332           7 :     plumed_massert(
+     333             :       optimizer_stride_,
+     334             :       "maze> OPTIMIZER_STRIDE should be explicitly specified and positive.\n"
+     335             :     );
+     336             : 
+     337           7 :     log.printf(
+     338             :       "maze> Launching optimization every %u steps.\n",
+     339             :       optimizer_stride_
+     340             :     );
+     341             :   }
+     342             : 
+     343           7 :   rnd::randomize();
+     344             : 
+     345           7 :   opt_.zero();
+     346             : 
+     347          14 :   addComponentWithDerivatives("x");
+     348          14 :   componentIsNotPeriodic("x");
+     349             : 
+     350          14 :   addComponentWithDerivatives("y");
+     351          14 :   componentIsNotPeriodic("y");
+     352             : 
+     353          14 :   addComponentWithDerivatives("z");
+     354          14 :   componentIsNotPeriodic("z");
+     355             : 
+     356          14 :   addComponent("loss");
+     357          14 :   componentIsNotPeriodic("loss");
+     358             : 
+     359          14 :   addComponent("sr");
+     360           7 :   componentIsNotPeriodic("sr");
+     361             : 
+     362           7 :   value_x_ = getPntrToComponent("x");
+     363           7 :   value_y_ = getPntrToComponent("y");
+     364           7 :   value_z_ = getPntrToComponent("z");
+     365           7 :   value_action_ = getPntrToComponent("loss");
+     366           7 :   value_sampling_radius_ = getPntrToComponent("sr");
+     367           7 : }
+     368             : 
+     369    15923130 : double Optimizer::pairing(double distance) const {
+     370    15923130 :   return loss_->pairing(distance);
+     371             : }
+     372             : 
+     373           6 : Vector Optimizer::center_of_mass() const {
+     374           6 :   const unsigned nl_size = neighbor_list_->size();
+     375             : 
+     376           6 :   Vector center_of_mass;
+     377           6 :   center_of_mass.zero();
+     378             :   double mass = 0;
+     379             : 
+     380      189654 :   for (unsigned int i = 0; i < nl_size; ++i) {
+     381      189648 :     unsigned int i0 = neighbor_list_->getClosePair(i).first;
+     382      189648 :     center_of_mass += getPosition(i0) * getMass(i0);
+     383      189648 :     mass += getMass(i0);
+     384             :   }
+     385             : 
+     386           6 :   return center_of_mass / mass;
+     387             : }
+     388             : 
+     389         210 : void Optimizer::prepare() {
+     390         210 :   if (neighbor_list_->getStride() > 0) {
+     391         210 :     if (first_time_ || (getStep() % neighbor_list_->getStride() == 0)) {
+     392           7 :       requestAtoms(neighbor_list_->getFullAtomList());
+     393             : 
+     394           7 :       validate_list_ = true;
+     395           7 :       first_time_ = false;
+     396             :     }
+     397             :     else {
+     398         203 :       requestAtoms(neighbor_list_->getReducedAtomList());
+     399             : 
+     400         203 :       validate_list_ = false;
+     401             : 
+     402         203 :       if (getExchangeStep()) {
+     403           0 :         plumed_merror(
+     404             :           "maze> Neighbor lists should be updated on exchange steps -- choose "
+     405             :           "an NL_STRIDE which divides the exchange stride.\n");
+     406             :       }
+     407             :     }
+     408             : 
+     409         210 :     if (getExchangeStep()) {
+     410           0 :       first_time_ = true;
+     411             :     }
+     412             :   }
+     413         210 : }
+     414             : 
+     415         226 : double Optimizer::score() {
+     416         226 :   const unsigned nl_size = neighbor_list_->size();
+     417         226 :   Vector distance;
+     418             :   double function = 0;
+     419             : 
+     420         226 :   #pragma omp parallel num_threads(n_threads_)
+     421             :   {
+     422             :     #pragma omp for reduction(+:function)
+     423             :     for(unsigned int i = 0; i < nl_size; i++) {
+     424             :       unsigned i0 = neighbor_list_->getClosePair(i).first;
+     425             :       unsigned i1 = neighbor_list_->getClosePair(i).second;
+     426             : 
+     427             :       if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     428             :         continue;
+     429             :       }
+     430             : 
+     431             :       if (pbc_) {
+     432             :         distance = pbcDistance(getPosition(i0), getPosition(i1));
+     433             :       }
+     434             :       else {
+     435             :         distance = delta(getPosition(i0), getPosition(i1));
+     436             :       }
+     437             : 
+     438             :       function += pairing(distance.modulo());
+     439             :     }
+     440             :   }
+     441             : 
+     442         226 :   return function;
+     443             : }
+     444             : 
+     445         210 : void Optimizer::update_nl() {
+     446         210 :   if (neighbor_list_->getStride() > 0 && validate_list_) {
+     447           7 :     neighbor_list_->update(getPositions());
+     448             :   }
+     449         210 : }
+     450             : 
+     451         355 : double Optimizer::sampling_radius()
+     452             : {
+     453         355 :   const unsigned nl_size=neighbor_list_->size();
+     454         355 :   Vector d;
+     455             :   double min=std::numeric_limits<int>::max();
+     456             : 
+     457     9433015 :   for (unsigned int i = 0; i < nl_size; ++i) {
+     458     9432660 :     unsigned i0 = neighbor_list_->getClosePair(i).first;
+     459     9432660 :     unsigned i1 = neighbor_list_->getClosePair(i).second;
+     460             : 
+     461     9432660 :     if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     462           0 :       continue;
+     463             :     }
+     464             : 
+     465     9432660 :     if (pbc_) {
+     466     9432660 :       d = pbcDistance(getPosition(i0), getPosition(i1));
+     467             :     }
+     468             :     else {
+     469           0 :       d = delta(getPosition(i0), getPosition(i1));
+     470             :     }
+     471             : 
+     472     9432660 :     double dist = d.modulo();
+     473             : 
+     474     9432660 :     if(dist < min) {
+     475             :       min = dist;
+     476             :     }
+     477             :   }
+     478             : 
+     479         355 :   return min;
+     480             : }
+     481             : 
+     482         210 : void Optimizer::calculate() {
+     483         210 :   update_nl();
+     484             : 
+     485         210 :   if (getStep() % optimizer_stride_ == 0 && !first_step_) {
+     486          19 :     optimize();
+     487             : 
+     488          19 :     value_x_->set(opt_[0]);
+     489          19 :     value_y_->set(opt_[1]);
+     490          19 :     value_z_->set(opt_[2]);
+     491             : 
+     492          19 :     value_action_->set(score());
+     493          19 :     value_sampling_radius_->set(sampling_radius());
+     494             :   }
+     495             :   else {
+     496         191 :     first_step_=false;
+     497             : 
+     498         191 :     value_x_->set(opt_[0]);
+     499         191 :     value_y_->set(opt_[1]);
+     500         191 :     value_z_->set(opt_[2]);
+     501             : 
+     502         191 :     value_action_->set(score());
+     503         191 :     value_sampling_radius_->set(sampling_radius());
+     504             :   }
+     505         210 : }
+     506             : 
+     507             : } // namespace maze
+     508             : } // 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 000000000..70a3307dd --- /dev/null +++ b/coverage/maze/Optimizer.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..1dee7fc0b --- /dev/null +++ b/coverage/maze/Optimizer.h.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..ed401f4ef --- /dev/null +++ b/coverage/maze/Optimizer.h.gcov.html @@ -0,0 +1,433 @@ + + + + + + + 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-10-17 16:45:00Functions: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         310 :   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 000000000..bf08cb750 --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:949697.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..06a239366 --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:949697.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..ef6c878f3 --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.gcov.html @@ -0,0 +1,508 @@ + + + + + + + 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:949697.9 %
Date:2024-10-17 16:45:00Functions: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 MAZE_OPTIMIZER.
+      53             : 
+      54             : OptimizerBias is a class deriving from Bias, and it is used to adaptively
+      55             : bias a ligand-protein system toward an optimal solution found by the chosen
+      56             : \ref MAZE_OPTIMIZER.
+      57             : 
+      58             : Remember to define the loss function (\ref MAZE_LOSS) and the optimizer
+      59             : (\ref MAZE_OPTIMIZER) prior to the adaptive bias for the optimizer.
+      60             : 
+      61             : The adaptive bias potential is the following:
+      62             : \f[
+      63             :   V({\bf x}_t)=\alpha
+      64             :     \left(wt -
+      65             :       ({\bf x} - {\bf x}^*_{t-\tau})
+      66             :       \cdot
+      67             :       \frac{{\bf x}^*_t - {\bf x}_t}{\|{\bf x}^*_t-{\bf x}_t\|}
+      68             :     \right)^2,
+      69             : \f]
+      70             : where \f${\bf x}^*_t\f$ is the optimal solution at time \f$t\f$, \f$w\f$ is the
+      71             : biasing rate, \f$\tau\f$ is the interval at which the loss function is minimized,
+      72             : and \f$\alpha\f$ is a scaled force constant.
+      73             : 
+      74             : \par Examples
+      75             : 
+      76             : In the following example the bias potential biases a ligand atom (which have to be
+      77             : given as an argument) with the biasing rate equal to 0.02 A/ps, and the biasing
+      78             : constant equal to 3.6 kcal/(mol A). It also takes an optimizer (see
+      79             : \ref MAZE_OPTIMIZER).
+      80             : 
+      81             : \plumedfile
+      82             : UNITS LENGTH=A TIME=ps ENERGY=kcal/mol
+      83             : 
+      84             : p: POSITION ATOM=2635 NOPBC
+      85             : 
+      86             : MAZE_OPTIMIZER_BIAS ...
+      87             :   LABEL=bias
+      88             : 
+      89             :   ARG=p.x,p.y,p.z
+      90             : 
+      91             :   BIASING_RATE=0.02
+      92             :   ALPHA=3.6
+      93             : 
+      94             :   OPTIMIZER=opt
+      95             : ... MAZE_OPTIMIZER_BIAS
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : /**
+     102             :  * @class OptimizerBias OptimizerBias.cpp "maze/OptimizerBias.cpp"
+     103             :  *
+     104             :  * @brief Adaptive bias for the maze optimizers.
+     105             :  *
+     106             :  * OptimizerBias is a class deriving from Bias, and it is used to adaptively
+     107             :  * bias a system toward an optimal solution found by an optimizer.
+     108             :  */
+     109             : class OptimizerBias: public bias::Bias {
+     110             : public:
+     111             :   /**
+     112             :    * Standard PLUMED2 constructor.
+     113             :    *
+     114             :    * @param ao ActionOptions&.
+     115             :    */
+     116             :   explicit OptimizerBias(const ActionOptions& ao);
+     117             : 
+     118             :   /**
+     119             :    * Destructor.
+     120             :    */
+     121           3 :   ~OptimizerBias() { /* Nothing to do. */ }
+     122             : 
+     123             :   /**
+     124             :    * Register PLUMED2 keywords.
+     125             :    *
+     126             :    * @param keys Keywords.
+     127             :    */
+     128             :   static void registerKeywords(Keywords& keys);
+     129             : 
+     130             :   /**
+     131             :    * Calculate the adaptive biasing potential for ligand unbinding.
+     132             :    */
+     133             :   void calculate();
+     134             : 
+     135             : private:
+     136             :   /**
+     137             :    * Biased collective variable with Cartesian components, i.e., position,
+     138             :    * center of mass.
+     139             :    */
+     140             :   std::vector<Value*> args_;
+     141             : 
+     142             :   /**
+     143             :    * Pointer to the optimizer used to minimize the collective variable for
+     144             :    * ligand unbinding.
+     145             :    */
+     146             :   Optimizer* optimizer_;
+     147             :   std::vector<Optimizer*> opt_pntrs_;
+     148             : 
+     149             :   //! Adaptive bias potential and the corresponding force.
+     150             :   double bias_;
+     151             :   double force_;
+     152             : 
+     153             :   /*
+     154             :    * Parameters of the adaptive biasing potential:
+     155             :    *  alpha_            rescaled force constant
+     156             :    *  biasing_speed     biasing rate
+     157             :    *  biasing_stride    biasing stride
+     158             :    *  biasing_direction biasing direction
+     159             :    */
+     160             : 
+     161             :   //! Rescaled force constant.
+     162             :   double alpha_;
+     163             :   //! Biasing rate.
+     164             :   double biasing_speed_;
+     165             :   //! Biasing stride.
+     166             :   int biasing_stride_;
+     167             : 
+     168             :   /**
+     169             :    * Biasing direction is approximated by an optimal solution found by an
+     170             :    * optimizer.
+     171             :    */
+     172             :   Vector biasing_direction_;
+     173             : 
+     174             :   //! Total distance traveled by biased atoms.
+     175             :   double total_distance_;
+     176             : 
+     177             :   //! Previous value of the collective variable.
+     178             :   Vector cv0_;
+     179             : 
+     180             :   /*
+     181             :    * Pointers to PLUMED2 output components.
+     182             :    */
+     183             : 
+     184             :   //! Biased collective variable components.
+     185             :   Value* value_dir_x_;
+     186             :   Value* value_dir_y_;
+     187             :   Value* value_dir_z_;
+     188             : 
+     189             :   //! Values of the bias and its force.
+     190             :   Value* value_bias_;
+     191             :   Value* value_force_;
+     192             : 
+     193             :   //! Total distance.
+     194             :   Value* value_total_distance_;
+     195             : };
+     196             : 
+     197             : // Register OPTIMIZER_BIAS as a keyword for PLUMED2 input files.
+     198             : 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           6 :   keys.addOutputComponent(
+     229             :     "force2",
+     230             :     "default",
+     231             :     "Square of the biasing force."
+     232             :   );
+     233             : 
+     234           6 :   keys.addOutputComponent(
+     235             :     "x",
+     236             :     "default",
+     237             :     "Optimal biasing direction: x component."
+     238             :   );
+     239             : 
+     240           6 :   keys.addOutputComponent(
+     241             :     "y",
+     242             :     "default",
+     243             :     "Optimal biasing direction: y component."
+     244             :   );
+     245             : 
+     246           6 :   keys.addOutputComponent(
+     247             :     "z",
+     248             :     "default",
+     249             :     "Optimal biasing direction: z component."
+     250             :   );
+     251             : 
+     252           6 :   keys.addOutputComponent(
+     253             :     "tdist",
+     254             :     "default",
+     255             :     "Total distance traveled by biased atoms."
+     256             :   );
+     257           3 : }
+     258             : 
+     259           1 : OptimizerBias::OptimizerBias(const ActionOptions& ao)
+     260             :   : PLUMED_BIAS_INIT(ao),
+     261           1 :     bias_(0.0),
+     262           1 :     force_(0.0),
+     263           1 :     total_distance_(0.0)
+     264             : {
+     265           1 :   log.printf(
+     266             :     "maze> You are using the maze module of PLUMED2,\
+     267             :     please read and cite "
+     268             :   );
+     269             : 
+     270           2 :   log << plumed.cite("Rydzewski J. and Valsson O., arXiv:1808.08089, 2018");
+     271           1 :   log.printf("\n");
+     272             : 
+     273           1 :   args_ = getArguments();
+     274           1 :   log.printf(
+     275             :     "maze> Number of args %zu\n",
+     276             :     args_.size()
+     277             :   );
+     278             : 
+     279           1 :   if (!args_.empty()) {
+     280           1 :     log.printf("maze> With arguments");
+     281           4 :     for (unsigned i = 0; i < args_.size(); i++) {
+     282           3 :       log.printf(" %s", args_[i]->getName().c_str());
+     283             :     }
+     284           1 :     log.printf("\n");
+     285             :   }
+     286             : 
+     287           2 :   if (keywords.exists("ALPHA")) {
+     288           1 :     parse("ALPHA", alpha_);
+     289             : 
+     290           1 :     plumed_massert(
+     291             :       alpha_>0,
+     292             :       "maze> ALPHA should be explicitly specified and positive.\n"
+     293             :     );
+     294             : 
+     295           1 :     log.printf(
+     296             :       "maze> ALPHA read: %f [kcal/mol/A].\n",
+     297             :       alpha_
+     298             :     );
+     299             :   }
+     300             : 
+     301           2 :   if (keywords.exists("BIASING_RATE")) {
+     302           1 :     parse("BIASING_RATE", biasing_speed_);
+     303             : 
+     304           1 :     plumed_massert(
+     305             :       biasing_speed_>0,
+     306             :       "maze> BIASING_RATE should be explicitly specified and positive.\n"
+     307             :     );
+     308             : 
+     309           1 :     log.printf(
+     310             :       "maze> BIASING_RATE read: %f [A/ps].\n",
+     311             :       biasing_speed_
+     312             :     );
+     313             :   }
+     314             : 
+     315           2 :   if (keywords.exists("OPTIMIZER")) {
+     316           1 :     std::vector<std::string> opt_labels(0);
+     317           2 :     parseVector("OPTIMIZER", opt_labels);
+     318             : 
+     319           1 :     plumed_massert(
+     320             :       opt_labels.size() > 0,
+     321             :       "maze> Problem with OPTIMIZER keyword.\n"
+     322             :     );
+     323             : 
+     324           1 :     std::string error_msg = "";
+     325           2 :     opt_pntrs_ = tls::get_pointers_labels<Optimizer*>(
+     326             :                    opt_labels,
+     327           1 :                    plumed.getActionSet(),
+     328             :                    error_msg
+     329             :                  );
+     330             : 
+     331           1 :     if (error_msg.size() > 0) {
+     332           0 :       plumed_merror(
+     333             :         "maze> Error in keyword OPTIMIZER of " + getName() + ": " + error_msg
+     334             :       );
+     335             :     }
+     336             : 
+     337           1 :     optimizer_ = opt_pntrs_[0];
+     338           1 :     log.printf(
+     339             :       "maze> Optimizer linked: %s.\n",
+     340           0 :       optimizer_->get_label().c_str()
+     341             :     );
+     342             : 
+     343           1 :     biasing_stride_=optimizer_->get_optimizer_stride();
+     344           1 :   }
+     345             : 
+     346           1 :   checkRead();
+     347             : 
+     348           2 :   addComponent("force2");
+     349           2 :   componentIsNotPeriodic("force2");
+     350             : 
+     351           2 :   addComponent("x");
+     352           2 :   componentIsNotPeriodic("x");
+     353             : 
+     354           2 :   addComponent("y");
+     355           2 :   componentIsNotPeriodic("y");
+     356             : 
+     357           2 :   addComponent("z");
+     358           2 :   componentIsNotPeriodic("z");
+     359             : 
+     360           2 :   addComponent("tdist");
+     361           1 :   componentIsNotPeriodic("tdist");
+     362             : 
+     363           1 :   biasing_direction_.zero();
+     364           1 :   cv0_.zero();
+     365             : 
+     366           1 :   value_bias_ = getPntrToComponent("bias");
+     367           1 :   value_force_ = getPntrToComponent("force2");
+     368             : 
+     369           1 :   value_dir_x_ = getPntrToComponent("x");
+     370           1 :   value_dir_y_ = getPntrToComponent("y");
+     371           1 :   value_dir_z_ = getPntrToComponent("z");
+     372             : 
+     373           1 :   value_total_distance_=getPntrToComponent("tdist");
+     374           1 : }
+     375             : 
+     376          30 : void OptimizerBias::calculate() {
+     377             :   // Unpack arguments and optimizers.
+     378             :   Vector cv(
+     379             :     args_[0]->get(),
+     380             :     args_[1]->get(),
+     381             :     args_[2]->get()
+     382          30 :   );
+     383             : 
+     384             :   Vector opt_direction(
+     385          30 :     optimizer_->value_x_->get(),
+     386          30 :     optimizer_->value_y_->get(),
+     387          30 :     optimizer_->value_z_->get()
+     388          30 :   );
+     389             : 
+     390          30 :   if (getStep() == 0) {
+     391           1 :     cv0_=cv;
+     392             :   }
+     393             : 
+     394             :   /*
+     395             :    * For details see a paper by Rydzewski and Valsson.
+     396             :    */
+     397          30 :   double dot = dotProduct(cv - cv0_, biasing_direction_);
+     398          30 :   double delta_cv = biasing_speed_ * getTime() - (dot + total_distance_);
+     399             : 
+     400          30 :   double sign = tls::sgn(delta_cv);
+     401             : 
+     402          30 :   bias_ = alpha_ * delta_cv * delta_cv;
+     403          30 :   force_ = 2.0 * sign * alpha_ * fabs(delta_cv);
+     404             : 
+     405          30 :   if (getStep() % biasing_stride_ == 0) {
+     406           3 :     biasing_direction_ = opt_direction;
+     407           3 :     cv0_ = cv;
+     408           3 :     total_distance_ += dot;
+     409             :   }
+     410             : 
+     411             :   /*
+     412             :    * Return the biasing force to MD engine.
+     413             :    */
+     414          30 :   setOutputForce(0, force_ * biasing_direction_[0]);
+     415          30 :   setOutputForce(1, force_ * biasing_direction_[1]);
+     416          30 :   setOutputForce(2, force_ * biasing_direction_[2]);
+     417             : 
+     418             :   /*
+     419             :    * Set values for PLUMED2 outputs.
+     420             :    */
+     421          30 :   value_bias_->set(bias_);
+     422          30 :   value_force_->set(force_);
+     423             : 
+     424          30 :   value_total_distance_->set(total_distance_);
+     425             : 
+     426          30 :   value_dir_x_->set(biasing_direction_[0]);
+     427          30 :   value_dir_y_->set(biasing_direction_[1]);
+     428          30 :   value_dir_z_->set(biasing_direction_[2]);
+     429          30 : }
+     430             : 
+     431             : } // namespace maze
+     432             : } // 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 000000000..3cb566f33 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d43bd7de6 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..87269ed35 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html @@ -0,0 +1,279 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_Acceleration_MD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Acceleration_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..1833e35ce --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd8next_intEii1
_ZN4PLMD4maze3rnd11next_cauchyEdd104
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd8next_intEi343
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1237
+
+
+ + + +
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 000000000..d18f653d8 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_cauchyEdd104
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1237
_ZN4PLMD4maze3rnd8next_intEi343
_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 000000000..77e9db04c --- /dev/null +++ b/coverage/maze/Random_MT.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-10-17 16:45:00Functions: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        1237 : std::mt19937_64& rnd::mt_eng() {
+      37        1244 :   static std::mt19937_64 mt{};
+      38             : 
+      39        1237 :   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         343 : int rnd::next_int(int e) {
+      59         343 :   static std::uniform_int_distribution<int> dist_int(0, e-1);
+      60         343 :   std::uniform_int_distribution<int>::param_type p(0, e-1);
+      61             :   dist_int.param(p);
+      62             : 
+      63         343 :   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         104 : double rnd::next_cauchy(double m, double s) {
+      75         104 :   static std::cauchy_distribution<double> dist_cauchy(m, s);
+      76             : 
+      77         104 :   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 000000000..0de29a9aa --- /dev/null +++ b/coverage/maze/Random_MT.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..98d2e6271 --- /dev/null +++ b/coverage/maze/Random_MT.h.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..20a77d8c4 --- /dev/null +++ b/coverage/maze/Random_MT.h.gcov.html @@ -0,0 +1,232 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..a8a5ffe65 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..bd33c8291 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c64283270 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_Walk.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Walk.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..2065047c5 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5c5cdb635 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..9e9800b19 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.gcov.html @@ -0,0 +1,351 @@ + + + + + + + LCOV - plumed test coverage - maze/Simulated_Annealing.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Simulated_Annealing.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434987.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..6f3008f1a --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..569ccffac --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c9569af2c --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + LCOV - plumed test coverage - maze/Steered_MD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Steered_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..ef5b22a95 --- /dev/null +++ b/coverage/maze/Tools.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - maze/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..23832eb49 --- /dev/null +++ b/coverage/maze/Tools.h.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - maze/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..888c4b58d --- /dev/null +++ b/coverage/maze/Tools.h.gcov.html @@ -0,0 +1,256 @@ + + + + + + + LCOV - plumed test coverage - maze/Tools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..5c3c3c04d --- /dev/null +++ b/coverage/maze/index-sort-f.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65376785.1 %
Date:2024-10-17 16:45:00Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Random_Acceleration_MD.cpp +
95.1%95.1%
+
95.1 %39 / 4175.0 %3 / 4
Random_Walk.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Memetic.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Loss.cpp +
100.0%
+
100.0 %24 / 2475.0 %3 / 4
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Steered_MD.cpp +
96.9%96.9%
+
96.9 %31 / 3275.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 %94 / 9683.3 %5 / 6
Optimizer.cpp +
89.9%89.9%
+
89.9 %161 / 17990.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 000000000..4f452ecb0 --- /dev/null +++ b/coverage/maze/index-sort-l.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65376785.1 %
Date:2024-10-17 16:45:00Functions: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 +
89.9%89.9%
+
89.9 %161 / 17990.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 %94 / 9683.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 %24 / 2475.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 000000000..e6765fa09 --- /dev/null +++ b/coverage/maze/index.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65376785.1 %
Date:2024-10-17 16:45:00Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.cpp +
100.0%
+
100.0 %24 / 2475.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 +
89.9%89.9%
+
89.9 %161 / 17990.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Optimizer_Bias.cpp +
97.9%97.9%
+
97.9 %94 / 9683.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 000000000..aa4d41a97 --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13815887.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..47f2f74e3 --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13815887.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..34815b488 --- /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:13815887.3 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the CV");
+     106           3 : }
+     107             : 
+     108           1 : fusionPoreExpansionP::fusionPoreExpansionP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     109             : {
+     110           2 :   parseAtomList("UMEMBRANE", UMEM);
+     111           1 :   if (UMEM.size() == 0)
+     112           0 :     error("UMEMBRANE has not any atom specified.");
+     113             : 
+     114           2 :   parseAtomList("LMEMBRANE", LMEM);
+     115           1 :   if (LMEM.size() == 0)
+     116           0 :     error("LMEMBRANE has not any atom specified.");
+     117             : 
+     118           2 :   parseAtomList("TAILS", TAILS);
+     119           1 :   if (TAILS.size() == 0)
+     120           0 :     error("TAILS has not any atom specified.");
+     121             : 
+     122           2 :   parseAtomList("WATERS", WATERS);
+     123           1 :   if (WATERS.size() == 0)
+     124           0 :     error("WATERS has not any atom specified.");
+     125             : 
+     126           2 :   parseAtomList("PHOSPHATEOXYGENS", POXYGENS);
+     127           1 :   if (POXYGENS.size() == 0)
+     128           0 :     error("PHOSPHATEOXYGENS has not any atom specified.");
+     129             : 
+     130           2 :   parseVector("NSMEM", NSMEM);
+     131           1 :   if (NSMEM.size() > 1)
+     132           0 :     error("NSMEM cannot take more than one value.");
+     133             : 
+     134           2 :   parseVector("DSMEM", DSMEM);
+     135           1 :   if (DSMEM.size() > 1)
+     136           0 :     error("DSMEM cannot take more than one value.");
+     137           1 :   if (DSMEM.size() == 0)
+     138           0 :     DSMEM.push_back(0.1);
+     139             : 
+     140           2 :   parseVector("HMEM", HMEM);
+     141           1 :   if (HMEM.size() > 1)
+     142           0 :     error("HMEM cannot take more than one value.");
+     143           1 :   if (HMEM.size() == 0)
+     144           0 :     HMEM.push_back(0.25);
+     145             : 
+     146           2 :   parseVector("VO", VO);
+     147           1 :   if (VO.size() > 1)
+     148           0 :     error("VO cannot take more than one value.");
+     149           1 :   if (VO.size() == 0)
+     150           0 :     VO.push_back(0.076879);
+     151             : 
+     152           2 :   parseVector("D", D);
+     153           1 :   if (D.size() > 1)
+     154           0 :     error("D cannot take more than one value.");
+     155             : 
+     156           2 :   parseVector("H", H);
+     157           1 :   if (H.size() > 1)
+     158           0 :     error("H cannot take more than one value.");
+     159           1 :   if (H.size() == 0)
+     160           0 :     H.push_back(0.1);
+     161             : 
+     162           2 :   parseVector("RMAX", RMAX);
+     163           1 :   if (RMAX.size() > 1)
+     164           0 :     error("RMAX cannot take more than one value.");
+     165           1 :   if (RMAX.size() == 0)
+     166           0 :     RMAX.push_back(2.5);
+     167             : 
+     168           2 :   parseVector("R0", R0);
+     169           1 :   if (R0.size() > 1)
+     170           0 :     error("R0 cannot take more than one value.");
+     171             : 
+     172           2 :   parseVector("XCYL", XCYL);
+     173           1 :   if (XCYL.size() > 1)
+     174           0 :     error("XCYL cannot take more than one value.");
+     175           1 :   if (XCYL.size() == 0)
+     176           1 :     XCYL.push_back(-1.0);
+     177             : 
+     178           2 :   parseVector("YCYL", YCYL);
+     179           1 :   if (YCYL.size() > 1)
+     180           0 :     error("YCYL cannot take more than one value.");
+     181           1 :   if (YCYL.size() == 0)
+     182           1 :     YCYL.push_back(-1.0);
+     183             : 
+     184           1 :   checkRead();
+     185             : 
+     186             :   std::vector<AtomNumber> atoms;
+     187       12445 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     188             :   {
+     189       12444 :     atoms.push_back(UMEM[i]);
+     190             :   }
+     191       12445 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     192             :   {
+     193       12444 :     atoms.push_back(LMEM[i]);
+     194             :   }
+     195        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     196             :   {
+     197        4096 :     atoms.push_back(TAILS[i]);
+     198             :   }
+     199       31800 :   for (unsigned i = 0; i < WATERS.size(); i++)
+     200             :   {
+     201       31799 :     atoms.push_back(WATERS[i]);
+     202             :   }
+     203        2049 :   for (unsigned i = 0; i < POXYGENS.size(); i++)
+     204             :   {
+     205        2048 :     atoms.push_back(POXYGENS[i]);
+     206             :   }
+     207             : 
+     208           1 :   addValueWithDerivatives();
+     209           1 :   setNotPeriodic();
+     210           1 :   requestAtoms(atoms);
+     211           1 : }
+     212           4 : void fusionPoreExpansionP::calculate()
+     213             : {
+     214             :   /*************************
+     215             :   *                        *
+     216             :   *         System         *
+     217             :   *                        *
+     218             :   **************************/
+     219             : 
+     220             :   // Box dimensions.
+     221           4 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     222             : 
+     223             :   // 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 .
+     224             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     225             : 
+     226             : #ifdef _OPENMP
+     227             : #if _OPENMP >= 201307
+     228           4 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     229             : #endif
+     230             : #endif
+     231             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     232             :   {
+     233             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     234             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     235             :     ZuMemcos += cos(uMemAngle);
+     236             :     ZuMemsin += sin(uMemAngle);
+     237             :     ZlMemcos += cos(lMemAngle);
+     238             :     ZlMemsin += sin(lMemAngle);
+     239             :   }
+     240           4 :   ZuMemcos = ZuMemcos / UMEM.size();
+     241           4 :   ZuMemsin = ZuMemsin / UMEM.size();
+     242           4 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     243           4 :   ZlMemcos = ZlMemcos / UMEM.size();
+     244           4 :   ZlMemsin = ZlMemsin / UMEM.size();
+     245           4 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     246             : 
+     247             :   // Z center of the boths membranes (upper and lower).
+     248           4 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     249             : 
+     250             :   /**************************
+     251             :   *                         *
+     252             :   *   Xcyl_Mem & Ycyl_Mem   *
+     253             :   *                         *
+     254             :   ***************************/
+     255             : 
+     256             :   // Quantity of beads of the membranes.
+     257           4 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     258             : 
+     259             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     260             :   double ZTailDistance;
+     261             : 
+     262             :   // Z position of the first slice.
+     263           4 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     264             : 
+     265             :   // Z distance between the first slice and the Z center of the membrane.
+     266           8 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     267             : 
+     268             :   // Position in the cylinder.
+     269             :   double PositionS_Mem;
+     270             : 
+     271             :   // Slices to analyze per particle.
+     272             :   unsigned s1_Mem, s2_Mem;
+     273             : 
+     274             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     275           4 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     276             : 
+     277             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     278           4 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     279             : 
+     280             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     281           4 :   std::vector<double> ws_Mem(NSMEM[0]);
+     282             : 
+     283             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     284             :   double W_Mem = 0.0;
+     285             : 
+     286             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     287           4 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     288             : 
+     289             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     290             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     291             : 
+     292             :   // Aux.
+     293             :   double x, aux;
+     294             : 
+     295             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     296           4 :   Vector TailPosition;
+     297             : 
+     298             : #ifdef _OPENMP
+     299             : #if _OPENMP >= 201307
+     300             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     301             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     302             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     303             : #endif
+     304             : #endif
+     305             : 
+     306             : #ifdef _OPENMP
+     307             : #if _OPENMP >= 201307
+     308           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)
+     309             : #endif
+     310             : #endif
+     311             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     312             :   {
+     313             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     314             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     315             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     316             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     317             :     {
+     318             :       //Defining the slices to analyze each particle.
+     319             :       if (PositionS_Mem < 1)
+     320             :       {
+     321             :         s1_Mem = 0;
+     322             :         s2_Mem = 2;
+     323             :       }
+     324             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     325             :       {
+     326             :         s1_Mem = floor(PositionS_Mem) - 1;
+     327             :         s2_Mem = floor(PositionS_Mem) + 1;
+     328             :       }
+     329             :       else
+     330             :       {
+     331             :         s1_Mem = NSMEM[0] - 3;
+     332             :         s2_Mem = NSMEM[0] - 1;
+     333             :       }
+     334             : 
+     335             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     336             : 
+     337             :       for (unsigned s = s1_Mem; s <= s2_Mem; s++)
+     338             :       {
+     339             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     340             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     341             :         {
+     342             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     343             :           {
+     344             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     345             :             Fs_Mem[s] += 1.0;
+     346             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     347             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     348             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     349             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     350             :           }
+     351             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     352             :           {
+     353             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     354             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     355             :             Fs_Mem[s] += aux;
+     356             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     357             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     358             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     359             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     360             :           }
+     361             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     362             :           {
+     363             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     364             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     365             :             Fs_Mem[s] += aux;
+     366             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     367             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     368             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     369             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     370             :           }
+     371             :         }
+     372             :       }
+     373             :     }
+     374             :   }
+     375             : 
+     376         344 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     377             :   {
+     378         340 :     if (Fs_Mem[s] != 0.0)
+     379             :     {
+     380         340 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     381         340 :       W_Mem += ws_Mem[s];
+     382         340 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     383         340 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     384         340 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     385         340 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     386         340 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     387         340 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     388         340 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     389         340 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     390             :     }
+     391             :   }
+     392             : 
+     393           4 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     394           4 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     395           4 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     396           4 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     397             : 
+     398             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     399             :   double Xcyl_Mem, Ycyl_Mem;
+     400             : 
+     401           4 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     402             :   {
+     403             :     Xcyl_Mem = XCYL[0];
+     404             :     Ycyl_Mem = YCYL[0];
+     405             :   }
+     406             :   else
+     407             :   {
+     408           4 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     409           4 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     410             :   }
+     411             : 
+     412             :   /*************************
+     413             :   *                        *
+     414             :   *         Xi_Exp         *
+     415             :   *                        *
+     416             :   **************************/
+     417             : 
+     418             :   // Quantity of beads that could participate in the calculation of the Xi_Chain
+     419           4 :   unsigned chainBeads = WATERS.size() + POXYGENS.size();
+     420             : 
+     421             :   // Quantity of beads that don't participate in the calculation of the Xi_Chain
+     422           4 :   unsigned noChainBeads = (UMEM.size() * 2) + TAILS.size();
+     423             : 
+     424             :   // Center of the cylinder. X and Y are calculated (or defined), Z is the Z component of the geometric center of the membranes.
+     425           8 :   Vector xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     426             : 
+     427             :   // Estimation of RO with the Hub 2021 JCTC method. Only needed for the expansion.
+     428           4 :   double RO = R0[0];
+     429             : 
+     430             :   // Number of polar atoms inside the horizontal layer. Eq. 3 Hub 2021 JCTC.
+     431             :   double np = 0.0, fz, fr, fz_prime, fr_prime;
+     432             : 
+     433             :   // Derivative of np. Eq. 8 Hub 2021 JCTC.
+     434           4 :   std::vector<double> d_np_dx(chainBeads), d_np_dy(chainBeads), d_np_dz(chainBeads);
+     435             : 
+     436             :   // Pore radius of the defect. Eq. 2 Hub 2021 JCTC.
+     437             :   double poreR = 1.0;
+     438             : 
+     439             :   // Z center of the Membrane in the RMAX radius.
+     440             :   double ZMemRMAX, ZMemRMAXcos = 0.0, ZMemRMAXsin = 0.0, countAux = 0.0, auxcos, auxsin;
+     441             : 
+     442             :   ZMemRMAX = ZMems;
+     443             : 
+     444             :   // The curvature of large membranes (1024 lipids) makes the Z-center of the membranes not to be representative
+     445             :   // in some sectors, particularly in the region of ​​the defect.
+     446             :   //
+     447             :   // To solve this, the center Z of the membranes in the defect sector is calculated and used to calculate
+     448             :   // the number of polar atoms within the horizontal layer AND in the radious of the defect.
+     449             :   //
+     450             :   // ________       | |       ________
+     451             :   // ________ \_____| |______/ _______<-- Top membrane.
+     452             :   //         \______|P|_______/
+     453             :   //                |O|
+     454             :   //                | |               <-- Z-center of the membranes in the region of the defect.
+     455             :   //          ______|R|_______        <-- Z-center of the membranes
+     456             :   //         / _____|E|______ \ 
+     457             :   //        / /     | |      \ \ 
+     458             :   // ______/ /      | |       \ \______
+     459             :   // _______/                  \_______<-- Bottom membrane.
+     460             : 
+     461             :   // Center of mass for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions
+     462           4 :   Vector MemCylDistances, distCylinder;
+     463             :   double angle, ri;
+     464             : 
+     465             : #ifdef _OPENMP
+     466             : #if _OPENMP >= 201307
+     467           4 :   #pragma omp parallel for private(MemCylDistances, x, angle, auxcos, auxsin) reduction(+:ZMemRMAXcos, ZMemRMAXsin, countAux)
+     468             : #endif
+     469             : #endif
+     470             :   for (unsigned i = 0; i < membraneBeads; i++)
+     471             : {
+     472             :   MemCylDistances = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)));
+     473             :     x = sqrt(pow(MemCylDistances[0], 2) + pow(MemCylDistances[1], 2)) / RMAX[0];
+     474             :     if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     475             :     {
+     476             :       angle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     477             :       auxcos = cos(angle);
+     478             :       auxsin = sin(angle);
+     479             :       if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     480             :       {
+     481             :         ZMemRMAXcos += 1.0 * auxcos;
+     482             :         ZMemRMAXsin += 1.0 * auxsin;
+     483             :         countAux += 1.0;
+     484             :       }
+     485             :       else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     486             :       {
+     487             :         ZMemRMAXcos += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3)) * auxcos;
+     488             :         ZMemRMAXsin += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3)) * auxsin;
+     489             :         countAux += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3));
+     490             :       }
+     491             :       else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     492             :       {
+     493             :         ZMemRMAXcos += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3)) * auxcos;
+     494             :         ZMemRMAXsin += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3)) * auxsin;
+     495             :         countAux += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3));
+     496             :       }
+     497             :     }
+     498             :   }
+     499             : 
+     500           4 :   ZMemRMAXcos = ZMemRMAXcos / countAux;
+     501           4 :   ZMemRMAXsin = ZMemRMAXsin / countAux;
+     502           4 :   ZMemRMAX = Lz * (atan2(-ZMemRMAXsin, -ZMemRMAXcos) + M_PI) / (2.0 * M_PI);
+     503             : 
+     504           4 :   xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMemRMAX));
+     505             : 
+     506             : #ifdef _OPENMP
+     507             : #if _OPENMP >= 201307
+     508           4 :   #pragma omp parallel for private(distCylinder, fz, fz_prime, fr, fr_prime, ri, x) reduction(+:np)
+     509             : #endif
+     510             : #endif
+     511             :   for (unsigned i = 0; i < chainBeads; i++)
+     512             : {
+     513             :   distCylinder = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     514             :     fz = 0.0;
+     515             :     fz_prime = 0.0;
+     516             :     fr = 0.0;
+     517             :     fr_prime = 0.0;
+     518             : 
+     519             :     ri = sqrt(pow(distCylinder[0], 2) + pow(distCylinder[1], 2));
+     520             :     x = ri / RMAX[0];
+     521             :     if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     522             :     {
+     523             :       if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     524             :       {
+     525             :         fr = 1.0;
+     526             :       }
+     527             :       else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     528             :       {
+     529             :         fr = 0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3);
+     530             :         fr_prime = (-0.75 / H[0] + 0.75 * pow((x - 1.0), 2) / pow(H[0], 3)) / (RMAX[0] * ri);
+     531             :       }
+     532             :       else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     533             :       {
+     534             :         fr = 0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3);
+     535             :         fr_prime = (0.75 / H[0] - 0.75 * pow((x + 1), 2) / pow(H[0], 3)) / (RMAX[0] * ri);
+     536             :       }
+     537             : 
+     538             :       x = distCylinder[2] * 2.0 / D[0];
+     539             :       if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     540             :       {
+     541             :         if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     542             :         {
+     543             :           fz = 1.0;
+     544             :         }
+     545             :         else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     546             :         {
+     547             :           fz = 0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3);
+     548             :           fz_prime = (-0.75 / H[0] + 0.75 * pow((x - 1.0), 2) / pow(H[0], 3)) * 2.0 / D[0];
+     549             :         }
+     550             :         else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     551             :         {
+     552             :           fz = 0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3);
+     553             :           fz_prime = (0.75 / H[0] - 0.75 * pow((x + 1), 2) / pow(H[0], 3)) * 2.0 / D[0];
+     554             :         }
+     555             : 
+     556             :         np += fz * fr;
+     557             :         d_np_dx[i] = fz * fr_prime * distCylinder[0];
+     558             :         d_np_dy[i] = fz * fr_prime * distCylinder[1];
+     559             :         d_np_dz[i] = fz_prime * fr;
+     560             :       }
+     561             :     }
+     562             :   }
+     563           4 :   poreR = sqrt(np * VO[0] / (M_PI * D[0]));
+     564             : 
+     565             :   // This is the CV that describes the Pore Expansion.
+     566           4 :   double Xi_Exp = (poreR - RO) / RO;
+     567             : 
+     568             :   // Derivatives vector.
+     569           4 :   std::vector<Vector> derivatives(chainBeads);
+     570             : 
+     571             :   // Aux for the derivatives calculations. Eq. 7 Hub 2021 JCTC.
+     572             :   double fact2 = 0.0;
+     573             : 
+     574           4 :   if (poreR != 0.0)
+     575             : {
+     576           4 :   fact2 = VO[0] / (2.0 * M_PI * RO * D[0] * poreR);
+     577             :   }
+     578             : 
+     579             :   // Distances from the oxygens to center of the cylinder.
+     580           4 :   std::vector<Vector> CylDistances(chainBeads);
+     581             : 
+     582             : #ifdef _OPENMP
+     583             : #if _OPENMP >= 201307
+     584           4 :   #pragma omp parallel for
+     585             : #endif
+     586             : #endif
+     587             :   for (unsigned i = 0; i < chainBeads; i++)
+     588             : {
+     589             :   derivatives[i][0] = fact2 * d_np_dx[i];
+     590             :     derivatives[i][1] = fact2 * d_np_dy[i];
+     591             :     derivatives[i][2] = fact2 * d_np_dz[i];
+     592             :     CylDistances[i] = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     593             :   }
+     594             : 
+     595           4 :   Tensor virial;
+     596      135392 :   for (unsigned i = 0; i < chainBeads; i++)
+     597             : {
+     598      135388 :   setAtomsDerivatives((i + noChainBeads), derivatives[i]);
+     599      135388 :     virial -= Tensor(CylDistances[i], derivatives[i]);
+     600             :   }
+     601             : 
+     602           4 :   setValue(Xi_Exp);
+     603           4 :   setBoxDerivatives(virial);
+     604           4 : }
+     605             : }
+     606             : }
+
+
+
+ + + + +
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 000000000..b0ded61d8 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18420888.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..9da7fe6a0 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18420888.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..cbb8e9375 --- /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:18420888.5 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the CV");
+     110           3 : }
+     111             : 
+     112           1 : fusionPoreNucleationP::fusionPoreNucleationP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     113             : {
+     114           2 :   parseAtomList("UMEMBRANE", UMEM);
+     115           1 :   if (UMEM.size() == 0)
+     116           0 :     error("UMEMBRANE has not any atom specified.");
+     117             : 
+     118           2 :   parseAtomList("LMEMBRANE", LMEM);
+     119           1 :   if (LMEM.size() == 0)
+     120           0 :     error("LMEMBRANE has not any atom specified.");
+     121             : 
+     122           2 :   parseAtomList("TAILS", TAILS);
+     123           1 :   if (TAILS.size() == 0)
+     124           0 :     error("TAILS has not any atom specified.");
+     125             : 
+     126           2 :   parseAtomList("WATERS", WATERS);
+     127           1 :   if (WATERS.size() == 0)
+     128           0 :     error("WATERS has not any atom specified.");
+     129             : 
+     130           2 :   parseAtomList("PHOSPHATEOXYGENS", POXYGENS);
+     131           1 :   if (POXYGENS.size() == 0)
+     132           0 :     error("PHOSPHATEOXYGENS has not any atom specified.");
+     133             : 
+     134           2 :   parseVector("NSMEM", NSMEM);
+     135           1 :   if (NSMEM.size() > 1)
+     136           0 :     error("NSMEM cannot take more than one value.");
+     137             : 
+     138           2 :   parseVector("DSMEM", DSMEM);
+     139           1 :   if (DSMEM.size() > 1)
+     140           0 :     error("DSMEM cannot take more than one value.");
+     141           1 :   if (DSMEM.size() == 0)
+     142           0 :     DSMEM.push_back(0.1);
+     143             : 
+     144           2 :   parseVector("HMEM", HMEM);
+     145           1 :   if (HMEM.size() > 1)
+     146           0 :     error("HMEM cannot take more than one value.");
+     147           1 :   if (HMEM.size() == 0)
+     148           0 :     HMEM.push_back(0.25);
+     149             : 
+     150           2 :   parseVector("NS", NS);
+     151           1 :   if (NS.size() > 1)
+     152           0 :     error("NS cannot take more than one value.");
+     153             : 
+     154           2 :   parseVector("DS", DS);
+     155           1 :   if (DS.size() > 1)
+     156           0 :     error("DS cannot take more than one value.");
+     157           1 :   if (DS.size() == 0)
+     158           0 :     DS.push_back(0.25);
+     159             : 
+     160           2 :   parseVector("HCH", HCH);
+     161           1 :   if (HCH.size() > 1)
+     162           0 :     error("H cannot take more than one value.");
+     163           1 :   if (HCH.size() == 0)
+     164           0 :     HCH.push_back(0.25);
+     165             : 
+     166           2 :   parseVector("RCYL", RCYL);
+     167           1 :   if (RCYL.size() > 1)
+     168           0 :     error("RCYL cannot take more than one value.");
+     169           1 :   if (RCYL.size() == 0)
+     170           0 :     RCYL.push_back(0.8);
+     171             : 
+     172           2 :   parseVector("ZETA", ZETA);
+     173           1 :   if (ZETA.size() > 1)
+     174           0 :     error("ZETA cannot take more than one value.");
+     175           1 :   if (ZETA.size() == 0)
+     176           0 :     ZETA.push_back(0.75);
+     177             : 
+     178           2 :   parseVector("ONEOVERS2C2CUTOFF", ONEOVERS2C2CUTOFF);
+     179           1 :   if (ONEOVERS2C2CUTOFF.size() > 1)
+     180           0 :     error("ONEOVERS2C2CUTOFF cannot take more than one value.");
+     181           1 :   if (ONEOVERS2C2CUTOFF.size() == 0)
+     182           1 :     ONEOVERS2C2CUTOFF.push_back(500);
+     183             : 
+     184           2 :   parseVector("XCYL", XCYL);
+     185           1 :   if (XCYL.size() > 1)
+     186           0 :     error("XCYL cannot take more than one value.");
+     187           1 :   if (XCYL.size() == 0)
+     188           1 :     XCYL.push_back(-1.0);
+     189             : 
+     190           2 :   parseVector("YCYL", YCYL);
+     191           1 :   if (YCYL.size() > 1)
+     192           0 :     error("YCYL cannot take more than one value.");
+     193           1 :   if (YCYL.size() == 0)
+     194           1 :     YCYL.push_back(-1.0);
+     195             : 
+     196           1 :   checkRead();
+     197             : 
+     198             :   std::vector<AtomNumber> atoms;
+     199       12445 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     200             :   {
+     201       12444 :     atoms.push_back(UMEM[i]);
+     202             :   }
+     203       12445 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     204             :   {
+     205       12444 :     atoms.push_back(LMEM[i]);
+     206             :   }
+     207        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     208             :   {
+     209        4096 :     atoms.push_back(TAILS[i]);
+     210             :   }
+     211       31603 :   for (unsigned i = 0; i < WATERS.size(); i++)
+     212             :   {
+     213       31602 :     atoms.push_back(WATERS[i]);
+     214             :   }
+     215        2049 :   for (unsigned i = 0; i < POXYGENS.size(); i++)
+     216             :   {
+     217        2048 :     atoms.push_back(POXYGENS[i]);
+     218             :   }
+     219             : 
+     220           1 :   addValueWithDerivatives();
+     221           1 :   setNotPeriodic();
+     222           1 :   requestAtoms(atoms);
+     223           1 : }
+     224             : 
+     225           4 : void fusionPoreNucleationP::calculate()
+     226             : {
+     227             :   /*************************
+     228             :   *                        *
+     229             :   *         System         *
+     230             :   *                        *
+     231             :   **************************/
+     232             : 
+     233             :   // Box dimensions.
+     234           4 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     235             : 
+     236             :   // 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 .
+     237             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     238             : 
+     239             : #ifdef _OPENMP
+     240             : #if _OPENMP >= 201307
+     241           4 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     242             : #endif
+     243             : #endif
+     244             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     245             :   {
+     246             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     247             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     248             :     ZuMemcos += cos(uMemAngle);
+     249             :     ZuMemsin += sin(uMemAngle);
+     250             :     ZlMemcos += cos(lMemAngle);
+     251             :     ZlMemsin += sin(lMemAngle);
+     252             :   }
+     253           4 :   ZuMemcos = ZuMemcos / UMEM.size();
+     254           4 :   ZuMemsin = ZuMemsin / UMEM.size();
+     255           4 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     256           4 :   ZlMemcos = ZlMemcos / UMEM.size();
+     257           4 :   ZlMemsin = ZlMemsin / UMEM.size();
+     258           4 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     259             : 
+     260             :   // Z center of the boths membranes (upper and lower).
+     261           4 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     262             : 
+     263             :   /**************************
+     264             :   *                         *
+     265             :   *   Xcyl_Mem & Ycyl_Mem   *
+     266             :   *                         *
+     267             :   ***************************/
+     268             : 
+     269             :   // Quantity of beads of the membranes.
+     270           4 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     271             : 
+     272             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     273             :   double ZTailDistance;
+     274             : 
+     275             :   // Z position of the first slice.
+     276           4 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     277             : 
+     278             :   // Z distance between the first slice and the Z center of the membrane.
+     279           8 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     280             : 
+     281             :   // Position in the cylinder.
+     282             :   double PositionS_Mem;
+     283             : 
+     284             :   // Slices to analyze per particle.
+     285             :   unsigned s1_Mem, s2_Mem;
+     286             : 
+     287             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     288           4 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     289             : 
+     290             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     291           4 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     292             : 
+     293             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     294           4 :   std::vector<double> ws_Mem(NSMEM[0]);
+     295             : 
+     296             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     297             :   double W_Mem = 0.0;
+     298             : 
+     299             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     300           4 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     301             : 
+     302             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     303             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     304             : 
+     305             :   // Aux.
+     306             :   double x, aux;
+     307             : 
+     308             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     309           4 :   Vector TailPosition;
+     310             : 
+     311             : #ifdef _OPENMP
+     312             : #if _OPENMP >= 201307
+     313             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     314             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     315             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     316             : #endif
+     317             : #endif
+     318             : 
+     319             : #ifdef _OPENMP
+     320             : #if _OPENMP >= 201307
+     321           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)
+     322             : #endif
+     323             : #endif
+     324             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     325             :   {
+     326             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     327             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     328             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     329             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     330             :     {
+     331             :       //Defining the slices to analyze each particle.
+     332             :       if (PositionS_Mem < 1)
+     333             :       {
+     334             :         s1_Mem = 0;
+     335             :         s2_Mem = 2;
+     336             :       }
+     337             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     338             :       {
+     339             :         s1_Mem = floor(PositionS_Mem) - 1;
+     340             :         s2_Mem = floor(PositionS_Mem) + 1;
+     341             :       }
+     342             :       else
+     343             :       {
+     344             :         s1_Mem = NSMEM[0] - 3;
+     345             :         s2_Mem = NSMEM[0] - 1;
+     346             :       }
+     347             : 
+     348             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     349             : 
+     350             :       for (unsigned s = s1_Mem; s <= s2_Mem; s++)
+     351             :       {
+     352             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     353             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     354             :         {
+     355             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     356             :           {
+     357             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     358             :             Fs_Mem[s] += 1.0;
+     359             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     360             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     361             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     362             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     363             :           }
+     364             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     365             :           {
+     366             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     367             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     368             :             Fs_Mem[s] += aux;
+     369             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     370             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     371             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     372             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     373             :           }
+     374             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     375             :           {
+     376             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     377             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     378             :             Fs_Mem[s] += aux;
+     379             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     380             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     381             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     382             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     383             :           }
+     384             :         }
+     385             :       }
+     386             :     }
+     387             :   }
+     388             : 
+     389         344 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     390             :   {
+     391         340 :     if (Fs_Mem[s] != 0.0)
+     392             :     {
+     393         339 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     394         339 :       W_Mem += ws_Mem[s];
+     395         339 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     396         339 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     397         339 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     398         339 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     399         339 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     400         339 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     401         339 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     402         339 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     403             :     }
+     404             :   }
+     405             : 
+     406           4 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     407           4 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     408           4 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     409           4 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     410             : 
+     411             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     412             :   double Xcyl_Mem, Ycyl_Mem;
+     413             : 
+     414           4 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     415             :   {
+     416             :     Xcyl_Mem = XCYL[0];
+     417             :     Ycyl_Mem = YCYL[0];
+     418             :   }
+     419             :   else
+     420             :   {
+     421           4 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     422           4 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     423             :   }
+     424             : 
+     425             :   /*************************
+     426             :   *                        *
+     427             :   *        Xi_n            *
+     428             :   *                        *
+     429             :   **************************/
+     430             : 
+     431             :   // Eq. 1 Hub & Awasthi JCTC 2017. This is the CV that describes de Pore Nucleation.
+     432           4 :   double Xi_n = 0.0;
+     433             : 
+     434             :   // Quantity of beads that could participate in the calculation of the Xi_Chain
+     435           4 :   unsigned chainBeads = WATERS.size() + POXYGENS.size();
+     436             : 
+     437             :   // Quantity of beads that don't participate in the calculation of the Xi_Chain
+     438           4 :   unsigned noChainBeads = (UMEM.size() * 2) + TAILS.size();
+     439             : 
+     440             :   // Z Distances from the oxygens to the geometric center of the membranes.
+     441             :   double ZMemDistance;
+     442             : 
+     443             :   // Scaled positions of the oxygens to respect of the origin of coordinates.
+     444           4 :   Vector Position;
+     445             : 
+     446             :   // Distance from the water/phosphate group to the defect cylinder.
+     447           4 :   Vector distCylinder;
+     448             : 
+     449             :   // Center of the cylinder. XY components are calculated (or defined), Z is the Z geometric center of the membranes of the system.
+     450           8 :   Vector xyzCyl_Mem = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     451             : 
+     452             :   // Average of the radius of the water and lipid cylinder.
+     453           4 :   double RCYLAVERAGE = RCYL[0] * (1 + HCH[0]);
+     454             : 
+     455             :   // Conditions.
+     456             :   bool condition1, condition2, condition3;
+     457             : 
+     458             :   // Z position of the first slice.
+     459           4 :   double firstSliceZ = ZMems + (0.0 + 0.5 - NS[0] / 2.0) * DS[0];
+     460             : 
+     461             :   // Z distance between the first slice and the Z center of the membrane.
+     462           4 :   double firstSliceZDist = pbcDistance(Vector(0.0, 0.0, firstSliceZ), Vector(0.0, 0.0, ZMems))[2];
+     463             : 
+     464             :   // Position in the cylinder.
+     465             :   double PositionS;
+     466             : 
+     467             :   // Mark the particles to analyze.
+     468           4 :   std::vector<double> analyzeThisParticle(chainBeads);
+     469             : 
+     470             :   // Slices to analyze per particle.
+     471           4 :   std::vector<unsigned> s1(chainBeads), s2(chainBeads);
+     472             : 
+     473             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     474           4 :   std::vector<double> faxial(chainBeads * NS[0]);
+     475             : 
+     476             :   // Eq. 16 Hub & Awasthi JCTC 2017.
+     477           4 :   std::vector<double> d_faxial_dz(chainBeads * NS[0]);
+     478             : 
+     479             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     480           4 :   std::vector<double> Fs(NS[0]);
+     481             : 
+     482             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     483           4 :   std::vector<double> ws(NS[0]);
+     484             : 
+     485             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     486             :   double W = 0.0;
+     487             : 
+     488             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     489           4 :   std::vector<double> sx(NS[0]), sy(NS[0]), cx(NS[0]), cy(NS[0]);
+     490             : 
+     491             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     492             :   double Xsc = 0.0, Xcc = 0.0, Ysc = 0.0, Ycc = 0.0;
+     493             : 
+     494             : #ifdef _OPENMP
+     495             : #if _OPENMP >= 201307
+     496           4 :   #pragma omp parallel for private(distCylinder, aux, condition1, condition2, condition3, ZMemDistance, PositionS, Position, x) reduction(vec_double_plus:Fs, sx, sy, cx, cy)
+     497             : #endif
+     498             : #endif
+     499             :   for (unsigned i = 0; i < chainBeads; i++)
+     500             : {
+     501             :   distCylinder = pbcDistance(xyzCyl_Mem, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     502             :     aux = sqrt(pow(distCylinder[0], 2) + pow(distCylinder[1], 2));
+     503             :     condition1 = ((aux / RCYLAVERAGE) < 1.0);
+     504             :     condition2 = ((pbcDistance(Vector(0.0, 0.0, ZuMem), getPosition(i + noChainBeads))[2] > 0) && (aux / RCYLAVERAGE) < 2.0);
+     505             :     condition3 = ((pbcDistance(getPosition(i + noChainBeads), Vector(0.0, 0.0, ZlMem))[2] > 0) && (aux / RCYLAVERAGE) < 2.0);
+     506             :     if (condition1 || condition2 || condition3)
+     507             :     {
+     508             :       ZMemDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + noChainBeads))[2];
+     509             :       PositionS = (ZMemDistance + firstSliceZDist) / DS[0];
+     510             :       // If the following condition is met the particle is in the Z space of the cylinder.
+     511             :       if ((PositionS >= (-0.5 - HCH[0])) && (PositionS <= (NS[0] + 0.5 - 1.0 + HCH[0])))
+     512             :       {
+     513             :         analyzeThisParticle[i] = 1.0;
+     514             : 
+     515             :         //Defining the slices to analyze each particle.
+     516             :         if (PositionS < 1)
+     517             :         {
+     518             :           s1[i] = 0;
+     519             :           s2[i] = 2;
+     520             :         }
+     521             :         else if (PositionS <= (NS[0] - 2.0))
+     522             :         {
+     523             :           s1[i] = floor(PositionS) - 1;
+     524             :           s2[i] = floor(PositionS) + 1;
+     525             :         }
+     526             :         else
+     527             :         {
+     528             :           s1[i] = NS[0] - 3;
+     529             :           s2[i] = NS[0] - 1;
+     530             :         }
+     531             : 
+     532             :         Position = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     533             : 
+     534             :         for (unsigned s = s1[i]; s <= s2[i]; s++)
+     535             :         {
+     536             :           x = (ZMemDistance - (s + 0.5 - NS[0] / 2.0) * DS[0]) * 2.0 / DS[0];
+     537             :           if (!((x <= -1.0 - HCH[0]) || (x >= 1.0 + HCH[0])))
+     538             :           {
+     539             :             if (((-1.0 + HCH[0]) <= x) && (x <= (1.0 - HCH[0])))
+     540             :             {
+     541             :               faxial[i + chainBeads * s] = 1.0;
+     542             :               Fs[s] += 1.0;
+     543             :               sx[s] += sin(2.0 * M_PI * Position[0]);
+     544             :               sy[s] += sin(2.0 * M_PI * Position[1]);
+     545             :               cx[s] += cos(2.0 * M_PI * Position[0]);
+     546             :               cy[s] += cos(2.0 * M_PI * Position[1]);
+     547             :             }
+     548             :             else if (((1.0 - HCH[0]) < x) && (x < (1.0 + HCH[0])))
+     549             :             {
+     550             :               aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HCH[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     551             :               faxial[i + chainBeads * s] = aux;
+     552             :               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];
+     553             :               Fs[s] += aux;
+     554             :               sx[s] += aux * sin(2.0 * M_PI * Position[0]);
+     555             :               sy[s] += aux * sin(2.0 * M_PI * Position[1]);
+     556             :               cx[s] += aux * cos(2.0 * M_PI * Position[0]);
+     557             :               cy[s] += aux * cos(2.0 * M_PI * Position[1]);
+     558             :             }
+     559             :             else if (((-1.0 - HCH[0]) < x) && (x < (-1.0 + HCH[0])))
+     560             :             {
+     561             :               aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HCH[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     562             :               faxial[i + chainBeads * s] = aux;
+     563             :               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];
+     564             :               Fs[s] += aux;
+     565             :               sx[s] += (aux * sin(2.0 * M_PI * Position[0]));
+     566             :               sy[s] += (aux * sin(2.0 * M_PI * Position[1]));
+     567             :               cx[s] += (aux * cos(2.0 * M_PI * Position[0]));
+     568             :               cy[s] += (aux * cos(2.0 * M_PI * Position[1]));
+     569             :             }
+     570             :           }
+     571             :         }
+     572             :       }
+     573             :     }
+     574             :   }
+     575             : 
+     576         184 :   for (unsigned s = 0; s < NS[0]; s++)
+     577             :   {
+     578         180 :     if (Fs[s] != 0.0)
+     579             :     {
+     580          49 :       ws[s] = tanh(Fs[s]);
+     581          49 :       W += ws[s];
+     582          49 :       sx[s] = sx[s] / Fs[s];
+     583          49 :       sy[s] = sy[s] / Fs[s];
+     584          49 :       cx[s] = cx[s] / Fs[s];
+     585          49 :       cy[s] = cy[s] / Fs[s];
+     586          49 :       Xsc += sx[s] * ws[s];
+     587          49 :       Ysc += sy[s] * ws[s];
+     588          49 :       Xcc += cx[s] * ws[s];
+     589          49 :       Ycc += cy[s] * ws[s];
+     590             :     }
+     591             :   }
+     592             : 
+     593           4 :   Xsc = Xsc / W;
+     594           4 :   Ysc = Ysc / W;
+     595           4 :   Xcc = Xcc / W;
+     596           4 :   Ycc = Ycc / W;
+     597             : 
+     598             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     599             :   double Xcyl, Ycyl;
+     600             : 
+     601             :   Xcyl = Xcyl_Mem;
+     602             :   Ycyl = Ycyl_Mem;
+     603             : 
+     604             :   // Eq. 25, 26 and 27 Hub & Awasthi JCTC 2017.
+     605             :   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;
+     606             : 
+     607             :   // Eq. 29 Hub & Awasthi JCTC 2017.
+     608             :   double d_ws_dz;
+     609             : 
+     610             :   // Eq. 31, 32 and 33 Hub & Awasthi JCTC 2017
+     611             :   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;
+     612             : 
+     613             :   // Center of the cylinder. X and Y are calculated (or defined), Z is the Z component of the geometric center of the membranes.
+     614           4 :   Vector xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl, Ycyl, ZMems));
+     615             : 
+     616             :   // Distances from the oxygens to center of the cylinder.
+     617           4 :   std::vector<Vector> CylDistances(chainBeads);
+     618             : 
+     619             :   // Modulo of the XY distances from the oxygens to the center of the cylinder.
+     620             :   double ri;
+     621             : 
+     622             :   // Eq. 8 Hub & Awasthi JCTC 2017.
+     623             :   double fradial;
+     624             : 
+     625             :   // Eq. 15 Hub & Awasthi JCTC 2017.
+     626           4 :   std::vector<double> d_fradial_dx(chainBeads), d_fradial_dy(chainBeads);
+     627             : 
+     628             :   // Eq. 35, 36, 37 and 38 Hub & Awasthi JCTC 2017.
+     629           4 :   std::vector<double> d_Xcyl_dx(chainBeads), d_Xcyl_dz(chainBeads), d_Ycyl_dy(chainBeads), d_Ycyl_dz(chainBeads);
+     630             : 
+     631             :   // To avoid rare instabilities auxX and auxY are truncated at a configurable value (default 500).
+     632           4 :   double auxX = (1 / (pow(Xsc, 2) + pow(Xcc, 2))), auxY = (1 / (pow(Ysc, 2) + pow(Ycc, 2)));
+     633             : 
+     634           4 :   if (auxX > ONEOVERS2C2CUTOFF[0])
+     635             :   {
+     636           0 :     auxX = Lx * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     637             :   }
+     638             :   else
+     639             :   {
+     640           4 :     auxX = Lx * auxX / (2 * M_PI);
+     641             :   }
+     642             : 
+     643           4 :   if (auxY > ONEOVERS2C2CUTOFF[0])
+     644             :   {
+     645           0 :     auxY = Ly * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     646             :   }
+     647             :   else
+     648             :   {
+     649           4 :     auxY = Ly * auxY / (2 * M_PI);
+     650             :   }
+     651             : 
+     652             :   //Number of oxygens within the slice s of the membrane-spanning cylinder.
+     653           4 :   std::vector<double> Nsp(NS[0]), psi(NS[0]), d_psi(NS[0]);
+     654             : 
+     655             :   // Eq. 3 Hub & Awasthi JCTC 2017.
+     656           4 :   double b = (ZETA[0] / (1.0 - ZETA[0])), c = ((1.0 - ZETA[0]) * exp(b));
+     657             : 
+     658             :   // Eq. 19 Hub & Awasthi JCTC 2017.
+     659           4 :   std::vector<double> fradial_d_faxial_dz(chainBeads * NS[0]);
+     660             : 
+     661             :   // Eq. 20 Hub & Awasthi JCTC 2017.
+     662           4 :   std::vector<double> Axs(NS[0]), Ays(NS[0]);
+     663             : 
+     664             : #ifdef _OPENMP
+     665             : #if _OPENMP >= 201307
+     666           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)
+     667             : #endif
+     668             : #endif
+     669             :   for (unsigned i = 0; i < chainBeads; i++)
+     670             : {
+     671             :   CylDistances[i] = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     672             :     if (analyzeThisParticle[i])
+     673             :     {
+     674             :       Position = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     675             :       d_Xsc_dx = 0.0;
+     676             :       d_Xcc_dx = 0.0;
+     677             :       d_Ysc_dy = 0.0;
+     678             :       d_Ycc_dy = 0.0;
+     679             :       d_Xsc_dz = 0.0;
+     680             :       d_Xcc_dz = 0.0;
+     681             :       d_Ysc_dz = 0.0;
+     682             :       d_Ycc_dz = 0.0;
+     683             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     684             :       {
+     685             :         if (Fs[s] != 0.0)
+     686             :         {
+     687             :           d_sx_dx = faxial[i + chainBeads * s] * 2.0 * M_PI * cos(2.0 * M_PI * Position[0]) / (Lx * Fs[s]);
+     688             :           d_sy_dy = faxial[i + chainBeads * s] * 2.0 * M_PI * cos(2.0 * M_PI * Position[1]) / (Ly * Fs[s]);
+     689             :           d_cx_dx = -faxial[i + chainBeads * s] * 2.0 * M_PI * sin(2.0 * M_PI * Position[0]) / (Lx * Fs[s]);
+     690             :           d_cy_dy = -faxial[i + chainBeads * s] * 2.0 * M_PI * sin(2.0 * M_PI * Position[1]) / (Ly * Fs[s]);
+     691             :           d_Xsc_dx += ws[s] * d_sx_dx / W;
+     692             :           d_Xcc_dx += ws[s] * d_cx_dx / W;
+     693             :           d_Ysc_dy += ws[s] * d_sy_dy / W;
+     694             :           d_Ycc_dy += ws[s] * d_cy_dy / W;
+     695             : 
+     696             :           d_sx_dz = d_faxial_dz[i + chainBeads * s] * (sin(2.0 * M_PI * Position[0]) - sx[s]) / Fs[s];
+     697             :           d_sy_dz = d_faxial_dz[i + chainBeads * s] * (sin(2.0 * M_PI * Position[1]) - sy[s]) / Fs[s];
+     698             :           d_cx_dz = d_faxial_dz[i + chainBeads * s] * (cos(2.0 * M_PI * Position[0]) - cx[s]) / Fs[s];
+     699             :           d_cy_dz = d_faxial_dz[i + chainBeads * s] * (cos(2.0 * M_PI * Position[1]) - cy[s]) / Fs[s];
+     700             :           d_ws_dz = (1 - pow(ws[s], 2)) * d_faxial_dz[i + chainBeads * s];
+     701             :           d_Xsc_dz += (ws[s] * d_sx_dz + d_ws_dz * (sx[s] - Xsc)) / W;
+     702             :           d_Xcc_dz += (ws[s] * d_cx_dz + d_ws_dz * (cx[s] - Xcc)) / W;
+     703             :           d_Ysc_dz += (ws[s] * d_sy_dz + d_ws_dz * (sy[s] - Ysc)) / W;
+     704             :           d_Ycc_dz += (ws[s] * d_cy_dz + d_ws_dz * (cy[s] - Ycc)) / W;
+     705             :         }
+     706             :       }
+     707             :       d_Xcyl_dx[i] = auxX * (-Xsc * d_Xcc_dx + Xcc * d_Xsc_dx);
+     708             :       d_Xcyl_dz[i] = auxX * (-Xsc * d_Xcc_dz + Xcc * d_Xsc_dz);
+     709             :       d_Ycyl_dy[i] = auxY * (-Ysc * d_Ycc_dy + Ycc * d_Ysc_dy);
+     710             :       d_Ycyl_dz[i] = auxY * (-Ysc * d_Ycc_dz + Ycc * d_Ysc_dz);
+     711             : 
+     712             :       ri = sqrt(pow(CylDistances[i][0], 2) + pow(CylDistances[i][1], 2));
+     713             :       x = ri / RCYL[0];
+     714             :       if (!((x <= -1.0 - HCH[0]) || (x >= 1.0 + HCH[0])))
+     715             :       {
+     716             :         if (((-1.0 + HCH[0]) <= x) && (x <= (1.0 - HCH[0])))
+     717             :         {
+     718             :           fradial = 1.0;
+     719             :         }
+     720             :         else if (((1.0 - HCH[0]) < x) && (x < (1.0 + HCH[0])))
+     721             :         {
+     722             :           fradial = 0.5 - ((3.0 * x - 3.0) / (4.0 * HCH[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     723             :           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);
+     724             :           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);
+     725             :         }
+     726             :         else if (((-1.0 - HCH[0]) < x) && (x < (-1.0 + HCH[0])))
+     727             :         {
+     728             :           fradial = 0.5 + ((3.0 * x + 3.0) / (4.0 * HCH[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     729             :           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);
+     730             :           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);
+     731             :         }
+     732             : 
+     733             :         for (unsigned s = s1[i]; s <= s2[i]; s++)
+     734             :         {
+     735             :           Nsp[s] += fradial * faxial[i + chainBeads * s];
+     736             :           Axs[s] += faxial[i + chainBeads * s] * d_fradial_dx[i];
+     737             :           Ays[s] += faxial[i + chainBeads * s] * d_fradial_dy[i];
+     738             :           fradial_d_faxial_dz[i + chainBeads * s] = fradial * d_faxial_dz[i + chainBeads * s];
+     739             :         }
+     740             :       }
+     741             :     }
+     742             :   }
+     743             : 
+     744         184 :   for (unsigned s = 0; s < NS[0]; s++)
+     745             :   {
+     746         180 :     if (Nsp[s] <= 1.0)
+     747             :     {
+     748         149 :       psi[s] = ZETA[0] * Nsp[s];
+     749         149 :       d_psi[s] = ZETA[0];
+     750         149 :       Xi_n += psi[s];
+     751             :     }
+     752             :     else
+     753             :     {
+     754          31 :       psi[s] = 1.0 - c * exp(-b * Nsp[s]);
+     755          31 :       d_psi[s] = b * c * exp(-b * Nsp[s]);
+     756          31 :       Xi_n += psi[s];
+     757             :     }
+     758             :   }
+     759             : 
+     760           4 :   Xi_n = Xi_n / NS[0];
+     761             : 
+     762             :   // Eq. 18 Hub & Awasthi JCTC 2017.
+     763           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]);
+     764             : 
+     765             :   // Eq. 13 Hub & Awasthi JCTC 2017 modified to considere the Heaviside_Chain step function (this only affect during the transition).
+     766           4 :   std::vector<Vector> derivatives_Chain(chainBeads);
+     767             : 
+     768             : #ifdef _OPENMP
+     769             : #if _OPENMP >= 201307
+     770           4 :   #pragma omp parallel for private(aux)
+     771             : #endif
+     772             : #endif
+     773             :   for (unsigned i = 0; i < chainBeads; i++)
+     774             : {
+     775             :   if (analyzeThisParticle[i])
+     776             :     {
+     777             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     778             :       {
+     779             :         if (faxial[i + chainBeads * s])
+     780             :         {
+     781             :           faxial_d_fradial_dx[i + chainBeads * s] = faxial[i + chainBeads * s] * d_fradial_dx[i] - d_Xcyl_dx[i] * Axs[s];
+     782             :           faxial_d_fradial_dy[i + chainBeads * s] = faxial[i + chainBeads * s] * d_fradial_dy[i] - d_Ycyl_dy[i] * Ays[s];
+     783             :           faxial_d_fradial_dz[i + chainBeads * s] = -d_Xcyl_dz[i] * Axs[s] - d_Ycyl_dz[i] * Ays[s];
+     784             :         }
+     785             :       }
+     786             : 
+     787             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     788             :       {
+     789             :         aux = d_psi[s] / NS[0];
+     790             :         derivatives_Chain[i][0] += aux * faxial_d_fradial_dx[i + chainBeads * s];
+     791             :         derivatives_Chain[i][1] += aux * faxial_d_fradial_dy[i + chainBeads * s];
+     792             :         derivatives_Chain[i][2] += aux * (faxial_d_fradial_dz[i + chainBeads * s] + fradial_d_faxial_dz[i + chainBeads * s]);
+     793             :       }
+     794             :     }
+     795             :   }
+     796             : 
+     797           4 :   Tensor virial;
+     798      134604 :   for (unsigned i = 0; i < chainBeads; i++)
+     799             : {
+     800      134600 :   setAtomsDerivatives((i + noChainBeads), derivatives_Chain[i]);
+     801      134600 :     virial -= Tensor(CylDistances[i], derivatives_Chain[i]);
+     802             :   }
+     803             : 
+     804           4 :   setValue(Xi_n);
+     805           4 :   setBoxDerivatives(virial);
+     806           4 : }
+     807             : }
+     808             : }
+
+
+
+ + + + +
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 000000000..ea10f7982 --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13415188.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..c2a5e1ed9 --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13415188.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..881093f64 --- /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:13415188.7 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the CV");
+     106           3 : }
+     107             : 
+     108           1 : memFusionP::memFusionP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     109             : {
+     110           2 :   parseAtomList("UMEMBRANE", UMEM);
+     111           1 :   if (UMEM.size() == 0)
+     112           0 :     error("UMEMBRANE has not any atom specified.");
+     113             : 
+     114           2 :   parseAtomList("LMEMBRANE", LMEM);
+     115           1 :   if (LMEM.size() == 0)
+     116           0 :     error("LMEMBRANE has not any atom specified.");
+     117             : 
+     118           2 :   parseAtomList("TAILS", TAILS);
+     119           1 :   if (TAILS.size() == 0)
+     120           0 :     error("TAILS has not any atom specified.");
+     121             : 
+     122           2 :   parseVector("NSMEM", NSMEM);
+     123           1 :   if (NSMEM.size() > 1)
+     124           0 :     error("NSMEM cannot take more than one value.");
+     125             : 
+     126           2 :   parseVector("DSMEM", DSMEM);
+     127           1 :   if (DSMEM.size() > 1)
+     128           0 :     error("DSMEM cannot take more than one value.");
+     129           1 :   if (DSMEM.size() == 0)
+     130           0 :     DSMEM.push_back(0.1);
+     131             : 
+     132           2 :   parseVector("HMEM", HMEM);
+     133           1 :   if (HMEM.size() > 1)
+     134           0 :     error("HMEM cannot take more than one value.");
+     135           1 :   if (HMEM.size() == 0)
+     136           0 :     HMEM.push_back(0.25);
+     137             : 
+     138           2 :   parseVector("RCYLMEM", RCYLMEM);
+     139           1 :   if (RCYLMEM.size() > 1)
+     140           0 :     error("RCYLMEM cannot take more than one value.");
+     141           1 :   if (RCYLMEM.size() == 0)
+     142           0 :     RCYLMEM.push_back(1.75);
+     143             : 
+     144           2 :   parseVector("ZETAMEM", ZETAMEM);
+     145           1 :   if (ZETAMEM.size() > 1)
+     146           0 :     error("ZETA cannot take more than one value.");
+     147           1 :   if (ZETAMEM.size() == 0)
+     148           0 :     ZETAMEM.push_back(0.5);
+     149             : 
+     150           2 :   parseVector("ONEOVERS2C2CUTOFF", ONEOVERS2C2CUTOFF);
+     151           1 :   if (ONEOVERS2C2CUTOFF.size() > 1)
+     152           0 :     error("ONEOVERS2C2CUTOFF cannot take more than one value.");
+     153           1 :   if (ONEOVERS2C2CUTOFF.size() == 0)
+     154           1 :     ONEOVERS2C2CUTOFF.push_back(500);
+     155             : 
+     156           2 :   parseVector("XCYL", XCYL);
+     157           1 :   if (XCYL.size() > 1)
+     158           0 :     error("XCYL cannot take more than one value.");
+     159           1 :   if (XCYL.size() == 0)
+     160           1 :     XCYL.push_back(-1.0);
+     161             : 
+     162           2 :   parseVector("YCYL", YCYL);
+     163           1 :   if (YCYL.size() > 1)
+     164           0 :     error("YCYL cannot take more than one value.");
+     165           1 :   if (YCYL.size() == 0)
+     166           1 :     YCYL.push_back(-1.0);
+     167             : 
+     168           1 :   checkRead();
+     169             : 
+     170             :   std::vector<AtomNumber> atoms;
+     171       12289 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     172             :   {
+     173       12288 :     atoms.push_back(UMEM[i]);
+     174             :   }
+     175       12289 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     176             :   {
+     177       12288 :     atoms.push_back(LMEM[i]);
+     178             :   }
+     179        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     180             :   {
+     181        4096 :     atoms.push_back(TAILS[i]);
+     182             :   }
+     183             : 
+     184           1 :   addValueWithDerivatives();
+     185           1 :   setNotPeriodic();
+     186           1 :   requestAtoms(atoms);
+     187           1 : }
+     188             : 
+     189           3 : void memFusionP::calculate()
+     190             : {
+     191             :   /**************************
+     192             :    *                        *
+     193             :    *         System         *
+     194             :    *                        *
+     195             :    **************************/
+     196             : 
+     197             :   // Box dimensions.
+     198           3 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     199             : 
+     200             :   // 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 .
+     201             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     202             : 
+     203             : #ifdef _OPENMP
+     204             : #if _OPENMP >= 201307
+     205           3 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     206             : #endif
+     207             : #endif
+     208             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     209             :   {
+     210             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     211             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     212             :     ZuMemcos += cos(uMemAngle);
+     213             :     ZuMemsin += sin(uMemAngle);
+     214             :     ZlMemcos += cos(lMemAngle);
+     215             :     ZlMemsin += sin(lMemAngle);
+     216             :   }
+     217             : 
+     218           3 :   ZuMemcos = ZuMemcos / UMEM.size();
+     219           3 :   ZuMemsin = ZuMemsin / UMEM.size();
+     220           3 :   ZlMemcos = ZlMemcos / UMEM.size();
+     221           3 :   ZlMemsin = ZlMemsin / UMEM.size();
+     222             : 
+     223           3 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     224           3 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     225             : 
+     226             :   // Z center of the boths membranes (upper and lower).
+     227           3 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     228             : 
+     229             :   /*************************
+     230             :    *                        *
+     231             :    *         Xi_Mem         *
+     232             :    *                        *
+     233             :    **************************/
+     234             : 
+     235             :   // Quantity of beads of the membranes.
+     236           3 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     237             : 
+     238             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     239             :   double ZTailDistance;
+     240             : 
+     241             :   // Z position of the first slice.
+     242           3 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     243             : 
+     244             :   // Z distance between the first slice and the Z center of the membrane.
+     245           6 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     246             : 
+     247             :   // Position in the cylinder.
+     248             :   double PositionS_Mem;
+     249             : 
+     250             :   // Slices to analyze per particle.
+     251           3 :   std::vector<unsigned> s1_Mem(TAILS.size()), s2_Mem(TAILS.size());
+     252             : 
+     253             :   // Mark the particles to analyze.
+     254           3 :   std::vector<double> analyzeThisParticle_Mem(TAILS.size());
+     255             : 
+     256             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     257           3 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     258             : 
+     259             :   // Eq. 16 Hub & Awasthi JCTC 2017.
+     260           3 :   std::vector<double> d_faxial_Mem_dz(TAILS.size() * NSMEM[0]);
+     261             : 
+     262             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     263           3 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     264             : 
+     265             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     266           3 :   std::vector<double> ws_Mem(NSMEM[0]);
+     267             : 
+     268             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     269             :   double W_Mem = 0.0;
+     270             : 
+     271             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     272           3 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     273             : 
+     274             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     275             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     276             : 
+     277             :   // Aux.
+     278             :   double x, aux;
+     279             : 
+     280             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     281           3 :   Vector TailPosition;
+     282             : 
+     283             :   // Thanks stack overflow.
+     284             : #ifdef _OPENMP
+     285             : #if _OPENMP >= 201307
+     286             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     287             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     288             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     289             : #endif
+     290             : #endif
+     291             : 
+     292             : #ifdef _OPENMP
+     293             : #if _OPENMP >= 201307
+     294           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)
+     295             : #endif
+     296             : #endif
+     297             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     298             :   {
+     299             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     300             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     301             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     302             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     303             :     {
+     304             :       analyzeThisParticle_Mem[i] = 1.0;
+     305             :       // Defining the slices to analyze each particle.
+     306             :       if (PositionS_Mem < 1)
+     307             :       {
+     308             :         s1_Mem[i] = 0;
+     309             :         s2_Mem[i] = 2;
+     310             :       }
+     311             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     312             :       {
+     313             :         s1_Mem[i] = floor(PositionS_Mem) - 1;
+     314             :         s2_Mem[i] = floor(PositionS_Mem) + 1;
+     315             :       }
+     316             :       else
+     317             :       {
+     318             :         s1_Mem[i] = NSMEM[0] - 3;
+     319             :         s2_Mem[i] = NSMEM[0] - 1;
+     320             :       }
+     321             : 
+     322             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     323             : 
+     324             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     325             :       {
+     326             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     327             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     328             :         {
+     329             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     330             :           {
+     331             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     332             :             Fs_Mem[s] += 1.0;
+     333             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     334             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     335             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     336             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     337             :           }
+     338             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     339             :           {
+     340             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     341             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     342             :             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];
+     343             :             Fs_Mem[s] += aux;
+     344             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     345             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     346             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     347             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     348             :           }
+     349             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     350             :           {
+     351             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     352             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     353             :             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];
+     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             :         }
+     361             :       }
+     362             :     }
+     363             :   }
+     364             : 
+     365         213 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     366             :   {
+     367         210 :     if (Fs_Mem[s] != 0.0)
+     368             :     {
+     369         106 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     370         106 :       W_Mem += ws_Mem[s];
+     371         106 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     372         106 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     373         106 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     374         106 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     375         106 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     376         106 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     377         106 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     378         106 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     379             :     }
+     380             :   }
+     381             : 
+     382           3 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     383           3 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     384           3 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     385           3 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     386             : 
+     387             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     388             :   double Xcyl_Mem, Ycyl_Mem;
+     389             : 
+     390           3 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     391             :   {
+     392             :     Xcyl_Mem = XCYL[0];
+     393             :     Ycyl_Mem = YCYL[0];
+     394             :   }
+     395             :   else
+     396             :   {
+     397           3 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     398           3 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     399             :   }
+     400             : 
+     401             :   // Eq. 25, 26 and 27 Hub & Awasthi JCTC 2017.
+     402             :   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;
+     403             : 
+     404             :   // Eq. 29 Hub & Awasthi JCTC 2017.
+     405             :   double d_ws_Mem_dz;
+     406             : 
+     407             :   // Eq. 31, 32 and 33 Hub & Awasthi JCTC 2017
+     408             :   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;
+     409             : 
+     410             :   // Center of the cylinder. XY components are calculated (or defined), Z is the Z geometric center of the membranes of the system.
+     411           6 :   Vector xyzCyl_Mem = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     412             : 
+     413             :   // Distances from the lipid tails to center of the cylinder.
+     414           3 :   std::vector<Vector> CylDistances_Mem(TAILS.size());
+     415             : 
+     416             :   // XY distance from the lipid tails to the center of the cylinder.
+     417             :   double ri_Mem;
+     418             : 
+     419             :   // Eq. 8 Hub & Awasthi JCTC 2017.
+     420             :   double fradial_Mem = 0;
+     421             : 
+     422             :   // Eq. 15 Hub & Awasthi JCTC 2017.
+     423           3 :   std::vector<double> d_fradial_Mem_dx(TAILS.size()), d_fradial_Mem_dy(TAILS.size());
+     424             : 
+     425             :   // Eq. 35, 36, 37 and 38 Hub & Awasthi JCTC 2017.
+     426           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());
+     427             : 
+     428             :   // To avoid rare instabilities auxX_Mem and auxY_Mem are truncated at a configurable value (default = 500).
+     429           3 :   double auxX_Mem = (1 / (pow(Xsc_Mem, 2) + pow(Xcc_Mem, 2))), auxY_Mem = (1 / (pow(Ysc_Mem, 2) + pow(Ycc_Mem, 2)));
+     430             : 
+     431           3 :   if (auxX_Mem > ONEOVERS2C2CUTOFF[0])
+     432             :   {
+     433           0 :     auxX_Mem = Lx * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     434             :   }
+     435             :   else
+     436             :   {
+     437           3 :     auxX_Mem = Lx * auxX_Mem / (2 * M_PI);
+     438             :   }
+     439             : 
+     440           3 :   if (auxY_Mem > ONEOVERS2C2CUTOFF[0])
+     441             :   {
+     442           0 :     auxY_Mem = Ly * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     443             :   }
+     444             :   else
+     445             :   {
+     446           3 :     auxY_Mem = Ly * auxY_Mem / (2 * M_PI);
+     447             :   }
+     448             : 
+     449             :   // Number of lipid tails within the slice s of the membranes cylinder.
+     450           3 :   std::vector<double> Nsp_Mem(NSMEM[0]), psi_Mem(NSMEM[0]), d_psi_Mem(NSMEM[0]);
+     451             : 
+     452             :   // Eq. 3 Hub & Awasthi JCTC 2017.
+     453           3 :   double b_Mem = (ZETAMEM[0] / (1.0 - ZETAMEM[0])), c_Mem = ((1.0 - ZETAMEM[0]) * exp(b_Mem));
+     454             : 
+     455             :   // Eq. 19 Hub & Awasthi JCTC 2017.
+     456           3 :   std::vector<double> fradial_Mem_d_faxial_Mem_dz(TAILS.size() * NSMEM[0]);
+     457             : 
+     458             :   // Eq. 20 Hub & Awasthi JCTC 2017.
+     459           3 :   std::vector<double> Axs_Mem(NSMEM[0]), Ays_Mem(NSMEM[0]);
+     460             : 
+     461             :   // Eq. 1 Hub & Awasthi JCTC 2017. This is the CV that describes de Pore Nucleation.
+     462           3 :   double Xi_Mem = 0.0;
+     463             : 
+     464             : #ifdef _OPENMP
+     465             : #if _OPENMP >= 201307
+     466           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)
+     467             : #endif
+     468             : #endif
+     469             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     470             :   {
+     471             :     if (analyzeThisParticle_Mem[i])
+     472             :     {
+     473             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     474             :       d_Xsc_Mem_dx = 0.0;
+     475             :       d_Xcc_Mem_dx = 0.0;
+     476             :       d_Ysc_Mem_dy = 0.0;
+     477             :       d_Ycc_Mem_dy = 0.0;
+     478             :       d_Xsc_Mem_dz = 0.0;
+     479             :       d_Xcc_Mem_dz = 0.0;
+     480             :       d_Ysc_Mem_dz = 0.0;
+     481             :       d_Ycc_Mem_dz = 0.0;
+     482             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     483             :       {
+     484             :         if (Fs_Mem[s] != 0.0)
+     485             :         {
+     486             :           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]);
+     487             :           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]);
+     488             :           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]);
+     489             :           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]);
+     490             :           d_Xsc_Mem_dx += ws_Mem[s] * d_sx_Mem_dx / W_Mem;
+     491             :           d_Xcc_Mem_dx += ws_Mem[s] * d_cx_Mem_dx / W_Mem;
+     492             :           d_Ysc_Mem_dy += ws_Mem[s] * d_sy_Mem_dy / W_Mem;
+     493             :           d_Ycc_Mem_dy += ws_Mem[s] * d_cy_Mem_dy / W_Mem;
+     494             : 
+     495             :           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];
+     496             :           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];
+     497             :           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];
+     498             :           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];
+     499             :           d_ws_Mem_dz = (1 - pow(ws_Mem[s], 2)) * d_faxial_Mem_dz[i + TAILS.size() * s];
+     500             :           d_Xsc_Mem_dz += (ws_Mem[s] * d_sx_Mem_dz + d_ws_Mem_dz * (sx_Mem[s] - Xsc_Mem)) / W_Mem;
+     501             :           d_Xcc_Mem_dz += (ws_Mem[s] * d_cx_Mem_dz + d_ws_Mem_dz * (cx_Mem[s] - Xcc_Mem)) / W_Mem;
+     502             :           d_Ysc_Mem_dz += (ws_Mem[s] * d_sy_Mem_dz + d_ws_Mem_dz * (sy_Mem[s] - Ysc_Mem)) / W_Mem;
+     503             :           d_Ycc_Mem_dz += (ws_Mem[s] * d_cy_Mem_dz + d_ws_Mem_dz * (cy_Mem[s] - Ycc_Mem)) / W_Mem;
+     504             :         }
+     505             :       }
+     506             :       d_Xcyl_Mem_dx[i] = auxX_Mem * (-Xsc_Mem * d_Xcc_Mem_dx + Xcc_Mem * d_Xsc_Mem_dx);
+     507             :       d_Xcyl_Mem_dz[i] = auxX_Mem * (-Xsc_Mem * d_Xcc_Mem_dz + Xcc_Mem * d_Xsc_Mem_dz);
+     508             :       d_Ycyl_Mem_dy[i] = auxY_Mem * (-Ysc_Mem * d_Ycc_Mem_dy + Ycc_Mem * d_Ysc_Mem_dy);
+     509             :       d_Ycyl_Mem_dz[i] = auxY_Mem * (-Ysc_Mem * d_Ycc_Mem_dz + Ycc_Mem * d_Ysc_Mem_dz);
+     510             : 
+     511             :       CylDistances_Mem[i] = pbcDistance(xyzCyl_Mem, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     512             :       ri_Mem = sqrt(pow(CylDistances_Mem[i][0], 2) + pow(CylDistances_Mem[i][1], 2));
+     513             :       x = ri_Mem / RCYLMEM[0];
+     514             :       if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     515             :       {
+     516             :         if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     517             :         {
+     518             :           fradial_Mem = 1.0;
+     519             :         }
+     520             :         else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     521             :         {
+     522             :           fradial_Mem = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     523             :           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);
+     524             :           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);
+     525             :         }
+     526             :         else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     527             :         {
+     528             :           fradial_Mem = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     529             :           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);
+     530             :           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);
+     531             :         }
+     532             : 
+     533             :         for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     534             :         {
+     535             :           Nsp_Mem[s] += fradial_Mem * faxial_Mem[i + TAILS.size() * s];
+     536             :           Axs_Mem[s] += faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dx[i];
+     537             :           Ays_Mem[s] += faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dy[i];
+     538             :           fradial_Mem_d_faxial_Mem_dz[i + TAILS.size() * s] = fradial_Mem * d_faxial_Mem_dz[i + TAILS.size() * s];
+     539             :         }
+     540             :       }
+     541             :     }
+     542             :   }
+     543             : 
+     544         213 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     545             :   {
+     546         210 :     if (Nsp_Mem[s] <= 1.0)
+     547             :     {
+     548         166 :       psi_Mem[s] = ZETAMEM[0] * Nsp_Mem[s];
+     549         166 :       d_psi_Mem[s] = ZETAMEM[0];
+     550         166 :       Xi_Mem += psi_Mem[s];
+     551             :     }
+     552             :     else
+     553             :     {
+     554          44 :       psi_Mem[s] = 1.0 - c_Mem * exp(-b_Mem * Nsp_Mem[s]);
+     555          44 :       d_psi_Mem[s] = b_Mem * c_Mem * exp(-b_Mem * Nsp_Mem[s]);
+     556          44 :       Xi_Mem += psi_Mem[s];
+     557             :     }
+     558             :   }
+     559             : 
+     560           3 :   Xi_Mem = Xi_Mem / NSMEM[0];
+     561             : 
+     562             :   // Eq. 18 Hub & Awasthi JCTC 2017.
+     563           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]);
+     564             : 
+     565             :   // Eq. 13 Hub & Awasthi JCTC 2017.
+     566           3 :   std::vector<Vector> derivatives_Mem(TAILS.size());
+     567             : 
+     568             : #ifdef _OPENMP
+     569             : #if _OPENMP >= 201307
+     570           3 :   #pragma omp parallel for private(aux)
+     571             : #endif
+     572             : #endif
+     573             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     574             :   {
+     575             :     if (analyzeThisParticle_Mem[i])
+     576             :     {
+     577             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     578             :       {
+     579             :         if (faxial_Mem[i + TAILS.size() * s])
+     580             :         {
+     581             :           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];
+     582             :           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];
+     583             :           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];
+     584             :         }
+     585             :       }
+     586             : 
+     587             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     588             :       {
+     589             :         aux = d_psi_Mem[s] / NSMEM[0];
+     590             :         derivatives_Mem[i][0] += aux * faxial_Mem_d_fradial_Mem_dx[i + TAILS.size() * s];
+     591             :         derivatives_Mem[i][1] += aux * faxial_Mem_d_fradial_Mem_dy[i + TAILS.size() * s];
+     592             :         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]);
+     593             :       }
+     594             :     }
+     595             :   }
+     596             : 
+     597             :   // Derivatives and virial for the Xi_Mem.
+     598           3 :   Tensor virial;
+     599       12291 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     600             :   {
+     601       12288 :     setAtomsDerivatives((i + membraneBeads), derivatives_Mem[i]);
+     602       12288 :     virial -= Tensor(CylDistances_Mem[i], derivatives_Mem[i]);
+     603             :   }
+     604             : 
+     605           3 :   setValue(Xi_Mem);
+     606           3 :   setBoxDerivatives(virial);
+     607           3 : }
+     608             : }
+     609             : }
+
+
+
+ + + + +
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 000000000..4d0889fb0 --- /dev/null +++ b/coverage/membranefusion/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45651788.2 %
Date:2024-10-17 16:45:00Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreNucleationP.cpp +
88.5%88.5%
+
88.5 %184 / 20875.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %134 / 15175.0 %3 / 4
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %138 / 15875.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 000000000..f720512af --- /dev/null +++ b/coverage/membranefusion/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45651788.2 %
Date:2024-10-17 16:45:00Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %138 / 15875.0 %3 / 4
FusionPoreNucleationP.cpp +
88.5%88.5%
+
88.5 %184 / 20875.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %134 / 15175.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 000000000..f845db1b8 --- /dev/null +++ b/coverage/membranefusion/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45651788.2 %
Date:2024-10-17 16:45:00Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %138 / 15875.0 %3 / 4
FusionPoreNucleationP.cpp +
88.5%88.5%
+
88.5 %184 / 20875.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %134 / 15175.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/index-sort-f.html b/coverage/metatensor/index-sort-f.html new file mode 100644 index 000000000..5bbcf0e5f --- /dev/null +++ b/coverage/metatensor/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - metatensor + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensorHitTotalCoverage
Test:plumed test coverageLines:163454.6 %
Date:2024-10-17 16:45:00Functions:1342.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
vesin.cpp +
0.0%
+
0.0 %0 / 3210.0 %0 / 29
metatensor.cpp +
66.7%66.7%
+
66.7 %16 / 2420.0 %1 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/index-sort-l.html b/coverage/metatensor/index-sort-l.html new file mode 100644 index 000000000..6d9843e47 --- /dev/null +++ b/coverage/metatensor/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - metatensor + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensorHitTotalCoverage
Test:plumed test coverageLines:163454.6 %
Date:2024-10-17 16:45:00Functions:1342.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
vesin.cpp +
0.0%
+
0.0 %0 / 3210.0 %0 / 29
metatensor.cpp +
66.7%66.7%
+
66.7 %16 / 2420.0 %1 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/index.html b/coverage/metatensor/index.html new file mode 100644 index 000000000..8fe8ef657 --- /dev/null +++ b/coverage/metatensor/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - metatensor + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensorHitTotalCoverage
Test:plumed test coverageLines:163454.6 %
Date:2024-10-17 16:45:00Functions:1342.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
metatensor.cpp +
66.7%66.7%
+
66.7 %16 / 2420.0 %1 / 5
vesin.cpp +
0.0%
+
0.0 %0 / 3210.0 %0 / 29
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/metatensor.cpp.func-sort-c.html b/coverage/metatensor/metatensor.cpp.func-sort-c.html new file mode 100644 index 000000000..85bba4a4f --- /dev/null +++ b/coverage/metatensor/metatensor.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - metatensor/metatensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensor - metatensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162466.7 %
Date:2024-10-17 16:45:00Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10metatensor22MetatensorPlumedAction22getNumberOfDerivativesEv0
_ZN4PLMD10metatensor22MetatensorPlumedAction5applyEv0
_ZN4PLMD10metatensor22MetatensorPlumedAction9calculateEv0
_ZN4PLMD10metatensor22MetatensorPlumedActionC1ERKNS_13ActionOptionsE0
_ZN4PLMD10metatensor22MetatensorPlumedAction16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/metatensor.cpp.func.html b/coverage/metatensor/metatensor.cpp.func.html new file mode 100644 index 000000000..69d326f14 --- /dev/null +++ b/coverage/metatensor/metatensor.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - metatensor/metatensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensor - metatensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162466.7 %
Date:2024-10-17 16:45:00Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10metatensor22MetatensorPlumedAction16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10metatensor22MetatensorPlumedAction22getNumberOfDerivativesEv0
_ZN4PLMD10metatensor22MetatensorPlumedAction5applyEv0
_ZN4PLMD10metatensor22MetatensorPlumedAction9calculateEv0
_ZN4PLMD10metatensor22MetatensorPlumedActionC1ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/metatensor.cpp.gcov.html b/coverage/metatensor/metatensor.cpp.gcov.html new file mode 100644 index 000000000..c7ca2304d --- /dev/null +++ b/coverage/metatensor/metatensor.cpp.gcov.html @@ -0,0 +1,1046 @@ + + + + + + + LCOV - plumed test coverage - metatensor/metatensor.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensor - metatensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162466.7 %
Date:2024-10-17 16:45:00Functions:1520.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2024 The METATENSOR code team
+       3             : (see the PEOPLE-METATENSOR file at the root of this folder for a list of names)
+       4             : 
+       5             : See https://docs.metatensor.org/latest/ for more information about the
+       6             : metatensor package that this module allows you to call from PLUMED.
+       7             : 
+       8             : This file is part of METATENSOR-PLUMED module.
+       9             : 
+      10             : The METATENSOR-PLUMED module is free software: you can redistribute it and/or modify
+      11             : it under the terms of the GNU Lesser General Public License as published by
+      12             : the Free Software Foundation, either version 3 of the License, or
+      13             : (at your option) any later version.
+      14             : 
+      15             : The METATENSOR-PLUMED module is distributed in the hope that it will be useful,
+      16             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      17             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      18             : GNU Lesser General Public License for more details.
+      19             : 
+      20             : You should have received a copy of the GNU Lesser General Public License
+      21             : along with the METATENSOR-PLUMED module. If not, see <http://www.gnu.org/licenses/>.
+      22             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      23             : 
+      24             : #include "core/ActionAtomistic.h"
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : 
+      29             : //+PLUMEDOC METATENSORMOD_COLVAR METATENSOR
+      30             : /*
+      31             : Use arbitrary machine learning models as collective variables.
+      32             : 
+      33             : Note that this action requires the metatensor-torch library. Check the
+      34             : instructions in the \ref METATENSORMOD page to enable this module.
+      35             : 
+      36             : This action enables the use of fully custom machine learning models — based on
+      37             : the [metatensor atomistic models][mts_models] interface — as collective
+      38             : variables in PLUMED. Such machine learning model are typically written and
+      39             : customized using Python code, and then exported to run within PLUMED as
+      40             : [TorchScript], which is a subset of Python that can be executed by the C++ torch
+      41             : library.
+      42             : 
+      43             : Metatensor offers a way to define such models and pass data from PLUMED (or any
+      44             : other simulation engine) to the model and back. For more information on how to
+      45             : define such model, have a look at the [corresponding tutorials][mts_tutorials],
+      46             : or at the code in `regtest/metatensor/`. Each of the Python scripts in this
+      47             : directory defines a custom machine learning CV that can be used with PLUMED.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following input shows how you can call metatensor and evaluate the model
+      52             : that is described in the file `custom_cv.pt` from PLUMED.
+      53             : 
+      54             : \plumedfile metatensor_cv: METATENSOR ... MODEL=custom_cv.pt
+      55             : 
+      56             :     SPECIES1=1-26
+      57             :     SPECIES2=27-62
+      58             :     SPECIES3=63-76
+      59             :     SPECIES_TO_TYPES=6,1,8
+      60             : ...
+      61             : \endplumedfile
+      62             : 
+      63             : The numbered `SPECIES` labels are used to indicate the list of atoms that belong
+      64             : to each atomic species in the system. The `SPECIES_TO_TYPE` keyword then
+      65             : provides information on the atom type for each species. The first number here is
+      66             : the atomic type of the atoms that have been specified using the `SPECIES1` flag,
+      67             : the second number is the atomic number of the atoms that have been specified
+      68             : using the `SPECIES2` flag and so on.
+      69             : 
+      70             : `METATENSOR` action also accepts the following options:
+      71             : 
+      72             : - `EXTENSIONS_DIRECTORY` should be the path to a directory containing
+      73             :   TorchScript extensions (as shared libraries) that are required to load and
+      74             :   execute the model. This matches the `collect_extensions` argument to
+      75             :   `MetatensorAtomisticModel.export` in Python.
+      76             : - `CHECK_CONSISTENCY` can be used to enable internal consistency checks;
+      77             : - `SELECTED_ATOMS` can be used to signal the metatensor models that it should
+      78             :   only run its calculation for the selected subset of atoms. The model still
+      79             :   need to know about all the atoms in the system (through the `SPECIES`
+      80             :   keyword); but this can be used to reduce the calculation cost. Note that the
+      81             :   indices of the selected atoms should start at 1 in the PLUMED input file, but
+      82             :   they will be translated to start at 0 when given to the model (i.e. in
+      83             :   Python/TorchScript, the `forward` method will receive a `selected_atoms` which
+      84             :   starts at 0)
+      85             : 
+      86             : Here is another example with all the possible keywords:
+      87             : 
+      88             : \plumedfile soap: METATENSOR ... MODEL=soap.pt EXTENSION_DIRECTORY=extensions
+      89             : CHECK_CONSISTENCY
+      90             : 
+      91             :     SPECIES1=1-10
+      92             :     SPECIES2=11-20
+      93             :     SPECIES_TO_TYPES=8,13
+      94             : 
+      95             :     # only run the calculation for the Aluminium (type 13) atoms, but
+      96             :     # include the Oxygen (type 8) as potential neighbors.
+      97             :     SELECTED_ATOMS=11-20
+      98             : ...
+      99             : \endplumedfile
+     100             : 
+     101             : \par Collective variables and metatensor models
+     102             : 
+     103             : PLUMED can use the [`"features"` output][features_output] of metatensor
+     104             : atomistic models as a collective variables. Alternatively, the code also accepts
+     105             : an output named `"plumed::cv"`, with the same metadata structure as the
+     106             : `"features"` output.
+     107             : 
+     108             : */ /*
+     109             : 
+     110             : [TorchScript]: https://pytorch.org/docs/stable/jit.html
+     111             : [mts_models]: https://docs.metatensor.org/latest/atomistic/index.html
+     112             : [mts_tutorials]: https://docs.metatensor.org/latest/examples/atomistic/index.html
+     113             : [mts_block]: https://docs.metatensor.org/latest/torch/reference/block.html
+     114             : [features_output]: https://docs.metatensor.org/latest/examples/atomistic/outputs/features.html
+     115             : */
+     116             : //+ENDPLUMEDOC
+     117             : 
+     118             : /*INDENT-OFF*/
+     119             : #if !defined(__PLUMED_HAS_METATENSOR) || !defined(__PLUMED_HAS_LIBTORCH)
+     120             : 
+     121             : namespace PLMD { namespace metatensor {
+     122             : class MetatensorPlumedAction: public ActionAtomistic, public ActionWithValue {
+     123             : public:
+     124             :     static void registerKeywords(Keywords& keys);
+     125           0 :     explicit MetatensorPlumedAction(const ActionOptions& options):
+     126             :         Action(options),
+     127             :         ActionAtomistic(options),
+     128           0 :         ActionWithValue(options)
+     129             :     {
+     130           0 :         throw std::runtime_error(
+     131             :             "Can not use metatensor action without the corresponding libraries. \n"
+     132             :             "Make sure to configure with `--enable-metatensor --enable-libtorch` "
+     133             :             "and that the corresponding libraries are found"
+     134           0 :         );
+     135           0 :     }
+     136             : 
+     137           0 :     void calculate() override {}
+     138           0 :     void apply() override {}
+     139           0 :     unsigned getNumberOfDerivatives() override {return 0;}
+     140             : };
+     141             : 
+     142             : }} // namespace PLMD::metatensor
+     143             : 
+     144             : #else
+     145             : 
+     146             : #include <type_traits>
+     147             : 
+     148             : #pragma GCC diagnostic push
+     149             : #pragma GCC diagnostic ignored "-Wpedantic"
+     150             : #pragma GCC diagnostic ignored "-Wunused-parameter"
+     151             : #pragma GCC diagnostic ignored "-Wfloat-equal"
+     152             : #pragma GCC diagnostic ignored "-Wfloat-conversion"
+     153             : #pragma GCC diagnostic ignored "-Wimplicit-float-conversion"
+     154             : #pragma GCC diagnostic ignored "-Wimplicit-int-conversion"
+     155             : #pragma GCC diagnostic ignored "-Wshorten-64-to-32"
+     156             : #pragma GCC diagnostic ignored "-Wsign-conversion"
+     157             : #pragma GCC diagnostic ignored "-Wold-style-cast"
+     158             : 
+     159             : #include <torch/script.h>
+     160             : #include <torch/version.h>
+     161             : #include <torch/cuda.h>
+     162             : #if TORCH_VERSION_MAJOR >= 2
+     163             : #include <torch/mps.h>
+     164             : #endif
+     165             : 
+     166             : #pragma GCC diagnostic pop
+     167             : 
+     168             : #include <metatensor/torch.hpp>
+     169             : #include <metatensor/torch/atomistic.hpp>
+     170             : 
+     171             : #include "vesin.h"
+     172             : 
+     173             : 
+     174             : namespace PLMD {
+     175             : namespace metatensor {
+     176             : 
+     177             : // We will cast Vector/Tensor to pointers to arrays and doubles, so let's make
+     178             : // sure this is legal to do
+     179             : static_assert(std::is_standard_layout<PLMD::Vector>::value);
+     180             : static_assert(sizeof(PLMD::Vector) == sizeof(std::array<double, 3>));
+     181             : static_assert(alignof(PLMD::Vector) == alignof(std::array<double, 3>));
+     182             : 
+     183             : static_assert(std::is_standard_layout<PLMD::Tensor>::value);
+     184             : static_assert(sizeof(PLMD::Tensor) == sizeof(std::array<std::array<double, 3>, 3>));
+     185             : static_assert(alignof(PLMD::Tensor) == alignof(std::array<std::array<double, 3>, 3>));
+     186             : 
+     187             : class MetatensorPlumedAction: public ActionAtomistic, public ActionWithValue {
+     188             : public:
+     189             :     static void registerKeywords(Keywords& keys);
+     190             :     explicit MetatensorPlumedAction(const ActionOptions&);
+     191             : 
+     192             :     void calculate() override;
+     193             :     void apply() override;
+     194             :     unsigned getNumberOfDerivatives() override;
+     195             : 
+     196             : private:
+     197             :     // fill this->system_ according to the current PLUMED data
+     198             :     void createSystem();
+     199             :     // compute a neighbor list following metatensor format, using data from PLUMED
+     200             :     metatensor_torch::TorchTensorBlock computeNeighbors(
+     201             :         metatensor_torch::NeighborListOptions request,
+     202             :         const std::vector<PLMD::Vector>& positions,
+     203             :         const PLMD::Tensor& cell
+     204             :     );
+     205             : 
+     206             :     // execute the model for the given system
+     207             :     metatensor_torch::TorchTensorBlock executeModel(metatensor_torch::System system);
+     208             : 
+     209             :     torch::jit::Module model_;
+     210             : 
+     211             :     metatensor_torch::ModelCapabilities capabilities_;
+     212             :     std::string model_output_;
+     213             : 
+     214             :     // neighbor lists requests made by the model
+     215             :     std::vector<metatensor_torch::NeighborListOptions> nl_requests_;
+     216             : 
+     217             :     // dtype/device to use to execute the model
+     218             :     torch::ScalarType dtype_;
+     219             :     torch::Device device_;
+     220             : 
+     221             :     torch::Tensor atomic_types_;
+     222             :     // store the strain to be able to compute the virial with autograd
+     223             :     torch::Tensor strain_;
+     224             : 
+     225             :     metatensor_torch::System system_;
+     226             :     metatensor_torch::ModelEvaluationOptions evaluations_options_;
+     227             :     bool check_consistency_;
+     228             : 
+     229             :     metatensor_torch::TorchTensorMap output_;
+     230             :     // shape of the output of this model
+     231             :     unsigned n_samples_;
+     232             :     unsigned n_properties_;
+     233             : };
+     234             : 
+     235             : 
+     236             : MetatensorPlumedAction::MetatensorPlumedAction(const ActionOptions& options):
+     237             :     Action(options),
+     238             :     ActionAtomistic(options),
+     239             :     ActionWithValue(options),
+     240             :     device_(torch::kCPU)
+     241             : {
+     242             :     if (metatensor_torch::version().find("0.5.") != 0) {
+     243             :         this->error(
+     244             :             "this code requires version 0.5.x of metatensor-torch, got version " +
+     245             :             metatensor_torch::version()
+     246             :         );
+     247             :     }
+     248             : 
+     249             :     // first, load the model
+     250             :     std::string extensions_directory_str;
+     251             :     this->parse("EXTENSIONS_DIRECTORY", extensions_directory_str);
+     252             : 
+     253             :     torch::optional<std::string> extensions_directory = torch::nullopt;
+     254             :     if (!extensions_directory_str.empty()) {
+     255             :         extensions_directory = std::move(extensions_directory_str);
+     256             :     }
+     257             : 
+     258             :     std::string model_path;
+     259             :     this->parse("MODEL", model_path);
+     260             : 
+     261             :     try {
+     262             :         this->model_ = metatensor_torch::load_atomistic_model(model_path, extensions_directory);
+     263             :     } catch (const std::exception& e) {
+     264             :         this->error("failed to load model at '" + model_path + "': " + e.what());
+     265             :     }
+     266             : 
+     267             :     // extract information from the model
+     268             :     auto metadata = this->model_.run_method("metadata").toCustomClass<metatensor_torch::ModelMetadataHolder>();
+     269             :     this->capabilities_ = this->model_.run_method("capabilities").toCustomClass<metatensor_torch::ModelCapabilitiesHolder>();
+     270             :     auto requests_ivalue = this->model_.run_method("requested_neighbor_lists");
+     271             :     for (auto request_ivalue: requests_ivalue.toList()) {
+     272             :         auto request = request_ivalue.get().toCustomClass<metatensor_torch::NeighborListOptionsHolder>();
+     273             :         this->nl_requests_.push_back(request);
+     274             :     }
+     275             : 
+     276             :     log.printf("\n%s\n", metadata->print().c_str());
+     277             :     // add the model references to PLUMED citation handling mechanism
+     278             :     for (const auto& it: metadata->references) {
+     279             :         for (const auto& ref: it.value()) {
+     280             :             this->cite(ref);
+     281             :         }
+     282             :     }
+     283             : 
+     284             :     // parse the atomic types from the input file
+     285             :     std::vector<int32_t> atomic_types;
+     286             :     std::vector<int32_t> species_to_types;
+     287             :     this->parseVector("SPECIES_TO_TYPES", species_to_types);
+     288             :     bool has_custom_types = !species_to_types.empty();
+     289             : 
+     290             :     std::vector<AtomNumber> all_atoms;
+     291             :     this->parseAtomList("SPECIES", all_atoms);
+     292             : 
+     293             :     size_t n_species = 0;
+     294             :     if (all_atoms.empty()) {
+     295             :         std::vector<AtomNumber> t;
+     296             :         int i = 0;
+     297             :         while (true) {
+     298             :             i += 1;
+     299             :             this->parseAtomList("SPECIES", i, t);
+     300             :             if (t.empty()) {
+     301             :                 break;
+     302             :             }
+     303             : 
+     304             :             int32_t type = i;
+     305             :             if (has_custom_types) {
+     306             :                 if (species_to_types.size() < static_cast<size_t>(i)) {
+     307             :                     this->error(
+     308             :                         "SPECIES_TO_TYPES is too small, it should have one entry "
+     309             :                         "for each species (we have at least " + std::to_string(i) +
+     310             :                         " species and " + std::to_string(species_to_types.size()) +
+     311             :                         "entries in SPECIES_TO_TYPES)"
+     312             :                     );
+     313             :                 }
+     314             : 
+     315             :                 type = species_to_types[static_cast<size_t>(i - 1)];
+     316             :             }
+     317             : 
+     318             :             log.printf("  atoms with type %d are: ", type);
+     319             :             for(unsigned j=0; j<t.size(); j++) {
+     320             :                 log.printf("%d ", t[j]);
+     321             :                 all_atoms.push_back(t[j]);
+     322             :                 atomic_types.push_back(type);
+     323             :             }
+     324             :             log.printf("\n"); t.resize(0);
+     325             : 
+     326             :             n_species += 1;
+     327             :         }
+     328             :     } else {
+     329             :         n_species = 1;
+     330             : 
+     331             :         int32_t type = 1;
+     332             :         if (has_custom_types) {
+     333             :             type = species_to_types[0];
+     334             :         }
+     335             :         atomic_types.resize(all_atoms.size(), type);
+     336             :     }
+     337             : 
+     338             :     if (has_custom_types && species_to_types.size() != n_species) {
+     339             :         this->warning(
+     340             :             "SPECIES_TO_TYPES contains more entries (" +
+     341             :             std::to_string(species_to_types.size()) +
+     342             :             ") than there where species (" + std::to_string(n_species) + ")"
+     343             :         );
+     344             :     }
+     345             : 
+     346             :     this->atomic_types_ = torch::tensor(std::move(atomic_types));
+     347             :     this->requestAtoms(all_atoms);
+     348             : 
+     349             :     this->check_consistency_ = false;
+     350             :     this->parseFlag("CHECK_CONSISTENCY", this->check_consistency_);
+     351             :     if (this->check_consistency_) {
+     352             :         log.printf("  checking for internal consistency of the model\n");
+     353             :     }
+     354             : 
+     355             :     // create evaluation options for the model. These won't change during the
+     356             :     // simulation, so we initialize them once here.
+     357             :     evaluations_options_ = torch::make_intrusive<metatensor_torch::ModelEvaluationOptionsHolder>();
+     358             :     evaluations_options_->set_length_unit(getUnits().getLengthString());
+     359             : 
+     360             :     auto outputs = this->capabilities_->outputs();
+     361             :     if (outputs.contains("features")) {
+     362             :         this->model_output_ = "features";
+     363             :     }
+     364             : 
+     365             :     if (outputs.contains("plumed::cv")) {
+     366             :         if (outputs.contains("features")) {
+     367             :             this->warning(
+     368             :                 "this model exposes both 'features' and 'plumed::cv' outputs, "
+     369             :                 "we will use 'features'. 'plumed::cv' is deprecated, please "
+     370             :                 "remove it from your models"
+     371             :             );
+     372             :         } else {
+     373             :             this->warning(
+     374             :                 "this model is using 'plumed::cv' output, which is deprecated. "
+     375             :                 "Please replace it with a 'features' output"
+     376             :             );
+     377             :             this->model_output_ = "plumed::cv";
+     378             :         }
+     379             :     }
+     380             : 
+     381             : 
+     382             :     if (this->model_output_.empty()) {
+     383             :         auto existing_outputs = std::vector<std::string>();
+     384             :         for (const auto& it: this->capabilities_->outputs()) {
+     385             :             existing_outputs.push_back(it.key());
+     386             :         }
+     387             : 
+     388             :         this->error(
+     389             :             "expected 'features' or 'plumed::cv' in the capabilities of the model, "
+     390             :             "could not find it. the following outputs exist: " + torch::str(existing_outputs)
+     391             :         );
+     392             :     }
+     393             : 
+     394             :     auto output = torch::make_intrusive<metatensor_torch::ModelOutputHolder>();
+     395             :     // this output has no quantity or unit to set
+     396             : 
+     397             :     output->per_atom = this->capabilities_->outputs().at(this->model_output_)->per_atom;
+     398             :     // we are using torch autograd system to compute gradients,
+     399             :     // so we don't need any explicit gradients.
+     400             :     output->explicit_gradients = {};
+     401             :     evaluations_options_->outputs.insert(this->model_output_, output);
+     402             : 
+     403             :     // Determine which device we should use based on user input, what the model
+     404             :     // supports and what's available
+     405             :     auto available_devices = std::vector<torch::Device>();
+     406             :     for (const auto& device: this->capabilities_->supported_devices) {
+     407             :         if (device == "cpu") {
+     408             :             available_devices.push_back(torch::kCPU);
+     409             :         } else if (device == "cuda") {
+     410             :             if (torch::cuda::is_available()) {
+     411             :                 available_devices.push_back(torch::Device("cuda"));
+     412             :             }
+     413             :         } else if (device == "mps") {
+     414             :             #if TORCH_VERSION_MAJOR >= 2
+     415             :             if (torch::mps::is_available()) {
+     416             :                 available_devices.push_back(torch::Device("mps"));
+     417             :             }
+     418             :             #endif
+     419             :         } else {
+     420             :             this->warning(
+     421             :                 "the model declared support for unknown device '" + device +
+     422             :                 "', it will be ignored"
+     423             :             );
+     424             :         }
+     425             :     }
+     426             : 
+     427             :     if (available_devices.empty()) {
+     428             :         this->error(
+     429             :             "failed to find a valid device for the model at '" + model_path + "': "
+     430             :             "the model supports " + torch::str(this->capabilities_->supported_devices) +
+     431             :             ", none of these where available"
+     432             :         );
+     433             :     }
+     434             : 
+     435             :     std::string requested_device;
+     436             :     this->parse("DEVICE", requested_device);
+     437             :     if (requested_device.empty()) {
+     438             :         // no user request, pick the device the model prefers
+     439             :         this->device_ = available_devices[0];
+     440             :     } else {
+     441             :         bool found_requested_device = false;
+     442             :         for (const auto& device: available_devices) {
+     443             :             if (device.is_cpu() && requested_device == "cpu") {
+     444             :                 this->device_ = device;
+     445             :                 found_requested_device = true;
+     446             :                 break;
+     447             :             } else if (device.is_cuda() && requested_device == "cuda") {
+     448             :                 this->device_ = device;
+     449             :                 found_requested_device = true;
+     450             :                 break;
+     451             :             } else if (device.is_mps() && requested_device == "mps") {
+     452             :                 this->device_ = device;
+     453             :                 found_requested_device = true;
+     454             :                 break;
+     455             :             }
+     456             :         }
+     457             : 
+     458             :         if (!found_requested_device) {
+     459             :             this->error(
+     460             :                 "failed to find requested device (" + requested_device + "): it is either "
+     461             :                 "not supported by this model or not available on this machine"
+     462             :             );
+     463             :         }
+     464             :     }
+     465             : 
+     466             :     this->model_.to(this->device_);
+     467             :     this->atomic_types_ = this->atomic_types_.to(this->device_);
+     468             : 
+     469             :     log.printf(
+     470             :         "  running model on %s device with %s data\n",
+     471             :         this->device_.str().c_str(),
+     472             :         this->capabilities_->dtype().c_str()
+     473             :     );
+     474             : 
+     475             :     if (this->capabilities_->dtype() == "float64") {
+     476             :         this->dtype_ = torch::kFloat64;
+     477             :     } else if (this->capabilities_->dtype() == "float32") {
+     478             :         this->dtype_ = torch::kFloat32;
+     479             :     } else {
+     480             :         this->error(
+     481             :             "the model requested an unsupported dtype '" + this->capabilities_->dtype() + "'"
+     482             :         );
+     483             :     }
+     484             : 
+     485             :     auto tensor_options = torch::TensorOptions().dtype(this->dtype_).device(this->device_);
+     486             :     this->strain_ = torch::eye(3, tensor_options.requires_grad(true));
+     487             : 
+     488             :     // determine how many properties there will be in the output by running the
+     489             :     // model once on a dummy system
+     490             :     auto dummy_system = torch::make_intrusive<metatensor_torch::SystemHolder>(
+     491             :         /*types = */ torch::zeros({0}, tensor_options.dtype(torch::kInt32)),
+     492             :         /*positions = */ torch::zeros({0, 3}, tensor_options),
+     493             :         /*cell = */ torch::zeros({3, 3}, tensor_options)
+     494             :     );
+     495             : 
+     496             :     log.printf("  the following neighbor lists have been requested:\n");
+     497             :     auto length_unit = this->getUnits().getLengthString();
+     498             :     auto model_length_unit = this->capabilities_->length_unit();
+     499             :     for (auto request: this->nl_requests_) {
+     500             :         log.printf("    - %s list, %g %s cutoff (requested %g %s)\n",
+     501             :             request->full_list() ? "full" : "half",
+     502             :             request->engine_cutoff(length_unit),
+     503             :             length_unit.c_str(),
+     504             :             request->cutoff(),
+     505             :             model_length_unit.c_str()
+     506             :         );
+     507             : 
+     508             :         auto neighbors = this->computeNeighbors(request, {PLMD::Vector(0, 0, 0)}, PLMD::Tensor(0, 0, 0, 0, 0, 0, 0, 0, 0));
+     509             :         metatensor_torch::register_autograd_neighbors(dummy_system, neighbors, this->check_consistency_);
+     510             :         dummy_system->add_neighbor_list(request, neighbors);
+     511             :     }
+     512             : 
+     513             :     this->n_properties_ = static_cast<unsigned>(
+     514             :         this->executeModel(dummy_system)->properties()->count()
+     515             :     );
+     516             : 
+     517             :     // parse and handle atom sub-selection. This is done AFTER determining the
+     518             :     // output size, since the selection might not be valid for the dummy system
+     519             :     std::vector<int32_t> selected_atoms;
+     520             :     this->parseVector("SELECTED_ATOMS", selected_atoms);
+     521             :     if (!selected_atoms.empty()) {
+     522             :         auto selection_value = torch::zeros(
+     523             :             {static_cast<int64_t>(selected_atoms.size()), 2},
+     524             :             torch::TensorOptions().dtype(torch::kInt32).device(this->device_)
+     525             :         );
+     526             : 
+     527             :         for (unsigned i=0; i<selected_atoms.size(); i++) {
+     528             :             auto n_atoms = static_cast<int32_t>(this->atomic_types_.size(0));
+     529             :             if (selected_atoms[i] <= 0 || selected_atoms[i] > n_atoms) {
+     530             :                 this->error(
+     531             :                     "Values in metatensor's SELECTED_ATOMS should be between 1 "
+     532             :                     "and the number of atoms (" + std::to_string(n_atoms) + "), "
+     533             :                     "got " + std::to_string(selected_atoms[i]));
+     534             :             }
+     535             :             // PLUMED input uses 1-based indexes, but metatensor wants 0-based
+     536             :             selection_value[i][1] = selected_atoms[i] - 1;
+     537             :         }
+     538             : 
+     539             :         evaluations_options_->set_selected_atoms(
+     540             :             torch::make_intrusive<metatensor_torch::LabelsHolder>(
+     541             :                 std::vector<std::string>{"system", "atom"}, selection_value
+     542             :             )
+     543             :         );
+     544             :     }
+     545             : 
+     546             :     // Now that we now both n_samples and n_properties, we can setup the
+     547             :     // PLUMED-side storage for the computed CV
+     548             :     if (output->per_atom) {
+     549             :         if (selected_atoms.empty()) {
+     550             :             this->n_samples_ = static_cast<unsigned>(this->atomic_types_.size(0));
+     551             :         } else {
+     552             :             this->n_samples_ = static_cast<unsigned>(selected_atoms.size());
+     553             :         }
+     554             :     } else {
+     555             :         this->n_samples_ = 1;
+     556             :     }
+     557             : 
+     558             :     if (n_samples_ == 1 && n_properties_ == 1) {
+     559             :         log.printf("  the output of this model is a scalar\n");
+     560             : 
+     561             :         this->addValue();
+     562             :     } else if (n_samples_ == 1) {
+     563             :         log.printf("  the output of this model is 1x%d vector\n", n_properties_);
+     564             : 
+     565             :         this->addValue({this->n_properties_});
+     566             :         this->getPntrToComponent(0)->buildDataStore();
+     567             :     } else if (n_properties_ == 1) {
+     568             :         log.printf("  the output of this model is %dx1 vector\n", n_samples_);
+     569             : 
+     570             :         this->addValue({this->n_samples_});
+     571             :         this->getPntrToComponent(0)->buildDataStore();
+     572             :     } else {
+     573             :         log.printf("  the output of this model is a %dx%d matrix\n", n_samples_, n_properties_);
+     574             : 
+     575             :         this->addValue({this->n_samples_, this->n_properties_});
+     576             :         this->getPntrToComponent(0)->buildDataStore();
+     577             :         this->getPntrToComponent(0)->reshapeMatrixStore(n_properties_);
+     578             :     }
+     579             : 
+     580             :     this->setNotPeriodic();
+     581             : }
+     582             : 
+     583             : unsigned MetatensorPlumedAction::getNumberOfDerivatives() {
+     584             :     // gradients w.r.t. positions (3 x N values) + gradients w.r.t. strain (9 values)
+     585             :     return 3 * this->getNumberOfAtoms() + 9;
+     586             : }
+     587             : 
+     588             : 
+     589             : void MetatensorPlumedAction::createSystem() {
+     590             :     if (this->getTotAtoms() != static_cast<unsigned>(this->atomic_types_.size(0))) {
+     591             :         std::ostringstream oss;
+     592             :         oss << "METATENSOR action needs to know about all atoms in the system. ";
+     593             :         oss << "There are " << this->getTotAtoms() << " atoms overall, ";
+     594             :         oss << "but we only have atomic types for " << this->atomic_types_.size(0) << " of them.";
+     595             :         plumed_merror(oss.str());
+     596             :     }
+     597             : 
+     598             :     // this->getTotAtoms()
+     599             : 
+     600             :     const auto& cell = this->getPbc().getBox();
+     601             : 
+     602             :     auto cpu_f64_tensor = torch::TensorOptions().dtype(torch::kFloat64).device(torch::kCPU);
+     603             :     auto torch_cell = torch::zeros({3, 3}, cpu_f64_tensor);
+     604             : 
+     605             :     torch_cell[0][0] = cell(0, 0);
+     606             :     torch_cell[0][1] = cell(0, 1);
+     607             :     torch_cell[0][2] = cell(0, 2);
+     608             : 
+     609             :     torch_cell[1][0] = cell(1, 0);
+     610             :     torch_cell[1][1] = cell(1, 1);
+     611             :     torch_cell[1][2] = cell(1, 2);
+     612             : 
+     613             :     torch_cell[2][0] = cell(2, 0);
+     614             :     torch_cell[2][1] = cell(2, 1);
+     615             :     torch_cell[2][2] = cell(2, 2);
+     616             : 
+     617             :     const auto& positions = this->getPositions();
+     618             : 
+     619             :     auto torch_positions = torch::from_blob(
+     620             :         const_cast<PLMD::Vector*>(positions.data()),
+     621             :         {static_cast<int64_t>(positions.size()), 3},
+     622             :         cpu_f64_tensor
+     623             :     );
+     624             : 
+     625             :     torch_positions = torch_positions.to(this->dtype_).to(this->device_);
+     626             :     torch_cell = torch_cell.to(this->dtype_).to(this->device_);
+     627             : 
+     628             :     // setup torch's automatic gradient tracking
+     629             :     if (!this->doNotCalculateDerivatives()) {
+     630             :         torch_positions.requires_grad_(true);
+     631             : 
+     632             :         // pretend to scale positions/cell by the strain so that it enters the
+     633             :         // computational graph.
+     634             :         torch_positions = torch_positions.matmul(this->strain_);
+     635             :         torch_positions.retain_grad();
+     636             : 
+     637             :         torch_cell = torch_cell.matmul(this->strain_);
+     638             :     }
+     639             : 
+     640             :     this->system_ = torch::make_intrusive<metatensor_torch::SystemHolder>(
+     641             :         this->atomic_types_,
+     642             :         torch_positions,
+     643             :         torch_cell
+     644             :     );
+     645             : 
+     646             :     // compute the neighbors list requested by the model, and register them with
+     647             :     // the system
+     648             :     for (auto request: this->nl_requests_) {
+     649             :         auto neighbors = this->computeNeighbors(request, positions, cell);
+     650             :         metatensor_torch::register_autograd_neighbors(this->system_, neighbors, this->check_consistency_);
+     651             :         this->system_->add_neighbor_list(request, neighbors);
+     652             :     }
+     653             : }
+     654             : 
+     655             : 
+     656             : metatensor_torch::TorchTensorBlock MetatensorPlumedAction::computeNeighbors(
+     657             :     metatensor_torch::NeighborListOptions request,
+     658             :     const std::vector<PLMD::Vector>& positions,
+     659             :     const PLMD::Tensor& cell
+     660             : ) {
+     661             :     auto labels_options = torch::TensorOptions().dtype(torch::kInt32).device(this->device_);
+     662             :     auto neighbor_component = torch::make_intrusive<metatensor_torch::LabelsHolder>(
+     663             :         "xyz",
+     664             :         torch::tensor({0, 1, 2}, labels_options).reshape({3, 1})
+     665             :     );
+     666             :     auto neighbor_properties = torch::make_intrusive<metatensor_torch::LabelsHolder>(
+     667             :         "distance", torch::zeros({1, 1}, labels_options)
+     668             :     );
+     669             : 
+     670             :     auto cutoff = request->engine_cutoff(this->getUnits().getLengthString());
+     671             : 
+     672             :     auto non_periodic = (
+     673             :         cell(0, 0) == 0.0 && cell(0, 1) == 0.0 && cell(0, 2) == 0.0 &&
+     674             :         cell(1, 0) == 0.0 && cell(1, 1) == 0.0 && cell(1, 2) == 0.0 &&
+     675             :         cell(2, 0) == 0.0 && cell(2, 2) == 0.0 && cell(2, 2) == 0.0
+     676             :     );
+     677             : 
+     678             :     // use https://github.com/Luthaf/vesin to compute the requested neighbor
+     679             :     // lists since we can not get these from PLUMED
+     680             :     vesin::VesinOptions options;
+     681             :     options.cutoff = cutoff;
+     682             :     options.full = request->full_list();
+     683             :     options.return_shifts = true;
+     684             :     options.return_distances = false;
+     685             :     options.return_vectors = true;
+     686             : 
+     687             :     vesin::VesinNeighborList* vesin_neighbor_list = new vesin::VesinNeighborList();
+     688             :     memset(vesin_neighbor_list, 0, sizeof(vesin::VesinNeighborList));
+     689             : 
+     690             :     const char* error_message = NULL;
+     691             :     int status = vesin_neighbors(
+     692             :         reinterpret_cast<const double (*)[3]>(positions.data()),
+     693             :         positions.size(),
+     694             :         reinterpret_cast<const double (*)[3]>(&cell(0, 0)),
+     695             :         !non_periodic,
+     696             :         vesin::VesinCPU,
+     697             :         options,
+     698             :         vesin_neighbor_list,
+     699             :         &error_message
+     700             :     );
+     701             : 
+     702             :     if (status != EXIT_SUCCESS) {
+     703             :         plumed_merror(
+     704             :             "failed to compute neighbor list (cutoff=" + std::to_string(cutoff) +
+     705             :             ", full=" + (request->full_list() ? "true" : "false") + "): " + error_message
+     706             :         );
+     707             :     }
+     708             : 
+     709             :     // transform from vesin to metatensor format
+     710             :     auto n_pairs = static_cast<int64_t>(vesin_neighbor_list->length);
+     711             : 
+     712             :     auto pair_vectors = torch::from_blob(
+     713             :         vesin_neighbor_list->vectors,
+     714             :         {n_pairs, 3, 1},
+     715             :         /*deleter*/ [=](void*) {
+     716             :             vesin_free(vesin_neighbor_list);
+     717             :             delete vesin_neighbor_list;
+     718             :         },
+     719             :         torch::TensorOptions().dtype(torch::kFloat64).device(torch::kCPU)
+     720             :     );
+     721             : 
+     722             :     auto pair_samples_values = torch::zeros({n_pairs, 5}, labels_options.device(torch::kCPU));
+     723             :     for (unsigned i=0; i<n_pairs; i++) {
+     724             :         pair_samples_values[i][0] = static_cast<int32_t>(vesin_neighbor_list->pairs[i][0]);
+     725             :         pair_samples_values[i][1] = static_cast<int32_t>(vesin_neighbor_list->pairs[i][1]);
+     726             :         pair_samples_values[i][2] = vesin_neighbor_list->shifts[i][0];
+     727             :         pair_samples_values[i][3] = vesin_neighbor_list->shifts[i][1];
+     728             :         pair_samples_values[i][4] = vesin_neighbor_list->shifts[i][2];
+     729             :     }
+     730             : 
+     731             :     auto neighbor_samples = torch::make_intrusive<metatensor_torch::LabelsHolder>(
+     732             :         std::vector<std::string>{"first_atom", "second_atom", "cell_shift_a", "cell_shift_b", "cell_shift_c"},
+     733             :         pair_samples_values.to(this->device_)
+     734             :     );
+     735             : 
+     736             :     auto neighbors = torch::make_intrusive<metatensor_torch::TensorBlockHolder>(
+     737             :         pair_vectors.to(this->dtype_).to(this->device_),
+     738             :         neighbor_samples,
+     739             :         std::vector<metatensor_torch::TorchLabels>{neighbor_component},
+     740             :         neighbor_properties
+     741             :     );
+     742             : 
+     743             :     return neighbors;
+     744             : }
+     745             : 
+     746             : metatensor_torch::TorchTensorBlock MetatensorPlumedAction::executeModel(metatensor_torch::System system) {
+     747             :     try {
+     748             :         auto ivalue_output = this->model_.forward({
+     749             :             std::vector<metatensor_torch::System>{system},
+     750             :             evaluations_options_,
+     751             :             this->check_consistency_,
+     752             :         });
+     753             : 
+     754             :         auto dict_output = ivalue_output.toGenericDict();
+     755             :         auto cv = dict_output.at(this->model_output_);
+     756             :         this->output_ = cv.toCustomClass<metatensor_torch::TensorMapHolder>();
+     757             :     } catch (const std::exception& e) {
+     758             :         plumed_merror("failed to evaluate the model: " + std::string(e.what()));
+     759             :     }
+     760             : 
+     761             :     plumed_massert(this->output_->keys()->count() == 1, "output should have a single block");
+     762             :     auto block = metatensor_torch::TensorMapHolder::block_by_id(this->output_, 0);
+     763             :     plumed_massert(block->components().empty(), "components are not yet supported in the output");
+     764             : 
+     765             :     return block;
+     766             : }
+     767             : 
+     768             : 
+     769             : void MetatensorPlumedAction::calculate() {
+     770             :     this->createSystem();
+     771             : 
+     772             :     auto block = this->executeModel(this->system_);
+     773             :     auto torch_values = block->values().to(torch::kCPU).to(torch::kFloat64);
+     774             : 
+     775             :     if (static_cast<unsigned>(torch_values.size(0)) != this->n_samples_) {
+     776             :         plumed_merror(
+     777             :             "expected the model to return a TensorBlock with " +
+     778             :             std::to_string(this->n_samples_) + " samples, got " +
+     779             :             std::to_string(torch_values.size(0)) + " instead"
+     780             :         );
+     781             :     } else if (static_cast<unsigned>(torch_values.size(1)) != this->n_properties_) {
+     782             :         plumed_merror(
+     783             :             "expected the model to return a TensorBlock with " +
+     784             :             std::to_string(this->n_properties_) + " properties, got " +
+     785             :             std::to_string(torch_values.size(1)) + " instead"
+     786             :         );
+     787             :     }
+     788             : 
+     789             :     Value* value = this->getPntrToComponent(0);
+     790             :     // reshape the plumed `Value` to hold the data returned by the model
+     791             :     if (n_samples_ == 1) {
+     792             :         if (n_properties_ == 1) {
+     793             :             value->set(torch_values.item<double>());
+     794             :         } else {
+     795             :             // we have multiple CV describing a single thing (atom or full system)
+     796             :             for (unsigned i=0; i<n_properties_; i++) {
+     797             :                 value->set(i, torch_values[0][i].item<double>());
+     798             :             }
+     799             :         }
+     800             :     } else {
+     801             :         auto samples = block->samples();
+     802             :         plumed_assert((samples->names() == std::vector<std::string>{"system", "atom"}));
+     803             : 
+     804             :         auto samples_values = samples->values().to(torch::kCPU);
+     805             :         auto selected_atoms = this->evaluations_options_->get_selected_atoms();
+     806             : 
+     807             :         // handle the possibility that samples are returned in
+     808             :         // a non-sorted order.
+     809             :         auto get_output_location = [&](unsigned i) {
+     810             :             if (selected_atoms.has_value()) {
+     811             :                 // If the users picked some selected atoms, then we store the
+     812             :                 // output in the same order as the selection was given
+     813             :                 auto sample = samples_values.index({static_cast<int64_t>(i), torch::indexing::Slice()});
+     814             :                 auto position = selected_atoms.value()->position(sample);
+     815             :                 plumed_assert(position.has_value());
+     816             :                 return static_cast<unsigned>(position.value());
+     817             :             } else {
+     818             :                 return static_cast<unsigned>(samples_values[i][1].item<int32_t>());
+     819             :             }
+     820             :         };
+     821             : 
+     822             :         if (n_properties_ == 1) {
+     823             :             // we have a single CV describing multiple things (i.e. atoms)
+     824             :             for (unsigned i=0; i<n_samples_; i++) {
+     825             :                 auto output_i = get_output_location(i);
+     826             :                 value->set(output_i, torch_values[i][0].item<double>());
+     827             :             }
+     828             :         } else {
+     829             :             // the CV is a matrix
+     830             :             for (unsigned i=0; i<n_samples_; i++) {
+     831             :                 auto output_i = get_output_location(i);
+     832             :                 for (unsigned j=0; j<n_properties_; j++) {
+     833             :                     value->set(output_i * n_properties_ + j, torch_values[i][j].item<double>());
+     834             :                 }
+     835             :             }
+     836             :         }
+     837             :     }
+     838             : }
+     839             : 
+     840             : 
+     841             : void MetatensorPlumedAction::apply() {
+     842             :     const auto* value = this->getPntrToComponent(0);
+     843             :     if (!value->forcesWereAdded()) {
+     844             :         return;
+     845             :     }
+     846             : 
+     847             :     auto block = metatensor_torch::TensorMapHolder::block_by_id(this->output_, 0);
+     848             :     auto torch_values = block->values().to(torch::kCPU).to(torch::kFloat64);
+     849             : 
+     850             :     auto output_grad = torch::zeros_like(torch_values);
+     851             :     if (n_samples_ == 1) {
+     852             :         if (n_properties_ == 1) {
+     853             :             output_grad[0][0] = value->getForce();
+     854             :         } else {
+     855             :             for (unsigned i=0; i<n_properties_; i++) {
+     856             :                 output_grad[0][i] = value->getForce(i);
+     857             :             }
+     858             :         }
+     859             :     } else {
+     860             :         auto samples = block->samples();
+     861             :         plumed_assert((samples->names() == std::vector<std::string>{"system", "atom"}));
+     862             : 
+     863             :         auto samples_values = samples->values().to(torch::kCPU);
+     864             :         auto selected_atoms = this->evaluations_options_->get_selected_atoms();
+     865             : 
+     866             :         // see above for an explanation of why we use this function
+     867             :         auto get_output_location = [&](unsigned i) {
+     868             :             if (selected_atoms.has_value()) {
+     869             :                 auto sample = samples_values.index({static_cast<int64_t>(i), torch::indexing::Slice()});
+     870             :                 auto position = selected_atoms.value()->position(sample);
+     871             :                 plumed_assert(position.has_value());
+     872             :                 return static_cast<unsigned>(position.value());
+     873             :             } else {
+     874             :                 return static_cast<unsigned>(samples_values[i][1].item<int32_t>());
+     875             :             }
+     876             :         };
+     877             : 
+     878             :         if (n_properties_ == 1) {
+     879             :             for (unsigned i=0; i<n_samples_; i++) {
+     880             :                 auto output_i = get_output_location(i);
+     881             :                 output_grad[i][0] = value->getForce(output_i);
+     882             :             }
+     883             :         } else {
+     884             :             for (unsigned i=0; i<n_samples_; i++) {
+     885             :                 auto output_i = get_output_location(i);
+     886             :                 for (unsigned j=0; j<n_properties_; j++) {
+     887             :                     output_grad[i][j] = value->getForce(output_i * n_properties_ + j);
+     888             :                 }
+     889             :             }
+     890             :         }
+     891             :     }
+     892             : 
+     893             :     this->system_->positions().mutable_grad() = torch::Tensor();
+     894             :     this->strain_.mutable_grad() = torch::Tensor();
+     895             : 
+     896             :     torch_values.backward(output_grad);
+     897             :     auto positions_grad = this->system_->positions().grad();
+     898             :     auto strain_grad = this->strain_.grad();
+     899             : 
+     900             :     positions_grad = positions_grad.to(torch::kCPU).to(torch::kFloat64);
+     901             :     strain_grad = strain_grad.to(torch::kCPU).to(torch::kFloat64);
+     902             : 
+     903             :     plumed_assert(positions_grad.sizes().size() == 2);
+     904             :     plumed_assert(positions_grad.is_contiguous());
+     905             : 
+     906             :     plumed_assert(strain_grad.sizes().size() == 2);
+     907             :     plumed_assert(strain_grad.is_contiguous());
+     908             : 
+     909             :     auto derivatives = std::vector<double>(
+     910             :         positions_grad.data_ptr<double>(),
+     911             :         positions_grad.data_ptr<double>() + 3 * this->system_->size()
+     912             :     );
+     913             : 
+     914             :     // add virials to the derivatives
+     915             :     derivatives.push_back(-strain_grad[0][0].item<double>());
+     916             :     derivatives.push_back(-strain_grad[0][1].item<double>());
+     917             :     derivatives.push_back(-strain_grad[0][2].item<double>());
+     918             : 
+     919             :     derivatives.push_back(-strain_grad[1][0].item<double>());
+     920             :     derivatives.push_back(-strain_grad[1][1].item<double>());
+     921             :     derivatives.push_back(-strain_grad[1][2].item<double>());
+     922             : 
+     923             :     derivatives.push_back(-strain_grad[2][0].item<double>());
+     924             :     derivatives.push_back(-strain_grad[2][1].item<double>());
+     925             :     derivatives.push_back(-strain_grad[2][2].item<double>());
+     926             : 
+     927             :     unsigned index = 0;
+     928             :     this->setForcesOnAtoms(derivatives, index);
+     929             : }
+     930             : 
+     931             : } // namespace metatensor
+     932             : } // namespace PLMD
+     933             : 
+     934             : 
+     935             : #endif
+     936             : 
+     937             : 
+     938             : namespace PLMD {
+     939             : namespace metatensor {
+     940             : 
+     941             : // use the same implementation for both the actual action and the dummy one
+     942             : // (when libtorch and libmetatensor could not be found).
+     943           2 : void MetatensorPlumedAction::registerKeywords(Keywords& keys) {
+     944           2 :     Action::registerKeywords(keys);
+     945           2 :     ActionAtomistic::registerKeywords(keys);
+     946           2 :     ActionWithValue::registerKeywords(keys);
+     947             : 
+     948           4 :     keys.add("compulsory", "MODEL", "path to the exported metatensor model");
+     949           4 :     keys.add("optional", "EXTENSIONS_DIRECTORY", "path to the directory containing TorchScript extensions to load");
+     950           4 :     keys.add("optional", "DEVICE", "Torch device to use for the calculation");
+     951             : 
+     952           4 :     keys.addFlag("CHECK_CONSISTENCY", false, "Should we enable internal consistency of the model");
+     953             : 
+     954           4 :     keys.add("numbered", "SPECIES", "the atoms in each PLUMED species");
+     955           4 :     keys.reset_style("SPECIES", "atoms");
+     956             : 
+     957           4 :     keys.add("optional", "SELECTED_ATOMS", "subset of atoms that should be used for the calculation");
+     958           4 :     keys.reset_style("SELECTED_ATOMS", "atoms");
+     959             : 
+     960           4 :     keys.add("optional", "SPECIES_TO_TYPES", "mapping from PLUMED SPECIES to metatensor's atomic types");
+     961             : 
+     962           4 :     keys.addOutputComponent("outputs", "default", "collective variable created by the metatensor model");
+     963             : 
+     964           2 :     keys.setValueDescription("collective variable created by the metatensor model");
+     965           2 : }
+     966             : 
+     967             : PLUMED_REGISTER_ACTION(MetatensorPlumedAction, "METATENSOR")
+     968             : 
+     969             : } // namespace metatensor
+     970             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/vesin.cpp.func-sort-c.html b/coverage/metatensor/vesin.cpp.func-sort-c.html new file mode 100644 index 000000000..4a3134787 --- /dev/null +++ b/coverage/metatensor/vesin.cpp.func-sort-c.html @@ -0,0 +1,188 @@ + + + + + + + LCOV - plumed test coverage - metatensor/vesin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensor - vesin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:03210.0 %
Date:2024-10-17 16:45:00Functions:0290.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_Z5allocIdEPT_S1_mm0
_Z5allocIdLm3EEPAT0__T_S2_mm0
_Z5allocIiLm3EEPAT0__T_S2_mm0
_Z5allocImLm2EEPAT0__T_S2_mm0
_ZL6divmodSt5arrayIiLm3EES_ImLm3EE0
_ZL6divmodim0
_ZN4PLMD10metatensor5vesin11BoundingBoxC2ENS1_6MatrixEb0
_ZN4PLMD10metatensor5vesin3cpu14free_neighborsERNS1_17VesinNeighborListE0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList10set_vectorEmNS1_6VectorE0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList12set_distanceEmd0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList4growEv0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList5resetEv0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList8set_pairEmmm0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList9set_shiftEmNS1_9CellShiftE0
_ZN4PLMD10metatensor5vesin3cpu8CellList12foreach_pairIZNS2_9neighborsEPKNS1_6VectorEmNS1_11BoundingBoxENS1_12VesinOptionsERNS1_17VesinNeighborListEEUlmmNS1_9CellShiftEE_EEvT_0
_ZN4PLMD10metatensor5vesin3cpu8CellList8get_cellESt5arrayIiLm3EE0
_ZN4PLMD10metatensor5vesin3cpu8CellList9add_pointEmNS1_6VectorE0
_ZN4PLMD10metatensor5vesin3cpu8CellListC2ENS1_11BoundingBoxEd0
_ZN4PLMD10metatensor5vesin3cpu9neighborsEPKNS1_6VectorEmNS1_11BoundingBoxENS1_12VesinOptionsERNS1_17VesinNeighborListE0
_ZN4PLMD10metatensor5vesinmlENS1_6VectorENS1_6MatrixE0
_ZNK4PLMD10metatensor5vesin11BoundingBox23distances_between_facesEv0
_ZNK4PLMD10metatensor5vesin6Matrix11determinantEv0
_ZNK4PLMD10metatensor5vesin6Matrix7inverseEv0
_ZNK4PLMD10metatensor5vesin6Vector4normEv0
_ZNK4PLMD10metatensor5vesin6Vector9normalizeEv0
_ZNK4PLMD10metatensor5vesin9CellShift9cartesianENS1_6MatrixE0
_ZZN4PLMD10metatensor5vesin3cpu9neighborsEPKNS1_6VectorEmNS1_11BoundingBoxENS1_12VesinOptionsERNS1_17VesinNeighborListEENKUlmmNS1_9CellShiftEE_clEmmSA_0
vesin_free0
vesin_neighbors0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/vesin.cpp.func.html b/coverage/metatensor/vesin.cpp.func.html new file mode 100644 index 000000000..bdd88df2a --- /dev/null +++ b/coverage/metatensor/vesin.cpp.func.html @@ -0,0 +1,188 @@ + + + + + + + LCOV - plumed test coverage - metatensor/vesin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensor - vesin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:03210.0 %
Date:2024-10-17 16:45:00Functions:0290.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_Z5allocIdEPT_S1_mm0
_Z5allocIdLm3EEPAT0__T_S2_mm0
_Z5allocIiLm3EEPAT0__T_S2_mm0
_Z5allocImLm2EEPAT0__T_S2_mm0
_ZL6divmodSt5arrayIiLm3EES_ImLm3EE0
_ZL6divmodim0
_ZN4PLMD10metatensor5vesin11BoundingBoxC2ENS1_6MatrixEb0
_ZN4PLMD10metatensor5vesin3cpu14free_neighborsERNS1_17VesinNeighborListE0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList10set_vectorEmNS1_6VectorE0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList12set_distanceEmd0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList4growEv0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList5resetEv0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList8set_pairEmmm0
_ZN4PLMD10metatensor5vesin3cpu20GrowableNeighborList9set_shiftEmNS1_9CellShiftE0
_ZN4PLMD10metatensor5vesin3cpu8CellList12foreach_pairIZNS2_9neighborsEPKNS1_6VectorEmNS1_11BoundingBoxENS1_12VesinOptionsERNS1_17VesinNeighborListEEUlmmNS1_9CellShiftEE_EEvT_0
_ZN4PLMD10metatensor5vesin3cpu8CellList8get_cellESt5arrayIiLm3EE0
_ZN4PLMD10metatensor5vesin3cpu8CellList9add_pointEmNS1_6VectorE0
_ZN4PLMD10metatensor5vesin3cpu8CellListC2ENS1_11BoundingBoxEd0
_ZN4PLMD10metatensor5vesin3cpu9neighborsEPKNS1_6VectorEmNS1_11BoundingBoxENS1_12VesinOptionsERNS1_17VesinNeighborListE0
_ZN4PLMD10metatensor5vesinmlENS1_6VectorENS1_6MatrixE0
_ZNK4PLMD10metatensor5vesin11BoundingBox23distances_between_facesEv0
_ZNK4PLMD10metatensor5vesin6Matrix11determinantEv0
_ZNK4PLMD10metatensor5vesin6Matrix7inverseEv0
_ZNK4PLMD10metatensor5vesin6Vector4normEv0
_ZNK4PLMD10metatensor5vesin6Vector9normalizeEv0
_ZNK4PLMD10metatensor5vesin9CellShift9cartesianENS1_6MatrixE0
_ZZN4PLMD10metatensor5vesin3cpu9neighborsEPKNS1_6VectorEmNS1_11BoundingBoxENS1_12VesinOptionsERNS1_17VesinNeighborListEENKUlmmNS1_9CellShiftEE_clEmmSA_0
vesin_free0
vesin_neighbors0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/metatensor/vesin.cpp.gcov.html b/coverage/metatensor/vesin.cpp.gcov.html new file mode 100644 index 000000000..2eaa83890 --- /dev/null +++ b/coverage/metatensor/vesin.cpp.gcov.html @@ -0,0 +1,952 @@ + + + + + + + LCOV - plumed test coverage - metatensor/vesin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - metatensor - vesin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:03210.0 %
Date:2024-10-17 16:45:00Functions:0290.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2024 The METATENSOR code team
+       3             : (see the PEOPLE-METATENSOR file at the root of this folder for a list of names)
+       4             : 
+       5             : See https://docs.metatensor.org/latest/ for more information about the
+       6             : metatensor package that this module allows you to call from PLUMED.
+       7             : 
+       8             : This file is part of METATENSOR-PLUMED module.
+       9             : 
+      10             : The METATENSOR-PLUMED module is free software: you can redistribute it and/or modify
+      11             : it under the terms of the GNU Lesser General Public License as published by
+      12             : the Free Software Foundation, either version 3 of the License, or
+      13             : (at your option) any later version.
+      14             : 
+      15             : The METATENSOR-PLUMED module is distributed in the hope that it will be useful,
+      16             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      17             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      18             : GNU Lesser General Public License for more details.
+      19             : 
+      20             : You should have received a copy of the GNU Lesser General Public License
+      21             : along with the METATENSOR-PLUMED module. If not, see <http://www.gnu.org/licenses/>.
+      22             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      23             : /*INDENT-OFF*/
+      24             : #include "vesin.h"
+      25             : #include <cassert>
+      26             : #include <cstdlib>
+      27             : #include <cstring>
+      28             : 
+      29             : #include <algorithm>
+      30             : #include <tuple>
+      31             : #include <new>
+      32             : 
+      33             : #ifndef VESIN_CPU_CELL_LIST_HPP
+      34             : #define VESIN_CPU_CELL_LIST_HPP
+      35             : 
+      36             : #include <vector>
+      37             : 
+      38             : #include "vesin.h"
+      39             : 
+      40             : #ifndef VESIN_TYPES_HPP
+      41             : #define VESIN_TYPES_HPP
+      42             : 
+      43             : #ifndef VESIN_MATH_HPP
+      44             : #define VESIN_MATH_HPP
+      45             : 
+      46             : #include <array>
+      47             : #include <cmath>
+      48             : #include <stdexcept>
+      49             : 
+      50             : namespace PLMD {
+      51             : namespace metatensor {
+      52             : namespace vesin {
+      53             : struct Vector;
+      54             : 
+      55             : Vector operator*(Vector vector, double scalar);
+      56             : 
+      57             : struct Vector: public std::array<double, 3> {
+      58             :     double dot(Vector other) const {
+      59           0 :         return (*this)[0] * other[0] + (*this)[1] * other[1] + (*this)[2] * other[2];
+      60             :     }
+      61             : 
+      62           0 :     double norm() const {
+      63           0 :         return std::sqrt(this->dot(*this));
+      64             :     }
+      65             : 
+      66           0 :     Vector normalize() const {
+      67           0 :         return *this * (1.0 / this->norm());
+      68             :     }
+      69             : 
+      70             :     Vector cross(Vector other) const {
+      71             :         return Vector{
+      72           0 :             (*this)[1] * other[2] - (*this)[2] * other[1],
+      73           0 :             (*this)[2] * other[0] - (*this)[0] * other[2],
+      74           0 :             (*this)[0] * other[1] - (*this)[1] * other[0],
+      75           0 :         };
+      76             :     }
+      77             : };
+      78             : 
+      79             : inline Vector operator+(Vector u, Vector v) {
+      80             :     return Vector{
+      81           0 :         u[0] + v[0],
+      82           0 :         u[1] + v[1],
+      83           0 :         u[2] + v[2],
+      84             :     };
+      85             : }
+      86             : 
+      87             : inline Vector operator-(Vector u, Vector v) {
+      88             :     return Vector{
+      89           0 :         u[0] - v[0],
+      90           0 :         u[1] - v[1],
+      91           0 :         u[2] - v[2],
+      92             :     };
+      93             : }
+      94             : 
+      95             : inline Vector operator*(double scalar, Vector vector) {
+      96             :     return Vector{
+      97             :         scalar * vector[0],
+      98             :         scalar * vector[1],
+      99             :         scalar * vector[2],
+     100             :     };
+     101             : }
+     102             : 
+     103             : inline Vector operator*(Vector vector, double scalar) {
+     104             :     return Vector{
+     105           0 :         scalar * vector[0],
+     106           0 :         scalar * vector[1],
+     107           0 :         scalar * vector[2],
+     108           0 :     };
+     109             : }
+     110             : 
+     111             : 
+     112             : struct Matrix: public std::array<std::array<double, 3>, 3> {
+     113           0 :     double determinant() const {
+     114           0 :         return (*this)[0][0] * ((*this)[1][1] * (*this)[2][2] - (*this)[2][1] * (*this)[1][2])
+     115           0 :              - (*this)[0][1] * ((*this)[1][0] * (*this)[2][2] - (*this)[1][2] * (*this)[2][0])
+     116           0 :              + (*this)[0][2] * ((*this)[1][0] * (*this)[2][1] - (*this)[1][1] * (*this)[2][0]);
+     117             :     }
+     118             : 
+     119           0 :     Matrix inverse() const {
+     120           0 :         auto det = this->determinant();
+     121             : 
+     122           0 :         if (std::abs(det) < 1e-30) {
+     123           0 :             throw std::runtime_error("this matrix is not invertible");
+     124             :         }
+     125             : 
+     126             :         auto inverse = Matrix();
+     127           0 :         inverse[0][0] = ((*this)[1][1] * (*this)[2][2] - (*this)[2][1] * (*this)[1][2]) / det;
+     128           0 :         inverse[0][1] = ((*this)[0][2] * (*this)[2][1] - (*this)[0][1] * (*this)[2][2]) / det;
+     129           0 :         inverse[0][2] = ((*this)[0][1] * (*this)[1][2] - (*this)[0][2] * (*this)[1][1]) / det;
+     130           0 :         inverse[1][0] = ((*this)[1][2] * (*this)[2][0] - (*this)[1][0] * (*this)[2][2]) / det;
+     131           0 :         inverse[1][1] = ((*this)[0][0] * (*this)[2][2] - (*this)[0][2] * (*this)[2][0]) / det;
+     132           0 :         inverse[1][2] = ((*this)[1][0] * (*this)[0][2] - (*this)[0][0] * (*this)[1][2]) / det;
+     133           0 :         inverse[2][0] = ((*this)[1][0] * (*this)[2][1] - (*this)[2][0] * (*this)[1][1]) / det;
+     134           0 :         inverse[2][1] = ((*this)[2][0] * (*this)[0][1] - (*this)[0][0] * (*this)[2][1]) / det;
+     135           0 :         inverse[2][2] = ((*this)[0][0] * (*this)[1][1] - (*this)[1][0] * (*this)[0][1]) / det;
+     136           0 :         return inverse;
+     137             :     }
+     138             : };
+     139             : 
+     140             : 
+     141             : inline Vector operator*(Matrix matrix, Vector vector) {
+     142             :     return Vector{
+     143             :         matrix[0][0] * vector[0] + matrix[0][1] * vector[1] + matrix[0][2] * vector[2],
+     144             :         matrix[1][0] * vector[0] + matrix[1][1] * vector[1] + matrix[1][2] * vector[2],
+     145             :         matrix[2][0] * vector[0] + matrix[2][1] * vector[1] + matrix[2][2] * vector[2],
+     146             :     };
+     147             : }
+     148             : 
+     149           0 : inline Vector operator*(Vector vector, Matrix matrix) {
+     150             :     return Vector{
+     151           0 :         vector[0] * matrix[0][0] + vector[1] * matrix[1][0] + vector[2] * matrix[2][0],
+     152           0 :         vector[0] * matrix[0][1] + vector[1] * matrix[1][1] + vector[2] * matrix[2][1],
+     153           0 :         vector[0] * matrix[0][2] + vector[1] * matrix[1][2] + vector[2] * matrix[2][2],
+     154           0 :     };
+     155             : }
+     156             : 
+     157             : } // namespace vesin
+     158             : } // namespace metatensor
+     159             : } // namespace PLMD
+     160             : 
+     161             : #endif
+     162             : 
+     163             : namespace PLMD {
+     164             : namespace metatensor {
+     165             : namespace vesin {
+     166             : 
+     167             : class BoundingBox {
+     168             : public:
+     169           0 :     BoundingBox(Matrix matrix, bool periodic): matrix_(matrix), periodic_(periodic) {
+     170           0 :         if (periodic) {
+     171           0 :             this->inverse_ = matrix_.inverse();
+     172             :         } else {
+     173           0 :             this->matrix_ = Matrix{{{
+     174             :                 {{1, 0, 0}},
+     175             :                 {{0, 1, 0}},
+     176             :                 {{0, 0, 1}}
+     177             :             }}};
+     178           0 :             this->inverse_ = matrix_;
+     179             :         }
+     180           0 :     }
+     181             : 
+     182             :     const Matrix& matrix() const {
+     183             :         return this->matrix_;
+     184             :     }
+     185             : 
+     186             :     bool periodic() const {
+     187           0 :         return this->periodic_;
+     188             :     }
+     189             : 
+     190             :     /// Convert a vector from cartesian coordinates to fractional coordinates
+     191             :     Vector cartesian_to_fractional(Vector cartesian) const {
+     192           0 :         return cartesian * inverse_;
+     193             :     }
+     194             : 
+     195             :     /// Convert a vector from fractional coordinates to cartesian coordinates
+     196             :     Vector fractional_to_cartesian(Vector fractional) const {
+     197             :         return fractional * matrix_;
+     198             :     }
+     199             : 
+     200             :     /// Get the three distances between faces of the bounding box
+     201           0 :     Vector distances_between_faces() const {
+     202           0 :         auto a = Vector{matrix_[0]};
+     203           0 :         auto b = Vector{matrix_[1]};
+     204           0 :         auto c = Vector{matrix_[2]};
+     205             : 
+     206             :         // Plans normal vectors
+     207           0 :         auto na = b.cross(c).normalize();
+     208           0 :         auto nb = c.cross(a).normalize();
+     209           0 :         auto nc = a.cross(b).normalize();
+     210             : 
+     211             :         return Vector{
+     212             :             std::abs(na.dot(a)),
+     213             :             std::abs(nb.dot(b)),
+     214             :             std::abs(nc.dot(c)),
+     215           0 :         };
+     216             :     }
+     217             : 
+     218             : private:
+     219             :     Matrix matrix_;
+     220             :     Matrix inverse_;
+     221             :     bool periodic_;
+     222             : };
+     223             : 
+     224             : 
+     225             : /// A cell shift represents the displacement along cell axis between the actual
+     226             : /// position of an atom and a periodic image of this atom.
+     227             : ///
+     228             : /// The cell shift can be used to reconstruct the vector between two points,
+     229             : /// wrapped inside the unit cell.
+     230             : struct CellShift: public std::array<int32_t, 3> {
+     231             :     /// Compute the shift vector in cartesian coordinates, using the given cell
+     232             :     /// matrix (stored in row major order).
+     233           0 :     Vector cartesian(Matrix cell) const {
+     234             :         auto vector = Vector{
+     235           0 :             static_cast<double>((*this)[0]),
+     236           0 :             static_cast<double>((*this)[1]),
+     237           0 :             static_cast<double>((*this)[2]),
+     238           0 :         };
+     239           0 :         return vector * cell;
+     240             :     }
+     241             : };
+     242             : 
+     243             : inline CellShift operator+(CellShift a, CellShift b) {
+     244             :     return CellShift{
+     245           0 :         a[0] + b[0],
+     246           0 :         a[1] + b[1],
+     247           0 :         a[2] + b[2],
+     248             :     };
+     249             : }
+     250             : 
+     251             : inline CellShift operator-(CellShift a, CellShift b) {
+     252             :     return CellShift{
+     253           0 :         a[0] - b[0],
+     254           0 :         a[1] - b[1],
+     255           0 :         a[2] - b[2],
+     256             :     };
+     257             : }
+     258             : 
+     259             : 
+     260             : } // namespace vesin
+     261             : } // namespace metatensor
+     262             : } // namespace PLMD
+     263             : 
+     264             : #endif
+     265             : 
+     266             : namespace PLMD {
+     267             : namespace metatensor {
+     268             : namespace vesin { namespace cpu {
+     269             : 
+     270             : void free_neighbors(VesinNeighborList& neighbors);
+     271             : 
+     272             : void neighbors(
+     273             :     const Vector* points,
+     274             :     size_t n_points,
+     275             :     BoundingBox cell,
+     276             :     VesinOptions options,
+     277             :     VesinNeighborList& neighbors
+     278             : );
+     279             : 
+     280             : 
+     281             : /// The cell list is used to sort atoms inside bins/cells.
+     282             : ///
+     283             : /// The list of potential pairs is then constructed by looking through all
+     284             : /// neighboring cells (the number of cells to search depends on the cutoff and
+     285             : /// the size of the cells) for each atom to create pair candidates.
+     286           0 : class CellList {
+     287             : public:
+     288             :     /// Create a new `CellList` for the given bounding box and cutoff,
+     289             :     /// determining all required parameters.
+     290             :     CellList(BoundingBox box, double cutoff);
+     291             : 
+     292             :     /// Add a single point to the cell list at the given `position`. The point
+     293             :     /// is uniquely identified by its `index`.
+     294             :     void add_point(size_t index, Vector position);
+     295             : 
+     296             :     /// Iterate over all possible pairs, calling the given callback every time
+     297             :     template <typename Function>
+     298             :     void foreach_pair(Function callback);
+     299             : 
+     300             : private:
+     301             :     /// How many cells do we need to look at when searching neighbors to include
+     302             :     /// all neighbors below cutoff
+     303             :     std::array<int32_t, 3> n_search_;
+     304             : 
+     305             :     /// the cells themselves are a list of points & corresponding
+     306             :     /// shift to place the point inside the cell
+     307             :     struct Point {
+     308             :         size_t index;
+     309             :         CellShift shift;
+     310             :     };
+     311           0 :     struct Cell: public std::vector<Point> {};
+     312             : 
+     313             :     // raw data for the cells
+     314             :     std::vector<Cell> cells_;
+     315             :     // shape of the cell array
+     316             :     std::array<size_t, 3> cells_shape_;
+     317             : 
+     318             :     BoundingBox box_;
+     319             : 
+     320             :     Cell& get_cell(std::array<int32_t, 3> index);
+     321             : };
+     322             : 
+     323             : /// Wrapper around `VesinNeighborList` that behaves like a std::vector,
+     324             : /// automatically growing memory allocations.
+     325             : class GrowableNeighborList {
+     326             : public:
+     327             :     VesinNeighborList& neighbors;
+     328             :     size_t capacity;
+     329             :     VesinOptions options;
+     330             : 
+     331             :     size_t length() const {
+     332           0 :         return neighbors.length;
+     333             :     }
+     334             : 
+     335             :     void increment_length() {
+     336           0 :         neighbors.length += 1;
+     337           0 :     }
+     338             : 
+     339             :     void set_pair(size_t index, size_t first, size_t second);
+     340             :     void set_shift(size_t index, PLMD::metatensor::vesin::CellShift shift);
+     341             :     void set_distance(size_t index, double distance);
+     342             :     void set_vector(size_t index, PLMD::metatensor::vesin::Vector vector);
+     343             : 
+     344             :     // reset length to 0, and allocate/deallocate members of
+     345             :     // `neighbors` according to `options`
+     346             :     void reset();
+     347             : 
+     348             :     // allocate more memory & update capacity
+     349             :     void grow();
+     350             : };
+     351             : 
+     352             : } // namespace vesin
+     353             : } // namespace metatensor
+     354             : } // namespace PLMD
+     355             : } // namespace cpu
+     356             : 
+     357             : #endif
+     358             : 
+     359             : using namespace PLMD::metatensor::vesin;
+     360             : using namespace PLMD::metatensor::vesin::cpu;
+     361             : 
+     362           0 : void PLMD::metatensor::vesin::cpu::neighbors(
+     363             :     const Vector* points,
+     364             :     size_t n_points,
+     365             :     BoundingBox cell,
+     366             :     VesinOptions options,
+     367             :     VesinNeighborList& raw_neighbors
+     368             : ) {
+     369           0 :     auto cell_list = CellList(cell, options.cutoff);
+     370             : 
+     371           0 :     for (size_t i=0; i<n_points; i++) {
+     372           0 :         cell_list.add_point(i, points[i]);
+     373             :     }
+     374             : 
+     375           0 :     auto cell_matrix = cell.matrix();
+     376           0 :     auto cutoff2 = options.cutoff * options.cutoff;
+     377             : 
+     378             :     // the cell list creates too many pairs, we only need to keep the
+     379             :     // one where the distance is actually below the cutoff
+     380           0 :     auto neighbors = GrowableNeighborList{raw_neighbors, raw_neighbors.length, options};
+     381           0 :     neighbors.reset();
+     382             : 
+     383           0 :     cell_list.foreach_pair([&](size_t first, size_t second, CellShift shift) {
+     384           0 :         if (!options.full) {
+     385             :             // filter out some pairs for half neighbor lists
+     386           0 :             if (first > second) {
+     387             :                 return;
+     388             :             }
+     389             : 
+     390           0 :             if (first == second) {
+     391             :                 // When creating pairs between a point and one of its periodic
+     392             :                 // images, the code generate multiple redundant pairs (e.g. with
+     393             :                 // shifts 0 1 1 and 0 -1 -1); and we want to only keep one of
+     394             :                 // these.
+     395           0 :                 if (shift[0] + shift[1] + shift[2] < 0) {
+     396             :                     // drop shifts on the negative half-space
+     397             :                     return;
+     398             :                 }
+     399             : 
+     400             :                 if ((shift[0] + shift[1] + shift[2] == 0)
+     401           0 :                     && (shift[2] < 0 || (shift[2] == 0 && shift[1] < 0))) {
+     402             :                     // drop shifts in the negative half plane or the negative
+     403             :                     // shift[1] axis. See below for a graphical representation:
+     404             :                     // we are keeping the shifts indicated with `O` and dropping
+     405             :                     // the ones indicated with `X`
+     406             :                     //
+     407             :                     //  O O O │ O O O
+     408             :                     //  O O O │ O O O
+     409             :                     //  O O O │ O O O
+     410             :                     // ─X─X─X─┼─O─O─O─
+     411             :                     //  X X X │ X X X
+     412             :                     //  X X X │ X X X
+     413             :                     //  X X X │ X X X
+     414             :                     return;
+     415             :                 }
+     416             :             }
+     417             :         }
+     418             : 
+     419           0 :         auto vector = points[second] - points[first] + shift.cartesian(cell_matrix);
+     420             :         auto distance2 = vector.dot(vector);
+     421             : 
+     422           0 :         if (distance2 < cutoff2) {
+     423           0 :             auto index = neighbors.length();
+     424           0 :             neighbors.set_pair(index, first, second);
+     425             : 
+     426           0 :             if (options.return_shifts) {
+     427           0 :                 neighbors.set_shift(index, shift);
+     428             :             }
+     429             : 
+     430           0 :             if (options.return_distances) {
+     431           0 :                 neighbors.set_distance(index, std::sqrt(distance2));
+     432             :             }
+     433             : 
+     434           0 :             if (options.return_vectors) {
+     435           0 :                 neighbors.set_vector(index, vector);
+     436             :             }
+     437             : 
+     438             :             neighbors.increment_length();
+     439             :         }
+     440             :     });
+     441           0 : }
+     442             : 
+     443             : /* ========================================================================== */
+     444             : 
+     445             : /// Maximal number of cells, we need to use this to prevent having too many
+     446             : /// cells with a small bounding box and a large cutoff
+     447             : #define MAX_NUMBER_OF_CELLS 1e5
+     448             : 
+     449             : 
+     450             : /// Function to compute both quotient and remainder of the division of a by b.
+     451             : /// This function follows Python convention, making sure the remainder have the
+     452             : /// same sign as `b`.
+     453           0 : static std::tuple<int32_t, int32_t> divmod(int32_t a, size_t b) {
+     454             :     assert(b < (std::numeric_limits<int32_t>::max()));
+     455           0 :     auto b_32 = static_cast<int32_t>(b);
+     456           0 :     auto quotient = a / b_32;
+     457           0 :     auto remainder = a % b_32;
+     458           0 :     if (remainder < 0) {
+     459           0 :         remainder += b_32;
+     460           0 :         quotient -= 1;
+     461             :     }
+     462           0 :     return std::make_tuple(quotient, remainder);
+     463             : }
+     464             : 
+     465             : /// Apply the `divmod` function to three components at the time
+     466             : static std::tuple<std::array<int32_t, 3>, std::array<int32_t, 3>>
+     467           0 : divmod(std::array<int32_t, 3> a, std::array<size_t, 3> b) {
+     468           0 :     auto [qx, rx] = divmod(a[0], b[0]);
+     469           0 :     auto [qy, ry] = divmod(a[1], b[1]);
+     470           0 :     auto [qz, rz] = divmod(a[2], b[2]);
+     471             :     return std::make_tuple(
+     472           0 :         std::array<int32_t, 3>{qx, qy, qz},
+     473           0 :         std::array<int32_t, 3>{rx, ry, rz}
+     474           0 :     );
+     475             : }
+     476             : 
+     477           0 : CellList::CellList(BoundingBox box, double cutoff):
+     478           0 :     n_search_({0, 0, 0}),
+     479           0 :     cells_shape_({0, 0, 0}),
+     480           0 :     box_(box)
+     481             : {
+     482           0 :     auto distances_between_faces = box_.distances_between_faces();
+     483             : 
+     484             :     auto n_cells = Vector{
+     485           0 :         std::clamp(std::trunc(distances_between_faces[0] / cutoff), 1.0, HUGE_VAL),
+     486           0 :         std::clamp(std::trunc(distances_between_faces[1] / cutoff), 1.0, HUGE_VAL),
+     487           0 :         std::clamp(std::trunc(distances_between_faces[2] / cutoff), 1.0, HUGE_VAL),
+     488           0 :     };
+     489             : 
+     490             :     assert(std::isfinite(n_cells[0]) && std::isfinite(n_cells[1]) && std::isfinite(n_cells[2]));
+     491             : 
+     492             :     // limit memory consumption by ensuring we have less than `MAX_N_CELLS`
+     493             :     // cells to look though
+     494           0 :     auto n_cells_total = n_cells[0] * n_cells[1] * n_cells[2];
+     495           0 :     if (n_cells_total > MAX_NUMBER_OF_CELLS) {
+     496             :         // set the total number of cells close to MAX_N_CELLS, while keeping
+     497             :         // roughly the ratio of cells in each direction
+     498           0 :         auto ratio_x_y = n_cells[0] / n_cells[1];
+     499           0 :         auto ratio_y_z = n_cells[1] / n_cells[2];
+     500             : 
+     501           0 :         n_cells[2] = std::trunc(std::cbrt(MAX_NUMBER_OF_CELLS / (ratio_x_y * ratio_y_z * ratio_y_z)));
+     502           0 :         n_cells[1] = std::trunc(ratio_y_z * n_cells[2]);
+     503           0 :         n_cells[0] = std::trunc(ratio_x_y * n_cells[1]);
+     504             :     }
+     505             : 
+     506             :     // number of cells to search in each direction to make sure all possible
+     507             :     // pairs below the cutoff are accounted for.
+     508           0 :     this->n_search_ = std::array<int32_t, 3>{
+     509           0 :         static_cast<int32_t>(std::ceil(cutoff * n_cells[0] / distances_between_faces[0])),
+     510           0 :         static_cast<int32_t>(std::ceil(cutoff * n_cells[1] / distances_between_faces[1])),
+     511           0 :         static_cast<int32_t>(std::ceil(cutoff * n_cells[2] / distances_between_faces[2])),
+     512             :     };
+     513             : 
+     514           0 :     this->cells_shape_ = std::array<size_t, 3>{
+     515           0 :         static_cast<size_t>(n_cells[0]),
+     516           0 :         static_cast<size_t>(n_cells[1]),
+     517           0 :         static_cast<size_t>(n_cells[2]),
+     518             :     };
+     519             : 
+     520           0 :     for (size_t spatial=0; spatial<3; spatial++) {
+     521           0 :         if (n_search_[spatial] < 1) {
+     522           0 :             n_search_[spatial] = 1;
+     523             :         }
+     524             : 
+     525             :         // don't look for neighboring cells if we have only one cell and no
+     526             :         // periodic boundary condition
+     527           0 :         if (n_cells[spatial] == 1 && !box.periodic()) {
+     528           0 :             n_search_[spatial] = 0;
+     529             :         }
+     530             :     }
+     531             : 
+     532           0 :     this->cells_.resize(cells_shape_[0] * cells_shape_[1] * cells_shape_[2]);
+     533           0 : }
+     534             : 
+     535           0 : void CellList::add_point(size_t index, Vector position) {
+     536           0 :     auto fractional = box_.cartesian_to_fractional(position);
+     537             : 
+     538             :     // find the cell in which this atom should go
+     539             :     auto cell_index = std::array<int32_t, 3>{
+     540           0 :         static_cast<int32_t>(std::floor(fractional[0] * static_cast<double>(cells_shape_[0]))),
+     541           0 :         static_cast<int32_t>(std::floor(fractional[1] * static_cast<double>(cells_shape_[1]))),
+     542           0 :         static_cast<int32_t>(std::floor(fractional[2] * static_cast<double>(cells_shape_[2]))),
+     543           0 :     };
+     544             : 
+     545             :     // deal with pbc by wrapping the atom inside if it was outside of the
+     546             :     // cell
+     547             :     CellShift shift;
+     548             :     // auto (shift, cell_index) =
+     549           0 :     if (box_.periodic()) {
+     550           0 :         auto result = divmod(cell_index, cells_shape_);
+     551           0 :         shift = CellShift{std::get<0>(result)};
+     552           0 :         cell_index = std::get<1>(result);
+     553             :     } else {
+     554             :         shift = CellShift({0, 0, 0});
+     555           0 :         cell_index = std::array<int32_t, 3>{
+     556           0 :             std::clamp(cell_index[0], 0, static_cast<int32_t>(cells_shape_[0] - 1)),
+     557           0 :             std::clamp(cell_index[1], 0, static_cast<int32_t>(cells_shape_[1] - 1)),
+     558           0 :             std::clamp(cell_index[2], 0, static_cast<int32_t>(cells_shape_[2] - 1)),
+     559             :         };
+     560             :     }
+     561             : 
+     562           0 :     this->get_cell(cell_index).emplace_back(Point{index, shift});
+     563           0 : }
+     564             : 
+     565             : 
+     566             : template <typename Function>
+     567           0 : void CellList::foreach_pair(Function callback) {
+     568           0 :     for (int32_t cell_i_x=0; cell_i_x<static_cast<int32_t>(cells_shape_[0]); cell_i_x++) {
+     569           0 :     for (int32_t cell_i_y=0; cell_i_y<static_cast<int32_t>(cells_shape_[1]); cell_i_y++) {
+     570           0 :     for (int32_t cell_i_z=0; cell_i_z<static_cast<int32_t>(cells_shape_[2]); cell_i_z++) {
+     571           0 :         const auto& current_cell = this->get_cell({cell_i_x, cell_i_y, cell_i_z});
+     572             :         // look through each neighboring cell
+     573           0 :         for (int32_t delta_x=-n_search_[0]; delta_x<=n_search_[0]; delta_x++) {
+     574           0 :         for (int32_t delta_y=-n_search_[1]; delta_y<=n_search_[1]; delta_y++) {
+     575           0 :         for (int32_t delta_z=-n_search_[2]; delta_z<=n_search_[2]; delta_z++) {
+     576           0 :             auto cell_i = std::array<int32_t, 3>{
+     577           0 :                 cell_i_x + delta_x,
+     578           0 :                 cell_i_y + delta_y,
+     579           0 :                 cell_i_z + delta_z,
+     580             :             };
+     581             : 
+     582             :             // shift vector from one cell to the other and index of
+     583             :             // the neighboring cell
+     584           0 :             auto [cell_shift, neighbor_cell_i] = divmod(cell_i, cells_shape_);
+     585             : 
+     586           0 :             for (const auto& atom_i: current_cell) {
+     587           0 :                 for (const auto& atom_j: this->get_cell(neighbor_cell_i)) {
+     588           0 :                     auto shift = CellShift{cell_shift} + atom_i.shift - atom_j.shift;
+     589           0 :                     auto shift_is_zero = shift[0] == 0 && shift[1] == 0 && shift[2] == 0;
+     590             : 
+     591           0 :                     if (!box_.periodic() && !shift_is_zero) {
+     592             :                         // do not create pairs crossing the periodic
+     593             :                         // boundaries in a non-periodic box
+     594           0 :                         continue;
+     595             :                     }
+     596             : 
+     597           0 :                     if (atom_i.index == atom_j.index && shift_is_zero) {
+     598             :                         // only create pairs with the same atom twice if the
+     599             :                         // pair spans more than one bounding box
+     600           0 :                         continue;
+     601             :                     }
+     602             : 
+     603           0 :                     callback(atom_i.index, atom_j.index, shift);
+     604             :                 }
+     605             :             } // loop over atoms in current neighbor cells
+     606             :         }}}
+     607             :     }}} // loop over neighboring cells
+     608           0 : }
+     609             : 
+     610           0 : CellList::Cell& CellList::get_cell(std::array<int32_t, 3> index) {
+     611           0 :     size_t linear_index = (cells_shape_[0] * cells_shape_[1] * index[2])
+     612           0 :                         + (cells_shape_[0] * index[1])
+     613           0 :                         + index[0];
+     614           0 :     return cells_[linear_index];
+     615             : }
+     616             : 
+     617             : /* ========================================================================== */
+     618             : 
+     619             : 
+     620           0 : void GrowableNeighborList::set_pair(size_t index, size_t first, size_t second) {
+     621           0 :     if (index >= this->capacity) {
+     622           0 :         this->grow();
+     623             :     }
+     624             : 
+     625           0 :     this->neighbors.pairs[index][0] = first;
+     626           0 :     this->neighbors.pairs[index][1] = second;
+     627           0 : }
+     628             : 
+     629           0 : void GrowableNeighborList::set_shift(size_t index, PLMD::metatensor::vesin::CellShift shift) {
+     630           0 :     if (index >= this->capacity) {
+     631           0 :         this->grow();
+     632             :     }
+     633             : 
+     634           0 :     this->neighbors.shifts[index][0] = shift[0];
+     635           0 :     this->neighbors.shifts[index][1] = shift[1];
+     636           0 :     this->neighbors.shifts[index][2] = shift[2];
+     637           0 : }
+     638             : 
+     639           0 : void GrowableNeighborList::set_distance(size_t index, double distance) {
+     640           0 :     if (index >= this->capacity) {
+     641           0 :         this->grow();
+     642             :     }
+     643             : 
+     644           0 :     this->neighbors.distances[index] = distance;
+     645           0 : }
+     646             : 
+     647           0 : void GrowableNeighborList::set_vector(size_t index, PLMD::metatensor::vesin::Vector vector) {
+     648           0 :     if (index >= this->capacity) {
+     649           0 :         this->grow();
+     650             :     }
+     651             : 
+     652           0 :     this->neighbors.vectors[index][0] = vector[0];
+     653           0 :     this->neighbors.vectors[index][1] = vector[1];
+     654           0 :     this->neighbors.vectors[index][2] = vector[2];
+     655           0 : }
+     656             : 
+     657             : template <typename scalar_t, size_t N>
+     658           0 : static scalar_t (*alloc(scalar_t (*ptr)[N], size_t size, size_t new_size))[N] {
+     659           0 :     auto* new_ptr = reinterpret_cast<scalar_t (*)[N]>(std::realloc(ptr, new_size * sizeof(scalar_t[N])));
+     660             : 
+     661           0 :     if (new_ptr == nullptr) {
+     662           0 :         throw std::bad_alloc();
+     663             :     }
+     664             : 
+     665             :     // initialize with a bit pattern that maps to NaN for double
+     666           0 :     std::memset(new_ptr + size, 0b11111111, (new_size - size) * sizeof(scalar_t[N]));
+     667             : 
+     668           0 :     return new_ptr;
+     669             : }
+     670             : 
+     671             : template <typename scalar_t>
+     672           0 : static scalar_t* alloc(scalar_t* ptr, size_t size, size_t new_size) {
+     673           0 :     auto* new_ptr = reinterpret_cast<scalar_t*>(std::realloc(ptr, new_size * sizeof(scalar_t)));
+     674             : 
+     675           0 :     if (new_ptr == nullptr) {
+     676           0 :         throw std::bad_alloc();
+     677             :     }
+     678             : 
+     679             :     // initialize with a bit pattern that maps to NaN for double
+     680           0 :     std::memset(new_ptr + size, 0b11111111, (new_size - size) * sizeof(scalar_t));
+     681             : 
+     682           0 :     return new_ptr;
+     683             : }
+     684             : 
+     685           0 : void GrowableNeighborList::grow() {
+     686           0 :     auto new_size = neighbors.length * 2;
+     687             :     if (new_size == 0) {
+     688             :         new_size = 1;
+     689             :     }
+     690             : 
+     691           0 :     auto* new_pairs = alloc<size_t, 2>(neighbors.pairs, neighbors.length, new_size);
+     692             : 
+     693             :     int32_t (*new_shifts)[3] = nullptr;
+     694           0 :     if (options.return_shifts) {
+     695           0 :         new_shifts = alloc<int32_t, 3>(neighbors.shifts, neighbors.length, new_size);
+     696             :     }
+     697             : 
+     698             :     double *new_distances = nullptr;
+     699           0 :     if (options.return_distances) {
+     700           0 :         new_distances = alloc<double>(neighbors.distances, neighbors.length, new_size);
+     701             :     }
+     702             : 
+     703             :     double (*new_vectors)[3] = nullptr;
+     704           0 :     if (options.return_vectors) {
+     705           0 :         new_vectors = alloc<double, 3>(neighbors.vectors, neighbors.length, new_size);
+     706             :     }
+     707             : 
+     708           0 :     this->neighbors.pairs = new_pairs;
+     709           0 :     this->neighbors.shifts = new_shifts;
+     710           0 :     this->neighbors.distances = new_distances;
+     711           0 :     this->neighbors.vectors = new_vectors;
+     712             : 
+     713           0 :     this->capacity = new_size;
+     714           0 : }
+     715             : 
+     716           0 : void GrowableNeighborList::reset() {
+     717             :     // set all allocated data to zero
+     718           0 :     auto size = this->neighbors.length;
+     719           0 :     std::memset(this->neighbors.pairs, 0, size * sizeof(size_t[2]));
+     720             : 
+     721           0 :     if (this->neighbors.shifts != nullptr) {
+     722           0 :         std::memset(this->neighbors.shifts, 0, size * sizeof(int32_t[3]));
+     723             :     }
+     724             : 
+     725           0 :     if (this->neighbors.distances != nullptr) {
+     726           0 :         std::memset(this->neighbors.distances, 0, size * sizeof(double));
+     727             :     }
+     728             : 
+     729           0 :     if (this->neighbors.vectors != nullptr) {
+     730           0 :         std::memset(this->neighbors.vectors, 0, size * sizeof(double[3]));
+     731             :     }
+     732             : 
+     733             :     // reset length (but keep the capacity where it's at)
+     734           0 :     this->neighbors.length = 0;
+     735             : 
+     736             :     // allocate/deallocate pointers as required
+     737           0 :     auto* shifts = this->neighbors.shifts;
+     738           0 :     if (this->options.return_shifts && shifts == nullptr) {
+     739           0 :         shifts = alloc<int32_t, 3>(shifts, 0, capacity);
+     740           0 :     } else if (!this->options.return_shifts && shifts != nullptr) {
+     741           0 :         std::free(shifts);
+     742             :         shifts = nullptr;
+     743             :     }
+     744             : 
+     745           0 :     auto* distances = this->neighbors.distances;
+     746           0 :     if (this->options.return_distances && distances == nullptr) {
+     747           0 :         distances = alloc<double>(distances, 0, capacity);
+     748           0 :     } else if (!this->options.return_distances && distances != nullptr) {
+     749           0 :         std::free(distances);
+     750             :         distances = nullptr;
+     751             :     }
+     752             : 
+     753           0 :     auto* vectors = this->neighbors.vectors;
+     754           0 :     if (this->options.return_vectors && vectors == nullptr) {
+     755           0 :         vectors = alloc<double, 3>(vectors, 0, capacity);
+     756           0 :     } else if (!this->options.return_vectors && vectors != nullptr) {
+     757           0 :         std::free(vectors);
+     758             :         vectors = nullptr;
+     759             :     }
+     760             : 
+     761           0 :     this->neighbors.shifts = shifts;
+     762           0 :     this->neighbors.distances = distances;
+     763           0 :     this->neighbors.vectors = vectors;
+     764           0 : }
+     765             : 
+     766             : 
+     767           0 : void PLMD::metatensor::vesin::cpu::free_neighbors(VesinNeighborList& neighbors) {
+     768             :     assert(neighbors.device == VesinCPU);
+     769             : 
+     770           0 :     std::free(neighbors.pairs);
+     771           0 :     std::free(neighbors.shifts);
+     772           0 :     std::free(neighbors.vectors);
+     773           0 :     std::free(neighbors.distances);
+     774           0 : }
+     775             : #include <cstring>
+     776             : #include <string>
+     777             : 
+     778             : 
+     779             : 
+     780             : thread_local std::string LAST_ERROR;
+     781             : 
+     782           0 : extern "C" int vesin_neighbors(
+     783             :     const double (*points)[3],
+     784             :     size_t n_points,
+     785             :     const double box[3][3],
+     786             :     bool periodic,
+     787             :     VesinDevice device,
+     788             :     VesinOptions options,
+     789             :     VesinNeighborList* neighbors,
+     790             :     const char** error_message
+     791             : ) {
+     792           0 :     if (error_message == nullptr) {
+     793             :         return EXIT_FAILURE;
+     794             :     }
+     795             : 
+     796           0 :     if (points == nullptr) {
+     797           0 :         *error_message = "`points` can not be a NULL pointer";
+     798           0 :         return EXIT_FAILURE;
+     799             :     }
+     800             : 
+     801           0 :     if (box == nullptr) {
+     802           0 :         *error_message = "`cell` can not be a NULL pointer";
+     803           0 :         return EXIT_FAILURE;
+     804             :     }
+     805             : 
+     806           0 :     if (neighbors == nullptr) {
+     807           0 :         *error_message = "`neighbors` can not be a NULL pointer";
+     808           0 :         return EXIT_FAILURE;
+     809             :     }
+     810             : 
+     811           0 :     if (neighbors->device != VesinUnknownDevice && neighbors->device != device) {
+     812           0 :         *error_message = "`neighbors` device and data `device` do not match, free the neighbors first";
+     813           0 :         return EXIT_FAILURE;
+     814             :     }
+     815             : 
+     816           0 :     if (device == VesinUnknownDevice) {
+     817           0 :         *error_message = "got an unknown device to use when running simulation";
+     818           0 :         return EXIT_FAILURE;
+     819             :     }
+     820             : 
+     821           0 :     if (neighbors->device == VesinUnknownDevice) {
+     822             :         // initialize the device
+     823           0 :         neighbors->device = device;
+     824           0 :     } else if (neighbors->device != device) {
+     825           0 :         *error_message = "`neighbors.device` and `device` do not match, free the neighbors first";
+     826           0 :         return EXIT_FAILURE;
+     827             :     }
+     828             : 
+     829             :     try {
+     830           0 :         if (device == VesinCPU) {
+     831             :             auto matrix = PLMD::metatensor::vesin::Matrix{{{
+     832           0 :                 {{box[0][0], box[0][1], box[0][2]}},
+     833           0 :                 {{box[1][0], box[1][1], box[1][2]}},
+     834           0 :                 {{box[2][0], box[2][1], box[2][2]}},
+     835           0 :             }}};
+     836             : 
+     837           0 :             PLMD::metatensor::vesin::cpu::neighbors(
+     838             :                 reinterpret_cast<const PLMD::metatensor::vesin::Vector*>(points),
+     839             :                 n_points,
+     840             :                 PLMD::metatensor::vesin::BoundingBox(matrix, periodic),
+     841             :                 options,
+     842             :                 *neighbors
+     843             :             );
+     844             :         } else {
+     845           0 :             throw std::runtime_error("unknown device " + std::to_string(device));
+     846             :         }
+     847           0 :     } catch (const std::bad_alloc&) {
+     848           0 :         LAST_ERROR = "failed to allocate memory";
+     849           0 :         *error_message = LAST_ERROR.c_str();
+     850             :         return EXIT_FAILURE;
+     851           0 :     } catch (const std::exception& e) {
+     852           0 :         LAST_ERROR = e.what();
+     853           0 :         *error_message = LAST_ERROR.c_str();
+     854             :         return EXIT_FAILURE;
+     855           0 :     } catch (...) {
+     856           0 :         *error_message = "fatal error: unknown type thrown as exception";
+     857             :         return EXIT_FAILURE;
+     858           0 :     }
+     859             : 
+     860           0 :     return EXIT_SUCCESS;
+     861             : }
+     862             : 
+     863             : 
+     864           0 : extern "C" void vesin_free(VesinNeighborList* neighbors) {
+     865           0 :     if (neighbors == nullptr) {
+     866             :         return;
+     867             :     }
+     868             : 
+     869           0 :     if (neighbors->device == VesinUnknownDevice) {
+     870             :         // nothing to do
+     871           0 :     } else if (neighbors->device == VesinCPU) {
+     872           0 :         PLMD::metatensor::vesin::cpu::free_neighbors(*neighbors);
+     873             :     }
+     874             : 
+     875             :     std::memset(neighbors, 0, sizeof(VesinNeighborList));
+     876             : }
+
+
+
+ + + + +
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 000000000..7d5bbffb3 --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:364090.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4f3bd2b68 --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:364090.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..fb7cf4a8e --- /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:364090.0 %
Date:2024-10-17 16:45:00Functions: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           4 :   keys.setValueDescription("the alpha beta CV");
+      63          20 :   keys.needsAction("CONSTANT"); keys.needsAction("TORSION"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("SUM");
+      64           4 : }
+      65             : 
+      66           2 : AlphaBeta::AlphaBeta(const ActionOptions& ao):
+      67             :   Action(ao),
+      68           2 :   ActionShortcut(ao)
+      69             : {
+      70             :   // Read in the reference value
+      71           4 :   std::string refstr; parse("REFERENCE",refstr); unsigned nref=0;
+      72           2 :   if( refstr.length()==0 ) {
+      73             :     for(unsigned i=0;; ++i) {
+      74             :       std::string refval;
+      75          18 :       if( !parseNumbered( "REFERENCE", i+1, refval ) ) break;
+      76          15 :       if( i==0 ) refstr = refval; else refstr += "," + refval;
+      77           8 :       nref++;
+      78           8 :     }
+      79             :   }
+      80           4 :   std::string coeffstr; parse("COEFFICIENT",coeffstr); unsigned ncoeff=0;
+      81           2 :   if( coeffstr.length()==0 ) {
+      82             :     for(unsigned i=0;; ++i) {
+      83             :       std::string coeff;
+      84           4 :       if( !parseNumbered( "COEFFICIENT", i+1, coeff) ) break;
+      85           0 :       if( i==0 ) coeffstr = coeff; else coeffstr += "," + coeff;
+      86           0 :       ncoeff++;
+      87           0 :     }
+      88             :   }
+      89           2 :   if( coeffstr.length()==0 ) coeffstr="1";
+      90             :   // Calculate angles
+      91           4 :   readInputLine( getShortcutLabel() + "_torsions: TORSION " + convertInputLineToString() );
+      92           2 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_torsions" );
+      93           2 :   plumed_assert( av && (av->copyOutput(0))->getRank()==1 );
+      94           2 :   if( nref==0 ) {
+      95           8 :     std::string refval=refstr; for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) refstr += "," + refval;
+      96           1 :   } else if( nref!=(av->copyOutput(0))->getShape()[0] ) error("mismatch between number of reference values and number of ATOMS specified");
+      97           2 :   if( ncoeff==0 ) {
+      98          16 :     std::string coeff=coeffstr; for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) coeffstr += "," + coeff;
+      99           0 :   } else if( ncoeff!=(av->copyOutput(0))->getShape()[0] ) error("mismatch between number of coefficients and number of ATOMS specified");
+     100           4 :   readInputLine( getShortcutLabel() + "_ref: CONSTANT VALUES=" + refstr );
+     101           4 :   readInputLine( getShortcutLabel() + "_coeff: CONSTANT VALUES=" + coeffstr );
+     102             :   // Caculate difference from reference using combine
+     103           4 :   readInputLine( getShortcutLabel() + "_comb: COMBINE ARG=" + getShortcutLabel() + "_torsions," + getShortcutLabel() + "_ref COEFFICIENTS=1,-1 PERIODIC=NO" );
+     104             :   // Now matheval for cosine bit
+     105           4 :   readInputLine( getShortcutLabel() + "_cos: CUSTOM ARG=" + getShortcutLabel() + "_comb," + getShortcutLabel() + "_coeff FUNC=y*(0.5+0.5*cos(x)) PERIODIC=NO");
+     106             :   // And combine to get final value
+     107           4 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_cos PERIODIC=NO");
+     108           2 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
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 000000000..2eb36c854 --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5df6dd3dc --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1b7c7a630 --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.gcov.html @@ -0,0 +1,251 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0ff88940b --- /dev/null +++ b/coverage/multicolvar/CoordAngles.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..9e35e5578 --- /dev/null +++ b/coverage/multicolvar/CoordAngles.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e093aa43f --- /dev/null +++ b/coverage/multicolvar/CoordAngles.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3df617c33 --- /dev/null +++ b/coverage/multicolvar/Dihcor.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:1212100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..c02c49435 --- /dev/null +++ b/coverage/multicolvar/Dihcor.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:1212100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..edbff21c9 --- /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:1212100.0 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the sum of all the dihedral correlations");
+      96           5 : }
+      97             : 
+      98           1 : Dihcor::Dihcor(const ActionOptions&ao):
+      99             :   Action(ao),
+     100           1 :   ActionShortcut(ao)
+     101             : {
+     102           2 :   readInputLine( getShortcutLabel() +"_data: DIHEDRAL_CORRELATION " + convertInputLineToString() );
+     103           2 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_data PERIODIC=NO");
+     104           1 : }
+     105             : 
+     106             : }
+     107             : }
+
+
+
+ + + + +
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 000000000..1ac872405 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:7777100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE58
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE132
+
+
+ + + +
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 000000000..6ae65d3a2 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:7777100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE132
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE58
_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 000000000..eef5a781b --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.gcov.html @@ -0,0 +1,366 @@ + + + + + + + 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:7777100.0 %
Date:2024-10-17 16:45:00Functions: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         132 : void Distances::registerKeywords(Keywords& keys) {
+     194         132 :   ActionShortcut::registerKeywords( keys );
+     195         264 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     196         264 :   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         264 :   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         264 :   keys.add("numbered","ATOMS","the pairs of atoms that you would like to calculate the angles for");
+     201         264 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     202         264 :   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         264 :   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         264 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     205         264 :   keys.reset_style("ATOMS","atoms"); MultiColvarShortcuts::shortcutKeywords( keys );
+     206         264 :   keys.add("atoms","ORIGIN","calculate the distance of all the atoms specified using the ATOMS keyword from this point");
+     207         264 :   keys.add("numbered","LOCATION","the location at which the CV is assumed to be in space");
+     208         264 :   keys.reset_style("LOCATION","atoms");
+     209         264 :   keys.addOutputComponent("x","COMPONENTS","the x-components of the distance vectors");
+     210         264 :   keys.addOutputComponent("y","COMPONENTS","the y-components of the distance vectors");
+     211         264 :   keys.addOutputComponent("z","COMPONENTS","the z-components of the distance vectors");
+     212         396 :   keys.needsAction("GROUP"); keys.needsAction("DISTANCE"); keys.needsAction("CENTER");
+     213         132 : }
+     214             : 
+     215          58 : Distances::Distances(const ActionOptions& ao):
+     216             :   Action(ao),
+     217          58 :   ActionShortcut(ao)
+     218             : {
+     219             :   // Create distances
+     220          58 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+     221          58 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     222          58 :   std::string dline = getShortcutLabel() + ": DISTANCE";
+     223         116 :   bool nopbc; parseFlag("NOPBC",nopbc); if( nopbc ) dline += " NOPBC";
+     224          58 :   if( getName()=="DISTANCES" ) {
+     225         110 :     bool comp; parseFlag("COMPONENTS",comp); if( comp ) dline += " COMPONENTS";
+     226         110 :     bool scomp; parseFlag("SCALED_COMPONENTS",scomp); if( scomp ) dline += " SCALED_COMPONENTS";
+     227             :   } else dline += " COMPONENTS";
+     228             :   // Parse origin
+     229         116 :   std::string num, ostr; parse("ORIGIN",ostr);
+     230          58 :   if( ostr.length()>0 ) {
+     231             :     // Parse atoms
+     232          23 :     std::vector<std::string> afstr; MultiColvarShortcuts::parseAtomList("ATOMS",afstr,this);
+     233       17118 :     for(unsigned i=0; i<afstr.size(); ++i) { Tools::convert( i+1, num ); dline += " ATOMS" + num + "=" + ostr + "," + afstr[i]; }
+     234          23 :   } else {
+     235          70 :     std::vector<std::string> grp; MultiColvarShortcuts::parseAtomList("GROUP",grp,this);
+     236          70 :     std::vector<std::string> grpa; MultiColvarShortcuts::parseAtomList("GROUPA",grpa,this);
+     237          35 :     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          32 :     } 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="; bool printcomment=false;
+     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         297 :           if( i*grpb.size() + j<6 ) readInputLine( getShortcutLabel() + "_vatom" + num + ": CENTER ATOMS=" + grpa[i] + "," + grpb[j], true );
+     255         570 :           else { readInputLine( getShortcutLabel() + "_vatom" + num + ": CENTER ATOMS=" + grpa[i] + "," + grpb[j], false ); printcomment=true; }
+     256         582 :           if( i+j==0 ) grpstr += getShortcutLabel() + "_vatom" + num; else grpstr += "," + getShortcutLabel() + "_vatom" + num;
+     257             :         }
+     258             :       }
+     259           1 :       std::string num; Tools::convert( grpa.size()*grpb.size(), num );
+     260           2 :       if( printcomment ) addCommentToShortcutOutput("# A further " + num + " CENTER like the ones above were also created but are not shown");
+     261           1 :       readInputLine( grpstr );
+     262           1 :     } else {
+     263          31 :       std::string grpstr = getShortcutLabel() + "_grp: GROUP ATOMS=";
+     264          31 :       for(unsigned i=1;; ++i) {
+     265        1844 :         std::string atstring; parseNumbered("ATOMS",i,atstring);
+     266         922 :         if( atstring.length()==0 ) break;
+     267        1782 :         std::string locstr; parseNumbered("LOCATION",i,locstr);
+     268         891 :         if( locstr.length()==0 ) {
+     269         281 :           std::string num; Tools::convert( i, num );
+     270         562 :           readInputLine( getShortcutLabel() + "_vatom" + num + ": CENTER ATOMS=" + atstring );
+     271         562 :           if( i==1 ) grpstr += getShortcutLabel() + "_vatom" + num; else grpstr += "," + getShortcutLabel() + "_vatom" + num;
+     272             :         } else {
+     273        1216 :           if( i==1 ) grpstr += locstr; else grpstr += "," + locstr;
+     274             :         }
+     275         891 :         std::string num; Tools::convert( i, num );
+     276        1782 :         dline += " ATOMS" + num + "=" + atstring;
+     277         891 :       }
+     278          31 :       readInputLine( grpstr );
+     279             :     }
+     280          35 :   }
+     281          58 :   readInputLine( dline );
+     282             :   // Add shortcuts to label
+     283         113 :   if( getName()=="DISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+     284           4 :   else if( getName()=="XDISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + ".x", "", this );
+     285           3 :   else if( getName()=="YDISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + ".y", "", this );
+     286           2 :   else if( getName()=="ZDISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + ".z", "", this );
+     287          58 : }
+     288             : 
+     289             : }
+     290             : }
+
+
+
+ + + + +
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 000000000..874a08acd --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0165461ab --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e633e25de --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html @@ -0,0 +1,141 @@ + + + + + + + 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-10-17 16:45:00Functions: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           4 :   keys.remove("HAS_VALUES"); 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 000000000..d42420cbd --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f24b333f3 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c7dd3d858 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fd70e4a8d --- /dev/null +++ b/coverage/multicolvar/MFilterLess.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:71546.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..c73f784b7 --- /dev/null +++ b/coverage/multicolvar/MFilterLess.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:71546.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..bf496aa98 --- /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:71546.7 %
Date:2024-10-17 16:45:00Functions: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           2 :   keys.setValueDescription("a vector that has the same dimension as the input vector with elements equal to one if the corresponding component of the vector is less than a tolerance and zero otherwise");
+      53           4 :   keys.needsAction("GROUP"); keys.needsAction("LESS_THAN");
+      54           2 : }
+      55             : 
+      56           0 : MFilterLess::MFilterLess(const ActionOptions& ao):
+      57             :   Action(ao),
+      58           0 :   ActionShortcut(ao)
+      59             : {
+      60           0 :   warning("This action has been depracated.  Look at the log to see how the same result is achieved with the new syntax");
+      61           0 :   std::string dd; parse("DATA",dd);
+      62           0 :   std::string swit; parse("SWITCH",swit);
+      63           0 :   readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + dd + "_grp");
+      64           0 :   readInputLine( getShortcutLabel() + ": LESS_THAN ARG=" + dd + " SWITCH={" + swit + "}");
+      65           0 : }
+      66             : 
+      67             : }
+      68             : }
+
+
+
+ + + + +
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 000000000..3b1cb5d8e --- /dev/null +++ b/coverage/multicolvar/MFilterMore.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8dd8de147 --- /dev/null +++ b/coverage/multicolvar/MFilterMore.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..affb94284 --- /dev/null +++ b/coverage/multicolvar/MFilterMore.cpp.gcov.html @@ -0,0 +1,154 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..46917ca7d --- /dev/null +++ b/coverage/multicolvar/MultiColvarShortcuts.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar20MultiColvarShortcuts13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EEPNS_14ActionShortcutE94
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_PNS_14ActionShortcutE125
_ZN4PLMD11multicolvar20MultiColvarShortcuts20readShortcutKeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEEPNS_14ActionShortcutE231
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKSt3mapIS7_S7_St4lessIS7_ESaISt4pairIS8_S7_EEEPNS_14ActionShortcutE240
_ZN4PLMD11multicolvar20MultiColvarShortcuts16shortcutKeywordsERNS_8KeywordsE736
+
+
+ + + +
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 000000000..1a0331368 --- /dev/null +++ b/coverage/multicolvar/MultiColvarShortcuts.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar20MultiColvarShortcuts13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EEPNS_14ActionShortcutE94
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_PNS_14ActionShortcutE125
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKSt3mapIS7_S7_St4lessIS7_ESaISt4pairIS8_S7_EEEPNS_14ActionShortcutE240
_ZN4PLMD11multicolvar20MultiColvarShortcuts16shortcutKeywordsERNS_8KeywordsE736
_ZN4PLMD11multicolvar20MultiColvarShortcuts20readShortcutKeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEEPNS_14ActionShortcutE231
+
+
+ + + +
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 000000000..3673e5331 --- /dev/null +++ b/coverage/multicolvar/MultiColvarShortcuts.cpp.gcov.html @@ -0,0 +1,327 @@ + + + + + + + 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-10-17 16:45:00Functions: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         736 : void MultiColvarShortcuts::shortcutKeywords( Keywords& keys ) {
+      31        1472 :   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        1472 :   keys.addOutputComponent("lessthan","LESS_THAN","the number of colvars that have a value less than a threshold");
+      35        1472 :   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        1472 :   keys.addOutputComponent("morethan","MORE_THAN","the number of colvars that have a value more than a threshold");
+      39        1472 :   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        1472 :   keys.addOutputComponent("altmin","ALT_MIN","the minimum value of the cv");
+      44        1472 :   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        1472 :   keys.addOutputComponent("min","MIN","the minimum colvar");
+      49        1472 :   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        1472 :   keys.addOutputComponent("max","MAX","the maximum colvar");
+      54        1472 :   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        1472 :   keys.addOutputComponent("between","BETWEEN","the number of colvars that have a value that lies in a particular interval");
+      58        1472 :   keys.addFlag("HIGHEST",false,"this flag allows you to recover the highest of these variables.");
+      59        1472 :   keys.addOutputComponent("highest","HIGHEST","the largest of the colvars");
+      60        1472 :   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        1472 :   keys.addFlag("LOWEST",false,"this flag allows you to recover the lowest of these variables.");
+      63        1472 :   keys.addOutputComponent("lowest","LOWEST","the smallest of the colvars");
+      64        1472 :   keys.addFlag("SUM",false,"calculate the sum of all the quantities.");
+      65        1472 :   keys.addOutputComponent("sum","SUM","the sum of the colvars");
+      66        1472 :   keys.addFlag("MEAN",false,"calculate the mean of all the quantities.");
+      67        1472 :   keys.addOutputComponent("mean","MEAN","the mean of the colvars");
+      68        3680 :   keys.needsAction("SUM"); keys.needsAction("MEAN"); keys.needsAction("CUSTOM"); keys.needsAction("HIGHEST"); keys.needsAction("LOWEST");
+      69        2208 :   keys.needsAction("LESS_THAN"); keys.needsAction("MORE_THAN"); keys.needsAction("BETWEEN");
+      70         736 : }
+      71             : 
+      72         125 : void MultiColvarShortcuts::expandFunctions( const std::string& labout, const std::string& argin, const std::string& weights, ActionShortcut* action ) {
+      73         125 :   std::map<std::string,std::string> keymap; readShortcutKeywords( keymap, action ); expandFunctions( labout, argin, weights, keymap, action );
+      74         125 : }
+      75             : 
+      76         231 : void MultiColvarShortcuts::readShortcutKeywords( std::map<std::string,std::string>& keymap, ActionShortcut* action ) {
+      77         231 :   Keywords keys; shortcutKeywords( keys ); action->readShortcutKeywords( keys, keymap );
+      78         231 : }
+      79             : 
+      80          94 : void MultiColvarShortcuts::parseAtomList( const std::string& key, std::vector<std::string>& atoms, ActionShortcut* action ) {
+      81          94 :   std::vector<std::string> astr; action->parseVector(key,astr); if( astr.size()==0 ) return ;
+      82          28 :   Tools::interpretRanges( astr );
+      83        1265 :   for(unsigned i=0; i<astr.size(); ++i) {
+      84        1237 :     Group* mygr=action->plumed.getActionSet().selectWithLabel<Group*>(astr[i]);
+      85        1237 :     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        1236 :       Group* mygr2=action->plumed.getActionSet().selectWithLabel<Group*>(astr[i] + "_grp");
+      90        1236 :       if( mygr2 ) {
+      91          10 :         std::vector<std::string> grstr( mygr2->getGroupAtoms() );
+      92       16082 :         for(unsigned j=0; j<grstr.size(); ++j) atoms.push_back(grstr[j]);
+      93        1236 :       } else atoms.push_back(astr[i]);
+      94             :     }
+      95             :   }
+      96          94 : }
+      97             : 
+      98         240 : 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         240 :   if( keymap.empty() ) return;
+     101             :   // Parse LESS_THAN
+     102         294 :   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         294 :   if( keymap.count("LESS_THAN1") ) {
+     112           2 :     for(unsigned i=1;; ++i) {
+     113           6 :       std::string istr; Tools::convert( i, istr );
+     114          12 :       if( !keymap.count("LESS_THAN" + istr ) ) { break; }
+     115          12 :       std::string sum_arg = labout + "_lt" + istr, lt_string1 = keymap.find("LESS_THAN" + istr)->second;
+     116           8 :       action->readInputLine( labout + "_lt" + istr + ": LESS_THAN ARG=" + argin + " SWITCH={" + lt_string1 + "}");
+     117           4 :       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           8 :       action->readInputLine( labout + "_lessthan-" + istr + ": SUM ARG=" + sum_arg + " PERIODIC=NO");
+     122           4 :     }
+     123             :   }
+     124             :   // Parse MORE_THAN
+     125         294 :   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         294 :   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         294 :   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         294 :   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         294 :   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         294 :   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         294 :   if( keymap.count("LOWEST") ) {
+     184           3 :     if( weights.length()>0 ) plumed_merror("cannot use LOWEST with this shortcut");
+     185           6 :     action->readInputLine( labout + "_lowest: LOWEST ARG=" + argin );
+     186             :   }
+     187             :   // Parse SUM
+     188         294 :   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         294 :   if( keymap.count("MEAN") ) {
+     198          64 :     if( weights.length()>0 ) plumed_merror("cannot use MEAN with this shortcut");
+     199         128 :     action->readInputLine( labout + "_mean: MEAN ARG=" + argin + " PERIODIC=NO");
+     200             :   }
+     201             :   // Parse BETWEEN
+     202         294 :   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         294 :   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         294 :   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 000000000..4dda6ba5d --- /dev/null +++ b/coverage/multicolvar/Planes.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..955e39479 --- /dev/null +++ b/coverage/multicolvar/Planes.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..acda39197 --- /dev/null +++ b/coverage/multicolvar/Planes.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..13a6c415f --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..dfa3e45dc --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..da8a4619d --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.gcov.html @@ -0,0 +1,173 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..745617892 --- /dev/null +++ b/coverage/multicolvar/UWalls.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6a7125e7e --- /dev/null +++ b/coverage/multicolvar/UWalls.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..74ca147c6 --- /dev/null +++ b/coverage/multicolvar/UWalls.cpp.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..49a43d694 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..951ff2ec4 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e17c4165d --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + 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-10-17 16:45:00Functions: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() + "_dists: 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() + "_dists.x" + "," + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_dists.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() + "_dists.x," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      91           2 :   readInputLine( getShortcutLabel() + "_norm_y: CUSTOM ARG=" + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      92           2 :   readInputLine( getShortcutLabel() + "_norm_z: CUSTOM ARG=" + getShortcutLabel() + "_dists.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 000000000..f23546552 --- /dev/null +++ b/coverage/multicolvar/XYTorsions.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..339019979 --- /dev/null +++ b/coverage/multicolvar/XYTorsions.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..bb6e5d4d3 --- /dev/null +++ b/coverage/multicolvar/XYTorsions.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2c714655d --- /dev/null +++ b/coverage/multicolvar/index-sort-f.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:51059785.4 %
Date:2024-10-17 16:45:00Functions:314963.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
UWalls.cpp +
75.0%75.0%
+
75.0 %15 / 2033.3 %1 / 3
DumpMultiColvar.cpp +
50.0%50.0%
+
50.0 %6 / 1233.3 %1 / 3
MFilterMore.cpp +
41.7%41.7%
+
41.7 %10 / 2433.3 %1 / 3
MFilterLess.cpp +
46.7%46.7%
+
46.7 %7 / 1533.3 %1 / 3
Dihcor.cpp +
100.0%
+
100.0 %12 / 1266.7 %2 / 3
Angles.cpp +
61.2%61.2%
+
61.2 %30 / 4966.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
AlphaBeta.cpp +
90.0%90.0%
+
90.0 %36 / 4066.7 %2 / 3
Torsions.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
Distances.cpp +
100.0%
+
100.0 %77 / 7766.7 %2 / 3
XYTorsions.cpp +
74.4%74.4%
+
74.4 %29 / 3966.7 %2 / 3
CoordAngles.cpp +
100.0%
+
100.0 %42 / 4275.0 %3 / 4
Planes.cpp +
88.9%88.9%
+
88.9 %40 / 4575.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 000000000..f67bb3651 --- /dev/null +++ b/coverage/multicolvar/index-sort-l.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:51059785.4 %
Date:2024-10-17 16:45:00Functions: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 +
46.7%46.7%
+
46.7 %7 / 1533.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 +
90.0%90.0%
+
90.0 %36 / 4066.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 %12 / 1266.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 %77 / 7766.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 000000000..ce8cae74e --- /dev/null +++ b/coverage/multicolvar/index.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:51059785.4 %
Date:2024-10-17 16:45:00Functions:314963.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AlphaBeta.cpp +
90.0%90.0%
+
90.0 %36 / 4066.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 %12 / 1266.7 %2 / 3
Distances.cpp +
100.0%
+
100.0 %77 / 7766.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 +
46.7%46.7%
+
46.7 %7 / 1533.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 000000000..3232f1123 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..99e1701a4 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..373b1d140 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.gcov.html @@ -0,0 +1,314 @@ + + + + + + + LCOV - plumed test coverage - opes/ECVcustom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVcustom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9210092.0 %
Date:2024-10-17 16:45:00Functions: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. Delta U_i, 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 beta");
+      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 000000000..e4bee119f --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..54f2df314 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c606693d1 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.gcov.html @@ -0,0 +1,344 @@ + + + + + + + LCOV - plumed test coverage - opes/ECVlinear.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVlinear.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11411995.8 %
Date:2024-10-17 16:45:00Functions: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. Delta U");
+     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 beta");
+     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 000000000..29ffb1100 --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f3c4a207c --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..46afa287c --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.gcov.html @@ -0,0 +1,344 @@ + + + + + + + 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-10-17 16:45:00Functions: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 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 000000000..c7d21845e --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c8cf53ab1 --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..64d4d2259 --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html @@ -0,0 +1,606 @@ + + + + + + + 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-10-17 16:45:00Functions: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 ENERGY and 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 000000000..fa3cdbd92 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..74e2a85c9 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..cbfddfaa4 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..e71f8162c --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c7419acdc --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b0a82f5f4 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.gcov.html @@ -0,0 +1,377 @@ + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasLine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasLine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12913198.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..a26cd9b2b --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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:9610690.6 %
Date:2024-10-17 16:45:00Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVsC1ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes12ExpansionCVs29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_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 000000000..f1679377a --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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:9610690.6 %
Date:2024-10-17 16:45:00Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZNK4PLMD4opes12ExpansionCVs29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE0
_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 000000000..fc91b7404 --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.gcov.html @@ -0,0 +1,302 @@ + + + + + + + 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:9610690.6 %
Date:2024-10-17 16:45:00Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "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           0 : std::string ExpansionCVs::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+      67           0 :   return "the value of the argument named " + cname;
+      68             : }
+      69             : 
+      70        1847 : void ExpansionCVs::calculate()
+      71             : {
+      72        1847 :   std::vector<double> args(getNumberOfArguments());
+      73        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      74             :   {
+      75        2623 :     args[j]=getArgument(j);
+      76        2623 :     getPntrToComponent(j)->set(args[j]); //components are equal to arguments
+      77        2623 :     getPntrToComponent(j)->addDerivative(0,1.); //the derivative of the identity is 1
+      78             :   }
+      79        1847 :   if(isReady_)
+      80        1417 :     calculateECVs(&args[0]);
+      81        1847 : }
+      82             : 
+      83        1847 : void ExpansionCVs::apply()
+      84             : {
+      85        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      86             :   {
+      87        2623 :     std::vector<double> force_j(1);
+      88        2623 :     if(getPntrToComponent(j)->applyForce(force_j)) //a bias is applied?
+      89        2623 :       getPntrToArgument(j)->addForce(force_j[0]); //just tell it to the CV!
+      90             :   }
+      91        1847 : }
+      92             : 
+      93          26 : std::vector< std::vector<unsigned> > ExpansionCVs::getIndex_k() const
+      94             : {
+      95          26 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+      96          26 :   std::vector< std::vector<unsigned> > index_k(totNumECVs_,std::vector<unsigned>(getNumberOfArguments()));
+      97         869 :   for(unsigned k=0; k<totNumECVs_; k++)
+      98        2391 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+      99        1548 :       index_k[k][j]=k; //each CV gives rise to the same number of ECVs
+     100          26 :   return index_k;
+     101           0 : }
+     102             : 
+     103             : //following methods are meant to be used only in case of linear expansions
+     104          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
+     105             : {
+     106          24 :   plumed_massert(!(lambda_min==lambda_max && lambda_steps>1),"cannot have multiple "+msg+"_STEPS if "+msg+"_MIN=="+msg+"_MAX");
+     107          24 :   std::vector<double> lambda(lambda_steps);
+     108          24 :   if(lambda_steps==1)
+     109             :   {
+     110           0 :     lambda[0]=(lambda_min+lambda_max)/2.;
+     111           0 :     log.printf(" +++ WARNING +++ using one single %s as target = %g\n",msg.c_str(),lambda[0]);
+     112             :   }
+     113             :   else
+     114             :   {
+     115          24 :     if(geom_spacing) //geometric spacing
+     116             :     { //this way lambda[k]/lambda[k+1] is constant
+     117          14 :       lambda_min+=shift;
+     118          14 :       lambda_max+=shift;
+     119          14 :       plumed_massert(lambda_min>0,"cannot use GEOM_SPACING when %s_MIN is not greater than zero");
+     120          14 :       plumed_massert(lambda_max>0,"cannot use GEOM_SPACING when %s_MAX is not greater than zero");
+     121          14 :       const double log_lambda_min=std::log(lambda_min);
+     122          14 :       const double log_lambda_max=std::log(lambda_max);
+     123         196 :       for(unsigned k=0; k<lambda.size(); k++)
+     124         182 :         lambda[k]=std::exp(log_lambda_min+k*(log_lambda_max-log_lambda_min)/(lambda_steps-1))-shift;
+     125             :     }
+     126             :     else //linear spacing
+     127         108 :       for(unsigned k=0; k<lambda.size(); k++)
+     128          98 :         lambda[k]=lambda_min+k*(lambda_max-lambda_min)/(lambda_steps-1);
+     129             :   }
+     130          24 :   return lambda;
+     131             : }
+     132             : 
+     133           6 : unsigned ExpansionCVs::estimateNumSteps(const double left_side,const double right_side,const std::vector<double>& obs,const std::string& msg) const
+     134             : { //for linear expansions only, it uses effective sample size (Neff) to estimate the grid spacing
+     135           6 :   if(left_side==0 && right_side==0)
+     136             :   {
+     137           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());
+     138           0 :     return 1;
+     139             :   }
+     140           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
+     141             :   {
+     142             :     //func: Neff/N-0.5 is a function between -0.5 and 0.5
+     143         109 :     auto func=[](const double delta,const std::vector<double>& obs)
+     144             :     {
+     145             :       double sum_w=0;
+     146             :       double sum_w2=0;
+     147             :       //we could avoid recomputing safe_shift every time, but here speed is not a concern
+     148         218 :       const double safe_shift=delta<0?*std::max_element(obs.begin(),obs.end()):*std::min_element(obs.begin(),obs.end());
+     149         899 :       for(unsigned t=0; t<obs.size(); t++)
+     150             :       {
+     151         790 :         const double w=std::exp(-delta*(obs[t]-safe_shift)); //robust to overflow
+     152         790 :         sum_w+=w;
+     153         790 :         sum_w2+=w*w;
+     154             :       }
+     155         109 :       return sum_w*sum_w/sum_w2/obs.size()-0.5;
+     156             :     };
+     157             :     //here we find the root of func using the regula falsi (false position) method
+     158             :     //but any method would be OK, not much precision is needed. src/tools/RootFindingBase.h looked complicated
+     159             :     const double tolerance=1e-4; //seems to be a good default
+     160             :     double a=0; //default is right side case
+     161             :     double func_a=0.5;
+     162             :     double b=side;
+     163           9 :     double func_b=func(side,obs);
+     164           9 :     if(func_b>=0)
+     165             :       return 0.0; //no zero is present!
+     166           9 :     if(b<0) //left side case
+     167             :     {
+     168             :       std::swap(a,b);
+     169             :       std::swap(func_a,func_b);
+     170             :     }
+     171             :     double c=a;
+     172             :     double func_c=func_a;
+     173         109 :     while(std::abs(func_c)>tolerance)
+     174             :     {
+     175         100 :       if(func_a*func_c>0)
+     176             :       {
+     177             :         a=c;
+     178             :         func_a=func_c;
+     179             :       }
+     180             :       else
+     181             :       {
+     182             :         b=c;
+     183             :         func_b=func_c;
+     184             :       }
+     185         100 :       c=(a*func_b-b*func_a)/(func_b-func_a);
+     186         100 :       func_c=func(c,obs); //func is evaluated only here, it might be expensive
+     187             :     }
+     188           9 :     return std::abs(c);
+     189             :   };
+     190             : 
+     191             : //estimation
+     192             :   double left_HWHM=0;
+     193           6 :   if(left_side!=0)
+     194           4 :     left_HWHM=get_neff_HWHM(left_side,obs);
+     195             :   double right_HWHM=0;
+     196           6 :   if(right_side!=0)
+     197           5 :     right_HWHM=get_neff_HWHM(right_side,obs);
+     198           6 :   if(left_HWHM==0)
+     199             :   {
+     200           2 :     right_HWHM*=2;
+     201           2 :     if(left_side==0)
+     202           2 :       log.printf(" --- %s_MIN is equal to %s\n",msg.c_str(),msg.c_str());
+     203             :     else
+     204           0 :       log.printf(" +++ WARNING +++ %s_MIN is very close to %s\n",msg.c_str(),msg.c_str());
+     205             :   }
+     206           6 :   if(right_HWHM==0)
+     207             :   {
+     208           1 :     left_HWHM*=2;
+     209           1 :     if(right_side==0)
+     210           1 :       log.printf(" --- %s_MAX is equal to %s\n",msg.c_str(),msg.c_str());
+     211             :     else
+     212           0 :       log.printf(" +++ WARNING +++ %s_MAX is very close to %s\n",msg.c_str(),msg.c_str());
+     213             :   }
+     214           6 :   const double grid_spacing=left_HWHM+right_HWHM;
+     215           6 :   log.printf("   estimated %s spacing = %g\n",msg.c_str(),grid_spacing);
+     216           6 :   unsigned steps=std::ceil(std::abs(right_side-left_side)/grid_spacing);
+     217           6 :   if(steps<2 || grid_spacing==0)
+     218             :   {
+     219           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());
+     220             :     steps=2;
+     221             :   }
+     222             :   return steps;
+     223             : }
+     224             : 
+     225             : }
+     226             : }
+
+
+
+ + + + +
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 000000000..a8c405547 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d4ad77c16 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..0f9ea4da6 --- /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-10-17 16:45:00Functions: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             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      52             :   void apply() override;
+      53             :   void calculate() override;
+      54             :   static void registerKeywords(Keywords&);
+      55         138 :   inline unsigned getNumberOfDerivatives() override {return 1;};
+      56             : 
+      57          67 :   inline double getKbT() const {return kbt_;};
+      58          50 :   inline unsigned getTotNumECVs() const {plumed_massert(isReady_,"cannot ask for totNumECVs before ECV isReady"); return totNumECVs_;};
+      59             :   virtual std::vector< std::vector<unsigned> > getIndex_k() const; //might need to override this
+      60             : 
+      61             :   virtual void calculateECVs(const double *) = 0;
+      62             :   virtual const double * getPntrToECVs(unsigned) = 0;
+      63             :   virtual const double * getPntrToDerECVs(unsigned) = 0;
+      64             :   virtual std::vector<std::string> getLambdas() const = 0;
+      65             :   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
+      66             :   virtual void initECVs_restart(const std::vector<std::string>&) = 0; //arg: the lambdas read from DeltaF_name relative to this ECV
+      67             : };
+      68             : 
+      69             : }
+      70             : }
+      71             : 
+      72             : #endif
+      73             : 
+
+
+
+ + + + +
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 000000000..c43aa7fe5 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43044297.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..fdc49c7fc --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43044297.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..6a99dcda6 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.gcov.html @@ -0,0 +1,1019 @@ + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43044297.3 %
Date:2024-10-17 16:45:00Functions: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          64 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     206          32 : }
+     207             : 
+     208          30 : OPESexpanded::OPESexpanded(const ActionOptions&ao)
+     209             :   : PLUMED_BIAS_INIT(ao)
+     210          30 :   , isFirstStep_(true)
+     211          30 :   , counter_(0)
+     212          30 :   , ncv_(getNumberOfArguments())
+     213          30 :   , deltaF_size_(0)
+     214          30 :   , rct_(0)
+     215          30 :   , work_(0)
+     216             : {
+     217             : //set pace
+     218          30 :   parse("PACE",stride_);
+     219          30 :   parse("OBSERVATION_STEPS",obs_steps_);
+     220          30 :   plumed_massert(obs_steps_!=0,"minimum is OBSERVATION_STEPS=1");
+     221          30 :   obs_cvs_.resize(obs_steps_*ncv_);
+     222             : 
+     223             : //deltaFs file
+     224             :   std::string deltaFsFileName;
+     225          30 :   parse("FILE",deltaFsFileName);
+     226          60 :   parse("PRINT_STRIDE",print_stride_);
+     227             :   std::string fmt;
+     228          60 :   parse("FMT",fmt);
+     229             : //output checkpoint of current state
+     230             :   std::string restartFileName;
+     231          60 :   parse("STATE_RFILE",restartFileName);
+     232             :   std::string stateFileName;
+     233          30 :   parse("STATE_WFILE",stateFileName);
+     234          30 :   wStateStride_=0;
+     235          30 :   parse("STATE_WSTRIDE",wStateStride_);
+     236          30 :   storeOldStates_=false;
+     237          30 :   parseFlag("STORE_STATES",storeOldStates_);
+     238          30 :   if(wStateStride_!=0 || storeOldStates_)
+     239           5 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     240          30 :   if(wStateStride_>0)
+     241           5 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus should be a multiple of PACE");
+     242          30 :   if(stateFileName.length()>0 && wStateStride_==0)
+     243           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     244             : 
+     245             : //work flag
+     246          30 :   parseFlag("CALC_WORK",calc_work_);
+     247             : 
+     248             : //multiple walkers //external MW for cp2k not supported, but anyway cp2k cannot put bias on energy!
+     249          30 :   bool walkers_mpi=false;
+     250          30 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     251          30 :   if(walkers_mpi)
+     252             :   {
+     253             :     //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     254           4 :     plumed_massert(Communicator::plumedHasMPI(),"Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation");
+     255           4 :     plumed_massert(Communicator::initialized(),"Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.");
+     256             : 
+     257           4 :     if(comm.Get_rank()==0) //multi_sim_comm works on first rank only
+     258             :     {
+     259           4 :       NumWalkers_=multi_sim_comm.Get_size();
+     260           4 :       walker_rank_=multi_sim_comm.Get_rank();
+     261             :     }
+     262           4 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     263           4 :     comm.Bcast(walker_rank_,0);
+     264             :   }
+     265             :   else
+     266             :   {
+     267          26 :     NumWalkers_=1;
+     268          26 :     walker_rank_=0;
+     269             :   }
+     270             : 
+     271             : //parallelization stuff
+     272          30 :   NumOMP_=OpenMP::getNumThreads();
+     273          30 :   NumParallel_=comm.Get_size();
+     274          30 :   rank_=comm.Get_rank();
+     275          30 :   bool serial=false;
+     276          30 :   parseFlag("SERIAL",serial);
+     277          30 :   if(serial)
+     278             :   {
+     279           5 :     NumOMP_=1;
+     280           5 :     NumParallel_=1;
+     281           5 :     rank_=0;
+     282             :   }
+     283             : 
+     284          30 :   checkRead();
+     285             : 
+     286             : //check ECVs and link them
+     287          30 :   init_pntrToECVsClass();
+     288             : //set kbt_
+     289          30 :   kbt_=pntrToECVsClass_[0]->getKbT();
+     290          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     291          37 :     plumed_massert(std::abs(kbt_-pntrToECVsClass_[l]->getKbT())<1e-4,"must set same TEMP for each ECV");
+     292             : 
+     293             : //restart if needed
+     294          30 :   if(getRestart())
+     295             :   {
+     296             :     bool stateRestart=true;
+     297          10 :     if(restartFileName.length()==0)
+     298             :     {
+     299             :       stateRestart=false;
+     300             :       restartFileName=deltaFsFileName;
+     301             :     }
+     302          10 :     IFile ifile;
+     303          10 :     ifile.link(*this);
+     304          10 :     if(ifile.FileExist(restartFileName))
+     305             :     {
+     306          10 :       log.printf("  RESTART - make sure all ECVs used are the same as before\n");
+     307          10 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     308          10 :       ifile.open(restartFileName);
+     309          10 :       if(stateRestart) //get all info
+     310             :       {
+     311           2 :         log.printf("    it should be a STATE file (not a DELTAFS file)\n");
+     312             :         double time; //not used
+     313           2 :         ifile.scanField("time",time);
+     314           2 :         ifile.scanField("counter",counter_);
+     315           4 :         ifile.scanField("rct",rct_);
+     316             :         std::string tmp_lambda;
+     317          66 :         while(ifile.scanField(getPntrToArgument(0)->getName(),tmp_lambda))
+     318             :         {
+     319          64 :           std::string subs="DeltaF_"+tmp_lambda;
+     320         128 :           for(unsigned jj=1; jj<ncv_; jj++)
+     321             :           {
+     322             :             tmp_lambda.clear();
+     323          64 :             ifile.scanField(getPntrToArgument(jj)->getName(),tmp_lambda);
+     324         128 :             subs+="_"+tmp_lambda;
+     325             :           }
+     326          64 :           deltaF_name_.push_back(subs);
+     327             :           double tmp_deltaF;
+     328          64 :           ifile.scanField("DeltaF",tmp_deltaF);
+     329          64 :           deltaF_.push_back(tmp_deltaF);
+     330          64 :           ifile.scanField();
+     331             :           tmp_lambda.clear();
+     332             :         }
+     333           2 :         log.printf("  successfully read %lu DeltaF values\n",deltaF_name_.size());
+     334           2 :         if(NumParallel_>1)
+     335           2 :           all_deltaF_=deltaF_;
+     336             :       }
+     337             :       else //get just deltaFs names
+     338             :       {
+     339           8 :         ifile.scanFieldList(deltaF_name_);
+     340           8 :         plumed_massert(deltaF_name_.size()>=4,"RESTART - fewer than expected FIELDS found in '"+deltaFsFileName+"' file");
+     341           8 :         plumed_massert(deltaF_name_[deltaF_name_.size()-1]=="print_stride","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     342           8 :         plumed_massert(deltaF_name_[0]=="time","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     343           8 :         plumed_massert(deltaF_name_[1]=="rct","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     344             :         deltaF_name_.pop_back();
+     345             :         deltaF_name_.erase(deltaF_name_.begin(),deltaF_name_.begin()+2);
+     346             :         std::size_t pos=5; //each name starts with "DeltaF"
+     347          22 :         for(unsigned j=0; j<ncv_; j++)
+     348          14 :           pos=deltaF_name_[0].find("_",pos+1); //checking only first one, hopefully is enough
+     349           8 :         plumed_massert(pos<deltaF_name_[0].length(),"RESTART - fewer '_' than expected in DeltaF fields: did you remove any CV?");
+     350           8 :         pos=deltaF_name_[0].find("_",pos+1);
+     351           8 :         plumed_massert(pos>deltaF_name_[0].length(),"RESTART - more '_' than expected in DeltaF fields: did you add new CV?");
+     352             :       }
+     353             :       //get lambdas, init ECVs and Link them
+     354          10 :       deltaF_size_=deltaF_name_.size();
+     355         525 :       auto getLambdaName=[](const std::string& name,const unsigned start,const unsigned dim)
+     356             :       {
+     357             :         std::size_t pos_start=5; //each name starts with "DeltaF"
+     358        1068 :         for(unsigned j=0; j<=start; j++)
+     359         543 :           pos_start=name.find("_",pos_start+1);
+     360             :         std::size_t pos_end=pos_start;
+     361        1527 :         for(unsigned j=0; j<dim; j++)
+     362        1002 :           pos_end=name.find("_",pos_end+1);
+     363         525 :         pos_start++; //do not include heading "_"
+     364         525 :         return name.substr(pos_start,pos_end-pos_start);
+     365             :       };
+     366          10 :       unsigned index_j=ncv_;
+     367             :       unsigned sizeSkip=1;
+     368          22 :       for(int l=pntrToECVsClass_.size()-1; l>=0; l--)
+     369             :       {
+     370          12 :         const unsigned dim_l=pntrToECVsClass_[l]->getNumberOfArguments();
+     371          12 :         index_j-=dim_l;
+     372          12 :         std::vector<std::string> lambdas_l(1);
+     373          12 :         lambdas_l[0]=getLambdaName(deltaF_name_[0],index_j,dim_l);
+     374         523 :         for(unsigned i=sizeSkip; i<deltaF_size_; i+=sizeSkip)
+     375             :         {
+     376         513 :           std::string tmp_lambda=getLambdaName(deltaF_name_[i],index_j,dim_l);
+     377         513 :           if(tmp_lambda==lambdas_l[0])
+     378             :             break;
+     379         511 :           lambdas_l.push_back(tmp_lambda);
+     380             :         }
+     381          12 :         pntrToECVsClass_[l]->initECVs_restart(lambdas_l);
+     382          12 :         sizeSkip*=lambdas_l.size();
+     383          12 :       }
+     384          10 :       plumed_massert(sizeSkip==deltaF_size_,"RESTART - this should not happen");
+     385          10 :       init_linkECVs(); //link ECVs and initializes index_k_
+     386          10 :       log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     387          10 :       obs_steps_=0; //avoid initializing again
+     388          10 :       if(stateRestart)
+     389             :       {
+     390           2 :         if(NumParallel_>1)
+     391             :         {
+     392           2 :           const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     393             :           unsigned iter=0;
+     394          34 :           for(unsigned i=start; i<start+deltaF_.size(); i++)
+     395          32 :             deltaF_[iter++]=all_deltaF_[i];
+     396             :         }
+     397             :       }
+     398             :       else //read each step
+     399             :       {
+     400           8 :         counter_=1;
+     401             :         unsigned count_lines=0;
+     402           8 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     403             :         double time;
+     404          48 :         while(ifile.scanField("time",time)) //only number of lines and last line is important
+     405             :         {
+     406             :           unsigned restart_stride;
+     407          16 :           ifile.scanField("print_stride",restart_stride);
+     408          16 :           ifile.scanField("rct",rct_);
+     409          16 :           if(NumParallel_==1)
+     410             :           {
+     411        1014 :             for(unsigned i=0; i<deltaF_size_; i++)
+     412         998 :               ifile.scanField(deltaF_name_[i],deltaF_[i]);
+     413             :           }
+     414             :           else
+     415             :           {
+     416           0 :             const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     417             :             unsigned iter=0;
+     418           0 :             for(unsigned i=start; i<start+deltaF_.size(); i++)
+     419           0 :               ifile.scanField(deltaF_name_[i],deltaF_[iter++]);
+     420             :           }
+     421          16 :           ifile.scanField();
+     422          16 :           if(count_lines>0)
+     423           8 :             counter_+=restart_stride;
+     424          16 :           count_lines++;
+     425             :         }
+     426           8 :         counter_*=NumWalkers_;
+     427           8 :         log.printf("  successfully read %u lines, up to t=%g\n",count_lines,time);
+     428             :       }
+     429          10 :       ifile.reset(false);
+     430          10 :       ifile.close();
+     431             :     }
+     432             :     else //same behaviour as METAD
+     433           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     434          10 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     435             :     {
+     436           2 :       std::vector<unsigned long long> all_counter(NumWalkers_);
+     437           2 :       if(comm.Get_rank()==0)
+     438           2 :         multi_sim_comm.Allgather(counter_,all_counter);
+     439           2 :       comm.Bcast(all_counter,0);
+     440             :       bool same_number_of_steps=true;
+     441           4 :       for(unsigned w=1; w<NumWalkers_; w++)
+     442           2 :         if(all_counter[0]!=all_counter[w])
+     443             :           same_number_of_steps=false;
+     444           2 :       plumed_massert(same_number_of_steps,"RESTART - not all walkers are reading the same file!");
+     445             :     }
+     446          10 :   }
+     447          20 :   else if(restartFileName.length()>0)
+     448           0 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     449             : 
+     450             : //sync all walkers to avoid opening files before reding is over (see also METAD)
+     451          30 :   comm.Barrier();
+     452          30 :   if(comm.Get_rank()==0 && walkers_mpi)
+     453           4 :     multi_sim_comm.Barrier();
+     454             : 
+     455             : //setup DeltaFs file
+     456          30 :   deltaFsOfile_.link(*this);
+     457          30 :   if(NumWalkers_>1)
+     458             :   {
+     459           4 :     if(walker_rank_>0)
+     460             :       deltaFsFileName="/dev/null"; //only first walker writes on file
+     461           8 :     deltaFsOfile_.enforceSuffix("");
+     462             :   }
+     463          30 :   deltaFsOfile_.open(deltaFsFileName);
+     464          30 :   if(fmt.length()>0)
+     465          60 :     deltaFsOfile_.fmtField(" "+fmt);
+     466             :   deltaFsOfile_.setHeavyFlush(); //do I need it?
+     467          30 :   deltaFsOfile_.addConstantField("print_stride");
+     468          30 :   deltaFsOfile_.printField("print_stride",print_stride_);
+     469             : 
+     470             : //open file for storing state
+     471          30 :   if(wStateStride_!=0)
+     472             :   {
+     473           6 :     stateOfile_.link(*this);
+     474           6 :     if(NumWalkers_>1)
+     475             :     {
+     476           0 :       if(walker_rank_>0)
+     477             :         stateFileName="/dev/null"; //only first walker writes on file
+     478           0 :       stateOfile_.enforceSuffix("");
+     479             :     }
+     480           6 :     stateOfile_.open(stateFileName);
+     481           6 :     if(fmt.length()>0)
+     482          12 :       stateOfile_.fmtField(" "+fmt);
+     483             :   }
+     484             : 
+     485             : //add output components
+     486          30 :   if(calc_work_)
+     487             :   {
+     488          12 :     addComponent("work");
+     489          12 :     componentIsNotPeriodic("work");
+     490             :   }
+     491             : 
+     492             : //printing some info
+     493          30 :   log.printf("  updating the bias with PACE = %u\n",stride_);
+     494          30 :   log.printf("  initial unbiased OBSERVATION_STEPS = %u (in units of PACE)\n",obs_steps_);
+     495          30 :   if(wStateStride_>0)
+     496           5 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     497          30 :   if(wStateStride_==-1)
+     498           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());
+     499          30 :   if(walkers_mpi)
+     500           4 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     501          30 :   if(NumWalkers_>1)
+     502             :   {
+     503           4 :     log.printf("  using multiple walkers\n");
+     504           4 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     505           4 :     log.printf("    walker rank: %u\n",walker_rank_);
+     506             :   }
+     507          30 :   int mw_warning=0;
+     508          30 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     509           0 :     mw_warning=1;
+     510          30 :   comm.Bcast(mw_warning,0);
+     511          30 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     512           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     513          30 :   if(NumParallel_>1)
+     514           2 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     515          30 :   if(NumOMP_>1)
+     516          25 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     517          30 :   if(serial)
+     518           5 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     519          30 :   log.printf("  Bibliography: ");
+     520          60 :   log<<plumed.cite("M. Invernizzi, P.M. Piaggi, and M. Parrinello, Phys. Rev. X 10, 041034 (2020)");
+     521          30 :   log.printf("\n");
+     522          30 : }
+     523             : 
+     524        1490 : void OPESexpanded::calculate()
+     525             : {
+     526        1490 :   if(deltaF_size_==0) //no bias before initialization
+     527         325 :     return;
+     528             : 
+     529             : //get diffMax, to avoid over/underflow
+     530        1165 :   double diffMax=-std::numeric_limits<double>::max();
+     531        1165 :   #pragma omp parallel num_threads(NumOMP_)
+     532             :   {
+     533             :     #pragma omp for reduction(max:diffMax)
+     534             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     535             :     {
+     536             :       diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     537             :       if(diff_[i]>diffMax)
+     538             :         diffMax=diff_[i];
+     539             :     }
+     540             :   }
+     541        1165 :   if(NumParallel_>1)
+     542         102 :     comm.Max(diffMax);
+     543             : 
+     544             : //calculate the bias and the forces
+     545        1165 :   double sum=0;
+     546        1165 :   std::vector<double> der_sum_cv(ncv_,0);
+     547        1165 :   if(NumOMP_==1)
+     548             :   {
+     549        2730 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     550             :     {
+     551        2520 :       double add_i=std::exp(diff_[i]-diffMax);
+     552        2520 :       sum+=add_i;
+     553             :       //set derivatives
+     554        6960 :       for(unsigned j=0; j<ncv_; j++)
+     555        4440 :         der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     556             :     }
+     557             :   }
+     558             :   else
+     559             :   {
+     560         955 :     #pragma omp parallel num_threads(NumOMP_)
+     561             :     {
+     562             :       std::vector<double> omp_der_sum_cv(ncv_,0);
+     563             :       #pragma omp for reduction(+:sum) nowait
+     564             :       for(unsigned i=0; i<deltaF_.size(); i++)
+     565             :       {
+     566             :         double add_i=std::exp(diff_[i]-diffMax);
+     567             :         sum+=add_i;
+     568             :         //set derivatives
+     569             :         for(unsigned j=0; j<ncv_; j++)
+     570             :           omp_der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     571             :       }
+     572             :       #pragma omp critical
+     573             :       for(unsigned j=0; j<ncv_; j++)
+     574             :         der_sum_cv[j]+=omp_der_sum_cv[j];
+     575             :     }
+     576             :   }
+     577        1165 :   if(NumParallel_>1)
+     578             :   { //each MPI process has part of the full deltaF_ vector, so must Sum
+     579         102 :     comm.Sum(sum);
+     580         102 :     comm.Sum(der_sum_cv);
+     581             :   }
+     582             : 
+     583             : //set bias and forces
+     584        1165 :   const double bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     585        1165 :   setBias(bias);
+     586        3163 :   for(unsigned j=0; j<ncv_; j++)
+     587        1998 :     setOutputForce(j,kbt_*der_sum_cv[j]/sum);
+     588             : }
+     589             : 
+     590        1490 : void OPESexpanded::update()
+     591             : {
+     592        1490 :   if(isFirstStep_) //skip very first step, as in METAD
+     593             :   {
+     594          30 :     isFirstStep_=false;
+     595          30 :     if(obs_steps_!=1) //if obs_steps_==1 go on with initialization
+     596             :       return;
+     597             :   }
+     598        1464 :   if(getStep()%stride_==0)
+     599             :   {
+     600         739 :     if(obs_steps_>0)
+     601             :     {
+     602         463 :       for(unsigned j=0; j<ncv_; j++)
+     603         304 :         obs_cvs_[counter_*ncv_+j]=getArgument(j);
+     604         159 :       counter_++;
+     605         159 :       if(counter_==obs_steps_)
+     606             :       {
+     607          20 :         log.printf("\nAction %s\n",getName().c_str());
+     608          20 :         init_fromObs();
+     609          20 :         log.printf("Finished initialization\n\n");
+     610          20 :         counter_=NumWalkers_; //all preliminary observations count 1
+     611          20 :         obs_steps_=0; //no more observation
+     612             :       }
+     613         159 :       return;
+     614             :     }
+     615             : 
+     616             :     //update averages
+     617         580 :     const double current_bias=getOutputQuantity(0); //the first value is always the bias
+     618         580 :     if(NumWalkers_==1)
+     619         500 :       updateDeltaF(current_bias);
+     620             :     else
+     621             :     {
+     622          80 :       std::vector<double> cvs(ncv_);
+     623         240 :       for(unsigned j=0; j<ncv_; j++)
+     624         160 :         cvs[j]=getArgument(j);
+     625          80 :       std::vector<double> all_bias(NumWalkers_);
+     626          80 :       std::vector<double> all_cvs(NumWalkers_*ncv_);
+     627          80 :       if(comm.Get_rank()==0)
+     628             :       {
+     629          80 :         multi_sim_comm.Allgather(current_bias,all_bias);
+     630          80 :         multi_sim_comm.Allgather(cvs,all_cvs);
+     631             :       }
+     632          80 :       comm.Bcast(all_bias,0);
+     633          80 :       comm.Bcast(all_cvs,0);
+     634         240 :       for(unsigned w=0; w<NumWalkers_; w++)
+     635             :       {
+     636             :         //calculate ECVs
+     637         160 :         unsigned index_wj=w*ncv_;
+     638         380 :         for(unsigned k=0; k<pntrToECVsClass_.size(); k++)
+     639             :         {
+     640         220 :           pntrToECVsClass_[k]->calculateECVs(&all_cvs[index_wj]);
+     641         220 :           index_wj+=pntrToECVsClass_[k]->getNumberOfArguments();
+     642             :         }
+     643         160 :         updateDeltaF(all_bias[w]);
+     644             :       }
+     645             :     }
+     646             : 
+     647             :     //write DeltaFs to file
+     648         580 :     if((counter_/NumWalkers_-1)%print_stride_==0)
+     649          44 :       printDeltaF();
+     650             : 
+     651             :     //calculate work if requested
+     652         580 :     if(calc_work_)
+     653             :     { //some copy and paste from calculate()
+     654             :       //get diffMax, to avoid over/underflow
+     655         110 :       double diffMax=-std::numeric_limits<double>::max();
+     656         110 :       #pragma omp parallel num_threads(NumOMP_)
+     657             :       {
+     658             :         #pragma omp for reduction(max:diffMax)
+     659             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     660             :         {
+     661             :           diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     662             :           if(diff_[i]>diffMax)
+     663             :             diffMax=diff_[i];
+     664             :         }
+     665             :       }
+     666         110 :       if(NumParallel_>1)
+     667          50 :         comm.Max(diffMax);
+     668             :       //calculate the bias
+     669         110 :       double sum=0;
+     670         110 :       #pragma omp parallel num_threads(NumOMP_)
+     671             :       {
+     672             :         #pragma omp for reduction(+:sum) nowait
+     673             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     674             :           sum+=std::exp(diff_[i]-diffMax);
+     675             :       }
+     676         110 :       if(NumParallel_>1)
+     677          50 :         comm.Sum(sum);
+     678         110 :       const double new_bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     679             :       //accumulate work
+     680         110 :       work_+=new_bias-current_bias;
+     681         220 :       getPntrToComponent("work")->set(work_);
+     682             :     }
+     683             :   }
+     684             : 
+     685             : //dump state if requested
+     686        1305 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+     687          11 :     dumpStateToFile();
+     688             : }
+     689             : 
+     690          30 : void OPESexpanded::init_pntrToECVsClass()
+     691             : {
+     692          30 :   std::vector<opes::ExpansionCVs*> all_pntrToECVsClass=plumed.getActionSet().select<opes::ExpansionCVs*>();
+     693          30 :   plumed_massert(all_pntrToECVsClass.size()>0,"no Expansion CVs found");
+     694          67 :   for(unsigned j=0; j<ncv_; j++)
+     695             :   {
+     696          74 :     std::string error_notECV("all the ARGs of "+getName()+" must be Expansion Collective Variables (ECV)");
+     697          37 :     const unsigned dot_pos=getPntrToArgument(j)->getName().find(".");
+     698          37 :     plumed_massert(dot_pos<getPntrToArgument(j)->getName().size(),error_notECV+", thus contain a dot in the name");
+     699          37 :     unsigned foundECV_l=all_pntrToECVsClass.size();
+     700          44 :     for(unsigned l=0; l<all_pntrToECVsClass.size(); l++)
+     701             :     {
+     702          44 :       if(getPntrToArgument(j)->getName().substr(0,dot_pos)==all_pntrToECVsClass[l]->getLabel())
+     703             :       {
+     704             :         foundECV_l=l;
+     705          37 :         pntrToECVsClass_.push_back(all_pntrToECVsClass[l]);
+     706          37 :         std::string missing_arg="some ECV component is missing from ARG";
+     707          37 :         plumed_massert(j+all_pntrToECVsClass[l]->getNumberOfArguments()<=getNumberOfArguments(),missing_arg);
+     708          90 :         for(unsigned h=0; h<all_pntrToECVsClass[l]->getNumberOfArguments(); h++)
+     709             :         {
+     710          53 :           std::string argName=getPntrToArgument(j+h)->getName();
+     711          53 :           std::string expectedECVname=all_pntrToECVsClass[l]->getComponentsVector()[h];
+     712          53 :           plumed_massert(argName==expectedECVname,missing_arg+", or is in wrong order: given ARG="+argName+" expected ARG="+expectedECVname);
+     713             :         }
+     714          37 :         j+=all_pntrToECVsClass[l]->getNumberOfArguments()-1;
+     715             :         break;
+     716             :       }
+     717             :     }
+     718          37 :     plumed_massert(foundECV_l<all_pntrToECVsClass.size(),error_notECV);
+     719             :   }
+     720          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     721          44 :     for(unsigned ll=l+1; ll<pntrToECVsClass_.size(); ll++)
+     722           7 :       plumed_massert(pntrToECVsClass_[l]->getLabel()!=pntrToECVsClass_[ll]->getLabel(),"cannot use same ECV twice");
+     723          30 : }
+     724             : 
+     725          30 : void OPESexpanded::init_linkECVs()
+     726             : {
+     727             :   //TODO It should be possible to make all of this more straightforward (and probably also faster):
+     728             :   //     - get rid of index_k_, making it trivial for each ECV
+     729             :   //     - store the ECVs_ and derECVs_ vectors here as a contiguous vector, and use pointers in the ECV classes
+     730             :   //     Some caveats:
+     731             :   //     - ECVmultiThermalBaric has a nontrivial index_k_ to avoid duplicates. use duplicates instead
+     732             :   //     - can the ECVs be MPI parallel or it's too complicated?
+     733          30 :   plumed_massert(deltaF_size_>0,"must set deltaF_size_ before calling init_linkECVs()");
+     734          30 :   if(NumParallel_==1)
+     735          28 :     deltaF_.resize(deltaF_size_);
+     736             :   else
+     737             :   {
+     738           2 :     const unsigned extra=(rank_<(deltaF_size_%NumParallel_)?1:0);
+     739           2 :     deltaF_.resize(deltaF_size_/NumParallel_+extra);
+     740             :     //these are used when printing deltaF_ to file
+     741           2 :     all_deltaF_.resize(deltaF_size_);
+     742           2 :     all_size_.resize(NumParallel_,deltaF_size_/NumParallel_);
+     743           2 :     disp_.resize(NumParallel_);
+     744           4 :     for(unsigned r=0; r<NumParallel_-1; r++)
+     745             :     {
+     746           2 :       if(r<deltaF_size_%NumParallel_)
+     747           0 :         all_size_[r]++;
+     748           2 :       disp_[r+1]=disp_[r]+all_size_[r];
+     749             :     }
+     750             :   }
+     751          30 :   diff_.resize(deltaF_.size());
+     752          30 :   ECVs_.resize(ncv_);
+     753          30 :   derECVs_.resize(ncv_);
+     754          30 :   index_k_.resize(deltaF_.size(),std::vector<unsigned>(ncv_));
+     755             :   unsigned index_j=0;
+     756          30 :   unsigned sizeSkip=deltaF_size_;
+     757          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     758             :   {
+     759          37 :     std::vector< std::vector<unsigned> > l_index_k(pntrToECVsClass_[l]->getIndex_k());
+     760          37 :     plumed_massert(deltaF_size_%l_index_k.size()==0,"buggy ECV: mismatch between getTotNumECVs() and getIndex_k().size()");
+     761          37 :     plumed_massert(l_index_k[0].size()==pntrToECVsClass_[l]->getNumberOfArguments(),"buggy ECV: mismatch between number of ARG and underlying CVs");
+     762          37 :     sizeSkip/=l_index_k.size();
+     763          90 :     for(unsigned h=0; h<pntrToECVsClass_[l]->getNumberOfArguments(); h++)
+     764             :     {
+     765          53 :       ECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToECVs(h);
+     766          53 :       derECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToDerECVs(h);
+     767          53 :       if(NumParallel_==1)
+     768             :       {
+     769       45589 :         for(unsigned i=0; i<deltaF_size_; i++)
+     770       45540 :           index_k_[i][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     771             :       }
+     772             :       else
+     773             :       {
+     774           4 :         const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     775             :         unsigned iter=0;
+     776          68 :         for(unsigned i=start; i<start+deltaF_.size(); i++)
+     777          64 :           index_k_[iter++][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     778             :       }
+     779             :     }
+     780          37 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     781          37 :   }
+     782          30 :   plumed_massert(sizeSkip==1,"this should not happen!");
+     783          30 : }
+     784             : 
+     785          20 : void OPESexpanded::init_fromObs() //This could probably be faster and/or require less memory...
+     786             : {
+     787             : //in case of multiple walkers gather all the statistics
+     788          20 :   if(NumWalkers_>1)
+     789             :   {
+     790           2 :     std::vector<double> all_obs_cv(ncv_*obs_steps_*NumWalkers_);
+     791           2 :     if(comm.Get_rank()==0)
+     792           2 :       multi_sim_comm.Allgather(obs_cvs_,all_obs_cv);
+     793           2 :     comm.Bcast(all_obs_cv,0);
+     794           2 :     obs_cvs_=all_obs_cv; //could this lead to memory issues?
+     795           2 :     obs_steps_*=NumWalkers_;
+     796             :   }
+     797             : 
+     798             : //initialize ECVs from observations
+     799             :   unsigned index_j=0;
+     800          20 :   deltaF_size_=1;
+     801          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     802             :   {
+     803          25 :     pntrToECVsClass_[l]->initECVs_observ(obs_cvs_,ncv_,index_j);
+     804          25 :     deltaF_size_*=pntrToECVsClass_[l]->getTotNumECVs(); //ECVs from different exansions will be combined
+     805          25 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     806             :   }
+     807          20 :   plumed_massert(index_j==getNumberOfArguments(),"mismatch between number of linked CVs and number of ARG");
+     808             : //link ECVs and initialize index_k_, mapping each deltaF to a single ECVs set
+     809          20 :   init_linkECVs();
+     810             : 
+     811             : //initialize deltaF_ from obs
+     812             : //for the first point, t=0, the ECVs are calculated by initECVs_observ, setting also any initial guess
+     813             :   index_j=0;
+     814       12379 :   for(unsigned i=0; i<deltaF_.size(); i++)
+     815       56923 :     for(unsigned j=0; j<ncv_; j++)
+     816       44564 :       deltaF_[i]+=kbt_*ECVs_[j][index_k_[i][j]];
+     817         179 :   for(unsigned t=1; t<obs_steps_; t++) //starts from t=1
+     818             :   {
+     819             :     unsigned index_j=0;
+     820         383 :     for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     821             :     {
+     822         224 :       pntrToECVsClass_[l]->calculateECVs(&obs_cvs_[t*ncv_+index_j]);
+     823         224 :       index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     824             :     }
+     825      102677 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     826             :     {
+     827      102518 :       const double diff_i=(-getExpansion(i)+deltaF_[i]/kbt_-std::log(t));
+     828      102518 :       if(diff_i>0) //save exp from overflow
+     829       16071 :         deltaF_[i]-=kbt_*(diff_i+std::log1p(std::exp(-diff_i))+std::log1p(-1./(1.+t)));
+     830             :       else
+     831       86447 :         deltaF_[i]-=kbt_*(std::log1p(std::exp(diff_i))+std::log1p(-1./(1.+t)));
+     832             :     }
+     833             :   }
+     834             :   obs_cvs_.clear();
+     835             : 
+     836             : //set deltaF_name_
+     837          20 :   deltaF_name_.resize(deltaF_size_,"DeltaF");
+     838          20 :   unsigned sizeSkip=deltaF_size_;
+     839          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     840             :   {
+     841          25 :     std::vector<std::string> lambdas_l=pntrToECVsClass_[l]->getLambdas();
+     842          25 :     plumed_massert(lambdas_l.size()==pntrToECVsClass_[l]->getTotNumECVs(),"buggy ECV: mismatch between getTotNumECVs() and getLambdas().size()");
+     843          25 :     sizeSkip/=lambdas_l.size();
+     844       22457 :     for(unsigned i=0; i<deltaF_size_; i++)
+     845       44864 :       deltaF_name_[i]+="_"+lambdas_l[(i/sizeSkip)%lambdas_l.size()];
+     846          25 :   }
+     847             : 
+     848             : //print initialization to file
+     849          20 :   log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     850          20 :   printDeltaF();
+     851          20 : }
+     852             : 
+     853          64 : void OPESexpanded::printDeltaF()
+     854             : {
+     855          64 :   deltaFsOfile_.printField("time",getTime());
+     856          64 :   deltaFsOfile_.printField("rct",rct_);
+     857          64 :   if(NumParallel_==1)
+     858             :   {
+     859       23988 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     860       23926 :       deltaFsOfile_.printField(deltaF_name_[i],deltaF_[i]);
+     861             :   }
+     862             :   else
+     863             :   {
+     864           2 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     865          66 :     for(unsigned i=0; i<deltaF_size_; i++)
+     866          64 :       deltaFsOfile_.printField(deltaF_name_[i],all_deltaF_[i]);
+     867             :   }
+     868          64 :   deltaFsOfile_.printField();
+     869          64 : }
+     870             : 
+     871          11 : void OPESexpanded::dumpStateToFile()
+     872             : {
+     873             : //rewrite header or rewind file
+     874          11 :   if(storeOldStates_)
+     875           3 :     stateOfile_.clearFields();
+     876           8 :   else if(walker_rank_==0)
+     877           8 :     stateOfile_.rewind();
+     878             : //define fields
+     879          11 :   stateOfile_.addConstantField("time");
+     880          11 :   stateOfile_.addConstantField("counter");
+     881          11 :   stateOfile_.addConstantField("rct");
+     882             : //print
+     883          11 :   stateOfile_.printField("time",getTime());
+     884          11 :   stateOfile_.printField("counter",counter_);
+     885          11 :   stateOfile_.printField("rct",rct_);
+     886          11 :   if(NumParallel_>1)
+     887           0 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     888         240 :   for(unsigned i=0; i<deltaF_size_; i++)
+     889             :   {
+     890             :     std::size_t pos_start=7; //skip "DeltaF_"
+     891         687 :     for(unsigned j=0; j<ncv_; j++)
+     892             :     {
+     893             :       plumed_dbg_massert(pos_start>6,"not enought _ in deltaF_name_"+std::to_string(i-1)+" string?");
+     894         458 :       const std::size_t pos_end=deltaF_name_[i].find("_",pos_start);
+     895         916 :       stateOfile_.printField(getPntrToArgument(j)->getName(),"  "+deltaF_name_[i].substr(pos_start,pos_end-pos_start));
+     896         458 :       pos_start=pos_end+1;
+     897             :     }
+     898         229 :     if(NumParallel_==1)
+     899         458 :       stateOfile_.printField("DeltaF",deltaF_[i]);
+     900             :     else
+     901           0 :       stateOfile_.printField("DeltaF",all_deltaF_[i]);
+     902         229 :     stateOfile_.printField();
+     903             :   }
+     904             : //make sure file is written even if small
+     905          11 :   if(!storeOldStates_)
+     906           8 :     stateOfile_.flush();
+     907          11 : }
+     908             : 
+     909         660 : void OPESexpanded::updateDeltaF(double bias)
+     910             : {
+     911             :   plumed_dbg_massert(counter_>0,"deltaF_ must be initialized");
+     912         660 :   counter_++;
+     913         660 :   const double arg=(bias-rct_)/kbt_-std::log(counter_-1.);
+     914             :   double increment;
+     915         660 :   if(arg>0) //save exp from overflow
+     916          28 :     increment=kbt_*(arg+std::log1p(std::exp(-arg)));
+     917             :   else
+     918         632 :     increment=kbt_*(std::log1p(std::exp(arg)));
+     919         660 :   #pragma omp parallel num_threads(NumOMP_)
+     920             :   {
+     921             :     #pragma omp for
+     922             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     923             :     {
+     924             :       const double diff_i=(-getExpansion(i)+(bias-rct_+deltaF_[i])/kbt_-std::log(counter_-1.));
+     925             :       if(diff_i>0) //save exp from overflow
+     926             :         deltaF_[i]+=increment-kbt_*(diff_i+std::log1p(std::exp(-diff_i)));
+     927             :       else
+     928             :         deltaF_[i]+=increment-kbt_*std::log1p(std::exp(diff_i));
+     929             :     }
+     930             :   }
+     931         660 :   rct_+=increment+kbt_*std::log1p(-1./counter_);
+     932         660 : }
+     933             : 
+     934      644469 : double OPESexpanded::getExpansion(unsigned i) const
+     935             : {
+     936             :   double expansion=0;
+     937     3003062 :   for(unsigned j=0; j<ncv_; j++)
+     938     2358593 :     expansion+=ECVs_[j][index_k_[i][j]]; //the index_k could be trivially guessed for most ECVs, but unfourtunately not all
+     939      644469 :   return expansion;
+     940             : }
+     941             : 
+     942             : }
+     943             : }
+
+
+
+ + + + +
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 000000000..5faa17102 --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func-sort-c.html @@ -0,0 +1,184 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..409a00f8f --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func.html @@ -0,0 +1,184 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2de04fd37 --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.gcov.html @@ -0,0 +1,1828 @@ + + + + + + + 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-10-17 16:45:00Functions: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). log(exp(beta V)/beta, 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 000000000..1827237cf --- /dev/null +++ b/coverage/opes/index-sort-f.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2142223096.1 %
Date:2024-10-17 16:45:00Functions:10811891.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ExpansionCVs.cpp +
90.6%90.6%
+
90.6 %96 / 10681.8 %9 / 11
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
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
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 %430 / 44292.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 000000000..398aca35b --- /dev/null +++ b/coverage/opes/index-sort-l.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2142223096.1 %
Date:2024-10-17 16:45:00Functions:10811891.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ExpansionCVs.cpp +
90.6%90.6%
+
90.6 %96 / 10681.8 %9 / 11
ECVcustom.cpp +
92.0%92.0%
+
92.0 %92 / 10090.9 %10 / 11
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 %430 / 44292.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 000000000..b3102e12f --- /dev/null +++ b/coverage/opes/index.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2142223096.1 %
Date:2024-10-17 16:45:00Functions:10811891.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
90.6%90.6%
+
90.6 %96 / 10681.8 %9 / 11
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %430 / 44292.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 000000000..5faabb4cb --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm14HBPammShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD4pamm14HBPammShortcutC1ERKNS_13ActionOptionsE6
_ZN4PLMD4pamm14HBPammShortcut16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE31
_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 000000000..1144d50ae --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE31
_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 000000000..411508a0c --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.gcov.html @@ -0,0 +1,334 @@ + + + + + + + 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-10-17 16:45:00Functions: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          31 : void HBPammMatrix::registerKeywords( Keywords& keys ) {
+      88          31 :   adjmat::AdjacencyMatrixBase::registerKeywords( keys ); keys.use("GROUPC");
+      89          62 :   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          62 :   keys.add("compulsory","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      92          62 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      93          62 :   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          93 :   keys.needsAction("PAMM"); keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      95          31 : }
+      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 000000000..274f58269 --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..20bd3bcee --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fcb802e9e --- /dev/null +++ b/coverage/pamm/PAMM.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f10f57377 --- /dev/null +++ b/coverage/pamm/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:14415692.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..56b584b2f --- /dev/null +++ b/coverage/pamm/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:14415692.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..8c5d8d508 --- /dev/null +++ b/coverage/pamm/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:14415692.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..c3a2a8f45 --- /dev/null +++ b/coverage/piv/PIV.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..de1d4d95f --- /dev/null +++ b/coverage/piv/PIV.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..920f45555 --- /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:42859671.8 %
Date:2024-10-17 16:45:00Functions: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 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 ith 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 :   keys.setValueDescription("the PIV-distance");
+     265          14 : }
+     266             : 
+     267          12 : PIV::PIV(const ActionOptions&ao):
+     268             :   PLUMED_COLVAR_INIT(ao),
+     269          12 :   pbc(true),
+     270          12 :   serial(false),
+     271          12 :   timer(false),
+     272          12 :   updatePIV(1),
+     273          12 :   Nprec(1000),
+     274          12 :   Natm(1),
+     275          12 :   Nlist(1),
+     276          12 :   NLsize(1),
+     277          12 :   Fvol(1.),
+     278          12 :   Vol0(0.),
+     279          12 :   m_PIVdistance(0.),
+     280          12 :   rPIV(std:: vector<std:: vector<double> >(Nlist)),
+     281          12 :   scaling(std:: vector<double>(Nlist)),
+     282          12 :   r00(std:: vector<double>(Nlist)),
+     283          12 :   nl_skin(std:: vector<double>(Nlist)),
+     284          12 :   fmass(std:: vector<double>(Nlist)),
+     285          12 :   dosort(std:: vector<bool>(Nlist)),
+     286          12 :   compos(std:: vector<Vector>(NLsize)),
+     287          12 :   sw(std:: vector<string>(Nlist)),
+     288          12 :   nl(Nlist),
+     289          12 :   nlcom(NLsize),
+     290          12 :   m_deriv(std:: vector<Vector>(1)),
+     291          12 :   Svol(false),
+     292          12 :   cross(true),
+     293          12 :   direct(true),
+     294          12 :   doneigh(false),
+     295          12 :   test(false),
+     296          12 :   CompDer(false),
+     297          24 :   com(false)
+     298             : {
+     299          12 :   log << "Starting PIV Constructor\n";
+     300             : 
+     301             :   {
+     302             :     // look for another PIV instance previously allocated
+     303          12 :     auto* previous=plumed.getActionSet().selectLatest<PIV*>(this);
+     304             : 
+     305             :     // Uncommenting the following line, it is possible to force
+     306             :     // a separate object per instance of the PIB object.
+     307             :     // Results are unaffected, but performance is worse.
+     308             :     // I think this is the expected behavior. GB
+     309             :     // previous=nullptr;
+     310             : 
+     311          12 :     if(!previous) {
+     312             :       // if not found, allocate the shared data struct
+     313           6 :       sharedData_unique=Tools::make_unique<SharedData>();
+     314             :       // then set the raw pointer
+     315           6 :       sharedData=sharedData_unique.get();
+     316             :     } else {
+     317             :       // if found, use the previous raw pointer
+     318           6 :       sharedData=previous->sharedData;
+     319           6 :       log << "(a previous PIV action was found)\n";
+     320             :     }
+     321             :   }
+     322             : 
+     323             :   // Precision on the real-to-integer transformation for the sorting
+     324          12 :   parse("PRECISION",Nprec);
+     325          12 :   if(Nprec<2) error("Precision must be => 2");
+     326             : 
+     327             :   // PBC
+     328          12 :   bool nopbc=!pbc;
+     329          12 :   parseFlag("NOPBC",nopbc);
+     330          12 :   pbc=!nopbc;
+     331          12 :   if(pbc) {
+     332          12 :     log << "Using Periodic Boundary Conditions\n";
+     333             :   } else  {
+     334           0 :     log << "Isolated System (NO PBC)\n";
+     335             :   }
+     336             : 
+     337             :   // SERIAL/PARALLEL
+     338          12 :   parseFlag("SERIAL",serial);
+     339          12 :   if(serial) {
+     340           0 :     log << "Serial PIV construction\n";
+     341             :   } else     {
+     342          12 :     log << "Parallel PIV construction\n";
+     343             :   }
+     344             : 
+     345             :   // Derivatives
+     346          12 :   parseFlag("DERIVATIVES",CompDer);
+     347          12 :   if(CompDer) log << "Computing Derivatives\n";
+     348             : 
+     349             :   // Timing
+     350          12 :   parseFlag("TIMER",timer);
+     351          12 :   if(timer) {
+     352           1 :     log << "Timing analysis\n";
+     353           1 :     stopwatch.start();
+     354           1 :     stopwatch.pause();
+     355             :   }
+     356             : 
+     357             :   // Test
+     358          12 :   parseFlag("TEST",test);
+     359             : 
+     360             :   // UPDATEPIV
+     361          24 :   if(keywords.exists("UPDATEPIV")) {
+     362          24 :     parse("UPDATEPIV",updatePIV);
+     363             :   }
+     364             : 
+     365             :   // Test
+     366          12 :   parseFlag("COM",com);
+     367          12 :   if(com) log << "Building PIV using COMs\n";
+     368             : 
+     369             :   // Volume Scaling
+     370          12 :   parse("VOLUME",Vol0);
+     371          12 :   if (Vol0>0) {
+     372          12 :     Svol=true;
+     373             :   }
+     374             : 
+     375             :   // PIV direct and cross blocks
+     376          12 :   bool oc=false,od=false;
+     377          12 :   parseFlag("ONLYCROSS",oc);
+     378          12 :   parseFlag("ONLYDIRECT",od);
+     379          12 :   if (oc&&od) {
+     380           0 :     error("ONLYCROSS and ONLYDIRECT are incompatible options!");
+     381             :   }
+     382          12 :   if(oc) {
+     383           4 :     direct=false;
+     384           4 :     log << "Using only CROSS-PIV blocks\n";
+     385             :   }
+     386          12 :   if(od) {
+     387           4 :     cross=false;
+     388           4 :     log << "Using only DIRECT-PIV blocks\n";
+     389             :   }
+     390             : 
+     391             :   // Atoms for PIV
+     392          12 :   parse("PIVATOMS",Natm);
+     393          12 :   std:: vector<string> atype(Natm);
+     394          12 :   parseVector("ATOMTYPES",atype);
+     395             :   //if(atype.size()!=getNumberOfArguments() && atype.size()!=0) error("not enough values for ATOMTYPES");
+     396             : 
+     397             :   // Reference PDB file
+     398          12 :   parse("REF_FILE",ref_file);
+     399          12 :   PDB mypdb;
+     400          12 :   FILE* fp=fopen(ref_file.c_str(),"r");
+     401          12 :   if (fp!=NULL) {
+     402          12 :     log<<"Opening PDB file with reference frame: "<<ref_file.c_str()<<"\n";
+     403          12 :     mypdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+     404          12 :     fclose (fp);
+     405             :   } else {
+     406           0 :     error("Error in reference PDB file");
+     407             :   }
+     408             : 
+     409             :   // Build COM/Atom lists of AtomNumbers (this might be done in PBC.cpp)
+     410             :   // Atomlist or Plist used to build pair lists
+     411          12 :   std:: vector<std:: vector<AtomNumber> > Plist(Natm);
+     412             :   // Atomlist used to build list of atoms for each COM
+     413          12 :   std:: vector<std:: vector<AtomNumber> > comatm(1);
+     414             :   // NLsize is the number of atoms in the pdb cell
+     415          12 :   NLsize=mypdb.getAtomNumbers().size();
+     416             :   // In the following P stands for Point (either an Atom or a COM)
+     417             :   unsigned resnum=0;
+     418             :   // Presind (array size: number of residues) contains the contains the residue number
+     419             :   //   this is because the residue numbers may not always be ordered from 1 to resnum
+     420             :   std:: vector<unsigned> Presind;
+     421             :   // Build Presind
+     422       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     423       19392 :     unsigned rind=mypdb.getResidueNumber(mypdb.getAtomNumbers()[i]);
+     424             :     bool oldres=false;
+     425     7705008 :     for (unsigned j=0; j<Presind.size(); j++) {
+     426     7685616 :       if(rind==Presind[j]) {
+     427             :         oldres=true;
+     428             :       }
+     429             :     }
+     430       19392 :     if(!oldres) {
+     431        4848 :       Presind.push_back(rind);
+     432             :     }
+     433             :   }
+     434          12 :   resnum=Presind.size();
+     435             : 
+     436             :   // Pind0 is the atom/COM used in Nlists (for COM Pind0 is the first atom in the pdb belonging to that COM)
+     437             :   unsigned Pind0size;
+     438          12 :   if(com) {
+     439             :     Pind0size=resnum;
+     440             :   } else {
+     441          12 :     Pind0size=NLsize;
+     442             :   }
+     443          12 :   std:: vector<unsigned> Pind0(Pind0size);
+     444             :   // If COM resize important arrays
+     445          12 :   comatm.resize(NLsize);
+     446          12 :   if(com) {
+     447           0 :     nlcom.resize(NLsize);
+     448           0 :     compos.resize(NLsize);
+     449           0 :     fmass.resize(NLsize,0.);
+     450             :   }
+     451          12 :   log << "Total COM/Atoms: " << Natm*resnum << " \n";
+     452             :   // Build lists of Atoms/COMs for NLists
+     453             :   //   comatm filled also for non_COM calculation for analysis purposes
+     454          36 :   for (unsigned j=0; j<Natm; j++) {
+     455             :     unsigned oind;
+     456       38808 :     for (unsigned i=0; i<Pind0.size(); i++) {
+     457       38784 :       Pind0[i]=0;
+     458             :     }
+     459       38808 :     for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     460             :       // Residue/Atom AtomNumber: used to build NL for COMS/Atoms pairs.
+     461       38784 :       AtomNumber anum=mypdb.getAtomNumbers()[i];
+     462             :       // ResidueName/Atomname associated to atom
+     463       38784 :       string rname=mypdb.getResidueName(anum);
+     464       38784 :       string aname=mypdb.getAtomName(anum);
+     465             :       // Index associated to residue/atom: used to separate COM-lists
+     466       38784 :       unsigned rind=mypdb.getResidueNumber(anum);
+     467             :       unsigned aind=anum.index();
+     468             :       // This builds lists for NL
+     469             :       string Pname;
+     470             :       unsigned Pind;
+     471       38784 :       if(com) {
+     472             :         Pname=rname;
+     473           0 :         for(unsigned l=0; l<resnum; l++) {
+     474           0 :           if(rind==Presind[l]) {
+     475             :             Pind=l;
+     476             :           }
+     477             :         }
+     478             :       } else {
+     479             :         Pname=aname;
+     480             :         Pind=aind;
+     481             :       }
+     482       38784 :       if(Pname==atype[j]) {
+     483       14544 :         if(Pind0[Pind]==0) {
+     484             :           // adding the atomnumber to the atom/COM list for pairs
+     485       14544 :           Plist[j].push_back(anum);
+     486       14544 :           Pind0[Pind]=aind+1;
+     487             :           oind=Pind;
+     488             :         }
+     489             :         // adding the atomnumber to list of atoms for every COM/Atoms
+     490       14544 :         comatm[Pind0[Pind]-1].push_back(anum);
+     491             :       }
+     492             :     }
+     493             :     // Output Lists
+     494          24 :     log << "  Groups of type  " << j << ": " << Plist[j].size() << " \n";
+     495             :     string gname;
+     496             :     unsigned gsize;
+     497          24 :     if(com) {
+     498           0 :       gname=mypdb.getResidueName(comatm[Pind0[oind]-1][0]);
+     499           0 :       gsize=comatm[Pind0[oind]-1].size();
+     500             :     } else {
+     501          48 :       gname=mypdb.getAtomName(comatm[Pind0[oind]-1][0]);
+     502             :       gsize=1;
+     503             :     }
+     504          24 :     log.printf("    %6s %3s %13s %10i %6s\n", "type  ", gname.c_str(),"   containing ",gsize," atoms");
+     505             :   }
+     506             : 
+     507             :   // This is to build the list with all the atoms
+     508             :   std:: vector<AtomNumber> listall;
+     509       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     510       19392 :     listall.push_back(mypdb.getAtomNumbers()[i]);
+     511             :   }
+     512             : 
+     513             :   // PIV blocks and Neighbour Lists
+     514          12 :   Nlist=0;
+     515             :   // Direct adds the A-A ad B-B blocks (N)
+     516          12 :   if(direct) {
+     517           8 :     Nlist=Nlist+unsigned(Natm);
+     518             :   }
+     519             :   // Cross adds the A-B blocks (N*(N-1)/2)
+     520          12 :   if(cross) {
+     521           8 :     Nlist=Nlist+unsigned(double(Natm*(Natm-1))/2.);
+     522             :   }
+     523             :   // Resize vectors according to Nlist
+     524          12 :   rPIV.resize(Nlist);
+     525             : 
+     526             :   // PIV scaled option
+     527          12 :   scaling.resize(Nlist);
+     528          36 :   for(unsigned j=0; j<Nlist; j++) {
+     529          24 :     scaling[j]=1.;
+     530             :   }
+     531          24 :   if(keywords.exists("SFACTOR")) {
+     532          24 :     parseVector("SFACTOR",scaling);
+     533             :     //if(scaling.size()!=getNumberOfArguments() && scaling.size()!=0) error("not enough values for SFACTOR");
+     534             :   }
+     535             :   // Neighbour Lists option
+     536          12 :   parseFlag("NLIST",doneigh);
+     537          12 :   nl.resize(Nlist);
+     538          12 :   nl_skin.resize(Nlist);
+     539          12 :   if(doneigh) {
+     540          12 :     std:: vector<double> nl_cut(Nlist,0.);
+     541          12 :     std:: vector<int> nl_st(Nlist,0);
+     542          12 :     parseVector("NL_CUTOFF",nl_cut);
+     543             :     //if(nl_cut.size()!=getNumberOfArguments() && nl_cut.size()!=0) error("not enough values for NL_CUTOFF");
+     544          12 :     parseVector("NL_STRIDE",nl_st);
+     545             :     //if(nl_st.size()!=getNumberOfArguments() && nl_st.size()!=0) error("not enough values for NL_STRIDE");
+     546          12 :     parseVector("NL_SKIN",nl_skin);
+     547             :     //if(nl_skin.size()!=getNumberOfArguments() && nl_skin.size()!=0) error("not enough values for NL_SKIN");
+     548          36 :     for (unsigned j=0; j<Nlist; j++) {
+     549          24 :       if(nl_cut[j]<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     550          24 :       if(nl_st[j]<=0) error("NL_STRIDE should be explicitly specified and positive");
+     551          24 :       if(nl_skin[j]<=0.) error("NL_SKIN should be explicitly specified and positive");
+     552          24 :       nl_cut[j]=nl_cut[j]+nl_skin[j];
+     553             :     }
+     554          12 :     log << "Creating Neighbor Lists \n";
+     555             :     // WARNING: is nl_cut meaningful here?
+     556          24 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     557          12 :     if(com) {
+     558             :       //Build lists of Atoms for every COM
+     559           0 :       for (unsigned i=0; i<compos.size(); i++) {
+     560             :         // WARNING: is nl_cut meaningful here?
+     561           0 :         nlcom[i] = Tools::make_unique<NeighborList>(comatm[i],true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     562             :       }
+     563             :     }
+     564             :     unsigned ncnt=0;
+     565             :     // Direct blocks AA, BB, CC, ...
+     566          12 :     if(direct) {
+     567          24 :       for (unsigned j=0; j<Natm; j++) {
+     568          16 :         nl[ncnt]= Tools::make_unique<NeighborList>(Plist[j],true,pbc,getPbc(),comm,nl_cut[j],nl_st[j]);
+     569          16 :         ncnt+=1;
+     570             :       }
+     571             :     }
+     572             :     // Cross blocks AB, AC, BC, ...
+     573          12 :     if(cross) {
+     574          24 :       for (unsigned j=0; j<Natm; j++) {
+     575          24 :         for (unsigned i=j+1; i<Natm; i++) {
+     576          16 :           nl[ncnt]= Tools::make_unique<NeighborList>(Plist[i],Plist[j],true,false,pbc,getPbc(),comm,nl_cut[ncnt],nl_st[ncnt]);
+     577           8 :           ncnt+=1;
+     578             :         }
+     579             :       }
+     580             :     }
+     581             :   } else {
+     582           0 :     log << "WARNING: Neighbor List not activated this has not been tested!!  \n";
+     583           0 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm);
+     584           0 :     for (unsigned j=0; j<Nlist; j++) {
+     585           0 :       nl[j]= Tools::make_unique<NeighborList>(Plist[j],Plist[j],true,true,pbc,getPbc(),comm);
+     586             :     }
+     587             :   }
+     588             :   // Output Nlist
+     589          12 :   log << "Total Nlists: " << Nlist << " \n";
+     590          36 :   for (unsigned j=0; j<Nlist; j++) {
+     591          24 :     log << "  list " << j+1 << "   size " << nl[j]->size() << " \n";
+     592             :   }
+     593             :   // Calculate COM masses once and for all from lists
+     594          12 :   if(com) {
+     595           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     596             :       double commass=0.;
+     597           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     598           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     599           0 :         commass+=mypdb.getOccupancy()[andx];
+     600             :       }
+     601           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     602           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     603           0 :         if(commass>0.) {
+     604           0 :           fmass[andx]=mypdb.getOccupancy()[andx]/commass;
+     605             :         } else {
+     606           0 :           fmass[andx]=1.;
+     607             :         }
+     608             :       }
+     609             :     }
+     610             :   }
+     611             : 
+     612             :   // Sorting
+     613          12 :   dosort.resize(Nlist);
+     614          12 :   std:: vector<int> ynsort(Nlist);
+     615          12 :   parseVector("SORT",ynsort);
+     616          36 :   for (unsigned i=0; i<Nlist; i++) {
+     617          24 :     if(ynsort[i]==0||CompDer) {
+     618             :       dosort[i]=false;
+     619             :     } else {
+     620             :       dosort[i]=true;
+     621             :     }
+     622             :   }
+     623             : 
+     624             :   //build box vectors and correct for pbc
+     625          12 :   log << "Building the box from PDB data ... \n";
+     626          12 :   Tensor Box=mypdb.getBoxVec();
+     627          12 :   log << "  Done! A,B,C vectors in Cartesian space:  \n";
+     628          12 :   log.printf("  A:  %12.6f%12.6f%12.6f\n", Box[0][0],Box[0][1],Box[0][2]);
+     629          12 :   log.printf("  B:  %12.6f%12.6f%12.6f\n", Box[1][0],Box[1][1],Box[1][2]);
+     630          12 :   log.printf("  C:  %12.6f%12.6f%12.6f\n", Box[2][0],Box[2][1],Box[2][2]);
+     631          12 :   log << "Changing the PBC according to the new box \n";
+     632          12 :   Pbc mypbc;
+     633          12 :   mypbc.setBox(Box);
+     634          12 :   log << "The box volume is " << mypbc.getBox().determinant() << " \n";
+     635             : 
+     636             :   //Compute scaling factor
+     637          12 :   if(Svol) {
+     638          12 :     Fvol=cbrt(Vol0/mypbc.getBox().determinant());
+     639          12 :     log << "Scaling atom distances by  " << Fvol << " \n";
+     640             :   } else {
+     641           0 :     log << "Using unscaled atom distances \n";
+     642             :   }
+     643             : 
+     644          12 :   r00.resize(Nlist);
+     645          12 :   sw.resize(Nlist);
+     646          36 :   for (unsigned j=0; j<Nlist; j++) {
+     647          48 :     if( !parseNumbered( "SWITCH", j+1, sw[j] ) ) break;
+     648             :   }
+     649          12 :   if(CompDer) {
+     650             :     // Set switching function parameters here only if computing derivatives
+     651             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     652           6 :     log << "Switching Function Parameters \n";
+     653           6 :     sfs.resize(Nlist);
+     654             :     std::string errors;
+     655          18 :     for (unsigned j=0; j<Nlist; j++) {
+     656          12 :       if(Svol) {
+     657             :         double r0;
+     658             :         std::string old_r0;
+     659          12 :         vector<string> data=Tools::getWords(sw[j]);
+     660             :         data.erase(data.begin());
+     661          12 :         Tools::parse(data,"R_0",old_r0);
+     662          12 :         Tools::convert(old_r0,r0);
+     663          12 :         r0*=Fvol;
+     664          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     665          12 :         std::size_t pos = sw[j].find("R_0");
+     666          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     667          12 :       }
+     668          12 :       sfs[j].set(sw[j],errors);
+     669             :       std::string num;
+     670          12 :       Tools::convert(j+1, num);
+     671          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     672          12 :       r00[j]=sfs[j].get_r0();
+     673          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     674             :     }
+     675             :   }
+     676             : 
+     677             :   // build COMs from positions if requested
+     678          12 :   if(com) {
+     679           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     680           0 :       compos[j][0]=0.;
+     681           0 :       compos[j][1]=0.;
+     682           0 :       compos[j][2]=0.;
+     683           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     684           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     685           0 :         compos[j]+=fmass[andx]*mypdb.getPositions()[andx];
+     686             :       }
+     687             :     }
+     688             :   }
+     689             :   // build the rPIV distances (transformation and sorting is done afterwards)
+     690          12 :   if(CompDer) {
+     691           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     692             :   }
+     693          36 :   for(unsigned j=0; j<Nlist; j++) {
+     694    11516328 :     for(unsigned i=0; i<nl[j]->size(); i++) {
+     695    11516304 :       unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     696    11516304 :       unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     697             :       //calculate/get COM position of centers i0 and i1
+     698    11516304 :       Vector Pos0,Pos1;
+     699    11516304 :       if(com) {
+     700             :         //if(pbc) makeWhole();
+     701           0 :         Pos0=compos[i0];
+     702           0 :         Pos1=compos[i1];
+     703             :       } else {
+     704    11516304 :         Pos0=mypdb.getPositions()[i0];
+     705    11516304 :         Pos1=mypdb.getPositions()[i1];
+     706             :       }
+     707    11516304 :       Vector ddist;
+     708    11516304 :       if(pbc) {
+     709    11516304 :         ddist=mypbc.distance(Pos0,Pos1);
+     710             :       } else {
+     711           0 :         ddist=delta(Pos0,Pos1);
+     712             :       }
+     713    11516304 :       double df=0.;
+     714             :       // Transformation and sorting done at the first timestep to solve the r0 definition issue
+     715    11516304 :       if(CompDer) {
+     716        1104 :         rPIV[j].push_back(sfs[j].calculate(ddist.modulo()*Fvol, df));
+     717             :       } else {
+     718    11515200 :         rPIV[j].push_back(ddist.modulo()*Fvol);
+     719             :       }
+     720             :     }
+     721          24 :     if(CompDer) {
+     722          12 :       if(dosort[j]) {
+     723           0 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     724             :       }
+     725             :       int lmt0=0;
+     726             :       int lmt1=0;
+     727        1116 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     728        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     729           0 :           lmt0+=1;
+     730             :         }
+     731        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     732           0 :           lmt1+=1;
+     733             :         }
+     734             :       }
+     735          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     736             :     }
+     737             :   }
+     738             : 
+     739          12 :   checkRead();
+     740             :   // From the plumed manual on how to build-up a new Colvar
+     741          24 :   addValueWithDerivatives();
+     742          12 :   requestAtoms(nlall->getFullAtomList());
+     743          12 :   setNotPeriodic();
+     744             :   // getValue()->setPeridodicity(false);
+     745             :   // set size of derivative vector
+     746          12 :   m_deriv.resize(getNumberOfAtoms());
+     747          12 : }
+     748             : 
+     749         327 : void PIV::calculate()
+     750             : {
+     751             : 
+     752             :   // Local variables
+     753             : 
+     754         327 :   if(sharedData_unique) {
+     755             :     // This is executed by the first PIV instance.
+     756             :     // We initialize variables with the correct Nlist.
+     757         321 :     sharedData_unique->prev_pos.resize(Nlist);
+     758         321 :     sharedData_unique->cPIV.resize(Nlist);
+     759         321 :     sharedData_unique->Atom0.resize(Nlist);
+     760         321 :     sharedData_unique->Atom1.resize(Nlist);
+     761             :   }
+     762             : 
+     763             :   // create references to minimize the impact of the code below
+     764         327 :   auto & prev_stp(sharedData->prev_stp);
+     765             :   auto & init_stp(sharedData->init_stp);
+     766             :   auto & prev_pos(sharedData->prev_pos);
+     767             :   auto & cPIV(sharedData->cPIV);
+     768             :   auto & Atom0(sharedData->Atom0);
+     769             :   auto & Atom1(sharedData->Atom1);
+     770             : 
+     771         327 :   std:: vector<std:: vector<int> > A0(Nprec);
+     772         327 :   std:: vector<std:: vector<int> > A1(Nprec);
+     773             :   size_t stride=1;
+     774             :   unsigned rank=0;
+     775             : 
+     776         327 :   if(!serial) {
+     777         327 :     stride=comm.Get_size();
+     778         327 :     rank=comm.Get_rank();
+     779             :   } else {
+     780             :     stride=1;
+     781             :     rank=0;
+     782             :   }
+     783             : 
+     784             :   // Transform (and sort) the rPIV before starting the dynamics
+     785         327 :   if (((prev_stp==-1) || (init_stp==1)) &&!CompDer) {
+     786           6 :     if(prev_stp!=-1) {init_stp=0;}
+     787             :     // Calculate the volume scaling factor
+     788           6 :     if(Svol) {
+     789           6 :       Fvol=cbrt(Vol0/getBox().determinant());
+     790             :     }
+     791             :     //Set switching function parameters
+     792           6 :     log << "\n";
+     793           6 :     log << "REFERENCE PDB # " << prev_stp+2 << " \n";
+     794             :     // Set switching function parameters here only if computing derivatives
+     795             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     796           6 :     log << "Switching Function Parameters \n";
+     797           6 :     sfs.resize(Nlist);
+     798             :     std::string errors;
+     799          18 :     for (unsigned j=0; j<Nlist; j++) {
+     800          12 :       if(Svol) {
+     801             :         double r0;
+     802             :         std::string old_r0;
+     803          12 :         vector<string> data=Tools::getWords(sw[j]);
+     804             :         data.erase(data.begin());
+     805          12 :         Tools::parse(data,"R_0",old_r0);
+     806          12 :         Tools::convert(old_r0,r0);
+     807          12 :         r0*=Fvol;
+     808          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     809          12 :         std::size_t pos = sw[j].find("R_0");
+     810          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     811          12 :       }
+     812          12 :       sfs[j].set(sw[j],errors);
+     813             :       std::string num;
+     814          12 :       Tools::convert(j+1, num);
+     815          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     816          12 :       r00[j]=sfs[j].get_r0();
+     817          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     818             :     }
+     819             :     //Transform and sort
+     820           6 :     log << "Building Reference PIV Vector \n";
+     821           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     822           6 :     double df=0.;
+     823          18 :     for (unsigned j=0; j<Nlist; j++) {
+     824    11515212 :       for (unsigned i=0; i<rPIV[j].size(); i++) {
+     825    11515200 :         rPIV[j][i]=sfs[j].calculate(rPIV[j][i], df);
+     826             :       }
+     827          12 :       if(dosort[j]) {
+     828          12 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     829             :       }
+     830             :       int lmt0=0;
+     831             :       int lmt1=0;
+     832    11515212 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     833    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     834          26 :           lmt0+=1;
+     835             :         }
+     836    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     837       63358 :           lmt1+=1;
+     838             :         }
+     839             :       }
+     840          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     841             :     }
+     842           6 :     log << "\n";
+     843             :   }
+     844             :   // Do the sorting only once per timestep to avoid building the PIV N times for N rPIV PDB structures!
+     845         327 :   if ((getStep()>prev_stp&&getStep()%updatePIV==0)||CompDer) {
+     846         324 :     if (CompDer) log << " Step " << getStep() << "  Computing Derivatives NON-SORTED PIV \n";
+     847             :     //
+     848             :     // build COMs from positions if requested
+     849         324 :     if(com) {
+     850           0 :       if(pbc) makeWhole();
+     851           0 :       for(unsigned j=0; j<compos.size(); j++) {
+     852           0 :         compos[j][0]=0.;
+     853           0 :         compos[j][1]=0.;
+     854           0 :         compos[j][2]=0.;
+     855           0 :         for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     856           0 :           unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     857           0 :           compos[j]+=fmass[andx]*getPosition(andx);
+     858             :         }
+     859             :       }
+     860             :     }
+     861             :     // update neighbor lists when an atom moves out of the Neighbor list skin
+     862         324 :     if (doneigh) {
+     863             :       bool doupdate=false;
+     864             :       // For the first step build previous positions = actual positions
+     865         324 :       if (prev_stp==-1) {
+     866           6 :         bool docom=com;
+     867          18 :         for (unsigned j=0; j<Nlist; j++) {
+     868        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     869        9696 :             Vector Pos;
+     870        9696 :             if(docom) {
+     871           0 :               Pos=compos[i];
+     872             :             } else {
+     873        9696 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     874             :             }
+     875        9696 :             prev_pos[j].push_back(Pos);
+     876             :           }
+     877             :         }
+     878             :         doupdate=true;
+     879             :       }
+     880             :       // Decide whether to update lists based on atom displacement, every stride
+     881         324 :       std:: vector<std:: vector<Vector> > tmp_pos(Nlist);
+     882         324 :       if (getStep() % nlall->getStride() ==0) {
+     883         324 :         bool docom=com;
+     884         972 :         for (unsigned j=0; j<Nlist; j++) {
+     885       20520 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     886       19872 :             Vector Pos;
+     887       19872 :             if(docom) {
+     888           0 :               Pos=compos[i];
+     889             :             } else {
+     890       19872 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     891             :             }
+     892       19872 :             tmp_pos[j].push_back(Pos);
+     893       19872 :             if (pbcDistance(tmp_pos[j][i],prev_pos[j][i]).modulo()>=nl_skin[j]) {
+     894             :               doupdate=true;
+     895             :             }
+     896             :           }
+     897             :         }
+     898             :       }
+     899             :       // Update Nlists if needed
+     900         324 :       if (doupdate==true) {
+     901          18 :         for (unsigned j=0; j<Nlist; j++) {
+     902        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     903        9696 :             prev_pos[j][i]=tmp_pos[j][i];
+     904             :           }
+     905          12 :           nl[j]->update(prev_pos[j]);
+     906          12 :           log << " Step " << getStep() << "  Neighbour lists updated " << nl[j]->size() << " \n";
+     907             :         }
+     908             :       }
+     909         324 :     }
+     910             :     // Calculate the volume scaling factor
+     911         324 :     if(Svol) {
+     912         324 :       Fvol=cbrt(Vol0/getBox().determinant());
+     913             :     }
+     914         324 :     Vector ddist;
+     915             :     // Global to local variables
+     916         324 :     bool doserial=serial;
+     917             :     // Build "Nlist" PIV blocks
+     918         972 :     for(unsigned j=0; j<Nlist; j++) {
+     919         648 :       if(dosort[j]) {
+     920             :         // from global to local variables to speedup the for loop with if statements
+     921           6 :         bool docom=com;
+     922           6 :         bool dopbc=pbc;
+     923             :         // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     924           6 :         std:: vector<int> OrdVec(Nprec,0);
+     925           6 :         cPIV[j].resize(0);
+     926           6 :         Atom0[j].resize(0);
+     927           6 :         Atom1[j].resize(0);
+     928             :         // Building distances for the PIV vector at time t
+     929           6 :         if(timer) stopwatch.start("1 Build cPIV");
+     930     5757606 :         for(unsigned i=rank; i<nl[j]->size(); i+=stride) {
+     931     5757600 :           unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     932     5757600 :           unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     933     5757600 :           Vector Pos0,Pos1;
+     934     5757600 :           if(docom) {
+     935           0 :             Pos0=compos[i0];
+     936           0 :             Pos1=compos[i1];
+     937             :           } else {
+     938     5757600 :             Pos0=getPosition(i0);
+     939     5757600 :             Pos1=getPosition(i1);
+     940             :           }
+     941     5757600 :           if(dopbc) {
+     942     5757600 :             ddist=pbcDistance(Pos0,Pos1);
+     943             :           } else {
+     944           0 :             ddist=delta(Pos0,Pos1);
+     945             :           }
+     946     5757600 :           double df=0.;
+     947             :           //Integer sorting ... faster!
+     948             :           //Transforming distances with the Switching function + real to integer transformation
+     949     5757600 :           int Vint=int(sfs[j].calculate(ddist.modulo()*Fvol, df)*double(Nprec-1)+0.5);
+     950             :           //Integer transformed distance values as index of the Ordering Vector OrdVec
+     951     5757600 :           OrdVec[Vint]+=1;
+     952             :           //Keeps track of atom indices for force and virial calculations
+     953     5757600 :           A0[Vint].push_back(i0);
+     954     5757600 :           A1[Vint].push_back(i1);
+     955             :         }
+     956           6 :         if(timer) stopwatch.stop("1 Build cPIV");
+     957           6 :         if(timer) stopwatch.start("2 Sort cPIV");
+     958           6 :         if(!doserial && comm.initialized()) {
+     959             :           // Vectors keeping track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     960           0 :           std:: vector<int> Vdim(stride,0);
+     961           0 :           std:: vector<int> Vpos(stride,0);
+     962             :           // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     963           0 :           std:: vector<int> OrdVecAll(stride*Nprec);
+     964             :           // Big vectors containing all Atom indexes for every occupancy (Atom0O(Nprec,n) and Atom1O(Nprec,n) matrices in one vector)
+     965             :           std:: vector<int> Atom0F;
+     966             :           std:: vector<int> Atom1F;
+     967             :           // Vector used to reconstruct arrays
+     968           0 :           std:: vector<unsigned> k(stride,0);
+     969             :           // Zeros might be many, this slows down a lot due to MPI communication
+     970             :           // Avoid passing the zeros (i=1) for atom indices
+     971           0 :           for(unsigned i=1; i<Nprec; i++) {
+     972             :             // Building long vectors with all atom indexes for occupancies ordered from i=1 to i=Nprec-1
+     973             :             // Can this be avoided ???
+     974           0 :             Atom0F.insert(Atom0F.end(),A0[i].begin(),A0[i].end());
+     975           0 :             Atom1F.insert(Atom1F.end(),A1[i].begin(),A1[i].end());
+     976           0 :             A0[i].resize(0);
+     977           0 :             A1[i].resize(0);
+     978             :           }
+     979             :           // Resize partial arrays to fill up for the next PIV block
+     980           0 :           A0[0].resize(0);
+     981           0 :           A1[0].resize(0);
+     982           0 :           A0[Nprec-1].resize(0);
+     983           0 :           A1[Nprec-1].resize(0);
+     984             :           // Avoid passing the zeros (i=1) for atom indices
+     985           0 :           OrdVec[0]=0;
+     986           0 :           OrdVec[Nprec-1]=0;
+     987             : 
+     988             :           // Wait for all ranks before communication of Vectors
+     989           0 :           comm.Barrier();
+     990             : 
+     991             :           // pass the array sizes before passing the arrays
+     992           0 :           int dim=Atom0F.size();
+     993             :           // Vdim and Vpos keep track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     994           0 :           comm.Allgather(&dim,1,&Vdim[0],1);
+     995             : 
+     996             :           // TO BE IMPROVED: the following may be done by the rank 0 (now every rank does it)
+     997             :           int Fdim=0;
+     998           0 :           for(unsigned i=1; i<stride; i++) {
+     999           0 :             Vpos[i]=Vpos[i-1]+Vdim[i-1];
+    1000           0 :             Fdim+=Vdim[i];
+    1001             :           }
+    1002           0 :           Fdim+=Vdim[0];
+    1003             :           // build big vectors for atom pairs on all ranks for all ranks
+    1004           0 :           std:: vector<int> Atom0FAll(Fdim);
+    1005           0 :           std:: vector<int> Atom1FAll(Fdim);
+    1006             :           // TO BE IMPROVED: Allgathers may be substituted by gathers by proc 0
+    1007             :           //   Moreover vectors are gathered head-to-tail and assembled later-on in a serial step.
+    1008             :           // Gather the full Ordering Vector (occupancies). This is what we need to build the PIV
+    1009           0 :           comm.Allgather(&OrdVec[0],Nprec,&OrdVecAll[0],Nprec);
+    1010             :           // Gather the vectors of atom pairs to keep track of the idexes for the forces
+    1011           0 :           comm.Allgatherv(Atom0F.data(),Atom0F.size(),&Atom0FAll[0],&Vdim[0],&Vpos[0]);
+    1012           0 :           comm.Allgatherv(Atom1F.data(),Atom1F.size(),&Atom1FAll[0],&Vdim[0],&Vpos[0]);
+    1013             : 
+    1014             :           // Reconstruct the full vectors from collections of Allgathered parts (this is a serial step)
+    1015             :           // This is the tricky serial step, to assemble together PIV and atom-pair info from head-tail big vectors
+    1016             :           // Loop before on l and then on i would be better but the allgather should be modified
+    1017             :           // Loop on blocks
+    1018             :           //for(unsigned m=0;m<Nlist;m++) {
+    1019             :           // Loop on Ordering Vector size excluding zeros (i=1)
+    1020           0 :           if(timer) stopwatch.stop("2 Sort cPIV");
+    1021           0 :           if(timer) stopwatch.start("3 Reconstruct cPIV");
+    1022           0 :           for(unsigned i=1; i<Nprec; i++) {
+    1023             :             // Loop on the ranks
+    1024           0 :             for(unsigned l=0; l<stride; l++) {
+    1025             :               // Loop on the number of head-to-tail pieces
+    1026           0 :               for(unsigned m=0; m<OrdVecAll[i+l*Nprec]; m++) {
+    1027             :                 // cPIV is the current PIV at time t
+    1028           0 :                 cPIV[j].push_back(double(i)/double(Nprec-1));
+    1029           0 :                 Atom0[j].push_back(Atom0FAll[k[l]+Vpos[l]]);
+    1030           0 :                 Atom1[j].push_back(Atom1FAll[k[l]+Vpos[l]]);
+    1031           0 :                 k[l]+=1;
+    1032             :               }
+    1033             :             }
+    1034             :           }
+    1035           0 :           if(timer) stopwatch.stop("3 Reconstruct cPIV");
+    1036             :         } else {
+    1037     6000000 :           for(unsigned i=1; i<Nprec; i++) {
+    1038    11757594 :             for(unsigned m=0; m<OrdVec[i]; m++) {
+    1039     5757600 :               cPIV[j].push_back(double(i)/double(Nprec-1));
+    1040     5757600 :               Atom0[j].push_back(A0[i][m]);
+    1041     5757600 :               Atom1[j].push_back(A1[i][m]);
+    1042             :             }
+    1043             :           }
+    1044             :         }
+    1045             :       }
+    1046             :     }
+    1047             :   }
+    1048         327 :   Vector distance;
+    1049         327 :   double dfunc=0.;
+    1050             :   // Calculate volume scaling factor
+    1051         327 :   if(Svol) {
+    1052         327 :     Fvol=cbrt(Vol0/getBox().determinant());
+    1053             :   }
+    1054             : 
+    1055             :   // This test may be run by specifying the TEST keyword as input, it pritnts rPIV and cPIV and quits
+    1056         327 :   if(test) {
+    1057             :     unsigned limit=0;
+    1058           0 :     for(unsigned j=0; j<Nlist; j++) {
+    1059           0 :       if(dosort[j]) {
+    1060           0 :         limit = cPIV[j].size();
+    1061             :       } else {
+    1062           0 :         limit = rPIV[j].size();
+    1063             :       }
+    1064           0 :       log.printf("PIV Block:  %6i %12s %6i \n", j, "      Size:", limit);
+    1065           0 :       log.printf("%6s%6s%12s%12s%36s\n","     i","     j", "    c-PIV   ","    r-PIV   ","   i-j distance vector       ");
+    1066           0 :       for(unsigned i=0; i<limit; i++) {
+    1067             :         unsigned i0=0;
+    1068             :         unsigned i1=0;
+    1069           0 :         if(dosort[j]) {
+    1070           0 :           i0=Atom0[j][i];
+    1071           0 :           i1=Atom1[j][i];
+    1072             :         } else {
+    1073           0 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1074           0 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1075             :         }
+    1076           0 :         Vector Pos0,Pos1;
+    1077           0 :         if(com) {
+    1078           0 :           Pos0=compos[i0];
+    1079           0 :           Pos1=compos[i1];
+    1080             :         } else {
+    1081           0 :           Pos0=getPosition(i0);
+    1082           0 :           Pos1=getPosition(i1);
+    1083             :         }
+    1084           0 :         if(pbc) {
+    1085           0 :           distance=pbcDistance(Pos0,Pos1);
+    1086             :         } else {
+    1087           0 :           distance=delta(Pos0,Pos1);
+    1088             :         }
+    1089           0 :         dfunc=0.;
+    1090             :         double cP,rP;
+    1091           0 :         if(dosort[j]) {
+    1092           0 :           cP = cPIV[j][i];
+    1093           0 :           rP = rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1094             :         } else {
+    1095           0 :           double dm=distance.modulo();
+    1096           0 :           cP = sfs[j].calculate(dm*Fvol, dfunc);
+    1097           0 :           rP = rPIV[j][i];
+    1098             :         }
+    1099           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]);
+    1100             :       }
+    1101             :     }
+    1102           0 :     log.printf("This was a test, now exit \n");
+    1103           0 :     exit();
+    1104             :   }
+    1105             : 
+    1106         327 :   if(timer) stopwatch.start("4 Build For Derivatives");
+    1107             :   // non-global variables Nder and Scalevol defined to speedup if structures in cycles
+    1108         327 :   bool Nder=CompDer;
+    1109         327 :   bool Scalevol=Svol;
+    1110         327 :   if(getStep()%updatePIV==0) {
+    1111             :     // set to zero PIVdistance, derivatives and virial when they are calculated
+    1112       29799 :     for(unsigned j=0; j<m_deriv.size(); j++) {
+    1113      117888 :       for(unsigned k=0; k<3; k++) {m_deriv[j][k]=0.;}
+    1114             :     }
+    1115        1308 :     for(unsigned j=0; j<3; j++) {
+    1116        3924 :       for(unsigned k=0; k<3; k++) {
+    1117        2943 :         m_virial[j][k]=0.;
+    1118             :       }
+    1119             :     }
+    1120         327 :     m_PIVdistance=0.;
+    1121             :     // Re-compute atomic distances for derivatives and compute PIV-PIV distance
+    1122         981 :     for(unsigned j=0; j<Nlist; j++) {
+    1123             :       unsigned limit=0;
+    1124             :       // dosorting definition is to speedup if structure in cycles with non-global variables
+    1125         654 :       bool dosorting=dosort[j];
+    1126         654 :       bool docom=com;
+    1127         654 :       bool dopbc=pbc;
+    1128         654 :       if(dosorting) {
+    1129          12 :         limit = cPIV[j].size();
+    1130             :       } else {
+    1131         642 :         limit = rPIV[j].size();
+    1132             :       }
+    1133    11574918 :       for(unsigned i=rank; i<limit; i+=stride) {
+    1134             :         unsigned i0=0;
+    1135             :         unsigned i1=0;
+    1136    11574264 :         if(dosorting) {
+    1137    11515200 :           i0=Atom0[j][i];
+    1138    11515200 :           i1=Atom1[j][i];
+    1139             :         } else {
+    1140       59064 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1141       59064 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1142             :         }
+    1143    11574264 :         Vector Pos0,Pos1;
+    1144    11574264 :         if(docom) {
+    1145           0 :           Pos0=compos[i0];
+    1146           0 :           Pos1=compos[i1];
+    1147             :         } else {
+    1148    11574264 :           Pos0=getPosition(i0);
+    1149    11574264 :           Pos1=getPosition(i1);
+    1150             :         }
+    1151    11574264 :         if(dopbc) {
+    1152    11574264 :           distance=pbcDistance(Pos0,Pos1);
+    1153             :         } else {
+    1154           0 :           distance=delta(Pos0,Pos1);
+    1155             :         }
+    1156    11574264 :         dfunc=0.;
+    1157             :         // this is needed for dfunc and dervatives
+    1158    11574264 :         double dm=distance.modulo();
+    1159    11574264 :         double tPIV = sfs[j].calculate(dm*Fvol, dfunc);
+    1160             :         // PIV distance
+    1161             :         double coord=0.;
+    1162    11574264 :         if(!dosorting||Nder) {
+    1163       59064 :           coord = tPIV - rPIV[j][i];
+    1164             :         } else {
+    1165    11515200 :           coord = cPIV[j][i] - rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1166             :         }
+    1167             :         // Calculate derivatives, virial, and variable=sum_j (scaling[j] *(cPIV-rPIV)_j^2)
+    1168             :         // WARNING: dfunc=dswf/(Fvol*dm)  (this may change in future Plumed versions)
+    1169    11574264 :         double tmp = 2.*scaling[j]*coord*Fvol*Fvol*dfunc;
+    1170    11574264 :         Vector tmpder = tmp*distance;
+    1171             :         // 0.5*(x_i-x_k)*f_ik         (force on atom k due to atom i)
+    1172    11574264 :         if(docom) {
+    1173           0 :           Vector dist;
+    1174           0 :           for(unsigned k=0; k<nlcom[i0]->getFullAtomList().size(); k++) {
+    1175           0 :             unsigned x0=nlcom[i0]->getFullAtomList()[k].index();
+    1176           0 :             m_deriv[x0] -= tmpder*fmass[x0];
+    1177           0 :             for(unsigned l=0; l<3; l++) {
+    1178           0 :               dist[l]=0.;
+    1179             :             }
+    1180           0 :             Vector P0=getPosition(x0);
+    1181           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1182           0 :               unsigned x1=nlcom[i0]->getFullAtomList()[l].index();
+    1183           0 :               Vector P1=getPosition(x1);
+    1184           0 :               if(dopbc) {
+    1185           0 :                 dist+=pbcDistance(P0,P1);
+    1186             :               } else {
+    1187           0 :                 dist+=delta(P0,P1);
+    1188             :               }
+    1189             :             }
+    1190           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1191           0 :               unsigned x1=nlcom[i1]->getFullAtomList()[l].index();
+    1192           0 :               Vector P1=getPosition(x1);
+    1193           0 :               if(dopbc) {
+    1194           0 :                 dist+=pbcDistance(P0,P1);
+    1195             :               } else {
+    1196           0 :                 dist+=delta(P0,P1);
+    1197             :               }
+    1198             :             }
+    1199           0 :             m_virial    -= 0.25*fmass[x0]*Tensor(dist,tmpder);
+    1200             :           }
+    1201           0 :           for(unsigned k=0; k<nlcom[i1]->getFullAtomList().size(); k++) {
+    1202           0 :             unsigned x1=nlcom[i1]->getFullAtomList()[k].index();
+    1203           0 :             m_deriv[x1] += tmpder*fmass[x1];
+    1204           0 :             for(unsigned l=0; l<3; l++) {
+    1205           0 :               dist[l]=0.;
+    1206             :             }
+    1207           0 :             Vector P1=getPosition(x1);
+    1208           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1209           0 :               unsigned x0=nlcom[i1]->getFullAtomList()[l].index();
+    1210           0 :               Vector P0=getPosition(x0);
+    1211           0 :               if(dopbc) {
+    1212           0 :                 dist+=pbcDistance(P1,P0);
+    1213             :               } else {
+    1214           0 :                 dist+=delta(P1,P0);
+    1215             :               }
+    1216             :             }
+    1217           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1218           0 :               unsigned x0=nlcom[i0]->getFullAtomList()[l].index();
+    1219           0 :               Vector P0=getPosition(x0);
+    1220           0 :               if(dopbc) {
+    1221           0 :                 dist+=pbcDistance(P1,P0);
+    1222             :               } else {
+    1223           0 :                 dist+=delta(P1,P0);
+    1224             :               }
+    1225             :             }
+    1226           0 :             m_virial    += 0.25*fmass[x1]*Tensor(dist,tmpder);
+    1227             :           }
+    1228             :         } else {
+    1229    11574264 :           m_deriv[i0] -= tmpder;
+    1230    11574264 :           m_deriv[i1] += tmpder;
+    1231    11574264 :           m_virial    -= tmp*Tensor(distance,distance);
+    1232             :         }
+    1233    11574264 :         if(Scalevol) {
+    1234    11574264 :           m_virial+=1./3.*tmp*dm*dm*Tensor::identity();
+    1235             :         }
+    1236    11574264 :         m_PIVdistance    += scaling[j]*coord*coord;
+    1237             :       }
+    1238             :     }
+    1239             : 
+    1240         327 :     if (!serial && comm.initialized()) {
+    1241           0 :       comm.Barrier();
+    1242           0 :       comm.Sum(&m_PIVdistance,1);
+    1243           0 :       if(!m_deriv.empty()) comm.Sum(&m_deriv[0][0],3*m_deriv.size());
+    1244           0 :       comm.Sum(&m_virial[0][0],9);
+    1245             :     }
+    1246             :   }
+    1247         327 :   prev_stp=getStep();
+    1248             : 
+    1249             :   //Timing
+    1250         327 :   if(timer) stopwatch.stop("4 Build For Derivatives");
+    1251         327 :   if(timer) {
+    1252           1 :     log.printf("Timings for action %s with label %s \n", getName().c_str(), getLabel().c_str() );
+    1253           1 :     log<<stopwatch;
+    1254             :   }
+    1255             : 
+    1256             :   // Update derivatives, virial, and variable (PIV-distance^2)
+    1257       29799 :   for(unsigned i=0; i<m_deriv.size(); ++i) setAtomsDerivatives(i,m_deriv[i]);
+    1258         327 :   setValue           (m_PIVdistance);
+    1259         327 :   setBoxDerivatives  (m_virial);
+    1260         327 : }
+    1261             : //Close Namespaces at the very beginning
+    1262             : }
+    1263             : }
+    1264             : 
+
+
+
+ + + + +
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 000000000..feded3bd6 --- /dev/null +++ b/coverage/piv/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %428 / 59660.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 000000000..b90527f12 --- /dev/null +++ b/coverage/piv/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %428 / 59660.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 000000000..2ae6e488e --- /dev/null +++ b/coverage/piv/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-10-17 16:45:00Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %428 / 59660.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 000000000..d048396b0 --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..74be30fce --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8590cbc29 --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.gcov.html @@ -0,0 +1,320 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..177484a2d --- /dev/null +++ b/coverage/pytorch/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..14eda38ad --- /dev/null +++ b/coverage/pytorch/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..1be244f81 --- /dev/null +++ b/coverage/pytorch/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..9bd0c2957 --- /dev/null +++ b/coverage/refdist/Difference.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:273284.4 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist10Difference24setPeriodicityForOutputsEPNS_15ActionWithValueE184
_ZN4PLMD7refdist10Difference4readEPNS_19ActionWithArgumentsE184
_ZN4PLMD7refdist10Difference16registerKeywordsERNS_8KeywordsE737
_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 000000000..dc6a3a5bc --- /dev/null +++ b/coverage/refdist/Difference.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:273284.4 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist10Difference16registerKeywordsERNS_8KeywordsE737
_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 000000000..d64ce7bae --- /dev/null +++ b/coverage/refdist/Difference.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + 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:273284.4 %
Date:2024-10-17 16:45:00Functions:44100.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        1105 : class Difference : public function::FunctionTemplateBase {
+      62             : private:
+      63             :   bool periodic;
+      64             :   std::string min0, max0;
+      65             : public:
+      66             :   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         737 : void Difference::registerKeywords(Keywords& keys) {
+      81         737 :   keys.setValueDescription("a function that measures the difference");
+      82         737 : }
+      83             : 
+      84         184 : void Difference::read( ActionWithArguments* action ) {
+      85         184 :   if( action->getNumberOfArguments()!=2 ) action->error("should be two arguments to this action");
+      86         184 :   if( action->getPntrToArgument(0)->getRank()==action->getPntrToArgument(1)->getRank() ) {
+      87          51 :     std::vector<unsigned> shape( action->getPntrToArgument(0)->getShape() );
+      88          61 :     for(unsigned i=0; i<shape.size(); ++i) {
+      89          10 :       if( shape[i]!=action->getPntrToArgument(1)->getShape()[i] ) action->error("shapes of input actions do not match");
+      90             :     }
+      91             :   }
+      92             : 
+      93         184 :   periodic=false;
+      94         184 :   if( action->getPntrToArgument(0)->isPeriodic() ) {
+      95          43 :     periodic=true; action->getPntrToArgument(0)->getDomain( min0, max0 );
+      96          43 :     if( !action->getPntrToArgument(1)->isConstant() && !action->getPntrToArgument(1)->isPeriodic() ) {
+      97           0 :       action->error("period for input variables " + action->getPntrToArgument(0)->getName() + " and " + action->getPntrToArgument(1)->getName() + " should be the same 0");
+      98             :     }
+      99          43 :     if( !action->getPntrToArgument(1)->isConstant() ) {
+     100           1 :       std::string min1, max1; action->getPntrToArgument(1)->getDomain( min1, max1 );
+     101           1 :       if( min0!=min0 || max0!=max1 ) action->error("domain for input variables should be the same");
+     102          42 :     } else action->getPntrToArgument(1)->setDomain( min0, max0 );
+     103         141 :   } else if( action->getPntrToArgument(1)->isPeriodic() ) {
+     104           0 :     periodic=true; action->getPntrToArgument(1)->getDomain( min0, max0 );
+     105           0 :     if( !action->getPntrToArgument(1)->isConstant() ) {
+     106           0 :       action->error("period for input variables " + action->getPntrToArgument(0)->getName() + " and " + action->getPntrToArgument(1)->getName() + " should be the same 1");
+     107           0 :     } else action->getPntrToArgument(0)->setDomain( min0, max0 );
+     108             :   }
+     109         184 : }
+     110             : 
+     111         184 : void Difference::setPeriodicityForOutputs( ActionWithValue* action ) {
+     112         184 :   if( periodic ) action->setPeriodic( min0, max0 );
+     113         141 :   else action->setNotPeriodic();
+     114         184 : }
+     115             : 
+     116     2877849 : void Difference::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     117     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;
+     118     2877849 : }
+     119             : 
+     120             : }
+     121             : }
+     122             : 
+     123             : 
+
+
+
+ + + + +
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 000000000..c46fc2bec --- /dev/null +++ b/coverage/refdist/Displacement.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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:3333100.0 %
Date:2024-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist12DisplacementC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist12DisplacementC1ERKNS_13ActionOptionsE52
_ZNK4PLMD7refdist12Displacement17getValueWithLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE59
_ZN4PLMD7refdist12Displacement16registerKeywordsERNS_8KeywordsE104
_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 000000000..482520ded --- /dev/null +++ b/coverage/refdist/Displacement.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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:3333100.0 %
Date:2024-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist12Displacement14fixArgumentDotERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE354
_ZN4PLMD7refdist12Displacement16registerKeywordsERNS_8KeywordsE104
_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 000000000..eb3441f9c --- /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:3333100.0 %
Date:2024-10-17 16:45:00Functions: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         104 : void Displacement::registerKeywords( Keywords& keys ) {
+      52         104 :   ActionShortcut::registerKeywords(keys);
+      53         208 :   keys.add("compulsory","ARG1","The point that we are calculating the distance from");
+      54         208 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      55         104 :   keys.setValueDescription("the differences between the input arguments");
+      56         312 :   keys.needsAction("DIFFERENCE"); keys.needsAction("TRANSPOSE"); keys.needsAction("VSTACK");
+      57         104 : }
+      58             : 
+      59         354 : std::string Displacement::fixArgumentDot( const std::string& argin ) {
+      60         354 :   std::string argout = argin; std::size_t dot=argin.find(".");
+      61         362 :   if( dot!=std::string::npos ) argout = argin.substr(0,dot) + "_" + argin.substr(dot+1);
+      62         354 :   return argout;
+      63             : }
+      64             : 
+      65          52 : Displacement::Displacement( const ActionOptions& ao):
+      66             :   Action(ao),
+      67          52 :   ActionShortcut(ao)
+      68             : {
+      69             :   // Read in argument names
+      70         156 :   std::vector<std::string> arg1f, arg2f; parseVector("ARG1",arg1f); parseVector("ARG2",arg2f);
+      71             :   // Check if one of the input arguments is a reference cluster
+      72          52 :   if( arg1f.size()!=arg2f.size() ) error("number of arguments specified to ARG1 should be same as number for ARG2");
+      73             : 
+      74          52 :   Value* val1=getValueWithLabel( arg1f[0] );
+      75          52 :   if( arg1f.size()==1 && val1->getRank()!=0 ) {
+      76           7 :     Value* val2=getValueWithLabel( arg2f[0] );
+      77           7 :     if( val1->getNumberOfValues()==val2->getNumberOfValues() ) {
+      78          10 :       readInputLine( getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff: DIFFERENCE ARG=" + arg1f[0] + "," + arg2f[0] );
+      79          10 :       readInputLine( getShortcutLabel() + ": TRANSPOSE ARG=" + getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff");
+      80           4 :     } else readInputLine( getShortcutLabel() + ": DIFFERENCE ARG=" + arg1f[0] + "," + arg2f[0] );
+      81             :   } else {
+      82         217 :     for(unsigned i=0; i<arg1f.size(); ++i) readInputLine( getShortcutLabel() + "_" + fixArgumentDot(arg1f[i]) + "_diff: DIFFERENCE ARG=" + arg1f[i] + "," + arg2f[i] );
+      83         217 :     std::string argdat = "ARG=" + getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff"; for(unsigned i=1; i<arg1f.size(); ++i) argdat += "," +  getShortcutLabel() + "_" + fixArgumentDot(arg1f[i]) + "_diff";
+      84          90 :     readInputLine( getShortcutLabel() + ": VSTACK " + argdat );
+      85             :   }
+      86          52 : }
+      87             : 
+      88          59 : Value* Displacement::getValueWithLabel( const std::string& name ) const {
+      89          59 :   std::size_t dot=name.find("."); std::string sname = name.substr(0,dot);
+      90          59 :   ActionWithValue* vv=plumed.getActionSet().selectWithLabel<ActionWithValue*>( sname );
+      91          59 :   if( !vv ) error("cannot find value with name " + name );
+      92          59 :   if( dot==std::string::npos ) return vv->copyOutput(0);
+      93           2 :   if( !vv->exists(name) ) error("cannot find value with name " + name );
+      94           2 :   return vv->copyOutput( name );
+      95             : }
+      96             : 
+      97             : }
+      98             : }
+
+
+
+ + + + +
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 000000000..e34de0bfa --- /dev/null +++ b/coverage/refdist/EuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:202195.2 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist17EuclideanDistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist17EuclideanDistanceC1ERKNS_13ActionOptionsE28
_ZN4PLMD7refdist17EuclideanDistance16registerKeywordsERNS_8KeywordsE35
+
+
+ + + +
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 000000000..0b6d040e2 --- /dev/null +++ b/coverage/refdist/EuclideanDistance.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:202195.2 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist17EuclideanDistance16registerKeywordsERNS_8KeywordsE35
_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 000000000..e9bf871c3 --- /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:202195.2 %
Date:2024-10-17 16:45:00Functions: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          35 : void EuclideanDistance::registerKeywords( Keywords& keys ) {
+      49          35 :   ActionShortcut::registerKeywords(keys);
+      50          70 :   keys.add("compulsory","ARG1","The poin that we are calculating the distance from");
+      51          70 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      52          70 :   keys.addFlag("SQUARED",false,"The squared distance should be calculated");
+      53          35 :   keys.setValueDescription("the euclidean distances between the input vectors");
+      54          70 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("CUSTOM");
+      55          70 :   keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_PRODUCT_DIAGONAL");
+      56          35 : }
+      57             : 
+      58          28 : EuclideanDistance::EuclideanDistance( const ActionOptions& ao):
+      59             :   Action(ao),
+      60          28 :   ActionShortcut(ao)
+      61             : {
+      62          56 :   std::string arg1, arg2; parse("ARG1",arg1); parse("ARG2",arg2);
+      63             :   // Vectors are in rows here
+      64          56 :   readInputLine( getShortcutLabel() + "_diff: DISPLACEMENT ARG1=" + arg1 + " ARG2=" + arg2 );
+      65             :   // Get the action that computes the differences
+      66          56 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diff"); plumed_assert( av );
+      67             :   // Check if squared
+      68          56 :   bool squared; parseFlag("SQUARED",squared); std::string olab = getShortcutLabel(); if( !squared ) olab += "_2";
+      69             :   // Deal with an annoying corner case when displacement has a single argument
+      70          28 :   if( av->copyOutput(0)->getRank()==0 ) {
+      71           0 :     readInputLine( olab + ": CUSTOM ARG=" + getShortcutLabel() + "_diff FUNC=x*x PERIODIC=NO");
+      72             :   } else {
+      73             :     // Notice that the vectors are in the columns here
+      74          56 :     readInputLine( getShortcutLabel() + "_diffT: TRANSPOSE ARG=" + getShortcutLabel() + "_diff");
+      75          56 :     readInputLine( olab + ": MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_diff," + getShortcutLabel() + "_diffT");
+      76             :   }
+      77          51 :   if( !squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+      78          28 : }
+      79             : 
+      80             : }
+      81             : }
+
+
+
+ + + + +
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 000000000..11551b16c --- /dev/null +++ b/coverage/refdist/Kernel.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:8410778.5 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist6KernelC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist6KernelC1ERKNS_13ActionOptionsE9
_ZN4PLMD7refdist6Kernel16registerKeywordsERNS_8KeywordsE20
_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 000000000..cc735d337 --- /dev/null +++ b/coverage/refdist/Kernel.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:8410778.5 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist6Kernel14fixArgumentDotERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32
_ZN4PLMD7refdist6Kernel16registerKeywordsERNS_8KeywordsE20
_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 000000000..e786a707d --- /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:8410778.5 %
Date:2024-10-17 16:45:00Functions: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          20 : void Kernel::registerKeywords(Keywords& keys) {
+      55          20 :   ActionShortcut::registerKeywords( keys );
+      56          40 :   keys.add("numbered","ARG","the arguments that should be used as input to this method");
+      57          40 :   keys.add("compulsory","TYPE","gaussian","the type of kernel to use");
+      58          40 :   keys.add("compulsory","CENTER","the position of the center of the kernel");
+      59          40 :   keys.add("optional","SIGMA","square root of variance of the cluster");
+      60          40 :   keys.add("compulsory","COVAR","the covariance of the kernel");
+      61          40 :   keys.add("compulsory","WEIGHT","1.0","the weight to multiply this kernel function by");
+      62          40 :   keys.add("optional","REFERENCE","the file from which to read the kernel parameters");
+      63          40 :   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          40 :   keys.addFlag("NORMALIZED",false,"would you like the kernel function to be normalized");
+      65          20 :   keys.setValueDescription("the value of the kernel evaluated at the argument values");
+      66          60 :   keys.needsAction("CONSTANT"); keys.needsAction("CUSTOM"); keys.needsAction("NORMALIZED_EUCLIDEAN_DISTANCE");
+      67          60 :   keys.needsAction("PRODUCT"); keys.needsAction("INVERT_MATRIX"); keys.needsAction("MAHALANOBIS_DISTANCE");
+      68          60 :   keys.needsAction("DIAGONALIZE"); keys.needsAction("CONCATENATE"); keys.needsAction("DETERMINANT");
+      69          20 :   keys.needsAction("BESSEL");
+      70          20 : }
+      71             : 
+      72          32 : std::string Kernel::fixArgumentDot( const std::string& argin ) {
+      73          32 :   std::string argout = argin; std::size_t dot=argin.find(".");
+      74          32 :   if( dot!=std::string::npos ) argout = argin.substr(0,dot) + "_" + argin.substr(dot+1);
+      75          32 :   return argout;
+      76             : }
+      77             : 
+      78           9 : Kernel::Kernel(const ActionOptions&ao):
+      79             :   Action(ao),
+      80           9 :   ActionShortcut(ao)
+      81             : {
+      82             :   // Read in the arguments
+      83          18 :   std::vector<std::string> argnames; parseVector("ARG",argnames);
+      84           9 :   if( argnames.size()==0 ) error("no arguments were specified");
+      85             :   // Now sort out the parameters
+      86          18 :   double weight; std::string fname; parse("REFERENCE",fname); bool usemahalanobis=false;
+      87           9 :   if( fname.length()>0 ) {
+      88           9 :     IFile ifile; ifile.open(fname); ifile.allowIgnoredFields();
+      89           9 :     unsigned number; parse("NUMBER",number); bool readline=false;
+      90             :     // Create actions to hold the position of the center
+      91          31 :     for(unsigned line=0; line<number; ++line) {
+      92          90 :       for(unsigned i=0; i<argnames.size(); ++i) {
+      93          59 :         std::string val; ifile.scanField(argnames[i], val);
+      94          75 :         if( line==number-1 ) readInputLine( getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref: CONSTANT VALUES=" + val );
+      95             :       }
+      96          62 :       if( ifile.FieldExist("sigma_" + argnames[0]) ) {
+      97             :         std::string varstr;
+      98           0 :         for(unsigned i=0; i<argnames.size(); ++i) {
+      99           0 :           std::string val; ifile.scanField("sigma_" + argnames[i], val);
+     100           0 :           if( i==0 ) varstr = val; else varstr += "," + val;
+     101             :         }
+     102           0 :         if( line==number-1 ) readInputLine( getShortcutLabel() + "_var: CONSTANT VALUES=" + varstr );
+     103             :       } else {
+     104          31 :         std::string varstr, nvals; Tools::convert( argnames.size(), nvals ); usemahalanobis=(argnames.size()>1);
+     105          90 :         for(unsigned i=0; i<argnames.size(); ++i) {
+     106         174 :           for(unsigned j=0; j<argnames.size(); j++) {
+     107         230 :             std::string val; ifile.scanField("sigma_" +argnames[i] + "_" + argnames[j], val );
+     108         199 :             if(i==0 && j==0 ) varstr = val; else varstr += "," + val;
+     109             :           }
+     110             :         }
+     111          31 :         if( line==number-1 ) {
+     112          11 :           if( !usemahalanobis ) readInputLine( getShortcutLabel() + "_var: CONSTANT VALUES=" + varstr );
+     113          14 :           else readInputLine( getShortcutLabel() + "_cov: CONSTANT NCOLS=" + nvals + " NROWS=" + nvals + " VALUES=" + varstr );
+     114             :         }
+     115             :       }
+     116          31 :       if( line==number-1 ) { readline=true; break; }
+     117          22 :       ifile.scanField();
+     118             :     }
+     119           9 :     if( !readline ) error("could not read reference configuration");
+     120           9 :     ifile.scanField(); ifile.close();
+     121           9 :   } else {
+     122             :     // Create actions to hold the position of the center
+     123           0 :     std::vector<std::string> center(argnames.size()); parseVector("CENTER",center);
+     124           0 :     for(unsigned i=0; i<argnames.size(); ++i) readInputLine( getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref: CONSTANT VALUES=" + center[i] );
+     125           0 :     std::vector<std::string> sig; parseVector("SIGMA",sig);
+     126           0 :     if( sig.size()==0 ) {
+     127             :       // Create actions to hold the covariance
+     128           0 :       std::string cov; parse("COVAR",cov); usemahalanobis=(argnames.size()>1);
+     129           0 :       if( !usemahalanobis ) {
+     130           0 :         readInputLine( getShortcutLabel() + "_var: CONSTANT VALUES=" + cov );
+     131             :       } else {
+     132           0 :         std::string nvals; Tools::convert( argnames.size(), nvals );
+     133           0 :         readInputLine( getShortcutLabel() + "_cov: CONSTANT NCOLS=" + nvals + " NROWS=" + nvals + " VALUES=" + cov );
+     134             :       }
+     135           0 :     } else if( sig.size()==argnames.size() ) {
+     136             :       // And actions to hold the standard deviation
+     137           0 :       std::string valstr = sig[0]; for(unsigned i=1; i<sig.size(); ++i) valstr += "," + sig[i];
+     138           0 :       readInputLine( getShortcutLabel() + "_sigma: CONSTANT VALUES=" + valstr );
+     139           0 :       readInputLine( getShortcutLabel() + "_var: CUSTOM ARG=" + getShortcutLabel() + "_sigma FUNC=x*x PERIODIC=NO");
+     140           0 :     } else error("sigma has wrong length");
+     141           0 :   }
+     142             : 
+     143             :   // Create the reference point and arguments
+     144             :   std::string refpoint, argstr;
+     145          25 :   for(unsigned i=0; i<argnames.size(); ++i) {
+     146          34 :     if( i==0 ) { argstr = argnames[0]; refpoint = getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref"; }
+     147          21 :     else { argstr += "," + argnames[1]; refpoint += "," + getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref"; }
+     148             :   }
+     149             : 
+     150             :   // Get the information on the kernel type
+     151          18 :   std::string func_str, ktype; parse("TYPE",ktype);
+     152          16 :   if( ktype=="gaussian" || ktype=="von-misses" ) func_str = "exp(-x/2)";
+     153           0 :   else if( ktype=="triangular" ) func_str = "step(1.-sqrt(x))*(1.-sqrt(x))";
+     154             :   else func_str = ktype;
+     155           9 :   std::string vm_str=""; if(  ktype=="von-misses" ) vm_str=" VON_MISSES";
+     156             : 
+     157           9 :   unsigned nvals = argnames.size(); bool norm; parseFlag("NORMALIZED",norm);
+     158           9 :   if( !usemahalanobis ) {
+     159             :     // Invert the variance
+     160           4 :     readInputLine( getShortcutLabel() + "_icov: CUSTOM ARG=" + getShortcutLabel() + "_var FUNC=1/x PERIODIC=NO");
+     161             :     // Compute the distance between the center of the basin and the current configuration
+     162           4 :     readInputLine( getShortcutLabel() + "_dist_2: NORMALIZED_EUCLIDEAN_DISTANCE SQUARED" + vm_str +" ARG1=" + argstr + " ARG2=" + refpoint + " METRIC=" + getShortcutLabel() + "_icov");
+     163             :     // And compute a determinent for the input covariance matrix if it is required
+     164           2 :     if( norm ) {
+     165           2 :       if( ktype=="von-misses" ) readInputLine( getShortcutLabel() + "_vec: CUSTOM ARG=" + getShortcutLabel() + "_icov FUNC=x PERIODIC=NO" );
+     166           4 :       else readInputLine( getShortcutLabel() + "_det: PRODUCT ARG=" + getShortcutLabel() + "_var");
+     167             :     }
+     168             :   } else {
+     169             :     // Invert the input covariance matrix
+     170          14 :     readInputLine( getShortcutLabel() + "_icov: INVERT_MATRIX ARG=" + getShortcutLabel() + "_cov" );
+     171             :     // Compute the distance between the center of the basin and the current configuration
+     172          14 :     readInputLine( getShortcutLabel() + "_dist_2: MAHALANOBIS_DISTANCE SQUARED ARG1=" + argstr + " ARG2=" + refpoint + " METRIC=" + getShortcutLabel() + "_icov " + vm_str );
+     173             :     // And compute a determinent for the input covariance matrix if it is required
+     174           7 :     if( norm ) {
+     175           7 :       if( ktype=="von-misses" ) {
+     176          14 :         readInputLine( getShortcutLabel() + "_det: DIAGONALIZE ARG=" + getShortcutLabel() + "_cov VECTORS=all" );
+     177           7 :         std::string num, argnames= getShortcutLabel() + "_det.vals-1";
+     178          14 :         for(unsigned i=1; i<nvals; ++i) { Tools::convert( i+1, num ); argnames += "," + getShortcutLabel() + "_det.vals-" + num; }
+     179          14 :         readInputLine( getShortcutLabel() + "_comp: CONCATENATE ARG=" + argnames );
+     180          14 :         readInputLine( getShortcutLabel() + "_vec: CUSTOM ARG=" + getShortcutLabel() + "_comp FUNC=1/x PERIODIC=NO");
+     181             :       } else {
+     182           0 :         readInputLine( getShortcutLabel() + "_det: DETERMINANT ARG=" + getShortcutLabel() + "_cov");
+     183             :       }
+     184             :     }
+     185             :   }
+     186             : 
+     187             :   // Compute the Gaussian
+     188           9 :   std::string wstr; parse("WEIGHT",wstr);
+     189           9 :   if( norm ) {
+     190           9 :     if( ktype=="gaussian" ) {
+     191           2 :       std::string pstr; Tools::convert( sqrt(pow(2*pi,nvals)), pstr );
+     192           4 :       readInputLine( getShortcutLabel() + "_vol: CUSTOM ARG=" + getShortcutLabel() + "_det FUNC=(sqrt(x)*" + pstr + ") PERIODIC=NO");
+     193           7 :     } else if( ktype=="von-misses" ) {
+     194             :       std::string wstr, min, max;
+     195          14 :       ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_dist_2_diff" ); plumed_assert( av );
+     196           7 :       if( !av->copyOutput(0)->isPeriodic() ) error("VON_MISSES only works with periodic variables");
+     197           7 :       av->copyOutput(0)->getDomain(min,max);
+     198          14 :       readInputLine( getShortcutLabel() + "_bes: BESSEL ORDER=0 ARG=" + getShortcutLabel() + "_vec");
+     199          14 :       readInputLine( getShortcutLabel() + "_cc: CUSTOM ARG=" + getShortcutLabel() + "_bes FUNC=("+max+"-"+min+")*x PERIODIC=NO");
+     200          14 :       readInputLine( getShortcutLabel() + "_vol: PRODUCT ARG=" + getShortcutLabel() + "_cc");
+     201           0 :     } else error("only gaussian and von-misses kernels are normalizable");
+     202             :     // And the (suitably normalized) kernel
+     203          18 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_dist_2," + getShortcutLabel() + "_vol FUNC=" + wstr + "*exp(-x/2)/y PERIODIC=NO");
+     204             :   } else {
+     205           0 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG1=" + getShortcutLabel() + "_dist_2 FUNC=" + wstr + "*" + func_str + " PERIODIC=NO");
+     206             :   }
+     207           9 :   checkRead();
+     208             : 
+     209           9 : }
+     210             : 
+     211             : }
+     212             : }
+     213             : 
+     214             : 
+
+
+
+ + + + +
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 000000000..7e7eaae85 --- /dev/null +++ b/coverage/refdist/MahalanobisDistance.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:6161100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist19MahalanobisDistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist19MahalanobisDistanceC1ERKNS_13ActionOptionsE12
_ZN4PLMD7refdist19MahalanobisDistance16registerKeywordsERNS_8KeywordsE21
+
+
+ + + +
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 000000000..4f61ef3a4 --- /dev/null +++ b/coverage/refdist/MahalanobisDistance.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:6161100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist19MahalanobisDistance16registerKeywordsERNS_8KeywordsE21
_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 000000000..8c617ecdf --- /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:6161100.0 %
Date:2024-10-17 16:45:00Functions: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          21 : void MahalanobisDistance::registerKeywords( Keywords& keys ) {
+      49          21 :   ActionShortcut::registerKeywords(keys);
+      50          42 :   keys.add("compulsory","ARG1","The point that we are calculating the distance from");
+      51          42 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      52          42 :   keys.add("compulsory","METRIC","The inverse covariance matrix that should be used when calculating the distance");
+      53          42 :   keys.addFlag("SQUARED",false,"The squared distance should be calculated");
+      54          42 :   keys.addFlag("VON_MISSES",false,"Compute the mahalanobis distance in a way that is more sympathetic to the periodic boundary conditions");
+      55          21 :   keys.setValueDescription("the Mahalanobis distances between the input vectors");
+      56          63 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("CUSTOM"); keys.needsAction("OUTER_PRODUCT");
+      57          63 :   keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_PRODUCT_DIAGONAL"); keys.needsAction("CONSTANT");
+      58          63 :   keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("MATRIX_PRODUCT"); keys.needsAction("COMBINE");
+      59          21 : }
+      60             : 
+      61          12 : MahalanobisDistance::MahalanobisDistance( const ActionOptions& ao):
+      62             :   Action(ao),
+      63          12 :   ActionShortcut(ao)
+      64             : {
+      65          36 :   std::string arg1, arg2, metstr; parse("ARG1",arg1); parse("ARG2",arg2); parse("METRIC",metstr);
+      66             :   // Check on input metric
+      67          12 :   ActionWithValue* mav=plumed.getActionSet().selectWithLabel<ActionWithValue*>( metstr );
+      68          12 :   if( !mav ) error("could not find action named " + metstr + " to use for metric");
+      69          12 :   if( mav->copyOutput(0)->getRank()!=2 ) error("metric has incorrect rank");
+      70             : 
+      71          24 :   readInputLine( getShortcutLabel() + "_diff: DISPLACEMENT ARG1=" + arg1 + " ARG2=" + arg2 );
+      72          24 :   readInputLine( getShortcutLabel() + "_diffT: TRANSPOSE ARG=" + getShortcutLabel() + "_diff");
+      73          24 :   bool von_miss, squared; parseFlag("VON_MISSES",von_miss); parseFlag("SQUARED",squared);
+      74          12 :   if( von_miss ) {
+      75           7 :     unsigned nrows = mav->copyOutput(0)->getShape()[0];
+      76           7 :     if( mav->copyOutput(0)->getShape()[1]!=nrows ) error("metric is not symmetric");
+      77             :     // Create a matrix that can be used to compute the off diagonal elements
+      78             :     std::string valstr, nrstr;
+      79           7 :     Tools::convert( mav->copyOutput(0)->get(0), valstr ); Tools::convert( nrows, nrstr );
+      80           7 :     std::string diagmet = getShortcutLabel() + "_diagmet: CONSTANT VALUES=" + valstr;
+      81          14 :     std::string offdiagmet = getShortcutLabel() + "_offdiagmet: CONSTANT NROWS=" + nrstr + " NCOLS=" + nrstr + " VALUES=0";
+      82          21 :     for(unsigned i=0; i<nrows; ++i) {
+      83          42 :       for(unsigned j=0; j<nrows; ++j) {
+      84          28 :         Tools::convert( mav->copyOutput(0)->get(i*nrows+j), valstr );
+      85          42 :         if( i==j && i>0 ) { offdiagmet += ",0"; diagmet += "," + valstr; }
+      86          35 :         else if( i!=j ) { offdiagmet += "," + valstr; }
+      87             :       }
+      88             :     }
+      89           7 :     readInputLine( diagmet ); readInputLine( offdiagmet );
+      90             :     // Compute distances scaled by periods
+      91          14 :     ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diff" ); plumed_assert( av );
+      92           7 :     if( !av->copyOutput(0)->isPeriodic() ) error("VON_MISSES only works with periodic variables");
+      93           7 :     std::string min, max; av->copyOutput(0)->getDomain(min,max);
+      94          14 :     readInputLine( getShortcutLabel() + "_scaled: CUSTOM ARG=" + getShortcutLabel() + "_diffT FUNC=2*pi*x/(" + max +"-" + min + ") PERIODIC=NO");
+      95             :     // We start calculating off-diagonal elements by computing the sines of the scaled differences (this is a column vector)
+      96          14 :     readInputLine( getShortcutLabel() + "_sinediffT: CUSTOM ARG=" + getShortcutLabel() + "_scaled FUNC=sin(x) PERIODIC=NO");
+      97             :     // Transpose sines to get a row vector
+      98          14 :     readInputLine( getShortcutLabel() + "_sinediff: TRANSPOSE ARG=" + getShortcutLabel() + "_sinediffT");
+      99             :     // Compute the off diagonal elements
+     100          14 :     readInputLine( getShortcutLabel() + "_matvec: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_offdiagmet," + getShortcutLabel() +"_sinediffT");
+     101          14 :     readInputLine( getShortcutLabel() + "_offdiag: MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_sinediff," + getShortcutLabel() +"_matvec");
+     102             :     // Sort out the metric for the diagonal elements
+     103           7 :     std::string metstr2 = getShortcutLabel() + "_diagmet";
+     104             :     // If this is a matrix we need create a matrix to multiply by
+     105           7 :     if( av->copyOutput(0)->getShape()[0]>1 ) {
+     106             :       // Create some ones
+     107          21 :       std::string ones=" VALUES=1"; for(unsigned i=1; i<av->copyOutput(0)->getShape()[0]; ++i ) ones += ",1";
+     108          14 :       readInputLine( getShortcutLabel() + "_ones: CONSTANT " + ones );
+     109             :       // Now do some multiplication to create a matrix that can be multiplied by our "inverse variance" vector
+     110          14 :       readInputLine( getShortcutLabel() + "_" + metstr + ": OUTER_PRODUCT ARG=" + metstr2 + "," + getShortcutLabel() + "_ones");
+     111          14 :       metstr2 = getShortcutLabel() + "_" + metstr;
+     112             :     }
+     113             :     // Compute the diagonal elements
+     114          14 :     readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + getShortcutLabel() + "_scaled," + metstr2 + " FUNC=2*(1-cos(x))*y PERIODIC=NO");
+     115           7 :     std::string ncstr; Tools::convert( nrows, ncstr ); Tools::convert( av->copyOutput(0)->getShape()[0], nrstr );
+     116          42 :     std::string ones=" VALUES=1"; for(unsigned i=1; i<av->copyOutput(0)->getNumberOfValues(); ++i) ones += ",1";
+     117          14 :     readInputLine( getShortcutLabel() + "_matones: CONSTANT NROWS=" + nrstr + " NCOLS=" + ncstr + ones );
+     118          14 :     readInputLine( getShortcutLabel() + "_diag: MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_matones," + getShortcutLabel() + "_prod");
+     119             :     // Sum everything
+     120           7 :     if( !squared ) readInputLine( getShortcutLabel() + "_2: COMBINE ARG=" + getShortcutLabel() + "_offdiag," + getShortcutLabel() + "_diag PERIODIC=NO");
+     121          14 :     else readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_offdiag," + getShortcutLabel() + "_diag PERIODIC=NO");
+     122             :   } else {
+     123          10 :     ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diffT" ); plumed_assert( av && av->getNumberOfComponents()==1 );
+     124           9 :     if( (av->copyOutput(0))->getRank()==1 ) readInputLine( getShortcutLabel() + "_matvec: MATRIX_VECTOR_PRODUCT ARG=" + metstr + "," + getShortcutLabel() +"_diffT");
+     125           2 :     else readInputLine( getShortcutLabel() + "_matvec: MATRIX_PRODUCT ARG=" + metstr + "," + getShortcutLabel() +"_diffT");
+     126           5 :     std::string olab = getShortcutLabel(); if( !squared ) olab += "_2";
+     127          10 :     readInputLine( olab + ": MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_diff," + getShortcutLabel() +"_matvec");
+     128             :   }
+     129          17 :   if( !squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+     130          12 : }
+     131             : 
+     132             : }
+     133             : }
+
+
+
+ + + + +
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 000000000..f3c556bd8 --- /dev/null +++ b/coverage/refdist/MatrixProductDiagonal.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:6060100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist21MatrixProductDiagonalC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist21MatrixProductDiagonalC1ERKNS_13ActionOptionsE55
_ZN4PLMD7refdist21MatrixProductDiagonal16registerKeywordsERNS_8KeywordsE112
_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 000000000..5e4a266cc --- /dev/null +++ b/coverage/refdist/MatrixProductDiagonal.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:6060100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist21MatrixProductDiagonal16registerKeywordsERNS_8KeywordsE112
_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 000000000..217d10997 --- /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:6060100.0 %
Date:2024-10-17 16:45:00Functions: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         112 : void MatrixProductDiagonal::registerKeywords( Keywords& keys ) {
+      50         112 :   ActionWithVector::registerKeywords(keys); keys.use("ARG");
+      51         112 :   keys.setValueDescription("a vector containing the diagonal elements of the matrix that obtaned by multiplying the two input matrices together");
+      52         112 : }
+      53             : 
+      54          55 : MatrixProductDiagonal::MatrixProductDiagonal(const ActionOptions&ao):
+      55             :   Action(ao),
+      56          55 :   ActionWithVector(ao)
+      57             : {
+      58          55 :   if( getNumberOfArguments()!=2 ) error("should be two arguments to this action, a matrix and a vector");
+      59             : 
+      60             :   unsigned ncols;
+      61          55 :   if( getPntrToArgument(0)->getRank()==1 ) {
+      62           2 :     if( getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a vector or matrix");
+      63             :     ncols = 1;
+      64          53 :   } else if( getPntrToArgument(0)->getRank()==2 ) {
+      65          53 :     if( getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a matrix");
+      66          53 :     ncols = getPntrToArgument(0)->getShape()[1];
+      67             :   }
+      68             : 
+      69          55 :   if( getPntrToArgument(1)->getRank()==1 ) {
+      70          32 :     if( getPntrToArgument(1)->hasDerivatives() ) error("second argument to this action should be a vector or matrix");
+      71          32 :     if( ncols!=getPntrToArgument(1)->getShape()[0] ) error("number of columns in first matrix does not equal number of elements in vector");
+      72          32 :     if( getPntrToArgument(0)->getShape()[0]!=1 ) error("matrix output by this action must be square");
+      73          64 :     addValueWithDerivatives(); setNotPeriodic();
+      74             :   } else {
+      75          23 :     if( getPntrToArgument(1)->getRank()!=2 || getPntrToArgument(1)->hasDerivatives() ) error("second argument to this action should be a vector or a matrix");
+      76          23 :     if( ncols!=getPntrToArgument(1)->getShape()[0] ) error("number of columns in first matrix does not equal number of rows in second matrix");
+      77          23 :     if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(1)->getShape()[1] ) error("matrix output by this action must be square");
+      78          23 :     std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getShape()[0];
+      79          23 :     addValue( shape ); setNotPeriodic();
+      80             :   }
+      81          55 :   getPntrToArgument(0)->buildDataStore(); getPntrToArgument(1)->buildDataStore();
+      82          55 : }
+      83             : 
+      84        2418 : unsigned MatrixProductDiagonal::getNumberOfDerivatives() {
+      85        2418 :   if( doNotCalculateDerivatives() ) return 0;
+      86         108 :   return getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();;
+      87             : }
+      88             : 
+      89      119881 : void MatrixProductDiagonal::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+      90      119881 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+      91             :   Value* arg1 = getPntrToArgument(0); Value* arg2 = getPntrToArgument(1);
+      92      119881 :   if( arg1->getRank()==1 ) {
+      93          40 :     double val1 = arg1->get( task_index );
+      94          40 :     double val2 = arg2->get( task_index );
+      95          40 :     myvals.addValue( ostrn, val1*val2 );
+      96             : 
+      97          40 :     if( doNotCalculateDerivatives() ) return;
+      98             : 
+      99          40 :     myvals.addDerivative( ostrn, task_index, val2 );
+     100          40 :     myvals.updateIndex( ostrn, task_index );
+     101          40 :     unsigned nvals = getPntrToArgument(0)->getNumberOfValues();
+     102          40 :     myvals.addDerivative( ostrn, nvals + task_index, val1 );
+     103          40 :     myvals.updateIndex( ostrn, nvals + task_index );
+     104             :   } else {
+     105             :     unsigned nmult = arg1->getRowLength(task_index);
+     106      119841 :     unsigned nrowsA = getPntrToArgument(0)->getShape()[1];
+     107      119841 :     unsigned nrowsB = 1; if( getPntrToArgument(1)->getRank()>1 ) nrowsB = getPntrToArgument(1)->getShape()[1];
+     108      119841 :     unsigned nvals1 = getPntrToArgument(0)->getNumberOfValues();
+     109             : 
+     110             :     double matval = 0;
+     111     3025572 :     for(unsigned i=0; i<nmult; ++i) {
+     112             :       unsigned kind = arg1->getRowIndex( task_index, i );
+     113     2905731 :       double val1 = arg1->get( task_index*nrowsA + kind );
+     114     2905731 :       double val2 = arg2->get( kind*nrowsB + task_index );
+     115     2905731 :       matval += val1*val2;
+     116             : 
+     117     2905731 :       if( doNotCalculateDerivatives() ) continue;
+     118             : 
+     119     2836839 :       myvals.addDerivative( ostrn, task_index*nrowsA + kind, val2 );
+     120     2836839 :       myvals.updateIndex( ostrn, task_index*nrowsA + kind );
+     121     2836839 :       myvals.addDerivative( ostrn, nvals1 + kind*nrowsB + task_index, val1 );
+     122     2836839 :       myvals.updateIndex( ostrn, nvals1 + kind*nrowsB + task_index );
+     123             :     }
+     124             :     // And add this part of the product
+     125      119841 :     myvals.addValue( ostrn, matval );
+     126             :   }
+     127             : }
+     128             : 
+     129        2792 : void MatrixProductDiagonal::calculate() {
+     130        2792 :   if( getPntrToArgument(1)->getRank()==1 ) {
+     131        1179 :     unsigned nder = getNumberOfDerivatives();
+     132        1179 :     MultiValue myvals( 1, nder, 0, 0, 0 ); performTask( 0, myvals );
+     133             : 
+     134        1179 :     Value* myval=getPntrToComponent(0); myval->set( myvals.get(0) );
+     135        1329 :     for(unsigned i=0; i<nder; ++i) myval->setDerivative( i, myvals.getDerivative(0,i) );
+     136        2792 :   } else runAllTasks();
+     137        2792 : }
+     138             : 
+     139             : }
+     140             : }
+
+
+
+ + + + +
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 000000000..bf239e41a --- /dev/null +++ b/coverage/refdist/NormalizedEuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:2929100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist27NormalizedEuclideanDistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist27NormalizedEuclideanDistanceC1ERKNS_13ActionOptionsE8
_ZN4PLMD7refdist27NormalizedEuclideanDistance16registerKeywordsERNS_8KeywordsE13
+
+
+ + + +
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 000000000..244543935 --- /dev/null +++ b/coverage/refdist/NormalizedEuclideanDistance.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:2929100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist27NormalizedEuclideanDistance16registerKeywordsERNS_8KeywordsE13
_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 000000000..2a1a8ea1d --- /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:2929100.0 %
Date:2024-10-17 16:45:00Functions: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          13 : void NormalizedEuclideanDistance::registerKeywords( Keywords& keys ) {
+      49          13 :   ActionShortcut::registerKeywords(keys);
+      50          26 :   keys.add("compulsory","ARG1","The poin that we are calculating the distance from");
+      51          26 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      52          26 :   keys.add("compulsory","METRIC","The inverse covariance matrix that should be used when calculating the distance");
+      53          26 :   keys.addFlag("SQUARED",false,"The squared distance should be calculated");
+      54          13 :   keys.setValueDescription("the normalized euclidean distances between the input vectors");
+      55          39 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("CUSTOM"); keys.needsAction("OUTER_PRODUCT");
+      56          39 :   keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_PRODUCT_DIAGONAL"); keys.needsAction("ONES");
+      57          13 : }
+      58             : 
+      59           8 : NormalizedEuclideanDistance::NormalizedEuclideanDistance( const ActionOptions& ao):
+      60             :   Action(ao),
+      61           8 :   ActionShortcut(ao)
+      62             : {
+      63          24 :   std::string arg1, arg2, metstr; parse("ARG1",arg1); parse("ARG2",arg2); parse("METRIC",metstr);
+      64             :   // Vectors are in rows here
+      65          16 :   readInputLine( getShortcutLabel() + "_diff: DISPLACEMENT ARG1=" + arg1 + " ARG2=" + arg2 );
+      66             :   // Vectors are in columns here
+      67          16 :   readInputLine( getShortcutLabel() + "_diffT: TRANSPOSE ARG=" + getShortcutLabel() + "_diff");
+      68             :   // Get the action that computes the differences
+      69          16 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diffT"); plumed_assert( av );
+      70             :   // If this is a matrix we need create a matrix to multiply by
+      71           8 :   if( av->copyOutput(0)->getRank()==2 ) {
+      72             :     // Create some ones
+      73           4 :     std::string nones; Tools::convert( av->copyOutput(0)->getShape()[1], nones );
+      74           8 :     readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + nones);
+      75             :     // Now do some multiplication to create a matrix that can be multiplied by our "inverse variance" vector
+      76           4 :     if( av->copyOutput(0)->getShape()[0]==1 ) {
+      77           4 :       readInputLine( getShortcutLabel() + "_" + metstr + "T: CUSTOM ARG=" + metstr + "," + getShortcutLabel() + "_ones FUNC=x*y PERIODIC=NO");
+      78           4 :       readInputLine( getShortcutLabel() + "_" + metstr + ": TRANSPOSE ARG=" + getShortcutLabel() + "_" + metstr + "T");
+      79           4 :     } else readInputLine( getShortcutLabel() + "_" + metstr + ": OUTER_PRODUCT ARG=" + metstr + "," + getShortcutLabel() + "_ones");
+      80           8 :     metstr = getShortcutLabel() + "_" + metstr;
+      81             :   }
+      82             :   // Now do the multiplication
+      83          16 :   readInputLine( getShortcutLabel() + "_sdiff: CUSTOM ARG=" + metstr + "," + getShortcutLabel() +"_diffT FUNC=x*y PERIODIC=NO");
+      84          16 :   bool squared; parseFlag("SQUARED",squared); std::string olab = getShortcutLabel(); if( !squared ) olab += "_2";
+      85          16 :   readInputLine( olab + ": MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() +"_diff," + getShortcutLabel() + "_sdiff");
+      86          13 :   if( !squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+      87           8 : }
+      88             : 
+      89             : }
+      90             : }
+
+
+
+ + + + +
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 000000000..3b126667b --- /dev/null +++ b/coverage/refdist/index-sort-f.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - refdist + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdistHitTotalCoverage
Test:plumed test coverageLines:31434391.5 %
Date:2024-10-17 16:45:00Functions:222878.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
MahalanobisDistance.cpp +
100.0%
+
100.0 %61 / 6166.7 %2 / 3
EuclideanDistance.cpp +
95.2%95.2%
+
95.2 %20 / 2166.7 %2 / 3
NormalizedEuclideanDistance.cpp +
100.0%
+
100.0 %29 / 2966.7 %2 / 3
Kernel.cpp +
78.5%78.5%
+
78.5 %84 / 10775.0 %3 / 4
Displacement.cpp +
100.0%
+
100.0 %33 / 3380.0 %4 / 5
MatrixProductDiagonal.cpp +
100.0%
+
100.0 %60 / 6083.3 %5 / 6
Difference.cpp +
84.4%84.4%
+
84.4 %27 / 32100.0 %4 / 4
+
+
+ + + + +
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 000000000..19e79fd85 --- /dev/null +++ b/coverage/refdist/index-sort-l.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - refdist + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdistHitTotalCoverage
Test:plumed test coverageLines:31434391.5 %
Date:2024-10-17 16:45:00Functions:222878.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Kernel.cpp +
78.5%78.5%
+
78.5 %84 / 10775.0 %3 / 4
Difference.cpp +
84.4%84.4%
+
84.4 %27 / 32100.0 %4 / 4
EuclideanDistance.cpp +
95.2%95.2%
+
95.2 %20 / 2166.7 %2 / 3
NormalizedEuclideanDistance.cpp +
100.0%
+
100.0 %29 / 2966.7 %2 / 3
Displacement.cpp +
100.0%
+
100.0 %33 / 3380.0 %4 / 5
MatrixProductDiagonal.cpp +
100.0%
+
100.0 %60 / 6083.3 %5 / 6
MahalanobisDistance.cpp +
100.0%
+
100.0 %61 / 6166.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 000000000..5dc228cbc --- /dev/null +++ b/coverage/refdist/index.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - refdist + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdistHitTotalCoverage
Test:plumed test coverageLines:31434391.5 %
Date:2024-10-17 16:45:00Functions:222878.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Difference.cpp +
84.4%84.4%
+
84.4 %27 / 32100.0 %4 / 4
Displacement.cpp +
100.0%
+
100.0 %33 / 3380.0 %4 / 5
EuclideanDistance.cpp +
95.2%95.2%
+
95.2 %20 / 2166.7 %2 / 3
Kernel.cpp +
78.5%78.5%
+
78.5 %84 / 10775.0 %3 / 4
MahalanobisDistance.cpp +
100.0%
+
100.0 %61 / 6166.7 %2 / 3
MatrixProductDiagonal.cpp +
100.0%
+
100.0 %60 / 6083.3 %5 / 6
NormalizedEuclideanDistance.cpp +
100.0%
+
100.0 %29 / 2966.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 000000000..7a7db1422 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..24875bbd9 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..e691729ac --- /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:15216691.6 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the value of the CV");
+     100          26 : }
+     101             : 
+     102          24 : S2ContactModel::S2ContactModel(const ActionOptions&ao):
+     103             :   PLUMED_COLVAR_INIT(ao),
+     104          24 :   pbc_(true),
+     105          24 :   serial_(false),
+     106          24 :   invalidateList(true),
+     107          24 :   firsttime(true),
+     108          24 :   r_eff_(0.0),
+     109          24 :   inv_r_eff_(0.0),
+     110          24 :   prefactor_a_(0.0),
+     111          24 :   exp_b_(0.0),
+     112          24 :   offset_c_(0.0),
+     113          24 :   n_i_(0.0),
+     114          24 :   total_prefactor_(0.0),
+     115          24 :   r_globalshift_(0.0),
+     116          24 :   modeltype_(methyl)
+     117             : {
+     118             : 
+     119          48 :   parseFlag("SERIAL",serial_);
+     120             : 
+     121             :   std::vector<AtomNumber> methyl_atom;
+     122          48 :   parseAtomList("METHYL_ATOM",methyl_atom);
+     123             :   std::vector<AtomNumber> nh_atoms;
+     124          48 :   parseAtomList("NH_ATOMS",nh_atoms);
+     125             : 
+     126          24 :   if(methyl_atom.size()==0 && nh_atoms.size()==0) {
+     127           0 :     error("you have to give either METHYL_ATOM or NH_ATOMS");
+     128             :   }
+     129          24 :   if(methyl_atom.size()>0 && nh_atoms.size()>0) {
+     130           0 :     error("you cannot give both METHYL_ATOM or NH_ATOMS");
+     131             :   }
+     132          24 :   if(methyl_atom.size()>0 && methyl_atom.size()!=1) {
+     133           0 :     error("you should give one atom in METHYL_ATOM, the methyl carbon atom of the residue");
+     134             :   }
+     135          24 :   if(nh_atoms.size()>0 && nh_atoms.size()!=2) {
+     136           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)");
+     137             :   }
+     138             : 
+     139             :   std::vector<AtomNumber> heavy_atoms;
+     140          48 :   parseAtomList("HEAVY_ATOMS",heavy_atoms);
+     141          24 :   if(heavy_atoms.size()==0) {
+     142           0 :     error("HEAVY_ATOMS is not given");
+     143             :   }
+     144             : 
+     145             :   std::vector<AtomNumber> main_atoms;
+     146          24 :   if(methyl_atom.size()>0) {
+     147           0 :     modeltype_= methyl;
+     148           0 :     main_atoms = methyl_atom;
+     149          24 :   } else if(nh_atoms.size()>0) {
+     150          24 :     modeltype_= nh;
+     151          24 :     main_atoms = nh_atoms;
+     152             :   }
+     153             : 
+     154          24 :   bool nopbc=!pbc_;
+     155          24 :   parseFlag("NOPBC",nopbc);
+     156          24 :   pbc_=!nopbc;
+     157             : 
+     158             :   // neighbor list stuff
+     159          24 :   bool doneigh=false;
+     160          24 :   double nl_cut=0.0;
+     161          24 :   int nl_st=0;
+     162          24 :   parseFlag("NLIST",doneigh);
+     163          24 :   if(doneigh) {
+     164          12 :     parse("NL_CUTOFF",nl_cut);
+     165          12 :     if(nl_cut<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     166          12 :     parse("NL_STRIDE",nl_st);
+     167          12 :     if(nl_st<=0) error("NL_STRIDE should be explicitly specified and positive");
+     168             :   }
+     169             : 
+     170          24 :   parse("R_EFF",r_eff_);
+     171          24 :   inv_r_eff_ = 1.0/r_eff_;
+     172          24 :   parse("PREFACTOR_A",prefactor_a_);
+     173          24 :   parse("EXPONENT_B",exp_b_);
+     174          24 :   parse("OFFSET_C",offset_c_);
+     175             :   unsigned int n_i_int;
+     176          24 :   parse("N_I",n_i_int);
+     177          24 :   n_i_ = static_cast<double>(n_i_int);
+     178          24 :   total_prefactor_ = prefactor_a_/pow(n_i_,exp_b_);
+     179             :   //
+     180          24 :   parse("R_SHIFT",r_globalshift_);
+     181             : 
+     182          24 :   checkRead();
+     183             : 
+     184          24 :   addValueWithDerivatives();
+     185          24 :   setNotPeriodic();
+     186             : 
+     187          24 :   bool dopair=false;
+     188          24 :   if(doneigh) {
+     189          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm,nl_cut,nl_st);
+     190             :   }
+     191             :   else {
+     192          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm);
+     193             :   }
+     194             : 
+     195          24 :   requestAtoms(nl->getFullAtomList());
+     196             : 
+     197             : 
+     198          24 :   log.printf("  NMR S2 contact model CV, please read and cite ");
+     199          48 :   log << plumed.cite("Palazzesi, Valsson, and Parrinello, J. Phys. Chem. Lett. 8, 4752 (2017) - DOI:10.1021/acs.jpclett.7b01770");
+     200             : 
+     201          24 :   if(modeltype_==methyl) {
+     202           0 :     log << plumed.cite("Ming and Bruschweiler, J. Biomol. NMR, 29, 363 (2004) - DOI:10.1023/B:JNMR.0000032612.70767.35");
+     203           0 :     log.printf("\n");
+     204           0 :     log.printf("  calculation of methyl order parameter using atom %d \n",methyl_atom[0].serial());
+     205             :   }
+     206          24 :   else if(modeltype_==nh) {
+     207          48 :     log << plumed.cite("Zhang and Bruschweiler, J. Am. Chem. Soc. 124, 12654 (2002) - DOI:10.1021/ja027847a");
+     208          24 :     log.printf("\n");
+     209          24 :     log.printf("  calculation of NH order parameter using atoms %d and %d\n",nh_atoms[0].serial(),nh_atoms[1].serial());
+     210             :   }
+     211          24 :   log.printf("  heavy atoms used in the calculation (%u in total):\n",static_cast<unsigned int>(heavy_atoms.size()));
+     212        1872 :   for(unsigned int i=0; i<heavy_atoms.size(); ++i) {
+     213        1848 :     if( (i+1) % 25 == 0 ) {log.printf("  \n");}
+     214        1848 :     log.printf("  %d", heavy_atoms[i].serial());
+     215             :   }
+     216          24 :   log.printf("  \n");
+     217          24 :   log.printf("  total number of distances: %u\n",nl->size());
+     218             :   //
+     219          24 :   log.printf("  using parameters");
+     220          24 :   log.printf(" r_eff=%f,",r_eff_);
+     221          24 :   log.printf(" a=%f,",prefactor_a_);
+     222          24 :   log.printf(" b=%f,",exp_b_);
+     223          24 :   log.printf(" c=%f,",offset_c_);
+     224          24 :   log.printf(" n_i=%u",n_i_int);
+     225          24 :   if(r_globalshift_!=0.0) {
+     226           4 :     log.printf(", r_shift=%f",r_globalshift_);
+     227             :   }
+     228          24 :   log.printf("\n");
+     229          24 :   if(pbc_) {
+     230          12 :     log.printf("  using periodic boundary conditions\n");
+     231             :   } else {
+     232          12 :     log.printf("  without periodic boundary conditions\n");
+     233             :   }
+     234          24 :   if(doneigh) {
+     235          12 :     log.printf("  using neighbor lists with\n");
+     236          12 :     log.printf("  update every %d steps and cutoff %f\n",nl_st,nl_cut);
+     237             :   }
+     238          24 :   if(serial_) {
+     239           0 :     log.printf("  calculation done in serial\n");
+     240             :   }
+     241          24 : }
+     242             : 
+     243          48 : S2ContactModel::~S2ContactModel() {
+     244          48 : }
+     245             : 
+     246          48 : void S2ContactModel::prepare() {
+     247          48 :   if(nl->getStride()>0) {
+     248          24 :     if(firsttime || (getStep()%nl->getStride()==0)) {
+     249          24 :       requestAtoms(nl->getFullAtomList());
+     250          24 :       invalidateList=true;
+     251          24 :       firsttime=false;
+     252             :     } else {
+     253           0 :       requestAtoms(nl->getReducedAtomList());
+     254           0 :       invalidateList=false;
+     255           0 :       if(getExchangeStep()) error("Neighbor lists should be updated on exchange steps - choose a NL_STRIDE which divides the exchange stride!");
+     256             :     }
+     257          24 :     if(getExchangeStep()) firsttime=true;
+     258             :   }
+     259          48 : }
+     260             : 
+     261             : // calculator
+     262        5952 : void S2ContactModel::calculate() {
+     263             : 
+     264        5952 :   Tensor virial;
+     265        5952 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     266             : 
+     267        5952 :   if(nl->getStride()>0 && invalidateList) {
+     268        2976 :     nl->update(getPositions());
+     269             :   }
+     270             : 
+     271        5952 :   unsigned int stride=comm.Get_size();
+     272        5952 :   unsigned int rank=comm.Get_rank();
+     273        5952 :   if(serial_) {
+     274             :     stride=1;
+     275             :     rank=0;
+     276             :   }
+     277             : 
+     278        5952 :   double contact_sum = 0.0;
+     279             : 
+     280        5952 :   const unsigned int nn=nl->size();
+     281             : 
+     282      321408 :   for(unsigned int i=rank; i<nn; i+=stride) {
+     283      315456 :     Vector distance;
+     284      315456 :     unsigned int i0=nl->getClosePair(i).first;
+     285      315456 :     unsigned int i1=nl->getClosePair(i).second;
+     286      315456 :     if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) {continue;}
+     287             : 
+     288      315456 :     if(pbc_) {
+     289       86304 :       distance=pbcDistance(getPosition(i0),getPosition(i1));
+     290             :     } else {
+     291      229152 :       distance=delta(getPosition(i0),getPosition(i1));
+     292             :     }
+     293             : 
+     294      315456 :     double exp_arg = exp(-(distance.modulo()-r_globalshift_)*inv_r_eff_);
+     295      315456 :     contact_sum += exp_arg;
+     296             : 
+     297      315456 :     exp_arg /= distance.modulo();
+     298      315456 :     Vector dd(exp_arg*distance);
+     299      315456 :     Tensor vv(dd,distance);
+     300      315456 :     deriv[i0]-=dd;
+     301      315456 :     deriv[i1]+=dd;
+     302      315456 :     virial-=vv;
+     303             :   }
+     304             : 
+     305        5952 :   if(!serial_) {
+     306        5952 :     comm.Sum(contact_sum);
+     307        5952 :     if(!deriv.empty()) {
+     308        5952 :       comm.Sum(&deriv[0][0],3*deriv.size());
+     309             :     }
+     310        5952 :     comm.Sum(virial);
+     311             :   }
+     312             : 
+     313        5952 :   double value = tanh(total_prefactor_*contact_sum);
+     314             :   // using that d/dx[tanh(x)]= 1-[tanh(x)]^2
+     315        5952 :   double deriv_f = -inv_r_eff_*total_prefactor_*(1.0-value*value);
+     316        5952 :   value -= offset_c_;
+     317             : 
+     318      476160 :   for(unsigned int i=0; i<deriv.size(); ++i) {
+     319      470208 :     setAtomsDerivatives(i,deriv_f*deriv[i]);
+     320             :   }
+     321        5952 :   setValue(value);
+     322       11904 :   setBoxDerivatives(deriv_f*virial);
+     323             : 
+     324        5952 : }
+     325             : }
+     326             : }
+
+
+
+ + + + +
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 000000000..8320d2e77 --- /dev/null +++ b/coverage/s2cm/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.6%91.6%
+
91.6 %152 / 16675.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 000000000..6c2884a1f --- /dev/null +++ b/coverage/s2cm/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.6%91.6%
+
91.6 %152 / 16675.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 000000000..de9c3846d --- /dev/null +++ b/coverage/s2cm/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-10-17 16:45:00Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.6%91.6%
+
91.6 %152 / 16675.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 000000000..67326cbe6 --- /dev/null +++ b/coverage/sasa/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:999121882.0 %
Date:2024-10-17 16:45:00Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %520 / 63276.9 %10 / 13
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %479 / 58684.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 000000000..4beed4f7a --- /dev/null +++ b/coverage/sasa/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:999121882.0 %
Date:2024-10-17 16:45:00Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %479 / 58684.6 %11 / 13
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %520 / 63276.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 000000000..c7661c613 --- /dev/null +++ b/coverage/sasa/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:999121882.0 %
Date:2024-10-17 16:45:00Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %479 / 58684.6 %11 / 13
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %520 / 63276.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 000000000..b2235434b --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47958681.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..da45906ae --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47958681.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..2594af803 --- /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:47958681.7 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the solvent accessible surface area (SASA) of the molecule");
+     175           4 : }
+     176             : 
+     177             : 
+     178           2 : SASA_HASEL::SASA_HASEL(const ActionOptions&ao):
+     179             :   PLUMED_COLVAR_INIT(ao),
+     180           2 :   nopbc(false),
+     181           2 :   stride(10),
+     182           2 :   nl_update(0),
+     183           4 :   DeltaGValues("absent"),
+     184           2 :   Ti(0),
+     185           2 :   firstStepFlag(0)
+     186             : {
+     187           2 :   rs = 0.14;
+     188           2 :   parse("DELTAGFILE",DeltaGValues);
+     189           2 :   parse("APPROACH", approach);
+     190           4 :   parseAtomList("ATOMS",atoms);
+     191           2 :   if(atoms.size()==0) error("no atoms specified");
+     192             :   std::string Type;
+     193           2 :   parse("TYPE",Type);
+     194           2 :   parse("NL_STRIDE", stride);
+     195           2 :   parseFlag("NOPBC",nopbc);
+     196           2 :   checkRead();
+     197             : 
+     198           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     199           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     200           0 :   else error("Unknown SASA type");
+     201             : 
+     202           2 :   switch(sasa_type)
+     203             :   {
+     204           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     205           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     206             :   }
+     207             : 
+     208           2 :   log.printf("  atoms involved : ");
+     209         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     210         240 :     if(i%25==0) log<<"\n";
+     211         240 :     log.printf("%d ",atoms[i].serial());
+     212             :   }
+     213           2 :   log.printf("\n");
+     214             : 
+     215           2 :   if(nopbc) {
+     216           0 :     log<<"  PBC will be ignored\n";
+     217             :   } else {
+     218           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     219             :   }
+     220             : 
+     221             : 
+     222           4 :   addValueWithDerivatives(); setNotPeriodic();
+     223           2 :   requestAtoms(atoms);
+     224             : 
+     225           2 :   natoms = getNumberOfAtoms();
+     226           2 :   AtomResidueName.resize(2);
+     227           2 :   SASAparam.resize(natoms);
+     228           2 :   CONNECTparam.resize(natoms);
+     229           2 :   MaxSurf.resize(natoms);
+     230           2 :   DeltaG.resize(natoms+1);
+     231           2 :   Nlist.resize(natoms);
+     232             : 
+     233             : 
+     234           2 : }
+     235             : 
+     236             : 
+     237             : //splits strings into tokens. Used to read into SASA parameters file and into reference pdb file
+     238             : template <class Container>
+     239          42 : void split(const std::string& str, Container& cont)
+     240             : {
+     241          42 :   std::istringstream iss(str);
+     242          84 :   std::copy(std::istream_iterator<std::string>(iss),
+     243          42 :             std::istream_iterator<std::string>(),
+     244             :             std::back_inserter(cont));
+     245          42 : }
+     246             : 
+     247             : 
+     248             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     249             : 
+     250           2 : void SASA_HASEL::readPDB() {
+     251           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     252           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     253             :   AtomResidueName[0].clear();
+     254             :   AtomResidueName[1].clear();
+     255             : 
+     256         242 :   for(unsigned i=0; i<natoms; i++) {
+     257         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     258         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     259         240 :     AtomResidueName[0].push_back (Aname);
+     260         240 :     AtomResidueName[1].push_back (Rname);
+     261             :   }
+     262             : 
+     263           2 : }
+     264             : 
+     265             : 
+     266             : //Hasel et al. parameters database
+     267           2 : map<string, vector<std::string> > SASA_HASEL::setupHASELparam() {
+     268             :   map<string, vector<std::string> > haselmap;
+     269          16 :   haselmap["ALA_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     270          16 :   haselmap["ALA_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     271          16 :   haselmap["ALA_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     272          16 :   haselmap["ALA_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     273          16 :   haselmap["ALA_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     274          16 :   haselmap["ALA_CB"] = { "2.0",  "0.88",  "CA",  "Z",  "Z",  "Z", };
+     275          16 :   haselmap["ASP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     276          16 :   haselmap["ASP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     277          16 :   haselmap["ASP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     278          16 :   haselmap["ASP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     279          16 :   haselmap["ASP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     280          16 :   haselmap["ASP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     281          16 :   haselmap["ASP_CG"] = { "1.72",  "1.554",  "CB",  "OD1",  "OD2",  "Z", };
+     282          16 :   haselmap["ASP_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     283          16 :   haselmap["ASP_OD2"] = { "1.7",  "0.922",  "CG",  "Z",  "Z",  "Z", };
+     284          16 :   haselmap["ASN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     285          16 :   haselmap["ASN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     286          16 :   haselmap["ASN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     287          16 :   haselmap["ASN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     288          16 :   haselmap["ASN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     289          16 :   haselmap["ASN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     290          16 :   haselmap["ASN_CG"] = { "1.7",  "2.149",  "CB",  "OD1",  "ND2",  "Z", };
+     291          16 :   haselmap["ASN_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     292          16 :   haselmap["ASN_ND2"] = { "1.6",  "1.215",  "CG",  "1HD2",  "1HD2",  "Z", };
+     293          16 :   haselmap["ASN_1HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     294          16 :   haselmap["ASN_2HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     295          16 :   haselmap["ARG_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     296          16 :   haselmap["ARG_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     297          16 :   haselmap["ARG_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     298          16 :   haselmap["ARG_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     299          16 :   haselmap["ARG_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     300          16 :   haselmap["ARG_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     301          16 :   haselmap["ARG_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     302          16 :   haselmap["ARG_CD"] = { "1.9",  "1.045",  "CG",  "NE",  "Z",  "Z", };
+     303          16 :   haselmap["ARG_NE"] = { "1.55",  "1.028",  "CD",  "HE",  "CZ",  "Z", };
+     304          16 :   haselmap["ARG_NH1"] = { "1.55",  "1.028",  "CZ",  "1HH1",  "2HH1",  "Z", };
+     305          16 :   haselmap["ARG_NH2"] = { "1.55",  "1.028",  "CZ",  "1HH2",  "2HH2",  "Z", };
+     306          16 :   haselmap["ARG_CZ"] = { "1.72",  "1.554",  "NE",  "NH1",  "NH2",  "Z", };
+     307          16 :   haselmap["ARG_HE"] = { "1.1",  "1.128",  "NE",  "Z",  "Z",  "Z", };
+     308          16 :   haselmap["ARG_1HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     309          16 :   haselmap["ARG_2HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     310          16 :   haselmap["ARG_2HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     311          16 :   haselmap["ARG_1HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     312          16 :   haselmap["CYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     313          16 :   haselmap["CYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     314          16 :   haselmap["CYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     315          16 :   haselmap["CYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     316          16 :   haselmap["CYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     317          16 :   haselmap["CYS_CB"] = { "1.9",  "1.045",  "CA",  "SG",  "Z",  "Z", };
+     318          16 :   haselmap["CYS_SG"] = { "1.8",  "1.121",  "CB",  "HG",  "Z",  "Z", };
+     319          16 :   haselmap["CYS_HG"] = { "1.2",  "0.928",  "SG",  "Z",  "Z",  "Z", };
+     320          16 :   haselmap["GLU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     321          16 :   haselmap["GLU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     322          16 :   haselmap["GLU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     323          16 :   haselmap["GLU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     324          16 :   haselmap["GLU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     325          16 :   haselmap["GLU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     326          16 :   haselmap["GLU_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     327          16 :   haselmap["GLU_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "OE2",  "Z", };
+     328          16 :   haselmap["GLU_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     329          16 :   haselmap["GLU_OE2"] = { "1.7",  "0.922",  "CD",  "Z",  "Z",  "Z", };
+     330          16 :   haselmap["GLN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     331          16 :   haselmap["GLN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     332          16 :   haselmap["GLN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     333          16 :   haselmap["GLN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     334          16 :   haselmap["GLN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     335          16 :   haselmap["GLN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     336          16 :   haselmap["GLN_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     337          16 :   haselmap["GLN_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "NE2",  "Z", };
+     338          16 :   haselmap["GLN_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     339          16 :   haselmap["GLN_NE2"] = { "1.6",  "1.215",  "CD",  "2HE2",  "1HE2",  "Z", };
+     340          16 :   haselmap["GLN_2HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     341          16 :   haselmap["GLN_1HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     342          16 :   haselmap["GLY_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     343          16 :   haselmap["GLY_CA"] = { "1.7",  "2.149",  "N",  "C",  "Z",  "Z", };
+     344          16 :   haselmap["GLY_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     345          16 :   haselmap["GLY_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     346          16 :   haselmap["GLY_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     347          16 :   haselmap["HIS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     348          16 :   haselmap["HIS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     349          16 :   haselmap["HIS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     350          16 :   haselmap["HIS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     351          16 :   haselmap["HIS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     352          16 :   haselmap["HIS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     353          16 :   haselmap["HIS_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "ND1",  "Z", };
+     354          16 :   haselmap["HIS_ND1"] = { "1.55",  "1.028",  "CG",  "CE1",  "Z",  "Z", };
+     355          16 :   haselmap["HIS_CE1"] = { "1.8",  "1.073",  "ND1",  "NE2",  "Z",  "Z", };
+     356          16 :   haselmap["HIS_NE2"] = { "1.55",  "1.413",  "CE1",  "2HE",  "CD2",  "Z", };
+     357          16 :   haselmap["HIS_CD2"] = { "1.8",  "1.073",  "NE2",  "CG",  "Z",  "Z", };
+     358          16 :   haselmap["HIS_2HE"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     359          16 :   haselmap["ILE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     360          16 :   haselmap["ILE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     361          16 :   haselmap["ILE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     362          16 :   haselmap["ILE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     363          16 :   haselmap["ILE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     364          16 :   haselmap["ILE_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "CG1",  "Z", };
+     365          16 :   haselmap["ILE_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     366          16 :   haselmap["ILE_CG1"] = { "1.9",  "1.045",  "CB",  "CD1",  "Z",  "Z", };
+     367          16 :   haselmap["ILE_CD1"] = { "2.0",  "0.88",  "CG1",  "Z",  "Z",  "Z", };
+     368          16 :   haselmap["LEU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     369          16 :   haselmap["LEU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     370          16 :   haselmap["LEU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     371          16 :   haselmap["LEU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     372          16 :   haselmap["LEU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     373          16 :   haselmap["LEU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     374          16 :   haselmap["LEU_CG"] = { "1.8",  "1.276",  "CB",  "CD1",  "CD2",  "Z", };
+     375          16 :   haselmap["LEU_CD1"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     376          16 :   haselmap["LEU_CD2"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     377          16 :   haselmap["LYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     378          16 :   haselmap["LYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     379          16 :   haselmap["LYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     380          16 :   haselmap["LYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     381          16 :   haselmap["LYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     382          16 :   haselmap["LYS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     383          16 :   haselmap["LYS_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     384          16 :   haselmap["LYS_CD"] = { "1.9",  "1.045",  "CG",  "CE",  "Z",  "Z", };
+     385          16 :   haselmap["LYS_CE"] = { "1.9",  "1.045",  "CD",  "NZ",  "Z",  "Z", };
+     386          16 :   haselmap["LYS_NZ"] = { "1.6",  "1.215",  "CE",  "1HZ",  "2HZ",  "3HZ", };
+     387          16 :   haselmap["LYS_1HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     388          16 :   haselmap["LYS_2HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     389          16 :   haselmap["LYS_3HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     390          16 :   haselmap["MET_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     391          16 :   haselmap["MET_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     392          16 :   haselmap["MET_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     393          16 :   haselmap["MET_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     394          16 :   haselmap["MET_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     395          16 :   haselmap["MET_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     396          16 :   haselmap["MET_CG"] = { "1.9",  "1.045",  "CB",  "SD",  "Z",  "Z", };
+     397          16 :   haselmap["MET_SD"] = { "1.8",  "1.121",  "CG",  "CE",  "Z",  "Z", };
+     398          16 :   haselmap["MET_CE"] = { "2.0",  "0.88",  "SD",  "Z",  "Z",  "Z", };
+     399          16 :   haselmap["PHE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     400          16 :   haselmap["PHE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     401          16 :   haselmap["PHE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     402          16 :   haselmap["PHE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     403          16 :   haselmap["PHE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     404          16 :   haselmap["PHE_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     405          16 :   haselmap["PHE_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     406          16 :   haselmap["PHE_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     407          16 :   haselmap["PHE_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     408          16 :   haselmap["PHE_CZ"] = { "1.8",  "1.073",  "CE1",  "CE2",  "Z",  "Z", };
+     409          16 :   haselmap["PHE_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     410          16 :   haselmap["PHE_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     411          16 :   haselmap["PRO_N"] = { "1.55",  "1.028",  "CD",  "CA",  "Z",  "Z", };
+     412          16 :   haselmap["PRO_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     413          16 :   haselmap["PRO_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     414          16 :   haselmap["PRO_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     415          16 :   haselmap["PRO_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     416          16 :   haselmap["PRO_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     417          16 :   haselmap["PRO_CD"] = { "1.9",  "1.045",  "CG",  "N",  "Z",  "Z", };
+     418          16 :   haselmap["SER_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     419          16 :   haselmap["SER_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     420          16 :   haselmap["SER_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     421          16 :   haselmap["SER_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     422          16 :   haselmap["SER_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     423          16 :   haselmap["SER_CB"] = { "1.9",  "1.045",  "CA",  "OG",  "Z",  "Z", };
+     424          16 :   haselmap["SER_OG"] = { "1.52",  "1.08",  "CB",  "HG",  "Z",  "Z", };
+     425          16 :   haselmap["SER_HG"] = { "1.0",  "0.944",  "OG",  "Z",  "Z",  "Z", };
+     426          16 :   haselmap["THR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     427          16 :   haselmap["THR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     428          16 :   haselmap["THR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     429          16 :   haselmap["THR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     430          16 :   haselmap["THR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     431          16 :   haselmap["THR_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "OG1",  "Z", };
+     432          16 :   haselmap["THR_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     433          16 :   haselmap["THR_OG1"] = { "1.52",  "1.08",  "1HG",  "CB",  "Z",  "Z", };
+     434          16 :   haselmap["THR_1HG"] = { "1.0",  "0.944",  "OG1",  "Z",  "Z",  "Z", };
+     435          16 :   haselmap["TRP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     436          16 :   haselmap["TRP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     437          16 :   haselmap["TRP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     438          16 :   haselmap["TRP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     439          16 :   haselmap["TRP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     440          16 :   haselmap["TRP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     441          16 :   haselmap["TRP_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "CD1",  "Z", };
+     442          16 :   haselmap["TRP_CD1"] = { "1.8",  "1.073",  "CG",  "NE1",  "Z",  "Z", };
+     443          16 :   haselmap["TRP_NE1"] = { "1.55",  "1.413",  "CD1",  "CE2",  "1HE",  "Z", };
+     444          16 :   haselmap["TRP_CE2"] = { "1.72",  "1.554",  "NE1",  "CD2",  "CZ2",  "Z", };
+     445          16 :   haselmap["TRP_CZ2"] = { "1.8",  "1.073",  "CE2",  "CH2",  "Z",  "Z", };
+     446          16 :   haselmap["TRP_CH2"] = { "1.8",  "1.073",  "CZ2",  "CZ3",  "Z",  "Z", };
+     447          16 :   haselmap["TRP_CZ3"] = { "1.8",  "1.073",  "CH2",  "CE3",  "Z",  "Z", };
+     448          16 :   haselmap["TRP_CE3"] = { "1.8",  "1.073",  "CZ3",  "CD2",  "Z",  "Z", };
+     449          16 :   haselmap["TRP_CD2"] = { "1.72",  "1.554",  "CE3",  "CE2",  "CG",  "Z", };
+     450          16 :   haselmap["TRP_1HE"] = { "1.1",  "1.128",  "NE1",  "Z",  "Z",  "Z", };
+     451          16 :   haselmap["TYR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     452          16 :   haselmap["TYR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     453          16 :   haselmap["TYR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     454          16 :   haselmap["TYR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     455          16 :   haselmap["TYR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     456          16 :   haselmap["TYR_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     457          16 :   haselmap["TYR_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     458          16 :   haselmap["TYR_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     459          16 :   haselmap["TYR_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     460          16 :   haselmap["TYR_CZ"] = { "1.72",  "1.554",  "CE1",  "OH",  "CE2",  "Z", };
+     461          16 :   haselmap["TYR_OH"] = { "1.52",  "1.08",  "CZ",  "HH",  "Z",  "Z", };
+     462          16 :   haselmap["TYR_HH"] = { "1.0",  "0.944",  "OH",  "Z",  "Z",  "Z", };
+     463          16 :   haselmap["TYR_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     464          16 :   haselmap["TYR_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     465          16 :   haselmap["VAL_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     466          16 :   haselmap["VAL_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     467          16 :   haselmap["VAL_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     468          16 :   haselmap["VAL_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     469          16 :   haselmap["VAL_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     470          16 :   haselmap["VAL_CB"] = { "1.8",  "1.276",  "CA",  "CG1",  "CG2",  "Z", };
+     471          16 :   haselmap["VAL_CG1"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     472          16 :   haselmap["VAL_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     473           2 :   return haselmap;
+     474             : }
+     475             : 
+     476             : //assigns SASA parameters to each atom reading from HASEL parameter database
+     477           2 : void SASA_HASEL::readSASAparam() {
+     478             : 
+     479         242 :   for(unsigned i=0; i<natoms; i++) {
+     480         240 :     SASAparam[i].clear();
+     481             :     CONNECTparam[i].clear();
+     482             :   }
+     483             : 
+     484             :   map<string, vector<std::string> > haselmap;
+     485           4 :   haselmap = setupHASELparam();
+     486             :   vector<std::string> HASELparamVector;
+     487             :   string identifier;
+     488             : 
+     489             : 
+     490         242 :   for(unsigned i=0; i<natoms; i++) {
+     491         480 :     identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     492         240 :     if (haselmap.find(identifier)!=haselmap.end()) {
+     493         144 :       HASELparamVector = haselmap.at(identifier);
+     494         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[0].c_str())+rs*10);
+     495         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[1].c_str()));
+     496         288 :       CONNECTparam[i].push_back (HASELparamVector[2].c_str());
+     497         288 :       CONNECTparam[i].push_back (HASELparamVector[3].c_str());
+     498         288 :       CONNECTparam[i].push_back (HASELparamVector[4].c_str());
+     499         288 :       CONNECTparam[i].push_back (HASELparamVector[5].c_str());
+     500             :     }
+     501             :   }
+     502             : 
+     503             : 
+     504         242 :   for(unsigned i=0; i<natoms; i++) {
+     505         240 :     if (SASAparam[i].size()==0 ) {
+     506          96 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     507           0 :         cout << "Could not find SASA paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     508           0 :         error ("missing SASA parameters\n");
+     509             :       }
+     510             :     }
+     511             :   }
+     512             : 
+     513             : 
+     514           4 : }
+     515             : 
+     516             : 
+     517             : 
+     518             : //Max Surf values, used only if TYPE=TRANSFER
+     519           1 : map<string, vector<double> > SASA_HASEL::setupMaxSurfMap() {
+     520             :   // Max Surface Area for backbone and sidechain, in nm2
+     521             :   map<string, vector<double> > valuemap;
+     522           1 :   valuemap ["ALA"]= {0.56425,0.584851,};
+     523           1 :   valuemap ["ARG"]= {0.498656,1.808093,};
+     524           1 :   valuemap ["ASN"]= {0.473409,0.818394,};
+     525           1 :   valuemap ["ASP"]= {0.477057,0.977303,};
+     526           1 :   valuemap ["CYS"]= {0.507512,0.791483,};
+     527           1 :   valuemap ["GLN"]= {0.485859,1.281534,};
+     528           1 :   valuemap ["GLU"]= {0.495054,1.464718,};
+     529           1 :   valuemap ["GLY"]= {0.658632,0,};
+     530           1 :   valuemap ["HIS"]= {0.48194,1.118851,};
+     531           1 :   valuemap ["ILE"]= {0.461283,1.450569,};
+     532           1 :   valuemap ["LEU"]= {0.476315,1.498843,};
+     533           1 :   valuemap ["LYS"]= {0.493533,1.619731,};
+     534           1 :   valuemap ["MET"]= {0.507019,1.631904,};
+     535           1 :   valuemap ["PHE"]= {0.457462, 1.275125,};
+     536           1 :   valuemap ["PRO"]= {0.315865,0.859456,};
+     537           1 :   valuemap ["SER"]= {0.48636,0.627233,};
+     538           1 :   valuemap ["THR"]= {0.45064,0.91088,};
+     539           1 :   valuemap ["TRP"]= {0.45762,1.366369,};
+     540           1 :   valuemap ["TYR"]= {0.461826,1.425822,};
+     541           1 :   valuemap ["VAL"]= {0.477054,1.149101,};
+     542           1 :   return valuemap;
+     543             : }
+     544             : 
+     545             : 
+     546             : 
+     547             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     548             : 
+     549           1 : void SASA_HASEL::readMaxSurf() {
+     550             :   map<string, vector<double> > valuemap;
+     551           2 :   valuemap = setupMaxSurfMap();
+     552             :   vector<double> MaxSurfVector;
+     553             : 
+     554         121 :   for(unsigned i=0; i<natoms; i++) {
+     555         120 :     MaxSurf[i].clear();
+     556         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     557         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     558         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     559             :   }
+     560           1 : }
+     561             : 
+     562             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     563             : 
+     564           1 : void SASA_HASEL::readDeltaG() {
+     565             : 
+     566         121 :   for(unsigned i=0; i<natoms; i++) {
+     567         120 :     DeltaG[i].clear();
+     568             :   }
+     569             : 
+     570             :   string DeltaGline;
+     571           1 :   fstream DeltaGFile;
+     572           1 :   DeltaGFile.open(DeltaGValues);
+     573           1 :   if (DeltaGFile) {
+     574             :     int backboneflag = 0;
+     575          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     576          22 :       if(!DeltaGline.empty()) {
+     577             :         std::vector<std::string> DeltaGtoken;
+     578          21 :         split(DeltaGline, DeltaGtoken);
+     579        2541 :         for(unsigned i=0; i<natoms; i++) {
+     580        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     581         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     582             :           }
+     583             :         }
+     584          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     585             :           backboneflag = 1;
+     586           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     587             :         }
+     588          21 :       }
+     589             :     }
+     590           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     591             :   }
+     592           0 :   else error("Cannot open DeltaG file");
+     593             : 
+     594         121 :   for(unsigned i=0; i<natoms; i++) {
+     595         120 :     if (DeltaG[i].size()==0 ) {
+     596           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     597           0 :       error ("missing Delta G parameter\n");
+     598             :     }
+     599             :   }
+     600             : 
+     601           2 : }
+     602             : 
+     603             : //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.
+     604             : 
+     605           0 : void SASA_HASEL::computeDeltaG() {
+     606             : 
+     607           0 :   for(unsigned i=0; i<natoms; i++) {
+     608           0 :     DeltaG[i].clear();
+     609             :   }
+     610             : 
+     611             :   double T;
+     612           0 :   T = getkBT()/getKBoltzmann();
+     613             : 
+     614           0 :   if (T != Ti) {
+     615           0 :     for(unsigned i=0; i<natoms; i++) {
+     616           0 :       if (approach==2) {
+     617           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     618           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     619             :         }
+     620           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     621           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     622             :         }
+     623           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     624           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     625             :         }
+     626           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     627           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     628             :         }
+     629           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     630           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     631             :         }
+     632           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     633           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     634             :         }
+     635           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     636           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     637             :         }
+     638           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     639           0 :           DeltaG[i].push_back (0);
+     640             :         }
+     641           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     642           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     643             :         }
+     644           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     645           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     646             :         }
+     647           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     648           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     649             :         }
+     650           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     651           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     652             :         }
+     653           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     654           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     655             :         }
+     656           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     657           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     658             :         }
+     659           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     660           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     661             :         }
+     662           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     663           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     664             :         }
+     665           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     666           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     667             :         }
+     668           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     669           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     670             :         }
+     671           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     672           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     673             :         }
+     674           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     675           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     676             :         }
+     677           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     678             :       }
+     679           0 :       if (approach==3) {
+     680           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     681           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     682             :         }
+     683           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     684           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     685             :         }
+     686           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     687           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     688             :         }
+     689           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     690           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     691             :         }
+     692           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     693           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     694             :         }
+     695           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     696           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     697             :         }
+     698           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     699           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     700             :         }
+     701           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     702           0 :           DeltaG[i].push_back (0);
+     703             :         }
+     704           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     705           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     706             :         }
+     707           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     708           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     709             :         }
+     710           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     711           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     712             :         }
+     713           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     714           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     715             :         }
+     716           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     717           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     718             :         }
+     719           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     720           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     721             :         }
+     722           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     723           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     724             :         }
+     725           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     726           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     727             :         }
+     728           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     729           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     730             :         }
+     731           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     732           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     733             :         }
+     734           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     735           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     736             :         }
+     737           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     738           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     739             :         }
+     740           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     741             :       }
+     742             :     }
+     743             :   }
+     744             : 
+     745           0 :   Ti = T;
+     746             : 
+     747           0 :   if (firstStepFlag ==0) {
+     748           0 :     if (approach!=2 && approach!=3) {
+     749           0 :       cout << "Unknown approach " << approach << endl;
+     750             :     }
+     751           0 :     for(unsigned i=0; i<natoms; i++) {
+     752           0 :       if (DeltaG[i].size()==0 ) {
+     753           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     754           0 :         error ("missing Delta G parameter\n");
+     755             :       }
+     756             :     }
+     757             :   }
+     758           0 : }
+     759             : 
+     760             : 
+     761             : //calculates neighbor list
+     762          24 : void SASA_HASEL::calcNlist() {
+     763          24 :   if(!nopbc) makeWhole();
+     764             : 
+     765        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     766        2880 :     Nlist[i].clear();
+     767             :   }
+     768             : 
+     769        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     770        2880 :     if (SASAparam[i].size()>0) {
+     771      103680 :       for (unsigned j = 0; j < i; j++) {
+     772      101952 :         if (SASAparam[j].size()>0) {
+     773       61344 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     774       61344 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     775       61344 :           double overlapD = SASAparam[i][0]+SASAparam[j][0];
+     776       61344 :           if (Delta_ij_mod < overlapD) {
+     777       26748 :             Nlist.at(i).push_back (j);
+     778       26748 :             Nlist.at(j).push_back (i);
+     779             :           }
+     780             :         }
+     781             :       }
+     782             :     }
+     783             :   }
+     784          24 : }
+     785             : 
+     786             : 
+     787             : //calculates SASA according to Hasel et al., Tetrahedron Computer Methodology Vol. 1, No. 2, pp. 103-116, 1988
+     788          24 : void SASA_HASEL::calculate() {
+     789          24 :   if(!nopbc) makeWhole();
+     790             : 
+     791          24 :   if(getExchangeStep()) nl_update = 0;
+     792          24 :   if (firstStepFlag ==0) {
+     793           2 :     readPDB();
+     794           2 :     readSASAparam();
+     795             :   }
+     796          24 :   if (nl_update == 0) {
+     797          24 :     calcNlist();
+     798             :   }
+     799             : 
+     800             : 
+     801          24 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     802          24 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     803             :   double Si, sasai, bij;
+     804          24 :   double sasa = 0;
+     805          24 :   vector<Vector> derivatives( natoms );
+     806        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     807        2880 :     derivatives[i][0] = 0.;
+     808        2880 :     derivatives[i][1] = 0.;
+     809        2880 :     derivatives[i][2] = 0.;
+     810             :   }
+     811             : 
+     812          24 :   Tensor virial;
+     813          24 :   vector <double> ddij_di(3);
+     814          24 :   vector <double> dbij_di(3);
+     815          24 :   vector <double> dAijt_di(3);
+     816             : 
+     817          24 :   if( sasa_type==TOTAL ) {
+     818        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     819        1440 :       if(SASAparam[i].size() > 0) {
+     820         864 :         double ri = SASAparam[i][0];
+     821         864 :         Si = 4*M_PI*ri*ri;
+     822             :         sasai = 1.0;
+     823             : 
+     824        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     825             : 
+     826         864 :         dAijt_di[0] = 0;
+     827         864 :         dAijt_di[1] = 0;
+     828         864 :         dAijt_di[2] = 0;
+     829         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     830             : 
+     831       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     832             :           double pij = 0.3516;
+     833             : 
+     834       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     835       26748 :           if (NumRes_i==NumRes_j) {
+     836        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) {
+     837             :               pij = 0.8875;
+     838             :             }
+     839             :           }
+     840       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     841       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     842             :               pij = 0.8875;
+     843             :             }
+     844             :           }
+     845             : 
+     846       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     847       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     848             : 
+     849       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     850       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     851             : 
+     852       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     853             : 
+     854       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     855       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     856       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     857             : 
+     858       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     859       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     860       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     861             : 
+     862       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     863       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     864       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     865             : 
+     866       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     867       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     868       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     869             : 
+     870             :         }
+     871             : 
+     872         864 :         sasa += Si*sasai/100; //nm2
+     873             : 
+     874         864 :         derivatives[i][0] += Si*sasai/10*dAijt_di[0]; //nm
+     875         864 :         derivatives[i][1] += Si*sasai/10*dAijt_di[1];
+     876         864 :         derivatives[i][2] += Si*sasai/10*dAijt_di[2];
+     877             : 
+     878       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     879       26748 :           derivatives[Nlist[i][j]][0] += Si*sasai/10*derTerm[j][0]; //nm
+     880       26748 :           derivatives[Nlist[i][j]][1] += Si*sasai/10*derTerm[j][1];
+     881       26748 :           derivatives[Nlist[i][j]][2] += Si*sasai/10*derTerm[j][2];
+     882             :         }
+     883         864 :       }
+     884             :     }
+     885             :   }
+     886             : 
+     887             : 
+     888          24 :   if( sasa_type==TRANSFER ) {
+     889             : 
+     890          12 :     if (firstStepFlag ==0) {
+     891           1 :       readMaxSurf();
+     892             :     }
+     893             : 
+     894          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     895           1 :       readDeltaG();
+     896             :     }
+     897             : 
+     898          12 :     if (DeltaGValues == "absent") {
+     899           0 :       computeDeltaG();
+     900             :     }
+     901             : 
+     902             : 
+     903        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     904             : 
+     905             : 
+     906             : 
+     907        1440 :       if(SASAparam[i].size() > 0) {
+     908         864 :         double ri = SASAparam[i][0];
+     909         864 :         Si = 4*M_PI*ri*ri;
+     910             :         sasai = 1.0;
+     911             : 
+     912        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     913             : 
+     914         864 :         dAijt_di[0] = 0;
+     915         864 :         dAijt_di[1] = 0;
+     916         864 :         dAijt_di[2] = 0;
+     917         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     918             : 
+     919       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     920             :           double pij = 0.3516;
+     921             : 
+     922       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     923       26748 :           if (NumRes_i==NumRes_j) {
+     924        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) {
+     925             :               pij = 0.8875;
+     926             :             }
+     927             :           }
+     928       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     929       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     930             :               pij = 0.8875;
+     931             :             }
+     932             :           }
+     933             : 
+     934       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     935       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     936             : 
+     937       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     938       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     939             : 
+     940       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     941             : 
+     942       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     943       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     944       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     945             : 
+     946       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     947       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     948       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     949             : 
+     950       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     951       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     952       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     953             : 
+     954       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     955       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     956       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     957             : 
+     958             :         }
+     959             : 
+     960        2880 :         if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     961             : 
+     962         720 :           sasa += Si*sasai/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol
+     963             : 
+     964             : 
+     965         720 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][0]*DeltaG[natoms][0]*10; //kJ/mol/nm
+     966         720 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     967         720 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     968             :         }
+     969             : 
+     970        2880 :         if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     971         144 :           sasa += Si*sasai/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol
+     972             : 
+     973         144 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][1]*DeltaG[i][0]*10; //kJ/mol/nm
+     974         144 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     975         144 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     976             :         }
+     977             : 
+     978             : 
+     979       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     980       86883 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     981       22438 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol/nm
+     982       22438 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][0]*DeltaG[natoms][0];
+     983       22438 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][0]*DeltaG[natoms][0];
+     984             :           }
+     985             : 
+     986       86883 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     987        4310 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol/nm
+     988        4310 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][1]*DeltaG[i][0];
+     989        4310 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][1]*DeltaG[i][0];
+     990             :           }
+     991             :         }
+     992         864 :       }
+     993             :     }
+     994             :   }
+     995             : 
+     996             : 
+     997        2904 :   for(unsigned i=0; i<natoms; i++) {
+     998        2880 :     setAtomsDerivatives(i,derivatives[i]);
+     999        2880 :     virial -= Tensor(getPosition(i),derivatives[i]);
+    1000             :   }
+    1001             : 
+    1002          24 :   setBoxDerivatives(virial);
+    1003          24 :   setValue(sasa);
+    1004          24 :   firstStepFlag = 1;
+    1005          24 :   ++nl_update;
+    1006          24 :   if (nl_update == stride) {
+    1007          24 :     nl_update = 0;
+    1008             :   }
+    1009             : // setBoxDerivativesNoPbc();
+    1010          24 : }
+    1011             : 
+    1012             : }//namespace sasa
+    1013             : }//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 000000000..19a0b1698 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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:52063282.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..b82bed10c --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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:52063282.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..d65e9c241 --- /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:52063282.3 %
Date:2024-10-17 16:45:00Functions: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 :   keys.setValueDescription("the solvent accessible surface area (SASA) of the molecule");
+     173           4 : }
+     174             : 
+     175             : 
+     176           2 : SASA_LCPO::SASA_LCPO(const ActionOptions&ao):
+     177             :   PLUMED_COLVAR_INIT(ao),
+     178           2 :   nopbc(false),
+     179           4 :   DeltaGValues("absent"),
+     180           2 :   Ti(0),
+     181           2 :   stride(10),
+     182           2 :   nl_update(0),
+     183           2 :   firstStepFlag(0)
+     184             : {
+     185           2 :   rs = 0.14;
+     186           2 :   parse("DELTAGFILE",DeltaGValues);
+     187           2 :   parse("APPROACH", approach);
+     188           4 :   parseAtomList("ATOMS",atoms);
+     189           2 :   if(atoms.size()==0) error("no atoms specified");
+     190             :   std::string Type;
+     191           2 :   parse("TYPE",Type);
+     192           2 :   parse("NL_STRIDE", stride);
+     193           2 :   parseFlag("NOPBC",nopbc);
+     194           2 :   checkRead();
+     195             : 
+     196           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     197           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     198           0 :   else error("Unknown SASA type");
+     199             : 
+     200           2 :   switch(sasa_type)
+     201             :   {
+     202           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     203           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     204             :   }
+     205             : 
+     206           2 :   log.printf("  atoms involved : ");
+     207         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     208         240 :     if(i%25==0) log<<"\n";
+     209         240 :     log.printf("%d ",atoms[i].serial());
+     210             :   }
+     211           2 :   log.printf("\n");
+     212             : 
+     213           2 :   if(nopbc) {
+     214           0 :     log<<"  PBC will be ignored\n";
+     215             :   } else {
+     216           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     217             :   }
+     218             : 
+     219             : 
+     220           4 :   addValueWithDerivatives(); setNotPeriodic();
+     221           2 :   requestAtoms(atoms);
+     222             : 
+     223           2 :   natoms = getNumberOfAtoms();
+     224           2 :   AtomResidueName.resize(2);
+     225           2 :   LCPOparam.resize(natoms);
+     226           2 :   MaxSurf.resize(natoms);
+     227           2 :   DeltaG.resize(natoms+1);
+     228           2 :   Nlist.resize(natoms);
+     229             : 
+     230             : 
+     231           2 : }
+     232             : 
+     233             : 
+     234             : //splits strings into tokens. Used to read into LCPO parameters file and into reference pdb file
+     235             : template <class Container>
+     236           0 : void split(const std::string& str, Container& cont)
+     237             : {
+     238           0 :   std::istringstream iss(str);
+     239           0 :   std::copy(std::istream_iterator<std::string>(iss),
+     240           0 :             std::istream_iterator<std::string>(),
+     241             :             std::back_inserter(cont));
+     242           0 : }
+     243             : 
+     244             : 
+     245             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     246             : 
+     247           2 : void SASA_LCPO::readPDB() {
+     248           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     249           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     250             :   AtomResidueName[0].clear();
+     251             :   AtomResidueName[1].clear();
+     252             : 
+     253         242 :   for(unsigned i=0; i<natoms; i++) {
+     254         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     255         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     256         240 :     AtomResidueName[0].push_back (Aname);
+     257         240 :     AtomResidueName[1].push_back (Rname);
+     258             :   }
+     259             : 
+     260           2 : }
+     261             : 
+     262             : //LCPO parameters database
+     263           2 : map<string, vector<double> > SASA_LCPO::setupLCPOparam() {
+     264             :   map<string, vector<double> > lcpomap;
+     265           2 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     266           2 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     267           2 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     268           2 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     269           2 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     270           2 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     271           2 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     272           2 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     273           2 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     274           2 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     275           2 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     276           2 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     277           2 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     278           2 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     279           2 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     280           2 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     281           2 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     282           2 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     283           2 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     284           2 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     285           2 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     286           2 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     287           2 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     288           2 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     289           2 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     290           2 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     291           2 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     292           2 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     293           2 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     294           2 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     295           2 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     296           2 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     297           2 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     298           2 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     299           2 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     300           2 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     301           2 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     302           2 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     303           2 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     304           2 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     305           2 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     306           2 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     307           2 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     308           2 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     309           2 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     310           2 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     311           2 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     312           2 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     313           2 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     314           2 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     315           2 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     316           2 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     317           2 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     318           2 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     319           2 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     320           2 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     321           2 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     322           2 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     323           2 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     324           2 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     325           2 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     326           2 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     327           2 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     328           2 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     329           2 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     330           2 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     331           2 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     332           2 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     333           2 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     334           2 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     335           2 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     336           2 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     337           2 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     338           2 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     339           2 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     340           2 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     341           2 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     342           2 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     343           2 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     344           2 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     345           2 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     346           2 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     347           2 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     348           2 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     349           2 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     350           2 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     351           2 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     352           2 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     353           2 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     354           2 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     355           2 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     356           2 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     357           2 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     358           2 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     359           2 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     360           2 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     361           2 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     362           2 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     363           2 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     364           2 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     365           2 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     366           2 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     367           2 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     368           2 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     369           2 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     370           2 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     371           2 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     372           2 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     373           2 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     374           2 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     375           2 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     376           2 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     377           2 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     378           2 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     379           2 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     380           2 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     381           2 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     382           2 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     383           2 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     384           2 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     385           2 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     386           2 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     387           2 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     388           2 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     389           2 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     390           2 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     391           2 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     392           2 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     393           2 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     394           2 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     395           2 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     396           2 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     397           2 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     398           2 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     399           2 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     400           2 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     401           2 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     402           2 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     403           2 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     404           2 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     405           2 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     406           2 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     407           2 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     408           2 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     409           2 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     410           2 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     411           2 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     412           2 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     413           2 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     414           2 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     415           2 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     416           2 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     417           2 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     418           2 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     419           2 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     420           2 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     421           2 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     422           2 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     423           2 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     424           2 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     425           2 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     426           2 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     427           2 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     428           2 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     429           2 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     430           2 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     431           2 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     432           2 :   return lcpomap;
+     433             : }
+     434             : 
+     435             : //assigns LCPO parameters to each atom reading from database
+     436           2 : void SASA_LCPO::readLCPOparam() {
+     437             : 
+     438         242 :   for(unsigned i=0; i<natoms; i++) {
+     439         240 :     LCPOparam[i].clear();
+     440             :   }
+     441             : 
+     442             :   map<string, vector<double> > lcpomap;
+     443           4 :   lcpomap = setupLCPOparam();
+     444             :   vector<double> LCPOparamVector;
+     445             :   string identifier;
+     446         242 :   for(unsigned i=0; i<natoms; i++) {
+     447         240 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     448         240 :       identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     449         120 :       LCPOparamVector = lcpomap.at(identifier);
+     450         120 :       LCPOparam[i].push_back (LCPOparamVector[0]+rs*10);
+     451         120 :       LCPOparam[i].push_back (LCPOparamVector[1]);
+     452         120 :       LCPOparam[i].push_back (LCPOparamVector[2]);
+     453         120 :       LCPOparam[i].push_back (LCPOparamVector[3]);
+     454         120 :       LCPOparam[i].push_back (LCPOparamVector[4]);
+     455             :     }
+     456             :   }
+     457             : 
+     458             : 
+     459         242 :   for(unsigned i=0; i<natoms; i++) {
+     460         240 :     if (LCPOparam[i].size()==0 ) {
+     461         120 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     462           0 :         cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     463           0 :         error ("missing LCPO parameters\n");
+     464             :       }
+     465             :     }
+     466             :   }
+     467             : 
+     468           2 :   if (AtomResidueName[0][0] == "N") {
+     469           2 :     LCPOparam[0][1] = 7.3511e-01;
+     470           2 :     LCPOparam[0][2] = -2.2116e-01;
+     471           2 :     LCPOparam[0][3] = -8.9148e-04;
+     472           2 :     LCPOparam[0][4] = 2.5230e-04;
+     473             :   }
+     474             : 
+     475           2 :   if (AtomResidueName[0][natoms-1] == "O") {
+     476           2 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+     477           2 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+     478           2 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+     479           2 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+     480             :   }
+     481           2 : }
+     482             : 
+     483             : 
+     484             : //Max Surf values, used only if TYPE=TRANSFER
+     485           1 : map<string, vector<double> > SASA_LCPO::setupMaxSurfMap() {
+     486             :   // Max Surface Area for backbone and sidechain, in nm2
+     487             :   map<string, vector<double> > valuemap;
+     488           1 :   valuemap ["ALA"]= {0.671446,0.420263,};
+     489           1 :   valuemap ["ARG"]= {0.578582,1.95454,};
+     490           1 :   valuemap ["ASN"]= {0.559411,1.07102,};
+     491           1 :   valuemap ["ASP"]= {0.558363,1.03971,};
+     492           1 :   valuemap ["CYS"]= {0.609271,0.657612,};
+     493           1 :   valuemap ["GLN"]= {0.565651,1.433031,};
+     494           1 :   valuemap ["GLU"]= {0.572399,1.41848,};
+     495           1 :   valuemap ["GLY"]= {0.861439,0,};
+     496           1 :   valuemap ["HIS"]= {0.559929,1.143827,};
+     497           1 :   valuemap ["ILE"]= {0.553491,1.25334,};
+     498           1 :   valuemap ["LEU"]= {0.570103,1.260459,};
+     499           1 :   valuemap ["LYS"]= {0.580304,1.687487,};
+     500           1 :   valuemap ["MET"]= {0.5856,1.498954,};
+     501           1 :   valuemap ["PHE"]= {0.54155,1.394861,};
+     502           1 :   valuemap ["PRO"]= {0.456048,0.849461,};
+     503           1 :   valuemap ["SER"]= {0.59074,0.714538,};
+     504           1 :   valuemap ["THR"]= {0.559116,0.951644,};
+     505           1 :   valuemap ["TRP"]= {0.55536,1.59324,};
+     506           1 :   valuemap ["TYR"]= {0.451171,1.566918,};
+     507           1 :   valuemap ["VAL"]= {0.454809,0.928685,};
+     508           1 :   return valuemap;
+     509             : }
+     510             : 
+     511             : 
+     512             : 
+     513             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     514             : 
+     515           1 : void SASA_LCPO::readMaxSurf() {
+     516             :   map<string, vector<double> > valuemap;
+     517           2 :   valuemap = setupMaxSurfMap();
+     518             :   vector<double> MaxSurfVector;
+     519             : 
+     520         121 :   for(unsigned i=0; i<natoms; i++) {
+     521         120 :     MaxSurf[i].clear();
+     522         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     523         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     524         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     525             :   }
+     526           1 : }
+     527             : 
+     528             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     529             : 
+     530           1 : void SASA_LCPO::readDeltaG() {
+     531             : 
+     532         121 :   for(unsigned i=0; i<natoms; i++) {
+     533         120 :     DeltaG[i].clear();
+     534             :   }
+     535             : 
+     536             :   string DeltaGline;
+     537           1 :   fstream DeltaGFile;
+     538           1 :   DeltaGFile.open(DeltaGValues);
+     539           1 :   if (DeltaGFile) {
+     540             :     int backboneflag = 0;
+     541          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     542          22 :       if(!DeltaGline.empty()) {
+     543             :         std::vector<std::string> DeltaGtoken;
+     544          21 :         split(DeltaGline, DeltaGtoken);
+     545        2541 :         for(unsigned i=0; i<natoms; i++) {
+     546        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     547         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     548             :           }
+     549             :         }
+     550          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     551             :           backboneflag = 1;
+     552           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     553             :         }
+     554          21 :       }
+     555             :     }
+     556           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     557             :   }
+     558           0 :   else error("Cannot open DeltaG file");
+     559             : 
+     560         121 :   for(unsigned i=0; i<natoms; i++) {
+     561         120 :     if (DeltaG[i].size()==0 ) {
+     562           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     563           0 :       error ("missing Delta G parameter\n");
+     564             :     }
+     565             :   }
+     566             : 
+     567           2 : }
+     568             : 
+     569             : //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.
+     570             : 
+     571           0 : void SASA_LCPO::computeDeltaG() {
+     572             : 
+     573           0 :   for(unsigned i=0; i<natoms; i++) {
+     574           0 :     DeltaG[i].clear();
+     575             :   }
+     576             : 
+     577             :   double T;
+     578           0 :   T = getkBT()/getKBoltzmann();
+     579             : 
+     580           0 :   if (T != Ti) {
+     581           0 :     for(unsigned i=0; i<natoms; i++) {
+     582           0 :       if (approach==2) {
+     583           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     584           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     585             :         }
+     586           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     587           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     588             :         }
+     589           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     590           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     591             :         }
+     592           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     593           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     594             :         }
+     595           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     596           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     597             :         }
+     598           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     599           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     600             :         }
+     601           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     602           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     603             :         }
+     604           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     605           0 :           DeltaG[i].push_back (0);
+     606             :         }
+     607           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     608           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     609             :         }
+     610           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     611           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     612             :         }
+     613           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     614           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     615             :         }
+     616           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     617           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     618             :         }
+     619           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     620           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     621             :         }
+     622           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     623           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     624             :         }
+     625           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     626           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     627             :         }
+     628           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     629           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     630             :         }
+     631           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     632           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     633             :         }
+     634           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     635           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     636             :         }
+     637           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     638           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     639             :         }
+     640           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     641           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     642             :         }
+     643           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     644             :       }
+     645           0 :       if (approach==3) {
+     646           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     647           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     648             :         }
+     649           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     650           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     651             :         }
+     652           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     653           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     654             :         }
+     655           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     656           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     657             :         }
+     658           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     659           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     660             :         }
+     661           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     662           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     663             :         }
+     664           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     665           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     666             :         }
+     667           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     668           0 :           DeltaG[i].push_back (0);
+     669             :         }
+     670           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     671           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     672             :         }
+     673           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     674           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     675             :         }
+     676           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     677           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     678             :         }
+     679           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     680           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     681             :         }
+     682           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     683           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     684             :         }
+     685           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     686           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     687             :         }
+     688           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     689           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     690             :         }
+     691           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     692           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     693             :         }
+     694           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     695           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     696             :         }
+     697           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     698           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     699             :         }
+     700           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     701           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     702             :         }
+     703           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     704           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     705             :         }
+     706           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     707             :       }
+     708             :     }
+     709             :   }
+     710             : 
+     711           0 :   Ti = T;
+     712             : 
+     713           0 :   if (firstStepFlag ==0) {
+     714           0 :     if (approach!=2 && approach!=3) {
+     715           0 :       cout << "Unknown approach " << approach << endl;
+     716             :     }
+     717           0 :     for(unsigned i=0; i<natoms; i++) {
+     718           0 :       if (DeltaG[i].size()==0 ) {
+     719           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     720           0 :         error ("missing Delta G parameter\n");
+     721             :       }
+     722             :     }
+     723             :   }
+     724           0 : }
+     725             : 
+     726             : 
+     727             : //calculates neighbor list
+     728          24 : void SASA_LCPO::calcNlist() {
+     729          24 :   if(!nopbc) makeWhole();
+     730             : 
+     731        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     732        2880 :     Nlist[i].clear();
+     733             :   }
+     734             : 
+     735        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     736        2880 :     if (LCPOparam[i].size()>0) {
+     737       87264 :       for (unsigned j = 0; j < i; j++) {
+     738       85824 :         if (LCPOparam[j].size()>0) {
+     739       42480 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     740       42480 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     741       42480 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     742       42480 :           if (Delta_ij_mod < overlapD) {
+     743       19030 :             Nlist.at(i).push_back (j);
+     744       19030 :             Nlist.at(j).push_back (i);
+     745             :           }
+     746             :         }
+     747             :       }
+     748             :     }
+     749             :   }
+     750          24 : }
+     751             : 
+     752             : 
+     753             : //calculates SASA according to LCPO algorithm
+     754          24 : void SASA_LCPO::calculate() {
+     755          24 :   if(!nopbc) makeWhole();
+     756             : 
+     757          24 :   if(getExchangeStep()) nl_update = 0;
+     758          24 :   if (firstStepFlag ==0) {
+     759           2 :     readPDB();
+     760           2 :     readLCPOparam();
+     761             :   }
+     762          24 :   if (nl_update == 0) {
+     763          24 :     calcNlist();
+     764             :   }
+     765             : 
+     766             : 
+     767             : 
+     768             :   double S1, Aij, Ajk, Aijk, Aijt, Ajkt, Aikt;
+     769             :   double dAdd;
+     770          24 :   double sasa = 0;
+     771          24 :   vector<Vector> derivatives( natoms );
+     772          24 :   Tensor virial;
+     773          24 :   vector <double> dAijdc_2t(3);
+     774          24 :   vector <double> dSASA_2_neigh_dc(3);
+     775          24 :   vector <double> ddij_di(3);
+     776          24 :   vector <double> ddik_di(3);
+     777             : 
+     778          24 :   if( sasa_type==TOTAL ) {
+     779        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     780        1440 :       derivatives[i][0] = 0.;
+     781        1440 :       derivatives[i][1] = 0.;
+     782        1440 :       derivatives[i][2] = 0.;
+     783        1440 :       if ( LCPOparam[i].size()>1) {
+     784         720 :         if (LCPOparam[i][1]>0.0) {
+     785             :           Aij = 0.0;
+     786             :           Aijk = 0.0;
+     787             :           Ajk = 0.0;
+     788         720 :           double ri = LCPOparam[i][0];
+     789         720 :           S1 = 4*M_PI*ri*ri;
+     790         720 :           vector <double> dAijdc_2(3, 0);
+     791         720 :           vector <double> dAijdc_4(3, 0);
+     792             : 
+     793             : 
+     794       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     795       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     796       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     797             : 
+     798       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     799       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     800       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     801             : 
+     802       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     803             : 
+     804       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     805       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     806       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     807             : 
+     808             :             Ajkt = 0.0;
+     809             :             Aikt = 0.0;
+     810             : 
+     811       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     812       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     813       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     814       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     815             : 
+     816       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     817       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     818       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     819             : 
+     820       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     821             : 
+     822             : 
+     823       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     824       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     825       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     826             : 
+     827      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     828      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     829      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     830      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     831             : 
+     832      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     833      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     834             : 
+     835      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     836      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     837      370872 :                 Ajkt += sjk;
+     838      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     839             : 
+     840      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     841             : 
+     842      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     843      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     844      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     845             : 
+     846             : 
+     847      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     848      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     849      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     850             : 
+     851      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     852             : 
+     853      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+     854      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+     855      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+     856             : 
+     857      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+     858      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+     859      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+     860             : 
+     861             :               }
+     862             :             }
+     863       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+     864       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+     865       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+     866             : 
+     867       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+     868       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+     869       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+     870             : 
+     871       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+     872       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+     873       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+     874             : 
+     875             : 
+     876       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;
+     877       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;
+     878       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;
+     879             : 
+     880             : 
+     881       19030 :             Aijk += (Aijt * Ajkt);
+     882       19030 :             Aij += Aijt;
+     883       19030 :             Ajk += Ajkt;
+     884             : 
+     885       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+     886       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+     887       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+     888             : 
+     889             : 
+     890       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+     891       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+     892       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+     893             : 
+     894             : 
+     895             :           }
+     896         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+     897         720 :           if (sasai > 0 ) sasa += sasai/100;
+     898         720 :           derivatives[i][0] += (dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/10;
+     899         720 :           derivatives[i][1] += (dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/10;
+     900         720 :           derivatives[i][2] += (dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/10;
+     901             :         }
+     902             :       }
+     903        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+     904             :     }
+     905             :   }
+     906             : 
+     907             : 
+     908             : 
+     909          24 :   if( sasa_type==TRANSFER ) {
+     910             : 
+     911          12 :     if (firstStepFlag ==0) {
+     912           1 :       readMaxSurf();
+     913             :     }
+     914             : 
+     915          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     916           1 :       readDeltaG();
+     917             :     }
+     918             : 
+     919          12 :     if (DeltaGValues == "absent") {
+     920           0 :       computeDeltaG();
+     921             :     }
+     922             : 
+     923             : 
+     924        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     925             : 
+     926             : 
+     927             : 
+     928        1440 :       derivatives[i][0] = 0.;
+     929        1440 :       derivatives[i][1] = 0.;
+     930        1440 :       derivatives[i][2] = 0.;
+     931             : 
+     932        1440 :       if ( LCPOparam[i].size()>1) {
+     933         720 :         if (LCPOparam[i][1]>0.0) {
+     934             :           Aij = 0.0;
+     935             :           Aijk = 0.0;
+     936             :           Ajk = 0.0;
+     937         720 :           double ri = LCPOparam[i][0];
+     938         720 :           S1 = 4*M_PI*ri*ri;
+     939         720 :           vector <double> dAijdc_2(3, 0);
+     940         720 :           vector <double> dAijdc_4(3, 0);
+     941             : 
+     942             : 
+     943       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     944       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     945       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     946             : 
+     947       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     948       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     949       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     950             : 
+     951       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     952       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     953       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     954       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     955             : 
+     956             :             Ajkt = 0.0;
+     957             :             Aikt = 0.0;
+     958             : 
+     959       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     960       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     961       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     962       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     963             : 
+     964       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     965       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     966       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     967             : 
+     968       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     969             : 
+     970       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     971       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     972       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     973             : 
+     974      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     975      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     976      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     977      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     978             : 
+     979      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     980      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     981             : 
+     982      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     983      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     984      370872 :                 Ajkt += sjk;
+     985      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     986             : 
+     987      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     988             : 
+     989      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     990      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     991      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     992             : 
+     993             : 
+     994      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     995      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     996      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     997             : 
+     998      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     999             : 
+    1000      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+    1001      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+    1002      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+    1003             : 
+    1004      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+    1005      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+    1006      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+    1007             : 
+    1008             :               }
+    1009             :             }
+    1010       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+    1011       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+    1012       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+    1013             : 
+    1014       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+    1015       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+    1016       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+    1017             : 
+    1018       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+    1019       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+    1020       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+    1021             : 
+    1022       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") {
+    1023       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;
+    1024       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;
+    1025       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;
+    1026             :             }
+    1027             : 
+    1028       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") {
+    1029        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;
+    1030        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;
+    1031        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;
+    1032             :             }
+    1033             : 
+    1034       19030 :             Aijk += (Aijt * Ajkt);
+    1035       19030 :             Aij += Aijt;
+    1036       19030 :             Ajk += Ajkt;
+    1037             : 
+    1038       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+    1039       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+    1040       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+    1041             : 
+    1042       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+    1043       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+    1044       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+    1045             : 
+    1046             :           }
+    1047         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1048             : 
+    1049        2016 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O") {
+    1050         576 :             if (sasai > 0 ) sasa += (sasai/MaxSurf[i][0]*DeltaG[natoms][0]);
+    1051         576 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1052         576 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1053         576 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1054             :           }
+    1055             : 
+    1056        2016 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O") {
+    1057         144 :             if (sasai > 0. ) sasa += (sasai/MaxSurf[i][1]*DeltaG[i][0]);
+    1058         144 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1059         144 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1060         144 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1061             :           }
+    1062             :         }
+    1063             :       }
+    1064        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+    1065             :     }
+    1066             :   }
+    1067             : 
+    1068             : 
+    1069        2904 :   for(unsigned i=0; i<natoms; i++) { setAtomsDerivatives(i,derivatives[i]);}
+    1070          24 :   setBoxDerivatives(virial);
+    1071          24 :   setValue(sasa);
+    1072          24 :   firstStepFlag = 1;
+    1073          24 :   ++nl_update;
+    1074          24 :   if (nl_update == stride) {
+    1075          24 :     nl_update = 0;
+    1076             :   }
+    1077             : // setBoxDerivativesNoPbc();
+    1078          24 : }
+    1079             : 
+    1080             : }//namespace sasa
+    1081             : }//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 000000000..671b7f65c --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..dc63065d3 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..305f7576a --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html @@ -0,0 +1,251 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a77bdfb39 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:959797.9 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE14
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE84
+
+
+ + + +
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 000000000..a750cee7c --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:959797.9 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE14
_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 000000000..237b1ae7d --- /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:959797.9 %
Date:2024-10-17 16:45:00Functions: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          84 : void AntibetaRMSD::registerKeywords( Keywords& keys ) {
+      98          84 :   SecondaryStructureRMSD::registerKeywords( keys );
+      99         252 :   keys.remove("ATOMS"); keys.remove("SEGMENT"); keys.remove("BONDLENGTH");
+     100         252 :   keys.remove("NO_ACTION_LOG"); keys.remove("CUTOFF_ATOMS"); keys.remove("STRUCTURE");
+     101         168 :   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          84 : }
+     106             : 
+     107          14 : AntibetaRMSD::AntibetaRMSD(const ActionOptions&ao):
+     108             :   Action(ao),
+     109          14 :   ActionShortcut(ao)
+     110             : {
+     111             :   // Read in the input and create a string that describes how to compute the less than
+     112          14 :   std::string ltmap; bool uselessthan=SecondaryStructureRMSD::readShortcutWords( ltmap, this );
+     113             :   // read in the backbone atoms
+     114          28 :   std::vector<unsigned> chains; std::string atoms; SecondaryStructureRMSD::readBackboneAtoms( this, plumed, "protein", chains, atoms );
+     115             : 
+     116             :   bool intra_chain(false), inter_chain(false);
+     117          14 :   std::string style; parse("STYLE",style);
+     118          28 :   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          14 :   std::string seglist; unsigned k=1;
+     130          14 :   if( intra_chain ) {
+     131          13 :     unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     132         230 :     for(unsigned i=0; i<chains.size(); ++i) {
+     133         217 :       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         217 :       unsigned nres=chains[i]/5;
+     136         217 :       if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     137         438 :       for(unsigned ires=0; ires<nres-7; ires++) {
+     138         452 :         for(unsigned jres=ires+7; jres<nres; jres++) {
+     139        3696 :           for(unsigned k=0; k<15; ++k) {
+     140        3465 :             nlist[k]=nprevious + ires*5+k;
+     141        3465 :             nlist[k+15]=nprevious + (jres-2)*5+k;
+     142             :           }
+     143             :           std::string nlstr, num;
+     144         231 :           Tools::convert( nlist[0], nlstr );
+     145         231 :           Tools::convert(k, num); k++;
+     146         462 :           seglist += " SEGMENT" + num + "=" + nlstr;
+     147        6930 :           for(unsigned kk=1; kk<nlist.size(); ++kk ) { Tools::convert( nlist[kk], nlstr ); seglist += "," + nlstr; }
+     148             :         }
+     149             :       }
+     150         217 :       nprevious+=chains[i];
+     151             :     }
+     152             :   }
+     153          14 :   if( inter_chain ) {
+     154          15 :     if( chains.size()==1 && style!="all" ) error("there is only one chain defined so cannot use inter_chain option");
+     155          14 :     std::vector<unsigned> nlist(30);
+     156         219 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     157        2042 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     158         205 :       unsigned inres=chains[ichain]/5;
+     159         205 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     160        1430 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     161       12242 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     162       69769 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     163       11017 :           unsigned jnres=chains[jchain]/5;
+     164       11017 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     165       77114 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     166     1057552 :             for(unsigned k=0; k<15; ++k) {
+     167      991455 :               nlist[k]=iprev+ ires*5+k;
+     168      991455 :               nlist[k+15]=jprev+ jres*5+k;
+     169             :             }
+     170             :             std::string nlstr, num;
+     171       66097 :             Tools::convert( nlist[0], nlstr );
+     172       66097 :             Tools::convert(k, num); k++;
+     173      132194 :             seglist += " SEGMENT" + num + "=" + nlstr;
+     174     1982910 :             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          14 :   std::vector<Vector> reference(30);
+     183          14 :   reference[0]=Vector( 2.263, -3.795,  1.722); // N    i
+     184          14 :   reference[1]=Vector( 2.493, -2.426,  2.263); // CA
+     185          14 :   reference[2]=Vector( 3.847, -1.838,  1.761); // CB
+     186          14 :   reference[3]=Vector( 1.301, -1.517,  1.921); // C
+     187          14 :   reference[4]=Vector( 0.852, -1.504,  0.739); // O
+     188          14 :   reference[5]=Vector( 0.818, -0.738,  2.917); // N    i+1
+     189          14 :   reference[6]=Vector(-0.299,  0.243,  2.748); // CA
+     190          14 :   reference[7]=Vector(-1.421, -0.076,  3.757); // CB
+     191          14 :   reference[8]=Vector( 0.273,  1.680,  2.854); // C
+     192          14 :   reference[9]=Vector( 0.902,  1.993,  3.888); // O
+     193          14 :   reference[10]=Vector( 0.119,  2.532,  1.813); // N    i+2
+     194          14 :   reference[11]=Vector( 0.683,  3.916,  1.680); // CA
+     195          14 :   reference[12]=Vector( 1.580,  3.940,  0.395); // CB
+     196          14 :   reference[13]=Vector(-0.394,  5.011,  1.630); // C
+     197          14 :   reference[14]=Vector(-1.459,  4.814,  0.982); // O
+     198          14 :   reference[15]=Vector(-2.962,  3.559, -1.359); // N    j-2
+     199          14 :   reference[16]=Vector(-2.439,  2.526, -2.287); // CA
+     200          14 :   reference[17]=Vector(-1.189,  3.006, -3.087); // CB
+     201          14 :   reference[18]=Vector(-2.081,  1.231, -1.520); // C
+     202          14 :   reference[19]=Vector(-1.524,  1.324, -0.409); // O
+     203          14 :   reference[20]=Vector(-2.326,  0.037, -2.095); // N    j-1
+     204          14 :   reference[21]=Vector(-1.858, -1.269, -1.554); // CA
+     205          14 :   reference[22]=Vector(-3.053, -2.199, -1.291); // CB
+     206          14 :   reference[23]=Vector(-0.869, -1.949, -2.512); // C
+     207          14 :   reference[24]=Vector(-1.255, -2.070, -3.710); // O
+     208          14 :   reference[25]=Vector( 0.326, -2.363, -2.072); // N    j
+     209          14 :   reference[26]=Vector( 1.405, -2.992, -2.872); // CA
+     210          14 :   reference[27]=Vector( 2.699, -2.129, -2.917); // CB
+     211          14 :   reference[28]=Vector( 1.745, -4.399, -2.330); // C
+     212          14 :   reference[29]=Vector( 1.899, -4.545, -1.102); // O
+     213             :   std::string ref0, ref1, ref2;
+     214          14 :   Tools::convert(  reference[0][0], ref0 );
+     215          14 :   Tools::convert(  reference[0][1], ref1 );
+     216          14 :   Tools::convert(  reference[0][2], ref2 );
+     217          28 :   std::string structure=" STRUCTURE1=" + ref0 + "," + ref1 + "," + ref2;
+     218         420 :   for(unsigned i=1; i<30; ++i) {
+     219        1624 :     for(unsigned k=0; k<3; ++k) { Tools::convert( reference[i][k], ref0 ); structure += "," + ref0; }
+     220             :   }
+     221             : 
+     222          28 :   std::string strands_cutoff; parse("STRANDS_CUTOFF",strands_cutoff);
+     223          27 :   if( strands_cutoff.length()>0 ) strands_cutoff=" CUTOFF_ATOMS=6,21 STRANDS_CUTOFF="+strands_cutoff;
+     224          28 :   std::string type; parse("TYPE",type); std::string lab = getShortcutLabel() + "_rmsd"; if( uselessthan ) lab = getShortcutLabel();
+     225          28 :   std::string nopbcstr=""; bool nopbc; parseFlag("NOPBC",nopbc); if( nopbc ) nopbcstr = " NOPBC";
+     226          14 :   if( seglist.length()==0 ) error("no segments to investigate");
+     227          28 :   readInputLine( lab + ": SECONDARY_STRUCTURE_RMSD BONDLENGTH=0.17" + seglist + structure + " " + atoms + " TYPE=" + type + strands_cutoff + nopbcstr );
+     228             :   // Create the less than object
+     229          14 :   if( ltmap.length()>0 ) SecondaryStructureRMSD::expandShortcut( uselessthan, getShortcutLabel(), lab, ltmap, this );
+     230          14 : }
+     231             : 
+     232             : }
+     233             : }
+
+
+
+ + + + +
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 000000000..1a0b67f0f --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:13213498.5 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE15
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE83
+
+
+ + + +
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 000000000..99b31a6d6 --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:13213498.5 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE15
_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 000000000..e7e3b906a --- /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:13213498.5 %
Date:2024-10-17 16:45:00Functions: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          83 : void ParabetaRMSD::registerKeywords( Keywords& keys ) {
+      99          83 :   SecondaryStructureRMSD::registerKeywords( keys );
+     100         249 :   keys.remove("ATOMS"); keys.remove("SEGMENT"); keys.remove("BONDLENGTH");
+     101         249 :   keys.remove("NO_ACTION_LOG"); keys.remove("CUTOFF_ATOMS"); keys.remove("STRUCTURE");
+     102         166 :   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          83 :   keys.needsAction("LOWEST");
+     107          83 : }
+     108             : 
+     109          15 : ParabetaRMSD::ParabetaRMSD(const ActionOptions&ao):
+     110             :   Action(ao),
+     111          15 :   ActionShortcut(ao)
+     112             : {
+     113             :   // Read in the input and create a string that describes how to compute the less than
+     114          15 :   std::string ltmap; bool uselessthan=SecondaryStructureRMSD::readShortcutWords( ltmap, this );
+     115             :   // read in the backbone atoms
+     116          30 :   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          15 :   std::string style; parse("STYLE",style); unsigned jjkk=1;
+     120          30 :   if( Tools::caseInSensStringCompare(style, "all") ) {
+     121             :     intra_chain=true; inter_chain=true;
+     122           2 :   } 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          14 :     unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     133         215 :     for(unsigned i=0; i<chains.size(); ++i) {
+     134         201 :       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         201 :       unsigned nres=chains[i]/5;
+     137         201 :       if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     138         213 :       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         201 :       nprevious+=chains[i];
+     152             :     }
+     153             :   }
+     154             :   // This constructs all conceivable sections of antibeta sheet that form between chains
+     155          15 :   if( inter_chain ) {
+     156          21 :     if( chains.size()==1 && !Tools::caseInSensStringCompare(style, "all") ) error("there is only one chain defined so cannot use inter_chain option");
+     157          15 :     std::vector<unsigned> nlist(30);
+     158         219 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     159        2040 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     160         204 :       unsigned inres=chains[ichain]/5;
+     161         204 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     162        1428 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     163       12240 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     164       69768 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     165       11016 :           unsigned jnres=chains[jchain]/5;
+     166       11016 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     167       77112 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     168     1057536 :             for(unsigned k=0; k<15; ++k) {
+     169      991440 :               nlist[k]=iprev + ires*5+k;
+     170      991440 :               nlist[k+15]=jprev + jres*5+k;
+     171             :             }
+     172             :             std::string nlstr, num;
+     173       66096 :             Tools::convert( nlist[0], nlstr );
+     174       66096 :             Tools::convert(jjkk, num); jjkk++;
+     175      132192 :             seglist += " SEGMENT" + num + "=" + nlstr;
+     176     1982880 :             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          15 :   std::vector<Vector> reference(30);
+     185          15 :   reference[0]=Vector( 1.244, -4.620, -2.127); // N    i
+     186          15 :   reference[1]=Vector(-0.016, -4.500, -1.395); // CA
+     187          15 :   reference[2]=Vector( 0.105, -5.089,  0.024); // CB
+     188          15 :   reference[3]=Vector(-0.287, -3.000, -1.301); // C
+     189          15 :   reference[4]=Vector( 0.550, -2.245, -0.822); // O
+     190          15 :   reference[5]=Vector(-1.445, -2.551, -1.779); // N    i+1
+     191          15 :   reference[6]=Vector(-1.752, -1.130, -1.677); // CA
+     192          15 :   reference[7]=Vector(-2.113, -0.550, -3.059); // CB
+     193          15 :   reference[8]=Vector(-2.906, -0.961, -0.689); // C
+     194          15 :   reference[9]=Vector(-3.867, -1.738, -0.695); // O
+     195          15 :   reference[10]=Vector(-2.774,  0.034,  0.190); // N    i+2
+     196          15 :   reference[11]=Vector(-3.788,  0.331,  1.201); // CA
+     197          15 :   reference[12]=Vector(-3.188,  0.300,  2.624); // CB
+     198          15 :   reference[13]=Vector(-4.294,  1.743,  0.937); // C
+     199          15 :   reference[14]=Vector(-3.503,  2.671,  0.821); // O
+     200          15 :   reference[15]=Vector( 4.746, -2.363,  0.188); // N    j
+     201          15 :   reference[16]=Vector( 3.427, -1.839,  0.545); // CA
+     202          15 :   reference[17]=Vector( 3.135, -1.958,  2.074); // CB
+     203          15 :   reference[18]=Vector( 3.346, -0.365,  0.181); // C
+     204          15 :   reference[19]=Vector( 4.237,  0.412,  0.521); // O
+     205          15 :   reference[20]=Vector( 2.261,  0.013, -0.487); // N    j+1
+     206          15 :   reference[21]=Vector( 2.024,  1.401, -0.875); // CA
+     207          15 :   reference[22]=Vector( 1.489,  1.514, -2.313); // CB
+     208          15 :   reference[23]=Vector( 0.914,  1.902,  0.044); // C
+     209          15 :   reference[24]=Vector(-0.173,  1.330,  0.052); // O
+     210          15 :   reference[25]=Vector( 1.202,  2.940,  0.828); // N    j+2
+     211          15 :   reference[26]=Vector( 0.190,  3.507,  1.718); // CA
+     212          15 :   reference[27]=Vector( 0.772,  3.801,  3.104); // CB
+     213          15 :   reference[28]=Vector(-0.229,  4.791,  1.038); // C
+     214          15 :   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          15 :   Tools::convert(  reference[0][0], ref0 );
+     218          15 :   Tools::convert(  reference[0][1], ref1 );
+     219          15 :   Tools::convert(  reference[0][2], ref2 );
+     220          30 :   std::string structure=" STRUCTURE1=" + ref0 + "," + ref1 + "," + ref2;
+     221         450 :   for(unsigned i=1; i<30; ++i) {
+     222        1740 :     for(unsigned k=0; k<3; ++k) { Tools::convert( reference[i][k], ref0 ); structure += "," + ref0; }
+     223             :   }
+     224             : 
+     225          15 :   reference[0]=Vector(-1.439, -5.122, -1.144); // N    i
+     226          15 :   reference[1]=Vector(-0.816, -3.803, -1.013); // CA
+     227          15 :   reference[2]=Vector( 0.099, -3.509, -2.206); // CB
+     228          15 :   reference[3]=Vector(-1.928, -2.770, -0.952); // C
+     229          15 :   reference[4]=Vector(-2.991, -2.970, -1.551); // O
+     230          15 :   reference[5]=Vector(-1.698, -1.687, -0.215); // N    i+1
+     231          15 :   reference[6]=Vector(-2.681, -0.613, -0.143); // CA
+     232          15 :   reference[7]=Vector(-3.323, -0.477,  1.267); // CB
+     233          15 :   reference[8]=Vector(-1.984,  0.681, -0.574); // C
+     234          15 :   reference[9]=Vector(-0.807,  0.921, -0.273); // O
+     235          15 :   reference[10]=Vector(-2.716,  1.492, -1.329); // N    i+2
+     236          15 :   reference[11]=Vector(-2.196,  2.731, -1.883); // CA
+     237          15 :   reference[12]=Vector(-2.263,  2.692, -3.418); // CB
+     238          15 :   reference[13]=Vector(-2.989,  3.949, -1.433); // C
+     239          15 :   reference[14]=Vector(-4.214,  3.989, -1.583); // O
+     240          15 :   reference[15]=Vector( 2.464, -4.352,  2.149); // N    j
+     241          15 :   reference[16]=Vector( 3.078, -3.170,  1.541); // CA
+     242          15 :   reference[17]=Vector( 3.398, -3.415,  0.060); // CB
+     243          15 :   reference[18]=Vector( 2.080, -2.021,  1.639); // C
+     244          15 :   reference[19]=Vector( 0.938, -2.178,  1.225); // O
+     245          15 :   reference[20]=Vector( 2.525, -0.886,  2.183); // N    j+1
+     246          15 :   reference[21]=Vector( 1.692,  0.303,  2.346); // CA
+     247          15 :   reference[22]=Vector( 1.541,  0.665,  3.842); // CB
+     248          15 :   reference[23]=Vector( 2.420,  1.410,  1.608); // C
+     249          15 :   reference[24]=Vector( 3.567,  1.733,  1.937); // O
+     250          15 :   reference[25]=Vector( 1.758,  1.976,  0.600); // N    j+2
+     251          15 :   reference[26]=Vector( 2.373,  2.987, -0.238); // CA
+     252          15 :   reference[27]=Vector( 2.367,  2.527, -1.720); // CB
+     253          15 :   reference[28]=Vector( 1.684,  4.331, -0.148); // C
+     254          15 :   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          15 :   Tools::convert(  reference[0][0], ref0 );
+     257          15 :   Tools::convert(  reference[0][1], ref1 );
+     258          15 :   Tools::convert(  reference[0][2], ref2 );
+     259          30 :   structure +=" STRUCTURE2=" + ref0 + "," + ref1 + "," + ref2;
+     260         450 :   for(unsigned i=1; i<30; ++i) {
+     261        1740 :     for(unsigned k=0; k<3; ++k) { Tools::convert( reference[i][k], ref0 ); structure += "," + ref0; }
+     262             :   }
+     263             : 
+     264          15 :   std::string strands_cutoff; parse("STRANDS_CUTOFF",strands_cutoff);
+     265          30 :   std::string nopbcstr=""; bool nopbc; parseFlag("NOPBC",nopbc); if( nopbc ) nopbcstr = " NOPBC";
+     266          28 :   if( strands_cutoff.length()>0 ) strands_cutoff=" CUTOFF_ATOMS=6,21 STRANDS_CUTOFF="+strands_cutoff;
+     267          30 :   std::string type; parse("TYPE",type); std::string lab = getShortcutLabel() + "_low"; if( uselessthan ) lab = getShortcutLabel();
+     268          15 :   if( seglist.length()==0 ) error("no segments to investigate");
+     269          30 :   readInputLine( getShortcutLabel() + "_both: SECONDARY_STRUCTURE_RMSD BONDLENGTH=0.17" + seglist + structure + " " + atoms + " TYPE=" + type + strands_cutoff + nopbcstr );
+     270          15 :   if( ltmap.length()>0 ) {
+     271             :     // Create the lowest line
+     272          30 :     readInputLine( lab + ": LOWEST ARG=" + getShortcutLabel() + "_both.struct-1," + getShortcutLabel() + "_both.struct-2" );
+     273             :     // Create the less than object
+     274          15 :     SecondaryStructureRMSD::expandShortcut( uselessthan, getShortcutLabel(), lab, ltmap, this );
+     275             :   }
+     276          15 : }
+     277             : 
+     278             : }
+     279             : }
+
+
+
+ + + + +
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 000000000..b20a3c487 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:18019094.7 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD14expandShortcutERKbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_PNS_14ActionShortcutE32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readBackboneAtomsEPNS_14ActionShortcutERNS_10PlumedMainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIjSaIjEERSB_32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readShortcutWordsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_14ActionShortcutE32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC1ERKNS_13ActionOptionsE32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE79
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv240
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE242
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjRNS_10MultiValueE55246
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD15checkTaskStatusERKjRi596136
+
+
+ + + +
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 000000000..e41a3d27f --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:18019094.7 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD14expandShortcutERKbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_PNS_14ActionShortcutE32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE242
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readBackboneAtomsEPNS_14ActionShortcutERNS_10PlumedMainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIjSaIjEERSB_32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readShortcutWordsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_14ActionShortcutE32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE79
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv240
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC1ERKNS_13ActionOptionsE32
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC2ERKNS_13ActionOptionsE0
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjRNS_10MultiValueE55246
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD15checkTaskStatusERKjRi596136
+
+
+ + + +
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 000000000..a22d6a502 --- /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:18019094.7 %
Date:2024-10-17 16:45:00Functions: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          32 : bool SecondaryStructureRMSD::readShortcutWords( std::string& ltmap, ActionShortcut* action ) {
+      44          64 :   action->parse("LESS_THAN",ltmap);
+      45          32 :   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          32 : void SecondaryStructureRMSD::expandShortcut( const bool& uselessthan, const std::string& labout, const std::string& labin, const std::string& ltmap, ActionShortcut* action ) {
+      56          64 :   action->readInputLine( labout + "_lt: LESS_THAN ARG=" + labin + " SWITCH={" + ltmap  +"}");
+      57          61 :   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          32 : }
+      60             : 
+      61         242 : void SecondaryStructureRMSD::registerKeywords( Keywords& keys ) {
+      62         242 :   ActionWithVector::registerKeywords( keys );
+      63         484 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions");
+      64         484 :   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         484 :   keys.add("atoms","ATOMS","this is the full list of atoms that we are investigating");
+      72         484 :   keys.add("numbered","SEGMENT","this is the lists of atoms in the segment that are being considered");
+      73         484 :   keys.add("compulsory","BONDLENGTH","the length to use for bonds");
+      74         484 :   keys.add("numbered","STRUCTURE","the reference structure");
+      75         484 :   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         484 :   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         484 :   keys.add("optional","CUTOFF_ATOMS","the pair of atoms that are used to calculate the strand cutoff");
+      83         484 :   keys.addFlag("VERBOSE",false,"write a more detailed output");
+      84         484 :   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         484 :   keys.add("optional","R_0","The r_0 parameter of the switching function.");
+      87         484 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      88         484 :   keys.add("compulsory","NN","8","The n parameter of the switching function");
+      89         484 :   keys.add("compulsory","MM","12","The m parameter of the switching function");
+      90         484 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      91         484 :   keys.addOutputComponent("struct","default","the vectors containing the rmsd distances between the residues and each of the reference structures");
+      92         484 :   keys.addOutputComponent("lessthan","default","the number blocks of residues that have an RMSD from the secondary structure that is less than the threshold");
+      93         726 :   keys.needsAction("SECONDARY_STRUCTURE_RMSD"); keys.needsAction("LESS_THAN"); keys.needsAction("SUM");
+      94         242 : }
+      95             : 
+      96          32 : void SecondaryStructureRMSD::readBackboneAtoms( ActionShortcut* action, PlumedMain& plumed, const std::string& moltype, std::vector<unsigned>& chain_lengths, std::string& all_atoms ) {
+      97          32 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(action);
+      98          32 :   if( ! moldat ) action->error("Unable to find MOLINFO in input");
+      99             : 
+     100          64 :   std::vector<std::string> resstrings; action->parseVector( "RESIDUES", resstrings );
+     101          32 :   if(resstrings.size()==0) action->error("residues are not defined, check the keyword RESIDUES");
+     102          64 :   else if( Tools::caseInSensStringCompare(resstrings[0], "all") ) {
+     103             :     resstrings[0]="all";
+     104          30 :     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          32 :   moldat->getBackbone( resstrings, moltype, backatoms );
+     112             : 
+     113          32 :   chain_lengths.resize( backatoms.size() );
+     114         473 :   for(unsigned i=0; i<backatoms.size(); ++i) {
+     115         441 :     chain_lengths[i]=backatoms[i].size();
+     116       18141 :     for(unsigned j=0; j<backatoms[i].size(); ++j) {
+     117       17700 :       std::string bat_str; Tools::convert( backatoms[i][j].serial(), bat_str );
+     118       17732 :       if( i==0 && j==0 ) all_atoms = "ATOMS=" + bat_str;
+     119       35336 :       else all_atoms += "," + bat_str;
+     120             :     }
+     121             :   }
+     122          32 : }
+     123             : 
+     124             : 
+     125          32 : SecondaryStructureRMSD::SecondaryStructureRMSD(const ActionOptions&ao):
+     126             :   Action(ao),
+     127             :   ActionWithVector(ao),
+     128          32 :   nopbc(false),
+     129          32 :   align_strands(false),
+     130          32 :   s_cutoff2(0),
+     131          32 :   align_atom_1(0),
+     132          32 :   align_atom_2(0)
+     133             : {
+     134          32 :   if( plumed.usingNaturalUnits() ) error("cannot use this collective variable when using natural units");
+     135             : 
+     136          64 :   parse("TYPE",alignType); parseFlag("NOPBC",nopbc);
+     137          32 :   log.printf("  distances from secondary structure elements are calculated using %s algorithm\n",alignType.c_str() );
+     138          64 :   log<<"  Bibliography "<<plumed.cite("Pietrucci and Laio, J. Chem. Theory Comput. 5, 2197 (2009)"); log<<"\n";
+     139             : 
+     140          32 :   parseFlag("VERBOSE",verbose_output);
+     141             : 
+     142          64 :   if( keywords.exists("STRANDS_CUTOFF") ) {
+     143          32 :     double s_cutoff = 0;
+     144          32 :     parse("STRANDS_CUTOFF",s_cutoff); align_strands=true;
+     145          32 :     if( s_cutoff>0) {
+     146          26 :       log.printf("  ignoring contributions from strands that are more than %f apart\n",s_cutoff);
+     147          52 :       std::vector<unsigned> cutatoms; parseVector("CUTOFF_ATOMS",cutatoms);
+     148          26 :       if( cutatoms.size()==2 ) {
+     149          26 :         align_atom_1=cutatoms[0]; align_atom_2=cutatoms[1];
+     150           0 :       } else error("did not find CUTOFF_ATOMS in input");
+     151             :     }
+     152          32 :     s_cutoff2=s_cutoff*s_cutoff;
+     153             :   }
+     154             : 
+     155             :   // Read in the atoms
+     156          64 :   std::vector<AtomNumber> all_atoms; parseAtomList("ATOMS",all_atoms); requestAtoms( all_atoms );
+     157             : 
+     158      132469 :   for(unsigned i=1;; ++i) {
+     159             :     std::vector<unsigned> newatoms;
+     160      265002 :     if( !parseNumberedVector("SEGMENT",i,newatoms) ) break;
+     161      132469 :     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      132469 :     colvar_atoms.push_back( newatoms );
+     167      132469 :   }
+     168          32 :   if( colvar_atoms.size()==0 ) error("missing SEGMENT keywords -- no atoms have been specified for comparison");
+     169             : 
+     170          64 :   double bondlength; parse("BONDLENGTH",bondlength); bondlength=bondlength/getUnits().getLength();
+     171             : 
+     172             :   // Read in the reference structure
+     173          47 :   for(unsigned ii=1;; ++ii) {
+     174             :     std::vector<double> cstruct;
+     175         158 :     if( !parseNumberedVector("STRUCTURE",ii,cstruct) ) break ;
+     176          47 :     plumed_assert( cstruct.size()%3==0 && cstruct.size()/3==colvar_atoms[0].size() );
+     177          47 :     std::vector<Vector> structure( cstruct.size()/3 );
+     178        1457 :     for(unsigned i=0; i<structure.size(); ++i) {
+     179        5640 :       for(unsigned j=0; j<3; ++j) structure[i][j] = 0.1*cstruct[3*i+j]/getUnits().getLength();
+     180             :     }
+     181          47 :     if( alignType=="DRMSD" ) {
+     182             :       std::map<std::pair<unsigned,unsigned>, double> targets;
+     183         660 :       for(unsigned i=0; i<structure.size()-1; ++i) {
+     184       10208 :         for(unsigned j=i+1; j<structure.size(); ++j) {
+     185        9570 :           double distance = delta( structure[i], structure[j] ).modulo();
+     186        9570 :           if(distance > bondlength) targets[std::make_pair(i,j)] = distance;
+     187             :         }
+     188             :       }
+     189          22 :       drmsd_targets.push_back( targets );
+     190             :     } else {
+     191          25 :       Vector center; std::vector<double> align( structure.size(), 1.0 ), displace( structure.size(), 1.0 );
+     192         775 :       for(unsigned i=0; i<structure.size(); ++i) center+=structure[i]*align[i];
+     193         775 :       for(unsigned i=0; i<structure.size(); ++i) structure[i] -= center;
+     194          25 :       RMSD newrmsd; newrmsd.clear();
+     195          25 :       newrmsd.set(align,displace,structure,alignType,true,true);
+     196          25 :       myrmsd.push_back( newrmsd );
+     197          25 :     }
+     198          47 :   }
+     199             : 
+     200             :   // And create values to hold everything
+     201          32 :   unsigned nref = myrmsd.size(); if( alignType=="DRMSD" ) nref=drmsd_targets.size();
+     202          32 :   plumed_assert( nref>0 );
+     203          32 :   std::vector<unsigned> shape(1); shape[0]=colvar_atoms.size();
+     204          32 :   if( nref==1 ) { addValue( shape ); setNotPeriodic(); }
+     205             :   else {
+     206             :     std::string num;
+     207          45 :     for(unsigned i=0; i<nref; ++i) {
+     208          30 :       Tools::convert( i+1, num ); addComponent( "struct-" + num, shape );
+     209          60 :       componentIsNotPeriodic( "struct-" + num );
+     210             :     }
+     211             :   }
+     212          32 : }
+     213             : 
+     214          79 : void SecondaryStructureRMSD::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     215          79 :   if( s_cutoff2>0 ) task_reducing_actions.push_back(this);
+     216          79 : }
+     217             : 
+     218      596136 : int SecondaryStructureRMSD::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+     219      596136 :   if( s_cutoff2>0 ) {
+     220      596136 :     Vector distance=pbcDistance( ActionAtomistic::getPosition( getAtomIndex(taskno,align_atom_1) ),
+     221             :                                  ActionAtomistic::getPosition( getAtomIndex(taskno,align_atom_2) ) );
+     222      596136 :     if( distance.modulo2()<s_cutoff2 ) return 1;
+     223      541322 :     return 0;
+     224           0 :   } return flag;
+     225             : }
+     226             : 
+     227         240 : void SecondaryStructureRMSD::calculate() {
+     228         240 :   runAllTasks();
+     229         240 : }
+     230             : 
+     231       55246 : void SecondaryStructureRMSD::performTask( const unsigned& current, MultiValue& myvals ) const {
+     232             :   // Resize the derivatives if need be
+     233       55246 :   unsigned nderi = 3*getNumberOfAtoms()+9;
+     234       55246 :   if( myvals.getNumberOfDerivatives()!=nderi ) myvals.resize( myvals.getNumberOfValues(), nderi, 0, 0 );
+     235             :   // Retrieve the positions
+     236       55246 :   const unsigned natoms = colvar_atoms[current].size();
+     237       55246 :   std::vector<Vector> pos( natoms ), deriv( natoms );
+     238     1712626 :   for(unsigned i=0; i<natoms; ++i) pos[i]=ActionAtomistic::getPosition( getAtomIndex(current,i) );
+     239             : 
+     240             :   // This aligns the two strands if this is required
+     241       55246 :   Vector distance=pbcDistance( pos[align_atom_1],pos[align_atom_2] );
+     242       55246 :   if( align_strands ) {
+     243       55246 :     Vector origin_old, origin_new; origin_old=pos[align_atom_2];
+     244       55246 :     origin_new=pos[align_atom_1]+distance;
+     245      883936 :     for(unsigned i=15; i<30; ++i) {
+     246      828690 :       pos[i]+=( origin_new - origin_old );
+     247             :     }
+     248           0 :   } else if( !nopbc ) {
+     249           0 :     for(unsigned i=0; i<natoms-1; ++i) {
+     250           0 :       const Vector & first (pos[i]);
+     251           0 :       Vector & second (pos[i+1]);
+     252           0 :       second=first+pbcDistance(first,second);
+     253             :     }
+     254             :   }
+     255             :   // Create a holder for the derivatives
+     256       55246 :   if( alignType=="DRMSD" ) {
+     257             :     // And now calculate the DRMSD
+     258       18826 :     const unsigned rs = drmsd_targets.size();
+     259       47061 :     for(unsigned i=0; i<rs; ++i) {
+     260       28235 :       double drmsd=0; Vector distance; Tensor vir; vir.zero();
+     261      875285 :       for(unsigned j=0; j<natoms; ++j) deriv[j].zero();
+     262    11519700 :       for(const auto & it : drmsd_targets[i] ) {
+     263    11491465 :         const unsigned k=it.first.first;
+     264    11491465 :         const unsigned j=it.first.second;
+     265             : 
+     266    11491465 :         distance=delta( pos[k], pos[j] );
+     267    11491465 :         const double len = distance.modulo();
+     268    11491465 :         const double diff = len - it.second;
+     269    11491465 :         const double der = diff / len;
+     270    11491465 :         drmsd += diff*diff;
+     271             : 
+     272    11491465 :         if( !doNotCalculateDerivatives() ) {
+     273    11262001 :           deriv[k] += -der*distance; deriv[j] += der*distance;
+     274    11262001 :           vir += -der*Tensor(distance,distance);
+     275             :         }
+     276             :       }
+     277             : 
+     278       28235 :       const double inpairs = 1./static_cast<double>(drmsd_targets[i].size());
+     279       28235 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     280       28235 :       drmsd = sqrt(inpairs*drmsd); myvals.setValue( ostrn, drmsd );
+     281             : 
+     282       28235 :       if( !doNotCalculateDerivatives() ) {
+     283       27671 :         double scalef = inpairs / drmsd;
+     284      857801 :         for(unsigned j=0; j<natoms; ++j) {
+     285             :           const unsigned ja = getAtomIndex( current, j );
+     286      830130 :           myvals.addDerivative( ostrn, 3*ja + 0, scalef*deriv[j][0] ); myvals.updateIndex( ostrn, 3*ja+0 );
+     287      830130 :           myvals.addDerivative( ostrn, 3*ja + 1, scalef*deriv[j][1] ); myvals.updateIndex( ostrn, 3*ja+1 );
+     288      830130 :           myvals.addDerivative( ostrn, 3*ja + 2, scalef*deriv[j][2] ); myvals.updateIndex( ostrn, 3*ja+2 );
+     289             :         }
+     290       27671 :         unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     291      110684 :         for(unsigned k=0; k<3; ++k) {
+     292      332052 :           for(unsigned j=0; j<3; ++j) {
+     293      249039 :             myvals.addDerivative( ostrn, nbase + 3*k + j, scalef*vir(k,j) );
+     294      249039 :             myvals.updateIndex( ostrn, nbase + 3*k + j );
+     295             :           }
+     296             :         }
+     297             :       }
+     298             :     }
+     299             :   } else {
+     300       36420 :     const unsigned rs = myrmsd.size();
+     301       91020 :     for(unsigned i=0; i<rs; ++i) {
+     302       54600 :       double nr = myrmsd[i].calculate( pos, deriv, false );
+     303       54600 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     304       54600 :       myvals.setValue( ostrn, nr );
+     305             : 
+     306       54600 :       if( !doNotCalculateDerivatives() ) {
+     307       54600 :         Tensor vir; vir.zero();
+     308     1692600 :         for(unsigned j=0; j<natoms; ++j) {
+     309             :           const unsigned ja = getAtomIndex( current, j );
+     310     1638000 :           myvals.addDerivative( ostrn, 3*ja + 0, deriv[j][0] ); myvals.updateIndex( ostrn, 3*colvar_atoms[current][j]+0 );
+     311     1638000 :           myvals.addDerivative( ostrn, 3*ja + 1, deriv[j][1] ); myvals.updateIndex( ostrn, 3*colvar_atoms[current][j]+1 );
+     312     1638000 :           myvals.addDerivative( ostrn, 3*ja + 2, deriv[j][2] ); myvals.updateIndex( ostrn, 3*colvar_atoms[current][j]+2 );
+     313     1638000 :           vir+=(-1.0*Tensor( pos[j], deriv[j] ));
+     314             :         }
+     315       54600 :         unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     316      218400 :         for(unsigned k=0; k<3; ++k) {
+     317      655200 :           for(unsigned j=0; j<3; ++j) {
+     318      491400 :             myvals.addDerivative( ostrn, nbase + 3*k + j, vir(k,j) );
+     319      491400 :             myvals.updateIndex( ostrn, nbase + 3*k + j );
+     320             :           }
+     321             :         }
+     322             :       }
+     323             :     }
+     324             :   }
+     325       55246 :   return;
+     326             : }
+     327             : 
+     328             : }
+     329             : }
+
+
+
+ + + + +
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 000000000..790ce64ae --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv110
+
+
+ + + +
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 000000000..a35c8a237 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-10-17 16:45:00Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv110
+
+
+ + + +
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 000000000..2ea8e128d --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html @@ -0,0 +1,161 @@ + + + + + + + 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-10-17 16:45:00Functions: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         110 : unsigned SecondaryStructureRMSD::getNumberOfDerivatives() {
+      74         110 :   return 3*getNumberOfAtoms()+9;
+      75             : }
+      76             : 
+      77             : inline
+      78             : unsigned SecondaryStructureRMSD::getAtomIndex( const unsigned& current, const unsigned& iatom ) const {
+      79     4721646 :   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 000000000..81d272acc --- /dev/null +++ b/coverage/secondarystructure/index-sort-f.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:47248697.1 %
Date:2024-10-17 16:45:00Functions: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 %95 / 9766.7 %2 / 3
ParabetaRMSD.cpp +
98.5%98.5%
+
98.5 %132 / 13466.7 %2 / 3
SecondaryStructureRMSD.cpp +
94.7%94.7%
+
94.7 %180 / 19090.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 000000000..eff7b9c75 --- /dev/null +++ b/coverage/secondarystructure/index-sort-l.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:47248697.1 %
Date:2024-10-17 16:45:00Functions:162080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SecondaryStructureRMSD.cpp +
94.7%94.7%
+
94.7 %180 / 19090.0 %9 / 10
AntibetaRMSD.cpp +
97.9%97.9%
+
97.9 %95 / 9766.7 %2 / 3
ParabetaRMSD.cpp +
98.5%98.5%
+
98.5 %132 / 13466.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 000000000..24341fb05 --- /dev/null +++ b/coverage/secondarystructure/index.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:47248697.1 %
Date:2024-10-17 16:45:00Functions: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 %95 / 9766.7 %2 / 3
ParabetaRMSD.cpp +
98.5%98.5%
+
98.5 %132 / 13466.7 %2 / 3
SecondaryStructureRMSD.cpp +
94.7%94.7%
+
94.7 %180 / 19090.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 000000000..92bacda87 --- /dev/null +++ b/coverage/setup/Load.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ebcff0cf2 --- /dev/null +++ b/coverage/setup/Load.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ec348552e --- /dev/null +++ b/coverage/setup/Load.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a8513450d --- /dev/null +++ b/coverage/setup/Restart.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6353cf339 --- /dev/null +++ b/coverage/setup/Restart.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fe0d6478b --- /dev/null +++ b/coverage/setup/Restart.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + LCOV - plumed test coverage - setup/Restart.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Restart.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..699c977ec --- /dev/null +++ b/coverage/setup/Units.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE34
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE36
+
+
+ + + +
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 000000000..b6d30120e --- /dev/null +++ b/coverage/setup/Units.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE34
_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 000000000..ada1918d0 --- /dev/null +++ b/coverage/setup/Units.cpp.gcov.html @@ -0,0 +1,274 @@ + + + + + + + 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-10-17 16:45:00Functions: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          36 : void Units::registerKeywords( Keywords& keys ) {
+     100          36 :   ActionSetup::registerKeywords(keys);
+     101          72 :   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          72 :   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          72 :   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          72 :   keys.add("optional","MASS","the units of masses.  Specify a conversion factor from the default, amu");
+     105          72 :   keys.add("optional","CHARGE","the units of charges.  Specify a conversion factor from the default, e");
+     106          72 :   keys.addFlag("NATURAL",false,"use natural units");
+     107          36 : }
+     108             : 
+     109          34 : Units::Units(const ActionOptions&ao):
+     110             :   Action(ao),
+     111          34 :   ActionSetup(ao)
+     112             : {
+     113          34 :   PLMD::Units u;
+     114             : 
+     115             :   std::string s;
+     116             : 
+     117             :   s="";
+     118          68 :   parse("LENGTH",s);
+     119          34 :   if(s.length()>0) u.setLength(s);
+     120          66 :   if(u.getLengthString().length()>0 && u.getLengthString()=="nm") {
+     121           8 :     log.printf("  length: %s\n",u.getLengthString().c_str());
+     122             :   }
+     123          50 :   else if(u.getLengthString().length()>0 && u.getLengthString()!="nm") {
+     124          24 :     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          68 :   parse("ENERGY",s);
+     132          34 :   if(s.length()>0) u.setEnergy(s);
+     133          66 :   if(u.getEnergyString().length()>0 && u.getEnergyString()=="kj/mol") {
+     134          21 :     log.printf("  energy: %s\n",u.getEnergyString().c_str());
+     135             :   }
+     136          24 :   else if(u.getEnergyString().length()>0 && u.getEnergyString()!="kj/mol") {
+     137          11 :     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          68 :   parse("TIME",s);
+     145          34 :   if(s.length()>0) u.setTime(s);
+     146          66 :   if(u.getTimeString().length()>0 && u.getTimeString()=="ps") {
+     147          29 :     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          68 :   parse("CHARGE",s);
+     158          34 :   if(s.length()>0) u.setCharge(s);
+     159          66 :   if(u.getChargeString().length()>0 && u.getChargeString()=="e") {
+     160          32 :     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          68 :   parse("MASS",s);
+     171          34 :   if(s.length()>0) u.setMass(s);
+     172          67 :   if(u.getMassString().length()>0 && u.getMassString()=="amu") {
+     173          33 :     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          34 :   bool natural=false;
+     183          34 :   parseFlag("NATURAL",natural);
+     184             : 
+     185          34 :   checkRead();
+     186             : 
+     187          34 :   if(natural) {
+     188           6 :     log.printf("  using natural units\n");
+     189             :   } else {
+     190          28 :     log.printf("  using physical units\n");
+     191             :   }
+     192          34 :   log.printf("  inside PLUMED, Boltzmann constant is %g\n",getKBoltzmann());
+     193             : 
+     194          34 :   plumed.setUnits(natural,u);
+     195          34 : }
+     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 000000000..25f8219bb --- /dev/null +++ b/coverage/setup/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-10-17 16:45:00Functions: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
Units.cpp +
96.4%96.4%
+
96.4 %54 / 5666.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-sort-l.html b/coverage/setup/index-sort-l.html new file mode 100644 index 000000000..c2d986c93 --- /dev/null +++ b/coverage/setup/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..283d80ecc --- /dev/null +++ b/coverage/setup/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-10-17 16:45:00Functions: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/sizeshape/index-sort-f.html b/coverage/sizeshape/index-sort-f.html new file mode 100644 index 000000000..506287c10 --- /dev/null +++ b/coverage/sizeshape/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sizeshape + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshapeHitTotalCoverage
Test:plumed test coverageLines:29530596.7 %
Date:2024-10-17 16:45:00Functions:161984.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
mahadist.cpp +
94.1%94.1%
+
94.1 %143 / 15280.0 %8 / 10
pos_proj.cpp +
99.3%99.3%
+
99.3 %152 / 15388.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/index-sort-l.html b/coverage/sizeshape/index-sort-l.html new file mode 100644 index 000000000..6643eba76 --- /dev/null +++ b/coverage/sizeshape/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sizeshape + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshapeHitTotalCoverage
Test:plumed test coverageLines:29530596.7 %
Date:2024-10-17 16:45:00Functions:161984.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
mahadist.cpp +
94.1%94.1%
+
94.1 %143 / 15280.0 %8 / 10
pos_proj.cpp +
99.3%99.3%
+
99.3 %152 / 15388.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/index.html b/coverage/sizeshape/index.html new file mode 100644 index 000000000..bdd65e0e3 --- /dev/null +++ b/coverage/sizeshape/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sizeshape + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshapeHitTotalCoverage
Test:plumed test coverageLines:29530596.7 %
Date:2024-10-17 16:45:00Functions:161984.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
mahadist.cpp +
94.1%94.1%
+
94.1 %143 / 15280.0 %8 / 10
pos_proj.cpp +
99.3%99.3%
+
99.3 %152 / 15388.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/mahadist.cpp.func-sort-c.html b/coverage/sizeshape/mahadist.cpp.func-sort-c.html new file mode 100644 index 000000000..67cabfa13 --- /dev/null +++ b/coverage/sizeshape/mahadist.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - sizeshape/mahadist.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshape - mahadist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14315294.1 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9sizeshape18position_maha_dist12numeric_mahaEv0
_ZN4PLMD9sizeshape18position_maha_distC2ERKNS_13ActionOptionsE0
_ZN4PLMD9sizeshape18position_maha_dist10readinputsEv1
_ZN4PLMD9sizeshape18position_maha_distC1ERKNS_13ActionOptionsE1
_ZN4PLMD9sizeshape18position_maha_dist16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9sizeshape18position_maha_dist13cal_maha_distEv5
_ZN4PLMD9sizeshape18position_maha_dist14kabsch_rot_matEv5
_ZN4PLMD9sizeshape18position_maha_dist9calculateEv5
_ZN4PLMD9sizeshape18position_maha_dist9grad_mahaEd5
_ZN4PLMD9sizeshape18position_maha_dist11determinantEiPKSt6vectorIS2_IdSaIdEESaIS4_EE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/mahadist.cpp.func.html b/coverage/sizeshape/mahadist.cpp.func.html new file mode 100644 index 000000000..de34b0df1 --- /dev/null +++ b/coverage/sizeshape/mahadist.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - sizeshape/mahadist.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshape - mahadist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14315294.1 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9sizeshape18position_maha_dist10readinputsEv1
_ZN4PLMD9sizeshape18position_maha_dist11determinantEiPKSt6vectorIS2_IdSaIdEESaIS4_EE10
_ZN4PLMD9sizeshape18position_maha_dist12numeric_mahaEv0
_ZN4PLMD9sizeshape18position_maha_dist13cal_maha_distEv5
_ZN4PLMD9sizeshape18position_maha_dist14kabsch_rot_matEv5
_ZN4PLMD9sizeshape18position_maha_dist16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9sizeshape18position_maha_dist9calculateEv5
_ZN4PLMD9sizeshape18position_maha_dist9grad_mahaEd5
_ZN4PLMD9sizeshape18position_maha_distC1ERKNS_13ActionOptionsE1
_ZN4PLMD9sizeshape18position_maha_distC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/mahadist.cpp.gcov.html b/coverage/sizeshape/mahadist.cpp.gcov.html new file mode 100644 index 000000000..48f9d4032 --- /dev/null +++ b/coverage/sizeshape/mahadist.cpp.gcov.html @@ -0,0 +1,525 @@ + + + + + + + LCOV - plumed test coverage - sizeshape/mahadist.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshape - mahadist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14315294.1 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2024 by Glen Hocky, New York University on behalf of authors
+       3             : 
+       4             : The sizeshape 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 sizeshape 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 "tools/Pbc.h"
+      20             : #include "tools/File.h"           // Input and output from files 
+      21             : #include "tools/Matrix.h"         // Linear Algebra operations
+      22             : #include <sstream>
+      23             : #include <cmath>
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace sizeshape {
+      27             : 
+      28             : //+PLUMEDOC sizeshapeMOD_COLVAR SIZESHAPE_POSITION_MAHA_DIST
+      29             : /*
+      30             : Calculates Mahalanobis distance of a current configuration from a  given reference configurational distribution in size-and-shape space.
+      31             : 
+      32             : The Mahalanobis distance is given as:
+      33             : 
+      34             : \f[
+      35             : d(\mathbf{x}, \mathbf{\mu}, \mathbf{\Sigma}) = \sqrt{(\mathbf{x}-\mathbf{\mu})^T \mathbf{\Sigma}^{-1} (\mathbf{x}-\mathbf{\mu})}
+      36             : \f]
+      37             : 
+      38             : Here \f$\mathbf{x}\f$ is the configuration at time t, \f$\mathbf{\mu}\f$ is the reference and \f$\mathbf{\Sigma}^{-1}\f$ is the \f$N \times N\f$ precision matrix.
+      39             : 
+      40             : Size-and-shape Gaussian Mixture Model (shapeGMM) \cite Heidi-shapeGMM-2022 is a probabilistic clustering technique that is used to perform structural clusteing on ensemble of molecular configurations and to obtain reference \f$(\mathbf{\mu})\f$ and precision \f$(\mathbf{\Sigma}^{-1})\f$ corresponding to each of the cluster centers. Please chcek out <a href="https://github.com/mccullaghlab/shapeGMMTorch">shapeGMMTorch-GitHub</a> and <a href="https://pypi.org/project/shapeGMMTorch/"> shapeGMMTorch-PyPI</a> for examples and informations on preforming shapeGMM clustering.
+      41             : 
+      42             : \par Examples
+      43             : In the following example, a group is defined with atom indices of selected atoms and then Mahalanobis distance is calculated with respect to the given reference and precision. Each file is a space separated list of 3N floating point numbers.
+      44             : 
+      45             : \plumedfile
+      46             : UNITS LENGTH=A TIME=ps ENERGY=kcal/mol
+      47             : GROUP ATOMS=18,20,22,31,33,35,44,46,48,57,59,61,70,72,74,83,85,87,96,98,100,109,111 LABEL=ga_list
+      48             : #SETTINGS AUXFILE=regtest/sizeshape/rt-mahadist/global_avg.txt
+      49             : #SETTINGS AUXFILE=regtest/sizeshape/rt-mahadist/global_precision.txt
+      50             : d: SIZESHAPE_POSITION_MAHA_DIST REFERENCE=global_avg.txt PRECISION=global_precision.txt GROUP=ga_list
+      51             : PRINT ARG=d STRIDE=1 FILE=output FMT=%8.8f
+      52             : \endplumedfile
+      53             : 
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : class position_maha_dist : public Colvar {
+      58             : 
+      59             : private:
+      60             :   bool pbc, squared;
+      61             :   std::string prec_f_name;                      // precision file name
+      62             :   std::string ref_f_name;                       // reference file name
+      63             :   IFile in_;                                    // create an object of class IFile
+      64             :   //Log out_;
+      65             :   Matrix<double> ref_str;                 // coords of reference
+      66             :   Matrix<double> mobile_str;              // coords of mobile
+      67             :   Matrix<double> prec;                            // precision data
+      68             :   Matrix<double> rotation;
+      69             :   Matrix<double> derv_;
+      70             :   Matrix<double> derv_numeric;
+      71             :   void readinputs();                            // reads the input data
+      72             :   double dist;
+      73             :   std::vector<AtomNumber> atom_list;            // list of atoms
+      74             :   const double SMALL = 1.0E-30;
+      75             :   const double delta = 0.00001;
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit position_maha_dist(const ActionOptions&);
+      79             :   double determinant(int n, const std::vector<std::vector<double>>* B);
+      80             :   void kabsch_rot_mat();                // gives rotation matrix
+      81             :   double cal_maha_dist();               // calculates the mahalanobis distance
+      82             :   void grad_maha(double);               // calculates the gradient
+      83             :   void numeric_maha();                  // calculates the numeric gradient
+      84             :   // active methods:
+      85             :   void calculate() override;
+      86             : };
+      87             : 
+      88             : PLUMED_REGISTER_ACTION(position_maha_dist,"SIZESHAPE_POSITION_MAHA_DIST")
+      89             : 
+      90           3 : void position_maha_dist::registerKeywords( Keywords& keys ) {
+      91           3 :   Colvar::registerKeywords( keys );
+      92           6 :   keys.add("compulsory", "PRECISION", "Precision Matrix (inverse of covariance)" );
+      93           6 :   keys.add("compulsory", "REFERENCE", "Reference structure.");
+      94           6 :   keys.add("atoms","GROUP","The group of atoms being used");
+      95           6 :   keys.addFlag("SQUARED",false,"Returns the square of distance.");
+      96           3 :   keys.setValueDescription("the Mahalanobis distance between the instantaneous configuration and a given reference distribution in size-and-shape space");
+      97           3 : }
+      98             : 
+      99             : // constructor function
+     100           1 : position_maha_dist::position_maha_dist(const ActionOptions&ao):
+     101             :   PLUMED_COLVAR_INIT(ao),
+     102           1 :   pbc(true),
+     103           1 :   squared(false),
+     104           1 :   dist(0),
+     105           2 :   prec_f_name(""),
+     106           2 :   ref_f_name("")    // Note! no comma here in the last line.
+     107             : {
+     108           1 :   parseAtomList("GROUP",atom_list);
+     109           1 :   parse("REFERENCE", ref_f_name);
+     110           1 :   parse("PRECISION", prec_f_name);
+     111             : 
+     112           1 :   bool nopbc=!pbc;
+     113           1 :   parseFlag("NOPBC",nopbc);
+     114           1 :   parseFlag("SQUARED",squared);
+     115           1 :   pbc=!nopbc;
+     116             : 
+     117           1 :   checkRead();
+     118             : 
+     119           1 :   log.printf("  of %u atoms\n",static_cast<unsigned>(atom_list.size()));
+     120          24 :   for(unsigned int i=0; i<atom_list.size(); ++i) {
+     121          23 :     log.printf("  %d", atom_list[i].serial());
+     122             :   }
+     123             : 
+     124           1 :   if(squared)log.printf("\n chosen to use SQUARED option for SIZESHAPE_POSITION_MAHA_DIST\n");
+     125             : 
+     126           1 :   if(pbc) log.printf("\n using periodic boundary conditions\n");
+     127           0 :   else log.printf("\n without periodic boundary conditions\n");
+     128             : 
+     129           2 :   addValueWithDerivatives(); setNotPeriodic();
+     130             : 
+     131           1 :   requestAtoms(atom_list);
+     132             : 
+     133             :   // call the readinputs() function here
+     134           1 :   readinputs();
+     135             : 
+     136           1 : }
+     137             : 
+     138             : // read inputs function
+     139           1 : void position_maha_dist::readinputs()
+     140             : {
+     141             :   unsigned N=getNumberOfAtoms();
+     142             :   // read ref coords
+     143           1 :   in_.open(ref_f_name);
+     144             : 
+     145             :   ref_str.resize(N,3); prec.resize(N,N);
+     146             : 
+     147             :   std::string line_, val_;
+     148             :   unsigned c_=0;
+     149             : 
+     150          24 :   while (c_ < N)
+     151             :   {
+     152          23 :     in_.getline(line_);
+     153             :     std::vector<std::string> items_;
+     154          23 :     std::stringstream check_(line_);
+     155             : 
+     156          92 :     while(std::getline(check_, val_, ' ')) { items_.push_back(val_); }
+     157          92 :     for(int i=0; i<3; ++i) { ref_str(c_,i) = std::stold(items_[i]); }
+     158          23 :     c_ += 1;
+     159          23 :   }
+     160           1 :   in_.close();
+     161             : 
+     162             :   //read precision
+     163           1 :   in_.open(prec_f_name);
+     164             : 
+     165             :   std::string line, val;
+     166             :   unsigned int c = 0;
+     167             : 
+     168          24 :   while(c < N)
+     169             :   {
+     170          23 :     in_.getline(line);
+     171             : 
+     172             :     // vector for storing the objects
+     173             :     std::vector<std::string> items;
+     174             : 
+     175             :     // stringstream helps to treat a string like an ifstream!
+     176          23 :     std::stringstream check(line);
+     177             : 
+     178         552 :     while (std::getline(check, val, ' '))
+     179             :     {
+     180         529 :       items.push_back(val);
+     181             :     }
+     182             : 
+     183         552 :     for(unsigned int i=0; i<N; ++i)
+     184             :     {
+     185         529 :       prec(c, i) = std::stold(items[i]);
+     186             :     }
+     187             : 
+     188          23 :     c += 1;
+     189             : 
+     190          23 :   }
+     191           1 :   in_.close();
+     192           1 : }
+     193             : 
+     194             : 
+     195          10 : double position_maha_dist::determinant(int n, const std::vector<std::vector<double>>* B)
+     196             : {
+     197             : 
+     198          10 :   std::vector<std::vector<double>> A(n, std::vector<double>(n, 0));
+     199             :   // make a copy first!
+     200          40 :   for(int i=0; i<n; ++i) {
+     201         120 :     for(int j=0; j<n; ++j) {A[i][j] = (*B)[i][j];}
+     202             :   }
+     203             : 
+     204             : 
+     205             :   //  It calculates determinant of a matrix using partial pivoting.
+     206             : 
+     207             :   double det = 1;
+     208             : 
+     209             :   // Row operations for i = 0, ,,,, n - 2 (n-1 not needed)
+     210          30 :   for ( int i = 0; i < n - 1; i++ )
+     211             :   {
+     212             :     // Partial pivot: find row r below with largest element in column i
+     213             :     int r = i;
+     214          20 :     double maxA = std::abs( A[i][i] );
+     215          50 :     for ( int k = i + 1; k < n; k++ )
+     216             :     {
+     217          30 :       double val = std::abs( A[k][i] );
+     218          30 :       if ( val > maxA )
+     219             :       {
+     220             :         r = k;
+     221             :         maxA = val;
+     222             :       }
+     223             :     }
+     224          20 :     if ( r != i )
+     225             :     {
+     226          70 :       for ( int j = i; j < n; j++ ) std::swap( A[i][j], A[r][j] );
+     227          20 :       det = -det;
+     228             :     }
+     229             : 
+     230             :     // Row operations to make upper-triangular
+     231          20 :     double pivot = A[i][i];
+     232          20 :     if (std::abs( pivot ) < SMALL ) return 0.0;              // Singular matrix
+     233             : 
+     234          50 :     for ( int r = i + 1; r < n; r++ )                    // On lower rows
+     235             :     {
+     236          30 :       double multiple = A[r][i] / pivot;                // Multiple of row i to clear element in ith column
+     237         110 :       for ( int j = i; j < n; j++ ) A[r][j] -= multiple * A[i][j];
+     238             :     }
+     239          20 :     det *= pivot;                                        // Determinant is product of diagonal
+     240             :   }
+     241             : 
+     242          10 :   det *= A[n-1][n-1];
+     243             : 
+     244          10 :   return det;
+     245          10 : }
+     246             : 
+     247             : // kabsch rotation
+     248           5 : void position_maha_dist::kabsch_rot_mat() {
+     249             : 
+     250             :   unsigned N=getNumberOfAtoms();
+     251             : 
+     252             :   Matrix<double> mobile_str_T(3,N);
+     253             :   Matrix<double> prec_dot_ref_str(N,3);
+     254             :   Matrix<double> correlation(3,3);
+     255             : 
+     256             : 
+     257           5 :   transpose(mobile_str, mobile_str_T);
+     258           5 :   mult(prec, ref_str, prec_dot_ref_str);
+     259           5 :   mult(mobile_str_T, prec_dot_ref_str, correlation);
+     260             : 
+     261             : 
+     262           5 :   int rw = correlation.nrows();
+     263           5 :   int cl = correlation.ncols();
+     264           5 :   int sz = rw*cl;
+     265             : 
+     266             :   // SVD part (taking from plu2/src/tools/Matrix.h: pseudoInvert function)
+     267             : 
+     268           5 :   std::vector<double> da(sz);
+     269             :   unsigned k=0;
+     270             : 
+     271             :   // Transfer the matrix to the local array
+     272          65 :   for (int i=0; i<cl; ++i) for (int j=0; j<rw; ++j) da[k++]=static_cast<double>( correlation(j,i) ); // note! its [j][i] not [i][j]
+     273             : 
+     274           5 :   int nsv, info, nrows=rw, ncols=cl;
+     275             :   if(rw>cl) {nsv=cl;} else {nsv=rw;}
+     276             : 
+     277             :   // Create some containers for stuff from single value decomposition
+     278           5 :   std::vector<double> S(nsv);
+     279           5 :   std::vector<double> U(nrows*nrows);
+     280           5 :   std::vector<double> VT(ncols*ncols);
+     281           5 :   std::vector<int> iwork(8*nsv);
+     282             : 
+     283             :   // This optimizes the size of the work array used in lapack singular value decomposition
+     284           5 :   int lwork=-1;
+     285           5 :   std::vector<double> work(1);
+     286           5 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     287             :   //if(info!=0) return info;
+     288           5 :   if(info!=0) log.printf("info:", info);
+     289             : 
+     290             :   // Retrieve correct sizes for work and rellocate
+     291           5 :   lwork=(int) work[0]; work.resize(lwork);
+     292             : 
+     293             :   // This does the singular value decomposition
+     294           5 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     295             :   //if(info!=0) return info;
+     296           5 :   if(info!=0) log.printf("info:", info);
+     297             : 
+     298             : 
+     299             :   // get U and VT in form of 2D vector (U_, VT_)
+     300           5 :   std::vector<std::vector<double>> U_(nrows, std::vector<double>(nrows,0));
+     301           5 :   std::vector<std::vector<double>> VT_(ncols, std::vector<double>(ncols,0));
+     302             : 
+     303             :   int  c=0;
+     304             : 
+     305          65 :   for(int i=0; i<nrows; ++i) { for(int j=0; j<nrows; ++j) { U_[j][i] = U[c]; c += 1;} } c = 0; // note! its [j][i] not [i][j]
+     306          65 :   for(int i=0; i<ncols; ++i) { for(int j=0; j<ncols; ++j) { VT_[j][i] = VT[c]; c += 1;} } c=0; // note! its [j][i] not [i][j]
+     307             : 
+     308             : 
+     309             :   // calculate determinants
+     310           5 :   double det_u = determinant(nrows, &U_);
+     311           5 :   double det_vt = determinant(ncols, &VT_);
+     312             : 
+     313             :   // check!
+     314          13 :   if (det_u * det_vt < 0.0) { for(int i=0; i<nrows; ++i) {U_[i][nrows-1] *= -1;} }
+     315             : 
+     316             : 
+     317             :   //Matrix<double> rotation(3,3);
+     318           5 :   rotation.resize(3,3);
+     319             :   Matrix<double> u(3,3), vt(3,3);
+     320          65 :   for(int i=0; i<3; ++i) { for(int j=0; j<3; ++j) { u(i,j)=U_[i][j]; vt(i,j)=VT_[i][j]; } }
+     321             : 
+     322             :   // get rotation matrix
+     323           5 :   mult(u, vt, rotation);
+     324             : 
+     325          10 : }
+     326             : 
+     327             : 
+     328             : // calculates maha dist
+     329           5 : double position_maha_dist::cal_maha_dist() {
+     330             : 
+     331             :   unsigned N=getNumberOfAtoms();
+     332             : 
+     333             :   Matrix<double> rotated_obj(N,3);
+     334             :   // rotate the object
+     335           5 :   mult(mobile_str, rotation, rotated_obj);
+     336             : 
+     337             :   // compute the displacement
+     338             :   Matrix<double> disp(N,3);
+     339         465 :   for(unsigned int i=0; i<N; ++i) { for(unsigned int j=0; j<3; ++j) { disp(i,j) = (rotated_obj(i,j)-ref_str(i,j)); } }
+     340             : 
+     341             :   Matrix<double> prec_dot_disp(N,3);
+     342             :   Matrix<double> disp_T(3,N);
+     343             :   Matrix<double> out(3,3);
+     344             : 
+     345           5 :   mult(prec, disp, prec_dot_disp);
+     346           5 :   transpose(disp, disp_T);
+     347           5 :   mult(disp_T, prec_dot_disp, out);
+     348             : 
+     349             : 
+     350             : 
+     351             :   double maha_d=0.0;
+     352          20 :   for(int i=0; i<3; ++i) { maha_d += out(i,i);}
+     353             : 
+     354           5 :   if (!squared) maha_d = std::sqrt(maha_d);
+     355             : 
+     356           5 :   return maha_d;
+     357             : }
+     358             : 
+     359             : // gradient function
+     360           5 : void position_maha_dist::grad_maha(double d) {
+     361             : 
+     362             :   unsigned N=getNumberOfAtoms();
+     363             : 
+     364           5 :   derv_.resize(N,3);
+     365             : 
+     366             :   Matrix<double> ref_str_rot_T(N,3);
+     367             :   Matrix<double> rot_T(3,3);
+     368             :   Matrix<double> diff_(N,3);
+     369             : 
+     370           5 :   transpose(rotation, rot_T);
+     371           5 :   mult(ref_str, rot_T, ref_str_rot_T);
+     372             : 
+     373         465 :   for(unsigned i=0; i<N; ++i) { for(unsigned j=0; j<3; ++j) { diff_(i,j) = mobile_str(i,j) - ref_str_rot_T(i,j); } }
+     374             : 
+     375           5 :   mult(prec, diff_, derv_);
+     376             : 
+     377             :   //for(unsigned i=0; i<N; ++i){ for(unsigned j=0; j<3; ++j) {derv_(i,j) /= (N*d);} }  // dividing by N here!
+     378         465 :   for(unsigned i=0; i<N; ++i) { for(unsigned j=0; j<3; ++j) { if (!squared) {derv_(i,j) /= d;} else {derv_(i,j) *= 2.0;}}}
+     379             : 
+     380             : 
+     381           5 : }
+     382             : 
+     383             : 
+     384             : // numeric gradient
+     385           0 : void position_maha_dist::numeric_maha() {
+     386             :   // This function performs numerical derivative.
+     387             :   unsigned N=getNumberOfAtoms();
+     388             :   derv_numeric.resize(N,3);
+     389             : 
+     390           0 :   for(unsigned int atom=0; atom<N; ++atom) {
+     391           0 :     for(unsigned int j=0; j<3; ++j) {
+     392           0 :       mobile_str(atom,j) += delta;
+     393           0 :       kabsch_rot_mat();
+     394           0 :       derv_numeric(atom,j) = (cal_maha_dist() - dist)/delta;
+     395           0 :       mobile_str(atom,j) -= delta;
+     396             :     }
+     397             :   }
+     398             : 
+     399           0 : }
+     400             : 
+     401             : 
+     402             : // calculator
+     403           5 : void position_maha_dist::calculate() {
+     404             : 
+     405           5 :   if(pbc) makeWhole();
+     406             :   unsigned N=getNumberOfAtoms();
+     407             : 
+     408             :   mobile_str.resize(N,3);
+     409             : 
+     410             :   // load the mobile str
+     411         120 :   for(unsigned int i=0; i<N; ++i) {
+     412         115 :     Vector pos=getPosition(i);  // const PLMD::Vector
+     413         460 :     for(unsigned j=0; j<3; ++j) {
+     414         345 :       mobile_str(i,j) = pos[j];
+     415             :     }
+     416             :   }
+     417             : 
+     418             :   // translating the structure to center of geometry
+     419           5 :   double center_of_geometry[3]= {0.0, 0.0, 0.0};
+     420             : 
+     421         120 :   for(unsigned int i=0; i<N; ++i)
+     422             :   {
+     423         115 :     center_of_geometry[0] += mobile_str(i,0); center_of_geometry[1] += mobile_str(i,1); center_of_geometry[2] += mobile_str(i,2);
+     424             :   }
+     425             : 
+     426         120 :   for(unsigned int i=0; i<N; ++i)
+     427             :   {
+     428         460 :     for(unsigned int j=0; j<3; ++j) { mobile_str(i,j) -= (center_of_geometry[j]/N); }
+     429             :   }
+     430             : 
+     431           5 :   kabsch_rot_mat();
+     432           5 :   dist = cal_maha_dist();
+     433             : 
+     434           5 :   grad_maha(dist);
+     435             :   // set derivatives
+     436         120 :   for(unsigned i=0; i<N; ++i) {
+     437         115 :     Vector vi(derv_(i,0), derv_(i,1), derv_(i,2) );
+     438         115 :     setAtomsDerivatives(i, vi);
+     439             :   }
+     440           5 :   setBoxDerivativesNoPbc();
+     441           5 :   setValue(dist);
+     442             : 
+     443           5 : }
+     444             : 
+     445             : }
+     446             : }
+     447             : 
+     448             : 
+     449             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/pos_proj.cpp.func-sort-c.html b/coverage/sizeshape/pos_proj.cpp.func-sort-c.html new file mode 100644 index 000000000..50425ac7e --- /dev/null +++ b/coverage/sizeshape/pos_proj.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - sizeshape/pos_proj.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshape - pos_proj.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9sizeshape20position_linear_projC2ERKNS_13ActionOptionsE0
_ZN4PLMD9sizeshape20position_linear_proj10readinputsEv5
_ZN4PLMD9sizeshape20position_linear_projC1ERKNS_13ActionOptionsE5
_ZN4PLMD9sizeshape20position_linear_proj16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD9sizeshape20position_linear_proj12numeric_gradEv25
_ZN4PLMD9sizeshape20position_linear_proj9calculateEv25
_ZN4PLMD9sizeshape20position_linear_proj14kabsch_rot_matEv715
_ZN4PLMD9sizeshape20position_linear_proj24cal_position_linear_projEv715
_ZN4PLMD9sizeshape20position_linear_proj11determinantEiPKSt6vectorIS2_IdSaIdEESaIS4_EE1430
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/pos_proj.cpp.func.html b/coverage/sizeshape/pos_proj.cpp.func.html new file mode 100644 index 000000000..849927ac1 --- /dev/null +++ b/coverage/sizeshape/pos_proj.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - sizeshape/pos_proj.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshape - pos_proj.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9sizeshape20position_linear_proj10readinputsEv5
_ZN4PLMD9sizeshape20position_linear_proj11determinantEiPKSt6vectorIS2_IdSaIdEESaIS4_EE1430
_ZN4PLMD9sizeshape20position_linear_proj12numeric_gradEv25
_ZN4PLMD9sizeshape20position_linear_proj14kabsch_rot_matEv715
_ZN4PLMD9sizeshape20position_linear_proj16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD9sizeshape20position_linear_proj24cal_position_linear_projEv715
_ZN4PLMD9sizeshape20position_linear_proj9calculateEv25
_ZN4PLMD9sizeshape20position_linear_projC1ERKNS_13ActionOptionsE5
_ZN4PLMD9sizeshape20position_linear_projC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sizeshape/pos_proj.cpp.gcov.html b/coverage/sizeshape/pos_proj.cpp.gcov.html new file mode 100644 index 000000000..f07b175ee --- /dev/null +++ b/coverage/sizeshape/pos_proj.cpp.gcov.html @@ -0,0 +1,535 @@ + + + + + + + LCOV - plumed test coverage - sizeshape/pos_proj.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sizeshape - pos_proj.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2024 by Glen Hocky, New York University on behalf of authors
+       3             : 
+       4             : The sizeshape 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 sizeshape 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 "tools/Pbc.h"
+      20             : #include "tools/File.h"           // Input and output from files 
+      21             : #include "tools/Matrix.h"         // Linear Algebra operations
+      22             : #include <sstream>
+      23             : #include <cmath>
+      24             : #include "tools/Communicator.h"   // All the MPI related stuffs
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace sizeshape {
+      28             : 
+      29             : //+PLUMEDOC sizeshapeMOD_COLVAR SIZESHAPE_POSITION_LINEAR_PROJ
+      30             : /*
+      31             : Calculates a linear projection in the space of a given reference configurational distribution in size-and-shape space.
+      32             : 
+      33             : This method is described in \cite Sasmal-poslda-2023.
+      34             : 
+      35             : The linear projection is given by:
+      36             : \f[
+      37             :     l(\mathbf{x}) = \mathbf{v}\cdot(\mathbf{R}\cdot(\mathbf{x}(t) - \vec{{\zeta}}(t)) - \mathbf{\mu}),
+      38             : \f]
+      39             : Where \f$\mathbf{v}\f$ is a vector of linear coefficients, \f$\mathbf{x}(t)\f$ is the configuration at time t, \f$\vec{\zeta}(t)\f$ is the difference in the geometric mean of the current configuration and that of the reference configuration \f$\mathbf{\mu}\f$. \f$\vec{\zeta}(t) = \frac{1}{N} \sum_{i=1}^N \vec{x_{i}}(t) - \frac{1}{N} \sum_{i=1}^N \vec{\mu_{i}}(t)\f$, for N atoms.
+      40             : 
+      41             : \f$\mathbf{R}\f$ is an optimal rotation matrix that minimizes the Mahalanobis distance between the current configuration and reference. \f$\mathbf{R}\f$ is obtained by using Kabsch algorithm within the code. The Mahalanobis distance is given as:
+      42             : 
+      43             : \f[
+      44             : d(\mathbf{x}, \mathbf{\mu}, \mathbf{\Sigma}) = \sqrt{(\mathbf{x}-\mathbf{\mu})^T \mathbf{\Sigma}^{-1} (\mathbf{x}-\mathbf{\mu})}
+      45             : \f]
+      46             : 
+      47             : where, \f$\mathbf{\Sigma}^{-1}\f$ is the \f$N\times N\f$ precision matrix. See also \ref POSITION_MAHA_DIST for information about calculating Mahalanobis distance in size-and-shape space.
+      48             : 
+      49             : Size-and-shape Gaussian Mixture Model (shapeGMM) \cite Heidi-shapeGMM-2022 is a probabilistic clustering technique that is used to perform structural clusteing on ensemble of molecular configurations and to obtain reference \f$(\mathbf{\mu})\f$ and precision \f$(\mathbf{\Sigma}^{-1})\f$ corresponding to each of the cluster centers. Please chcek out <a href="https://github.com/mccullaghlab/shapeGMMTorch">shapeGMMTorch-GitHub</a> and <a href="https://pypi.org/project/shapeGMMTorch/"> shapeGMMTorch-PyPI</a> for examples and informations on preforming shapeGMM clustering.
+      50             : 
+      51             : \par Examples
+      52             : In the following example, a group is defined with atom indices of selected atoms and then linear projection is calculated for the given reference, precision and coefficients. Each file is a space separated list of 3N floating point numbers.
+      53             : 
+      54             : \plumedfile
+      55             : UNITS LENGTH=A TIME=ps ENERGY=kcal/mol
+      56             : GROUP ATOMS=18,20,22,31,33,35,44,46,48,57,59,61,70,72,74,83,85,87,96,98,100,109,111 LABEL=ga_list
+      57             : #SETTINGS AUXFILE=regtest/sizeshape/rt-sizeshape/global_avg.txt
+      58             : #SETTINGS AUXFILE=regtest/sizeshape/rt-sizeshape/global_precision.txt
+      59             : #SETTINGS AUXFILE=regtest/sizeshape/rt-sizeshape/ld1_scalings.txt
+      60             : proj: SIZESHAPE_POSITION_LINEAR_PROJ REFERENCE=global_avg.txt PRECISION=global_precision.txt COEFFS=ld1_scalings.txt GROUP=ga_list
+      61             : PRINT ARG=proj STRIDE=1 FILE=COLVAR FMT=%8.8f
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : 
+      68             : class position_linear_proj : public Colvar {
+      69             : 
+      70             : private:
+      71             :   bool pbc, serial;
+      72             :   std::string prec_f_name;                      // precision file name
+      73             :   std::string ref_f_name;                       // reference file name
+      74             :   std::string coeffs_f_name;                    // file containing linear coeffs
+      75             :   IFile in_;                                    // create an object of class IFile
+      76             :   Log out_;
+      77             :   Matrix<double> ref_str;                 // coords of reference
+      78             :   Matrix<double> mobile_str;              // coords of mobile
+      79             :   Matrix<double> prec;                            // precision data
+      80             :   Matrix<double> rotation;
+      81             :   std::vector<double> linear_coeffs;            // Linear Coefficients
+      82             :   Matrix<double> derv_numeric;
+      83             :   void readinputs();                            // reads the input data
+      84             :   double proj;                                  // projection value
+      85             :   std::vector<AtomNumber> atom_list;            // list of atoms
+      86             :   const double SMALL = 1.0E-30;
+      87             :   const double delta = 0.00001;
+      88             : public:
+      89             :   static void registerKeywords( Keywords& keys );
+      90             :   explicit position_linear_proj(const ActionOptions&);
+      91             :   double determinant(int n, const std::vector<std::vector<double>>* B);
+      92             :   void kabsch_rot_mat();                // gives rotation matrix
+      93             :   double cal_position_linear_proj();    // calculates the linear projection
+      94             :   void numeric_grad();                  // calculates the numeric gradient
+      95             :   // active methods:
+      96             :   void calculate() override;
+      97             : };
+      98             : 
+      99             : PLUMED_REGISTER_ACTION(position_linear_proj, "SIZESHAPE_POSITION_LINEAR_PROJ")
+     100             : 
+     101             : // register keywords function
+     102           7 : void position_linear_proj::registerKeywords( Keywords& keys ) {
+     103           7 :   Colvar::registerKeywords( keys );
+     104          14 :   keys.add("compulsory", "PRECISION", "Precision Matrix (inverse of covariance)." );
+     105          14 :   keys.add("compulsory", "REFERENCE", "Coordinates of the reference structure.");
+     106          14 :   keys.add("atoms","GROUP","Group of atoms being used");
+     107          14 :   keys.add("compulsory", "COEFFS", "Vector of linear coefficients.");
+     108          14 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial, for debug purposes only.");
+     109           7 :   keys.setValueDescription("the linear projection");
+     110           7 : }
+     111             : 
+     112             : // constructor function
+     113           5 : position_linear_proj::position_linear_proj(const ActionOptions&ao):
+     114             :   PLUMED_COLVAR_INIT(ao),
+     115           5 :   pbc(true),
+     116           5 :   serial(false),
+     117           5 :   proj(0),
+     118          10 :   prec_f_name(""),
+     119           5 :   ref_f_name(""),
+     120          15 :   coeffs_f_name("")   // Note! no comma here in the last line.
+     121             : {
+     122           5 :   parseFlag("SERIAL",serial);
+     123           5 :   parseAtomList("GROUP",atom_list);
+     124           5 :   parse("REFERENCE", ref_f_name);
+     125           5 :   parse("PRECISION", prec_f_name);
+     126           5 :   parse("COEFFS", coeffs_f_name);
+     127           5 :   bool nopbc=!pbc;
+     128           5 :   parseFlag("NOPBC",nopbc);
+     129           5 :   pbc=!nopbc;
+     130             : 
+     131           5 :   checkRead();
+     132             : 
+     133           5 :   log.printf("  of %u atoms\n",static_cast<unsigned>(atom_list.size()));
+     134         120 :   for(unsigned int i=0; i<atom_list.size(); ++i) {
+     135         115 :     log.printf("  %d", atom_list[i].serial());
+     136             :   }
+     137             : 
+     138           5 :   if(pbc) log.printf("\n using periodic boundary conditions\n");
+     139           0 :   else log.printf("\n without periodic boundary conditions\n");
+     140             : 
+     141          10 :   addValueWithDerivatives(); setNotPeriodic();
+     142             : 
+     143           5 :   requestAtoms(atom_list);
+     144             : 
+     145             :   // call the readinputs() function here
+     146           5 :   readinputs();
+     147             : 
+     148           5 : }
+     149             : 
+     150             : // read inputs function
+     151           5 : void position_linear_proj::readinputs()
+     152             : {
+     153             :   unsigned N=getNumberOfAtoms();
+     154             :   // read ref coords
+     155           5 :   in_.open(ref_f_name);
+     156             : 
+     157             :   ref_str.resize(N,3); prec.resize(N,N);
+     158             :   derv_numeric.resize(N,3);
+     159             : 
+     160             :   std::string line_, val_;
+     161             :   unsigned c_=0;
+     162             : 
+     163         120 :   while (c_ < N)
+     164             :   {
+     165         115 :     in_.getline(line_);
+     166             :     std::vector<std::string> items_;
+     167         115 :     std::stringstream check_(line_);
+     168             : 
+     169         460 :     while(std::getline(check_, val_, ' ')) { items_.push_back(val_); }
+     170         460 :     for(int i=0; i<3; ++i) { ref_str(c_,i) = std::stold(items_[i]); }
+     171         115 :     c_ += 1;
+     172         115 :   }
+     173           5 :   in_.close();
+     174             : 
+     175             :   //read precision
+     176           5 :   in_.open(prec_f_name);
+     177             : 
+     178             :   std::string line, val;
+     179             :   unsigned int c = 0;
+     180             : 
+     181         120 :   while(c < N)
+     182             :   {
+     183         115 :     in_.getline(line);
+     184             : 
+     185             :     // vector for storing the objects
+     186             :     std::vector<std::string> items;
+     187             : 
+     188             :     // stringstream helps to treat a string like an ifstream!
+     189         115 :     std::stringstream check(line);
+     190             : 
+     191        2760 :     while (std::getline(check, val, ' '))
+     192             :     {
+     193        2645 :       items.push_back(val);
+     194             :     }
+     195             : 
+     196        2760 :     for(unsigned int i=0; i<N; ++i)
+     197             :     {
+     198        2645 :       prec(c, i) = std::stold(items[i]);
+     199             :     }
+     200             : 
+     201         115 :     c += 1;
+     202             : 
+     203         115 :   }
+     204           5 :   in_.close();
+     205             : 
+     206             :   // read in the linear coeffs
+     207           5 :   in_.open(coeffs_f_name);
+     208             :   unsigned n_=0;
+     209             :   std::string l_;
+     210         350 :   while (n_ < N*3) { in_.getline(l_); linear_coeffs.push_back(std::stod(l_)); n_ += 1; }
+     211           5 :   linear_coeffs.resize(N*3);
+     212             : 
+     213           5 :   in_.close();
+     214             : 
+     215           5 : }
+     216             : 
+     217             : 
+     218             : 
+     219        1430 : double position_linear_proj::determinant(int n, const std::vector<std::vector<double>>* B)
+     220             : {
+     221             : 
+     222        1430 :   std::vector<std::vector<double>> A(n, std::vector<double>(n, 0));
+     223             :   // make a copy first!
+     224        5720 :   for(int i=0; i<n; ++i) {
+     225       17160 :     for(int j=0; j<n; ++j) {A[i][j] = (*B)[i][j];}
+     226             :   }
+     227             : 
+     228             : 
+     229             :   //  It calculates determinant of a matrix using partial pivoting.
+     230             : 
+     231             :   double det = 1;
+     232             : 
+     233             :   // Row operations for i = 0, ,,,, n - 2 (n-1 not needed)
+     234        4290 :   for ( int i = 0; i < n - 1; i++ )
+     235             :   {
+     236             :     // Partial pivot: find row r below with largest element in column i
+     237             :     int r = i;
+     238        2860 :     double maxA = std::abs( A[i][i] );
+     239        7150 :     for ( int k = i + 1; k < n; k++ )
+     240             :     {
+     241        4290 :       double val = std::abs( A[k][i] );
+     242        4290 :       if ( val > maxA )
+     243             :       {
+     244             :         r = k;
+     245             :         maxA = val;
+     246             :       }
+     247             :     }
+     248        2860 :     if ( r != i )
+     249             :     {
+     250       10010 :       for ( int j = i; j < n; j++ ) std::swap( A[i][j], A[r][j] );
+     251        2860 :       det = -det;
+     252             :     }
+     253             : 
+     254             :     // Row operations to make upper-triangular
+     255        2860 :     double pivot = A[i][i];
+     256        2860 :     if (std::abs( pivot ) < SMALL ) return 0.0;              // Singular matrix
+     257             : 
+     258        7150 :     for ( int r = i + 1; r < n; r++ )                    // On lower rows
+     259             :     {
+     260        4290 :       double multiple = A[r][i] / pivot;                // Multiple of row i to clear element in ith column
+     261       15730 :       for ( int j = i; j < n; j++ ) A[r][j] -= multiple * A[i][j];
+     262             :     }
+     263        2860 :     det *= pivot;                                        // Determinant is product of diagonal
+     264             :   }
+     265             : 
+     266        1430 :   det *= A[n-1][n-1];
+     267             : 
+     268        1430 :   return det;
+     269        1430 : }
+     270             : 
+     271             : // kabsch rotation
+     272         715 : void position_linear_proj::kabsch_rot_mat() {
+     273             : 
+     274             :   unsigned N=getNumberOfAtoms();
+     275             : 
+     276             :   Matrix<double> mobile_str_T(3,N);
+     277             :   Matrix<double> prec_dot_ref_str(N,3);
+     278             :   Matrix<double> correlation(3,3);
+     279             : 
+     280             : 
+     281         715 :   transpose(mobile_str, mobile_str_T);
+     282         715 :   mult(prec, ref_str, prec_dot_ref_str);
+     283         715 :   mult(mobile_str_T, prec_dot_ref_str, correlation);
+     284             : 
+     285             : 
+     286         715 :   int rw = correlation.nrows();
+     287         715 :   int cl = correlation.ncols();
+     288         715 :   int sz = rw*cl;
+     289             : 
+     290             :   // SVD part (taking from plu2/src/tools/Matrix.h: pseudoInvert function)
+     291             : 
+     292         715 :   std::vector<double> da(sz);
+     293             :   unsigned k=0;
+     294             : 
+     295             :   // Transfer the matrix to the local array
+     296        9295 :   for (int i=0; i<cl; ++i) for (int j=0; j<rw; ++j) da[k++]=static_cast<double>( correlation(j,i) ); // note! its [j][i] not [i][j]
+     297             : 
+     298         715 :   int nsv, info, nrows=rw, ncols=cl;
+     299             :   if(rw>cl) {nsv=cl;} else {nsv=rw;}
+     300             : 
+     301             :   // Create some containers for stuff from single value decomposition
+     302         715 :   std::vector<double> S(nsv);
+     303         715 :   std::vector<double> U(nrows*nrows);
+     304         715 :   std::vector<double> VT(ncols*ncols);
+     305         715 :   std::vector<int> iwork(8*nsv);
+     306             : 
+     307             :   // This optimizes the size of the work array used in lapack singular value decomposition
+     308         715 :   int lwork=-1;
+     309         715 :   std::vector<double> work(1);
+     310         715 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     311             :   //if(info!=0) return info;
+     312         715 :   if(info!=0) log.printf("info:", info);
+     313             : 
+     314             :   // Retrieve correct sizes for work and rellocate
+     315         715 :   lwork=(int) work[0]; work.resize(lwork);
+     316             : 
+     317             :   // This does the singular value decomposition
+     318         715 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     319             :   //if(info!=0) return info;
+     320         715 :   if(info!=0) log.printf("info:", info);
+     321             : 
+     322             : 
+     323             :   // get U and VT in form of 2D vector (U_, VT_)
+     324         715 :   std::vector<std::vector<double>> U_(nrows, std::vector<double>(nrows,0));
+     325         715 :   std::vector<std::vector<double>> VT_(ncols, std::vector<double>(ncols,0));
+     326             : 
+     327             :   int  c=0;
+     328             : 
+     329        9295 :   for(int i=0; i<nrows; ++i) { for(int j=0; j<nrows; ++j) { U_[j][i] = U[c]; c += 1;} } c = 0; // note! its [j][i] not [i][j]
+     330        9295 :   for(int i=0; i<ncols; ++i) { for(int j=0; j<ncols; ++j) { VT_[j][i] = VT[c]; c += 1;} } c=0; // note! its [j][i] not [i][j]
+     331             : 
+     332             : 
+     333             :   // calculate determinants
+     334         715 :   double det_u = determinant(nrows, &U_);
+     335         715 :   double det_vt = determinant(ncols, &VT_);
+     336             : 
+     337             :   // check!
+     338        1859 :   if (det_u * det_vt < 0.0) { for(int i=0; i<nrows; ++i) {U_[i][nrows-1] *= -1;} }
+     339             : 
+     340             : 
+     341             :   //Matrix<double> rotation(3,3);
+     342         715 :   rotation.resize(3,3);
+     343             :   Matrix<double> u(3,3), vt(3,3);
+     344        9295 :   for(int i=0; i<3; ++i) { for(int j=0; j<3; ++j) { u(i,j)=U_[i][j]; vt(i,j)=VT_[i][j]; } }
+     345             : 
+     346             :   // get rotation matrix
+     347         715 :   mult(u, vt, rotation);
+     348             : 
+     349        1430 : }
+     350             : 
+     351             : 
+     352             : // calculates linear projection
+     353         715 : double position_linear_proj::cal_position_linear_proj() {
+     354             : 
+     355             :   unsigned N=getNumberOfAtoms();
+     356             : 
+     357             :   Matrix<double> rotated_obj(N,3);
+     358             :   // rotate the object
+     359         715 :   mult(mobile_str, rotation, rotated_obj);
+     360             : 
+     361             :   // compute the displacement
+     362         715 :   std::vector<double> disp(N*3);
+     363             :   unsigned c=0;
+     364       66495 :   for(unsigned int i=0; i<N; ++i) { for(int j=0; j<3; ++j) { disp[c] = (rotated_obj(i,j)-ref_str(i,j)); c+=1;} }
+     365             : 
+     366             :   //double proj_val = dotProduct(disp, linear_coeffs);
+     367             :   double proj_val = 0.0;
+     368       50050 :   for(unsigned int i=0; i<N*3; ++i) { proj_val += (linear_coeffs[i]*disp[i]);}
+     369             : 
+     370         715 :   return proj_val;
+     371             : }
+     372             : 
+     373             : // numeric gradient
+     374          25 : void position_linear_proj::numeric_grad() {
+     375             :   // This function performs numerical derivative.
+     376             :   unsigned N=getNumberOfAtoms();
+     377             : 
+     378             :   unsigned stride;
+     379             :   unsigned rank;
+     380          25 :   if(serial) {
+     381             :     // when using components the parallelisation do not work
+     382             :     stride=1;
+     383             :     rank=0;
+     384             :   } else {
+     385          25 :     stride=comm.Get_size();
+     386          25 :     rank=comm.Get_rank();
+     387             :   }
+     388             : 
+     389         255 :   for(unsigned i=rank; i<N; i+=stride) {
+     390         920 :     for (unsigned j=0; j<3; ++j) {
+     391             : 
+     392         690 :       mobile_str(i,j) += delta;
+     393         690 :       kabsch_rot_mat();
+     394         690 :       derv_numeric(i,j) = ((cal_position_linear_proj() - proj)/delta);
+     395             : 
+     396         690 :       mobile_str(i,j) -= delta;
+     397             :     }
+     398             : 
+     399             :   }
+     400             : 
+     401          25 :   if(!serial) {
+     402          25 :     if(!derv_numeric.getVector().empty()) comm.Sum(&derv_numeric(0,0), derv_numeric.getVector().size());
+     403             :   }
+     404             : 
+     405             : 
+     406         600 :   for(unsigned i=0; i<N; ++i) {
+     407         575 :     Vector vi(derv_numeric(i,0), derv_numeric(i,1), derv_numeric(i,2) );
+     408         575 :     setAtomsDerivatives(i, vi);
+     409             :   }
+     410             : 
+     411             :   // clear the matrix (very important step!!)
+     412          25 :   derv_numeric *= 0;
+     413          25 : }
+     414             : 
+     415             : 
+     416             : // calculator
+     417          25 : void position_linear_proj::calculate() {
+     418             : 
+     419          25 :   if(pbc) makeWhole();
+     420             :   unsigned N=getNumberOfAtoms();
+     421             : 
+     422             :   mobile_str.resize(N,3);
+     423             : 
+     424             :   // load the mobile str
+     425         600 :   for(unsigned int i=0; i<N; ++i) {
+     426         575 :     Vector pos=getPosition(i);  // const PLMD::Vector
+     427        2300 :     for(unsigned j=0; j<3; ++j) {
+     428        1725 :       mobile_str(i,j) = pos[j];
+     429             :     }
+     430             :   }
+     431             : 
+     432             :   // translating the structure to center of geometry
+     433          25 :   double center_of_geometry[3]= {0.0, 0.0, 0.0};
+     434             : 
+     435         600 :   for(unsigned int i=0; i<N; ++i)
+     436             :   {
+     437         575 :     center_of_geometry[0] += mobile_str(i,0); center_of_geometry[1] += mobile_str(i,1); center_of_geometry[2] += mobile_str(i,2);
+     438             :   }
+     439             : 
+     440         600 :   for(unsigned int i=0; i<N; ++i)
+     441             :   {
+     442        2300 :     for(int j=0; j<3; ++j) { mobile_str(i,j) -= (center_of_geometry[j]/N); }
+     443             :   }
+     444             : 
+     445          25 :   kabsch_rot_mat();
+     446          25 :   proj = cal_position_linear_proj();
+     447             : 
+     448          25 :   numeric_grad();
+     449          25 :   setBoxDerivativesNoPbc();
+     450          25 :   setValue(proj);
+     451             : 
+     452             : 
+     453          25 : }
+     454             : 
+     455             : }
+     456             : }
+     457             : 
+     458             : 
+     459             : 
+
+
+
+ + + + +
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 000000000..3407ca3c5 --- /dev/null +++ b/coverage/small_vector/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..e00afb1a5 --- /dev/null +++ b/coverage/small_vector/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..c670c5f8a --- /dev/null +++ b/coverage/small_vector/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..5a4a7cfac --- /dev/null +++ b/coverage/small_vector/small_vector.h.func-sort-c.html @@ -0,0 +1,244 @@ + + + + + + + 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-10-17 16:45:00Functions: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_20272
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE4wipeEv47814
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE16request_capacityEm49755
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE4wipeEv52099
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE24emplace_into_current_endIJSI_EEEPSI_DpOT_134510
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE14append_elementIJSI_EEEPSI_DpOT_135651
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE14append_elementIJS8_EEEPS8_DpOT_140434
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE24emplace_into_current_endIJS8_EEEPS8_DpOT_140434
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE4wipeEv163664
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE7end_ptrEv335311
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE14append_elementIJS4_EEEPS4_DpOT_475318
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE24emplace_into_current_endIJS4_EEEPS4_DpOT_475318
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE4wipeEv1346744
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE24emplace_into_current_endIJRPKcRmEEEPS6_DpOT_1388015
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE14append_elementIJRPKcRmEEEPS6_DpOT_1388187
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE19copy_assign_defaultILj6EEERS6_RKNS2_IS5_XT_EEE4195800
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv4195800
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE7end_ptrEv5395206
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE7end_ptrEv5469518
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv5469924
+
+
+ + + +
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 000000000..dd6fe9622 --- /dev/null +++ b/coverage/small_vector/small_vector.h.func.html @@ -0,0 +1,244 @@ + + + + + + + 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-10-17 16:45:00Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE14append_elementIJS4_EEEPS4_DpOT_475318
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE19copy_assign_defaultILj6EEERS6_RKNS2_IS5_XT_EEE4195800
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE24emplace_into_current_endIJS4_EEEPS4_DpOT_475318
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE29emplace_into_reallocation_endIJS4_EEEPS4_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE4wipeEv163664
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv5469924
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE14append_elementIJS8_EEEPS8_DpOT_140434
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE16request_capacityEm49755
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE24emplace_into_current_endIJS8_EEEPS8_DpOT_140434
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE29emplace_into_reallocation_endIJS8_EEEPS8_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE4wipeEv52099
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE7end_ptrEv335311
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE14append_elementIJRPKcRmEEEPS6_DpOT_1388187
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE18allocation_end_ptrEv172
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE24emplace_into_current_endIJRPKcRmEEEPS6_DpOT_1388015
_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_traitsIcEEELj2EE4wipeEv1346744
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE7end_ptrEv5469518
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE14append_elementIJSI_EEEPSI_DpOT_135651
_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_134510
_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_EEE5EntryELj32EE4wipeEv47814
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE7end_ptrEv5395206
_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_20272
_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_ptrEv4195800
_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 000000000..24377e8c9 --- /dev/null +++ b/coverage/small_vector/small_vector.h.gcov.html @@ -0,0 +1,6559 @@ + + + + + + + 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-10-17 16:45:00Functions: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     1792109 :     --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    12779470 :     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     2379628 :     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   142066720 :     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     6733689 :   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      215407 :     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       23929 :     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    20896079 :     unchecked_advance (pos, static_cast<IteratorDiffT> (n));
+    2144    20920008 :     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     2138277 :     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       23929 :   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       23929 :     if (num_copy != 0)
+    2316       21585 :       std::memcpy (to_address (dest), to_address (first), num_copy * sizeof (value_ty));
+    2317       23929 :     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   150057352 :   constexpr ptr     data_ptr (void) const noexcept { return m_data_ptr; }
+    2484     8004147 :   constexpr size_ty capacity (void) const noexcept { return m_capacity; }
+    2485   183431321 :   constexpr size_ty size     (void) const noexcept { return m_size; }
+    2486             : 
+    2487     1636965 :   PLUMED_GCH_CPP20_CONSTEXPR void set_data_ptr (ptr     data_ptr) noexcept { m_data_ptr = data_ptr; }
+    2488     1636965 :   PLUMED_GCH_CPP20_CONSTEXPR void set_capacity (size_ty capacity) noexcept { m_capacity = capacity; }
+    2489     7535716 :   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     1614032 :   wipe (void)
+    2953             :   {
+    2954     1614032 :     destroy_range (begin_ptr (), end_ptr ());
+    2955     1614032 :     if (has_allocation ())
+    2956             :       deallocate (data_ptr (), get_capacity ());
+    2957     1614032 :   }
+    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     4195800 :   }
+    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     2138277 :     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      135651 :     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     4195800 :   copy_assign_default (const small_vector_base<Allocator, I>& other)
+    3096             :   {
+    3097     4195800 :     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     4195800 :       if (get_size () < other.get_size ())
+    3118             :       {
+    3119             :         // No reallocation, partially in uninitialized space.
+    3120       20272 :         std::copy_n (other.begin_ptr (), get_size (), begin_ptr ());
+    3121       40544 :         uninitialized_copy (
+    3122             :           unchecked_next (other.begin_ptr (), get_size ()),
+    3123             :           other.end_ptr (),
+    3124             :           end_ptr ());
+    3125             :       }
+    3126             :       else
+    3127             :       {
+    3128     4175528 :         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     4195800 :     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     1607124 :   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     1425597 :     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     2139590 :   append_element (Args&&... args)
+    3932             :   {
+    3933     2139590 :     if (get_size () < get_capacity ())
+    3934     2138277 :           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     2138277 :   emplace_into_current_end (Args&&... args)
+    4380             :   {
+    4381     2138277 :     construct (end_ptr (), std::forward<Args> (args)...);
+    4382             :     increase_size (1);
+    4383     2138277 :     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       49755 :   request_capacity (size_ty request)
+    4609             :   {
+    4610       49755 :     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      135651 :     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     1506396 :     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    16673670 :   end_ptr (void) noexcept
+    5099             :   {
+    5100    16673670 :     return unchecked_next (begin_ptr (), get_size ());
+    5101             :   }
+    5102             : 
+    5103             :   PLUMED_GCH_NODISCARD constexpr
+    5104             :   cptr
+    5105     4195800 :   end_ptr (void) const noexcept
+    5106             :   {
+    5107     4195800 :     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     1425597 :   ~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     4941580 :     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     2515279 :     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      140434 :   }
+    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     2139590 :     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      135651 :   }
+    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       49755 :     base::request_capacity (new_capacity);
+    5980       49755 :   }
+    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     1506396 :     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/sprint/Sprint.cpp.func-sort-c.html b/coverage/sprint/Sprint.cpp.func-sort-c.html new file mode 100644 index 000000000..ec73c77e1 --- /dev/null +++ b/coverage/sprint/Sprint.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - sprint/Sprint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sprint - Sprint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6sprint6SprintC2ERKNS_13ActionOptionsE0
_ZN4PLMD6sprint6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6sprint6Sprint16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sprint/Sprint.cpp.func.html b/coverage/sprint/Sprint.cpp.func.html new file mode 100644 index 000000000..c64cf66f6 --- /dev/null +++ b/coverage/sprint/Sprint.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - sprint/Sprint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sprint - Sprint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6sprint6Sprint16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6sprint6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6sprint6SprintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sprint/Sprint.cpp.gcov.html b/coverage/sprint/Sprint.cpp.gcov.html new file mode 100644 index 000000000..fec7b9d59 --- /dev/null +++ b/coverage/sprint/Sprint.cpp.gcov.html @@ -0,0 +1,219 @@ + + + + + + + LCOV - plumed test coverage - sprint/Sprint.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sprint - Sprint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions: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 sprint {
+      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/sprint/index-sort-f.html b/coverage/sprint/index-sort-f.html new file mode 100644 index 000000000..04a89a696 --- /dev/null +++ b/coverage/sprint/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - sprint + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sprintHitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Sprint.cpp +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sprint/index-sort-l.html b/coverage/sprint/index-sort-l.html new file mode 100644 index 000000000..202f744fe --- /dev/null +++ b/coverage/sprint/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - sprint + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sprintHitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Sprint.cpp +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sprint/index.html b/coverage/sprint/index.html new file mode 100644 index 000000000..e0ee6f034 --- /dev/null +++ b/coverage/sprint/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - sprint + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sprintHitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Sprint.cpp +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + 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 000000000..6dffe0819 --- /dev/null +++ b/coverage/symfunc/AngularTetra.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..96dc9eae2 --- /dev/null +++ b/coverage/symfunc/AngularTetra.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..517e3d2a7 --- /dev/null +++ b/coverage/symfunc/AngularTetra.cpp.gcov.html @@ -0,0 +1,161 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..78302188d --- /dev/null +++ b/coverage/symfunc/AtomicSMAC.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..77c2f8837 --- /dev/null +++ b/coverage/symfunc/AtomicSMAC.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..bc9ad436f --- /dev/null +++ b/coverage/symfunc/AtomicSMAC.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d85bb3027 --- /dev/null +++ b/coverage/symfunc/CoordShellVectorFunction.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc24CoordShellVectorFunctionC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc24CoordShellVectorFunctionC1ERKNS_13ActionOptionsE9
_ZN4PLMD7symfunc24CoordShellVectorFunction16registerKeywordsERNS_8KeywordsE23
+
+
+ + + +
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 000000000..4518dedca --- /dev/null +++ b/coverage/symfunc/CoordShellVectorFunction.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc24CoordShellVectorFunction16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD7symfunc24CoordShellVectorFunctionC1ERKNS_13ActionOptionsE9
_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 000000000..42892c09b --- /dev/null +++ b/coverage/symfunc/CoordShellVectorFunction.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + 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-10-17 16:45:00Functions: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          23 : void CoordShellVectorFunction::registerKeywords( Keywords& keys ) {
+     148          23 :   CoordinationNumbers::shortcutKeywords( keys );
+     149          46 :   keys.add("compulsory","FUNCTION","the function of the bond vectors that you would like to evaluate");
+     150          46 :   keys.add("compulsory","PHI","0.0","The Euler rotational angle phi");
+     151          46 :   keys.add("compulsory","THETA","0.0","The Euler rotational angle theta");
+     152          46 :   keys.add("compulsory","PSI","0.0","The Euler rotational angle psi");
+     153          46 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function that is used for FCCUBIC");
+     154          46 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     155          69 :   keys.needsAction("CONTACT_MATRIX"); keys.needsAction("FCCUBIC_FUNC"); keys.needsAction("CUSTOM");
+     156          46 :   keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+     157          23 : }
+     158             : 
+     159           9 : CoordShellVectorFunction::CoordShellVectorFunction(const ActionOptions& ao):
+     160             :   Action(ao),
+     161           9 :   ActionShortcut(ao)
+     162             : {
+     163           9 :   std::string matlab, sp_str, specA, specB; bool lowmem; parseFlag("LOWMEM",lowmem);
+     164           9 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     165          36 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+     166           9 :   if( sp_str.length()>0 || specA.length()>0 ) {
+     167           9 :     matlab = getShortcutLabel() + "_mat";
+     168           9 :     CoordinationNumbers::expandMatrix( true, getShortcutLabel(),  sp_str, specA, specB, this );
+     169           0 :   } else error("found no input atoms use SPECIES/SPECIESA");
+     170          27 :   double phi, theta, psi; parse("PHI",phi); parse("THETA",theta); parse("PSI",psi);
+     171           9 :   std::vector<std::string> rotelements(9); std::string xvec = matlab + ".x", yvec = matlab + ".y", zvec = matlab + ".z";
+     172           9 :   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           9 :   if( getName()=="FCCUBIC" ) {
+     190           5 :     std::string alpha; parse("ALPHA",alpha);
+     191          10 :     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          18 :   readInputLine( getShortcutLabel() + "_wvfunc: CUSTOM ARG=" + getShortcutLabel() + "_vfunc," + matlab + ".w FUNC=x*y PERIODIC=NO");
+     209             :   // And coordination numbers
+     210           9 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+     211           9 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     212           9 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     213          18 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     214          18 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_wvfunc," + getShortcutLabel() + "_ones");
+     215           9 :   std::string olab=getShortcutLabel();
+     216           9 :   if( getName()!="COORDINATION_SHELL_FUNCTION" ) {
+     217           7 :     olab = getShortcutLabel() + "_n";
+     218             :     // Calculate coordination numbers for denominator
+     219          14 :     readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + matlab + ".w," + getShortcutLabel() + "_ones");
+     220             :     // And normalise
+     221          14 :     readInputLine( getShortcutLabel() + "_n: CUSTOM ARG=" + getShortcutLabel() + "," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     222             :   }
+     223             :   // And expand the functions
+     224           9 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     225          18 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), olab, "", keymap, this );
+     226          18 : }
+     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 000000000..95a7adf50 --- /dev/null +++ b/coverage/symfunc/CoordinationNumbers.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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_14ActionShortcutE108
_ZN4PLMD7symfunc19CoordinationNumbers16shortcutKeywordsERNS_8KeywordsE176
+
+
+ + + +
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 000000000..049c1a26d --- /dev/null +++ b/coverage/symfunc/CoordinationNumbers.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19CoordinationNumbers12expandMatrixERKbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_PNS_14ActionShortcutE108
_ZN4PLMD7symfunc19CoordinationNumbers16registerKeywordsERNS_8KeywordsE67
_ZN4PLMD7symfunc19CoordinationNumbers16shortcutKeywordsERNS_8KeywordsE176
_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 000000000..2e0674095 --- /dev/null +++ b/coverage/symfunc/CoordinationNumbers.cpp.gcov.html @@ -0,0 +1,271 @@ + + + + + + + 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-10-17 16:45:00Functions: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         176 : void CoordinationNumbers::shortcutKeywords( Keywords& keys ) {
+      95         176 :   ActionShortcut::registerKeywords( keys );
+      96         352 :   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         352 :   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         352 :   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         352 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     109         352 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     110         352 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     111         352 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     112         352 :   keys.add("optional","SWITCH","the switching function that it used in the construction of the contact matrix");
+     113         176 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+     114         352 :   keys.needsAction("CONTACT_MATRIX"); keys.needsAction("GROUP");
+     115         176 : }
+     116             : 
+     117         108 : 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         108 :   if( sp_str.length()==0 && spa_str.length()==0 ) return;
+     120             : 
+     121         108 :   std::string matinp = lab  + "_mat: CONTACT_MATRIX";
+     122         108 :   if( sp_str.length()>0 ) {
+     123          69 :     matinp += " GROUP=" + sp_str;
+     124         138 :     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         216 :   std::string sw_str; action->parse("SWITCH",sw_str);
+     131         108 :   if( sw_str.length()>0 ) {
+     132         162 :     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         108 :   if( components ) matinp += " COMPONENTS";
+     140         108 :   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","MOMENTS","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 000000000..bf2f3525a --- /dev/null +++ b/coverage/symfunc/CylindricalHarmonic.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19CylindricalHarmonic24setPeriodicityForOutputsEPNS_15ActionWithValueE2
_ZN4PLMD7symfunc19CylindricalHarmonic4readEPNS_19ActionWithArgumentsE2
_ZN4PLMD7symfunc19CylindricalHarmonic16registerKeywordsERNS_8KeywordsE9
_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 000000000..a809390d5 --- /dev/null +++ b/coverage/symfunc/CylindricalHarmonic.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19CylindricalHarmonic16registerKeywordsERNS_8KeywordsE9
_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 000000000..1a3555714 --- /dev/null +++ b/coverage/symfunc/CylindricalHarmonic.cpp.gcov.html @@ -0,0 +1,173 @@ + + + + + + + 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-10-17 16:45:00Functions: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 "function/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          12 : 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 function::FunctionOfMatrix<CylindricalHarmonic> MatrixCyHarm;
+      66             : PLUMED_REGISTER_ACTION(MatrixCyHarm,"CYLINDRICAL_HARMONIC_MATRIX")
+      67             : 
+      68           9 : void CylindricalHarmonic::registerKeywords( Keywords& keys ) {
+      69          18 :   keys.add("compulsory","DEGREE","the value of the n parameter in the equation above");
+      70          18 :   keys.addOutputComponent("rm","default","the real part of the cylindrical harmonic");
+      71          18 :   keys.addOutputComponent("im","default","the imaginary part of the cylindrical harmonic");
+      72           9 : }
+      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 000000000..c8e78d970 --- /dev/null +++ b/coverage/symfunc/Fccubic.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:3030100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc7Fccubic4readEPNS_19ActionWithArgumentsE6
_ZN4PLMD7symfunc7Fccubic16registerKeywordsERNS_8KeywordsE28
_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 000000000..87805486d --- /dev/null +++ b/coverage/symfunc/Fccubic.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:3030100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc7Fccubic16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD7symfunc7Fccubic4readEPNS_19ActionWithArgumentsE6
_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 000000000..d374c3690 --- /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:3030100.0 %
Date:2024-10-17 16:45:00Functions: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 "function/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          40 : 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 function::FunctionOfMatrix<Fccubic> MatrixFccubic;
+     104             : PLUMED_REGISTER_ACTION(MatrixFccubic,"FCCUBIC_FUNC_MATRIX")
+     105             : 
+     106          28 : void Fccubic::registerKeywords( Keywords& keys ) {
+     107          56 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function");
+     108          28 :   keys.setValueDescription("a function that measures the similarity with an fcc environment");
+     109          28 : }
+     110             : 
+     111           6 : void Fccubic::read( ActionWithArguments* action ) {
+     112             :   // Scaling factors such that '1' corresponds to fcc lattice
+     113             :   // and '0' corresponds to isotropic (liquid)
+     114           6 :   parse(action,"ALPHA",alpha);
+     115           6 :   a1 = 80080. / (2717. + 16*alpha); b1 = 16.*(alpha-143)/(2717+16*alpha);
+     116           6 :   action->log.printf("  setting alpha paramter equal to %f \n",alpha);
+     117           6 : }
+     118             : 
+     119     2486314 : void Fccubic::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     120     2486314 :   double x2 = args[0]*args[0];
+     121     2486314 :   double x4 = x2*x2;
+     122             : 
+     123     2486314 :   double y2 = args[1]*args[1];
+     124     2486314 :   double y4 = y2*y2;
+     125             : 
+     126     2486314 :   double z2 = args[2]*args[2];
+     127     2486314 :   double z4 = z2*z2;
+     128             : 
+     129     2486314 :   double d2 = x2 + y2 + z2;
+     130     2486314 :   double r8 = pow( d2, 4 );
+     131     2486314 :   double r12 = pow( d2, 6 );
+     132             : 
+     133     2486314 :   double tmp = ((x4*y4)+(x4*z4)+(y4*z4))/r8-alpha*x4*y4*z4/r12;
+     134             : 
+     135     2486314 :   double t0 = (x2*y4+x2*z4)/r8-alpha*x2*y4*z4/r12;
+     136     2486314 :   double t1 = (y2*x4+y2*z4)/r8-alpha*y2*x4*z4/r12;
+     137     2486314 :   double t2 = (z2*x4+z2*y4)/r8-alpha*z2*x4*y4/r12;
+     138     2486314 :   double t3 = (2*tmp-alpha*x4*y4*z4/r12)/d2;
+     139             : 
+     140     2486314 :   derivatives(0,0)=4*a1*args[0]*(t0-t3);
+     141     2486314 :   derivatives(0,1)=4*a1*args[1]*(t1-t3);
+     142     2486314 :   derivatives(0,2)=4*a1*args[2]*(t2-t3);
+     143             : 
+     144             :   // Set the value and the derivatives
+     145     2486314 :   vals[0] = (a1*tmp+b1);
+     146     2486314 : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+
+
+
+ + + + +
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 000000000..466549fe1 --- /dev/null +++ b/coverage/symfunc/HexaticParameter.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7f7160ed3 --- /dev/null +++ b/coverage/symfunc/HexaticParameter.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..19bf41b7a --- /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-10-17 16:45:00Functions: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             : Calculate the hexatic order parameter
+      38             : 
+      39             : \bug Virial is not working currently
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : 
+      44             : */
+      45             : //+ENDPLUMEDOC
+      46             : 
+      47             : 
+      48             : class HexacticParameter : public ActionShortcut {
+      49             : private:
+      50             :   void createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab );
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   explicit HexacticParameter(const ActionOptions&);
+      54             : };
+      55             : 
+      56             : PLUMED_REGISTER_ACTION(HexacticParameter,"HEXACTIC_PARAMETER")
+      57             : 
+      58           5 : void HexacticParameter::registerKeywords( Keywords& keys ) {
+      59           5 :   CoordinationNumbers::shortcutKeywords( keys );
+      60          10 :   keys.add("compulsory","PLANE","the plane to use when calculating the value of the order parameter should be xy, xz or yz");
+      61          10 :   keys.addFlag("VMEAN",false,"calculate the norm of the mean vector.");
+      62          10 :   keys.addOutputComponent("_vmean","VMEAN","the norm of the mean vector");
+      63          10 :   keys.addFlag("VSUM",false,"calculate the norm of the sum of all the vectors");
+      64          10 :   keys.addOutputComponent("_vsum","VSUM","the norm of the mean vector");
+      65          10 :   keys.needsAction("CYLINDRICAL_HARMONIC_MATRIX"); keys.needsAction("ONES");
+      66          10 :   keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("CUSTOM");
+      67          15 :   keys.needsAction("MEAN"); keys.needsAction("SUM"); keys.needsAction("COMBINE");
+      68           5 : }
+      69             : 
+      70           1 : HexacticParameter::HexacticParameter( const ActionOptions& ao):
+      71             :   Action(ao),
+      72           1 :   ActionShortcut(ao)
+      73             : {
+      74           3 :   std::string sp_str, specA, specB; parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+      75           1 :   CoordinationNumbers::expandMatrix( true, getShortcutLabel(), sp_str, specA, specB, this );
+      76           2 :   std::string myplane; parse("PLANE",myplane);
+      77           1 :   if( myplane=="xy" ) {
+      78           2 :     readInputLine( getShortcutLabel() + ": CYLINDRICAL_HARMONIC_MATRIX DEGREE=6 ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.w" );
+      79           0 :   } else if( myplane=="xz" ) {
+      80           0 :     readInputLine( getShortcutLabel() + ": CYLINDRICAL_HARMONIC_MATRIX DEGREE=6 ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.z," + getShortcutLabel() + "_mat.w" );
+      81           0 :   } else if( myplane=="yz" ) {
+      82           0 :     readInputLine( getShortcutLabel() + ": CYLINDRICAL_HARMONIC_MATRIX DEGREE=6 ARG=" + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.z," + getShortcutLabel() + "_mat.w" );
+      83           0 :   } else error("invalid input for plane -- should be xy, xz or yz");
+      84             :   // And coordination number
+      85           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+      86           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+      87           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+      88           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+      89           2 :   readInputLine( getShortcutLabel() + "_rm: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + ".rm," + getShortcutLabel() + "_ones");
+      90           2 :   readInputLine( getShortcutLabel() + "_im: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + ".im," + getShortcutLabel() + "_ones");
+      91             :   // Input for denominator (coord)
+      92           2 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat.w," + getShortcutLabel() + "_ones");
+      93             :   // Divide real part by coordination numbers
+      94           2 :   readInputLine( getShortcutLabel() + "_rmn: CUSTOM ARG=" + getShortcutLabel() + "_rm," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+      95             :   // Devide imaginary part by coordination number
+      96           2 :   readInputLine( getShortcutLabel() + "_imn: CUSTOM ARG=" + getShortcutLabel() + "_im," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+      97             : 
+      98             :   // If we are doing VMEAN determine sum of vector components
+      99           1 :   bool do_vmean; parseFlag("VMEAN",do_vmean);
+     100           1 :   if( do_vmean ) {
+     101             :     // Real part
+     102           0 :     readInputLine( getShortcutLabel() + "_rms: MEAN ARG=" + getShortcutLabel() + "_rmn PERIODIC=NO");
+     103             :     // Imaginary part
+     104           0 :     readInputLine( getShortcutLabel() + "_ims: MEAN ARG=" + getShortcutLabel() + "_imn PERIODIC=NO");
+     105             :     // Now calculate the total length of the vector
+     106           0 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vmean", "ms" );
+     107             :   }
+     108           1 :   bool do_vsum; parseFlag("VSUM",do_vsum);
+     109           1 :   if( do_vsum ) {
+     110             :     // Real part
+     111           0 :     readInputLine( getShortcutLabel() + "_rmz: SUM ARG=" + getShortcutLabel() + "_rmn PERIODIC=NO");
+     112             :     // Imaginary part
+     113           0 :     readInputLine( getShortcutLabel() + "_imz: SUM ARG=" + getShortcutLabel() + "_imn PERIODIC=NO");
+     114             :     // Now calculate the total length of the vector
+     115           0 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vsum", "mz" );
+     116             :   }
+     117             : 
+     118             :   // Now calculate the total length of the vector
+     119           2 :   createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_norm", "mn" );
+     120           2 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_norm", "", this );
+     121           1 : }
+     122             : 
+     123           1 : void HexacticParameter::createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab ) {
+     124           2 :   readInputLine( olab + "2: COMBINE PERIODIC=NO ARG=" + ilab + "_r" + vlab + "," + ilab + "_i" + vlab + " POWERS=2,2" );
+     125           2 :   readInputLine( olab + ": CUSTOM ARG=" + olab + "2 FUNC=sqrt(x) PERIODIC=NO");
+     126           1 : }
+     127             : 
+     128             : }
+     129             : }
+     130             : 
+
+
+
+ + + + +
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 000000000..28d3f5038 --- /dev/null +++ b/coverage/symfunc/LocalAverage.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..52bc3a7eb --- /dev/null +++ b/coverage/symfunc/LocalAverage.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0edc651da --- /dev/null +++ b/coverage/symfunc/LocalAverage.cpp.gcov.html @@ -0,0 +1,246 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e9804a435 --- /dev/null +++ b/coverage/symfunc/LocalCrystalinity.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ed9520ad2 --- /dev/null +++ b/coverage/symfunc/LocalCrystalinity.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..07428167b --- /dev/null +++ b/coverage/symfunc/LocalCrystalinity.cpp.gcov.html @@ -0,0 +1,182 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0b10d2b34 --- /dev/null +++ b/coverage/symfunc/LocalSteinhardt.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a2d0e4105 --- /dev/null +++ b/coverage/symfunc/LocalSteinhardt.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..56253f246 --- /dev/null +++ b/coverage/symfunc/LocalSteinhardt.cpp.gcov.html @@ -0,0 +1,521 @@ + + + + + + + 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-10-17 16:45:00Functions: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 q_1 vector on the central atom and the q_3 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 q_3 vector on the central atom and the q_3 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 q_4 vector on the central atom and the q_4 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 q_6 vector on the central atom and the q_6 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 000000000..8415ba308 --- /dev/null +++ b/coverage/symfunc/RadialTetra.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..85278dbb5 --- /dev/null +++ b/coverage/symfunc/RadialTetra.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..afd41b6bf --- /dev/null +++ b/coverage/symfunc/RadialTetra.cpp.gcov.html @@ -0,0 +1,177 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..248681d58 --- /dev/null +++ b/coverage/symfunc/SMAC.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..ff7bcfbb6 --- /dev/null +++ b/coverage/symfunc/SMAC.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1b7c4e3c6 --- /dev/null +++ b/coverage/symfunc/SMAC.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3ebabe576 --- /dev/null +++ b/coverage/symfunc/SphericalHarmonic.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc17SphericalHarmonic24setPeriodicityForOutputsEPNS_15ActionWithValueE42
_ZN4PLMD7symfunc17SphericalHarmonic4readEPNS_19ActionWithArgumentsE42
_ZNK4PLMD7symfunc17SphericalHarmonic21getComponentsPerLabelB5cxx11Ev84
_ZN4PLMD7symfunc17SphericalHarmonic16registerKeywordsERNS_8KeywordsE215
_ZNK4PLMD7symfunc17SphericalHarmonic9factorialERKj1858
_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 000000000..20ec84ae0 --- /dev/null +++ b/coverage/symfunc/SphericalHarmonic.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc17SphericalHarmonic16registerKeywordsERNS_8KeywordsE215
_ZN4PLMD7symfunc17SphericalHarmonic24setPeriodicityForOutputsEPNS_15ActionWithValueE42
_ZN4PLMD7symfunc17SphericalHarmonic4readEPNS_19ActionWithArgumentsE42
_ZNK4PLMD7symfunc17SphericalHarmonic10deriv_polyERKjRKdRd1794050
_ZNK4PLMD7symfunc17SphericalHarmonic20addVectorDerivativesERKjRKNS_13VectorGenericILj3EEERNS_6MatrixIdEE6353585
_ZNK4PLMD7symfunc17SphericalHarmonic21getComponentsPerLabelB5cxx11Ev84
_ZNK4PLMD7symfunc17SphericalHarmonic4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE1742755
_ZNK4PLMD7symfunc17SphericalHarmonic9factorialERKj1858
+
+
+ + + +
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 000000000..f39c4a491 --- /dev/null +++ b/coverage/symfunc/SphericalHarmonic.cpp.gcov.html @@ -0,0 +1,313 @@ + + + + + + + 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-10-17 16:45:00Functions: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 "function/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         299 : 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 function::FunctionOfMatrix<SphericalHarmonic> MatrixSpHarm;
+      71             : PLUMED_REGISTER_ACTION(MatrixSpHarm,"SPHERICAL_HARMONIC_MATRIX")
+      72             : 
+      73         215 : void SphericalHarmonic::registerKeywords( Keywords& keys ) {
+      74         430 :   keys.add("compulsory","L","the value of the angular momentum");
+      75         430 :   keys.addOutputComponent("rm","default","the real parts of the spherical harmonic values with the m value given");
+      76         430 :   keys.addOutputComponent("im","default","the real parts of the spherical harmonic values with the m value given");
+      77         215 : }
+      78             : 
+      79        1858 : unsigned SphericalHarmonic::factorial( const unsigned& n ) const {
+      80        1858 :   return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
+      81             : }
+      82             : 
+      83          42 : void SphericalHarmonic::read( ActionWithArguments* action ) {
+      84          42 :   parse(action,"L",tmom);
+      85          42 :   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          42 :   if( action->getNumberOfArguments()==4 ) action->log.printf("  multiplying cylindrical harmonic by weight from %s \n", action->getPntrToArgument(3)->getName().c_str() );
+      87             : 
+      88          42 :   normaliz.resize( tmom+1 );
+      89         232 :   for(unsigned i=0; i<=tmom; ++i) {
+      90         190 :     normaliz[i] = sqrt( (2*tmom+1)*factorial(tmom-i)/(4*pi*factorial(tmom+i)) );
+      91         190 :     if( i%2==1 ) normaliz[i]*=-1;
+      92             :   }
+      93             : 
+      94          42 :   coeff_poly.resize( tmom+1 );
+      95          42 :   if( tmom==1 ) {
+      96             :     // Legendre polynomial coefficients of order one
+      97          19 :     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          42 : }
+     126             : 
+     127          84 : std::vector<std::string> SphericalHarmonic::getComponentsPerLabel() const {
+     128             :   std::vector<std::string> comp; std::string num;
+     129         760 :   for(int i=-tmom; i<=tmom; ++i) {
+     130         676 :     Tools::convert(fabs(i),num);
+     131         972 :     if( i<0 ) comp.push_back( "-n" + num );
+     132         676 :     else if( i>0 ) comp.push_back( "-p" + num );
+     133         168 :     else comp.push_back( "-0");
+     134             :   }
+     135          84 :   return comp;
+     136           0 : }
+     137             : 
+     138          42 : void SphericalHarmonic::setPeriodicityForOutputs( ActionWithValue* action ) {
+     139          42 :   std::vector<std::string> comp( getComponentsPerLabel() );
+     140         718 :   for(unsigned i=0; i<comp.size(); ++i) { action->componentIsNotPeriodic("rm" + comp[i]); action->componentIsNotPeriodic("im" + comp[i]); }
+     141          42 : }
+     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 000000000..d2b182212 --- /dev/null +++ b/coverage/symfunc/Steinhardt.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc10SteinhardtC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc10SteinhardtC1ERKNS_13ActionOptionsE42
_ZN4PLMD7symfunc10Steinhardt21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKiS9_S9_43
_ZN4PLMD7symfunc10Steinhardt16registerKeywordsERNS_8KeywordsE60
_ZNK4PLMD7symfunc10Steinhardt9getSymbolB5cxx11ERKi377
+
+
+ + + +
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 000000000..2ff63fb61 --- /dev/null +++ b/coverage/symfunc/Steinhardt.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc10Steinhardt16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD7symfunc10Steinhardt21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKiS9_S9_43
_ZN4PLMD7symfunc10SteinhardtC1ERKNS_13ActionOptionsE42
_ZN4PLMD7symfunc10SteinhardtC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7symfunc10Steinhardt9getSymbolB5cxx11ERKi377
+
+
+ + + +
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 000000000..fdb3ce32b --- /dev/null +++ b/coverage/symfunc/Steinhardt.cpp.gcov.html @@ -0,0 +1,468 @@ + + + + + + + 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-10-17 16:45:00Functions: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          60 : void Steinhardt::registerKeywords( Keywords& keys ) {
+     281          60 :   CoordinationNumbers::shortcutKeywords( keys );
+     282         120 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     283         120 :   keys.addFlag("VMEAN",false,"calculate the norm of the mean vector.");
+     284         120 :   keys.addOutputComponent("_vmean","VMEAN","the norm of the mean vector");
+     285         120 :   keys.addFlag("VSUM",false,"calculate the norm of the sum of all the vectors");
+     286         120 :   keys.addOutputComponent("_vsum","VSUM","the norm of the mean vector");
+     287         240 :   keys.needsAction("GROUP"); keys.needsAction("CONTACT_MATRIX"); keys.needsAction("SPHERICAL_HARMONIC"); keys.needsAction("ONES");
+     288         300 :   keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("MEAN"); keys.needsAction("SUM");
+     289          60 : }
+     290             : 
+     291          42 : Steinhardt::Steinhardt( const ActionOptions& ao):
+     292             :   Action(ao),
+     293          42 :   ActionShortcut(ao)
+     294             : {
+     295          42 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+     296          42 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     297         126 :   std::string sp_str, specA, specB; parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+     298          42 :   CoordinationNumbers::expandMatrix( true, getShortcutLabel(), sp_str, specA, specB, this ); int l;
+     299          84 :   std::string sph_input = getShortcutLabel() + "_sh: SPHERICAL_HARMONIC ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.z," + getShortcutLabel() + "_mat.w";
+     300             : 
+     301          42 :   if( getName()=="Q1" ) {
+     302          19 :     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          42 :   readInputLine( sph_input );
+     313             : 
+     314             :   // Input for denominator (coord)
+     315          42 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+     316          42 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     317          42 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     318          84 :   readInputLine( getShortcutLabel() + "_denom_ones: ONES SIZE=" + size );
+     319          84 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat.w," + getShortcutLabel() + "_denom_ones" );
+     320          84 :   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          42 :   bool do_vmean; parseFlag("VMEAN",do_vmean);
+     325          42 :   bool do_vsum; parseFlag("VSUM",do_vsum);
+     326          42 :   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          42 :   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          42 :   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          84 :   createVectorNormInput( getShortcutLabel() + "_sp", getShortcutLabel() + "_norm", l, ".", "m" );
+     362             :   // And take average
+     363          84 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_norm," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     364          84 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+     365          42 : }
+     366             : 
+     367          43 : void Steinhardt::createVectorNormInput( const std::string& ilab, const std::string& olab, const int& l, const std::string& sep, const std::string& vlab ) {
+     368          43 :   std::string arg_inp, norm_input = olab + "2: COMBINE PERIODIC=NO POWERS=2,2"; std::string snum = getSymbol( -l );
+     369          86 :   arg_inp = " ARG=" + ilab + sep + "r" + vlab + "-" + snum +"," + ilab + sep + "i" + vlab + "-" + snum;
+     370         351 :   for(int i=-l+1; i<=l; ++i) {
+     371         308 :     snum = getSymbol( i );
+     372         616 :     arg_inp += "," + ilab + sep + "r" + vlab + "-" + snum + "," + ilab + sep + "i" + vlab + "-" + snum;
+     373             :     norm_input += ",2,2";
+     374             :   }
+     375          43 :   readInputLine( norm_input + arg_inp );
+     376          86 :   readInputLine( olab + ": CUSTOM ARG=" + olab + "2 FUNC=sqrt(x) PERIODIC=NO");
+     377          43 : }
+     378             : 
+     379         377 : std::string Steinhardt::getSymbol( const int& m ) const {
+     380         377 :   if( m<0 ) {
+     381         166 :     std::string num; Tools::convert( -1*m, num );
+     382         166 :     return "n" + num;
+     383         211 :   } else if( m>0 ) {
+     384         166 :     std::string num; Tools::convert( m, num );
+     385         166 :     return "p" + num;
+     386             :   }
+     387          45 :   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 000000000..0fe50566a --- /dev/null +++ b/coverage/symfunc/ThreeBodyGFunctions.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:949598.9 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7symfunc19ThreeBodyGFunctions29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE2
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC1ERKNS_13ActionOptionsE6
_ZN4PLMD7symfunc19ThreeBodyGFunctions16registerKeywordsERNS_8KeywordsE11
_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 000000000..82f6c73e2 --- /dev/null +++ b/coverage/symfunc/ThreeBodyGFunctions.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:949598.9 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19ThreeBodyGFunctions16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7symfunc19ThreeBodyGFunctions22getNumberOfDerivativesEv36
_ZN4PLMD7symfunc19ThreeBodyGFunctions9calculateEv19
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC1ERKNS_13ActionOptionsE6
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7symfunc19ThreeBodyGFunctions11performTaskERKjRNS_10MultiValueE472
_ZNK4PLMD7symfunc19ThreeBodyGFunctions29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_8KeywordsE2
+
+
+ + + +
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 000000000..c07f6939e --- /dev/null +++ b/coverage/symfunc/ThreeBodyGFunctions.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + 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:949598.9 %
Date:2024-10-17 16:45:00Functions:6785.7 %
+
+ + + + + + + + +

+
          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             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
+      46             :   void calculate() override ;
+      47             :   unsigned getNumberOfDerivatives() override;
+      48             :   void performTask( const unsigned& task_index, MultiValue& myvals ) const override ;
+      49             : };
+      50             : 
+      51             : PLUMED_REGISTER_ACTION(ThreeBodyGFunctions,"GSYMFUNC_THREEBODY")
+      52             : 
+      53          11 : void ThreeBodyGFunctions::registerKeywords( Keywords& keys ) {
+      54          11 :   ActionWithVector::registerKeywords( keys ); keys.use("ARG");
+      55          22 :   keys.add("compulsory","WEIGHT","the matrix that contains the weights that should be used for each connection");
+      56          22 :   keys.add("numbered","FUNCTION","the parameters of the function you would like to compute");
+      57          11 :   ActionWithValue::useCustomisableComponents( keys );
+      58          11 : }
+      59             : 
+      60           6 : ThreeBodyGFunctions::ThreeBodyGFunctions(const ActionOptions&ao):
+      61             :   Action(ao),
+      62           6 :   ActionWithVector(ao)
+      63             : {
+      64           6 :   if( getNumberOfArguments()!=3 ) error("found wrong number of arguments in input");
+      65          12 :   std::vector<Value*> wval; parseArgumentList("WEIGHT",wval);
+      66           6 :   if( wval.size()!=1 ) error("keyword WEIGHT should be provided with the label of a single action");
+      67             : 
+      68          24 :   for(unsigned i=0; i<3; ++i) {
+      69          18 :     if( getPntrToArgument(i)->getRank()!=2 ) error("input argument should be a matrix");
+      70          18 :     if( wval[0]->getShape()[0]!=getPntrToArgument(i)->getShape()[0] || wval[0]->getShape()[1]!=getPntrToArgument(i)->getShape()[1] ) error("mismatched shapes of matrices in input");
+      71             :   }
+      72           6 :   log.printf("  using bond weights from matrix labelled %s \n",wval[0]->getName().c_str() );
+      73             :   // Rerequest the arguments
+      74           6 :   std::vector<Value*> myargs( getArguments() ); myargs.push_back( wval[0] ); requestArguments( myargs );
+      75          30 :   for(unsigned i=0; i<myargs.size(); ++i) myargs[i]->buildDataStore();
+      76           6 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0];
+      77             : 
+      78             :   // And now read the functions to compute
+      79           6 :   for(int i=1;; i++) {
+      80          17 :     std::string myfunc, mystr, lab, num; Tools::convert(i,num);
+      81          34 :     if( !parseNumbered("FUNCTION",i,mystr ) ) break;
+      82          11 :     std::vector<std::string> data=Tools::getWords(mystr);
+      83          22 :     if( !Tools::parse(data,"LABEL",lab ) ) error("found no LABEL in FUNCTION" + num + " specification");
+      84          11 :     addComponent( lab, shape ); componentIsNotPeriodic( lab );
+      85          22 :     if( !Tools::parse(data,"FUNC",myfunc) ) error("found no FUNC in FUNCTION" + num + " specification");
+      86          11 :     log.printf("  component labelled %s is computed using %s \n",lab.c_str(), myfunc.c_str() );
+      87          11 :     functions.push_back( LeptonCall() ); std::vector<std::string> argnames(1); argnames[0]="ajik";
+      88          15 :     if( myfunc.find("rij")!=std::string::npos ) argnames.push_back("rij");
+      89          11 :     if( myfunc.find("rik")!=std::string::npos ) {
+      90           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");
+      91           8 :       argnames.push_back("rik");
+      92             :     }
+      93          11 :     if( myfunc.find("rjk")!=std::string::npos ) {
+      94           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");
+      95           6 :       argnames.push_back("rjk");
+      96             :     }
+      97          11 :     functions[i-1].set( myfunc, argnames, this, true );
+      98          22 :   }
+      99           6 :   checkRead();
+     100           6 : }
+     101             : 
+     102           2 : std::string ThreeBodyGFunctions::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
+     103           3 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     104           6 :     if( getConstPntrToComponent(i)->getName().find(cname)!=std::string::npos ) {
+     105           4 :       std::string num; Tools::convert( i+1, num ); return "the function defined by the FUNCTION" + num + " keyword";
+     106             :     }
+     107             :   }
+     108           0 :   plumed_error(); return "";
+     109             : }
+     110             : 
+     111          36 : unsigned ThreeBodyGFunctions::getNumberOfDerivatives() {
+     112          36 :   return 0;
+     113             : }
+     114             : 
+     115          19 : void ThreeBodyGFunctions::calculate() {
+     116          19 :   runAllTasks();
+     117          19 : }
+     118             : 
+     119         472 : void ThreeBodyGFunctions::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+     120             :   const Value* wval = getPntrToArgument(3);
+     121             :   const Value* xval = getPntrToArgument(0);
+     122             :   const Value* yval = getPntrToArgument(1);
+     123             :   const Value* zval = getPntrToArgument(2);
+     124         472 :   Angle angle; Vector disti, distj; unsigned matsize = wval->getNumberOfValues();
+     125         472 :   std::vector<double> values(4); std::vector<Vector> der_i(4), der_j(4);
+     126         472 :   unsigned nbonds = wval->getRowLength( task_index ), ncols = wval->getShape()[1];
+     127       13880 :   for(unsigned i=0; i<nbonds; ++i) {
+     128       13408 :     unsigned ipos = ncols*task_index + wval->getRowIndex( task_index, i );
+     129       13408 :     double weighti = wval->get( ipos );
+     130       13408 :     if( weighti<epsilon ) continue ;
+     131        6824 :     disti[0] = xval->get( ipos );
+     132        6824 :     disti[1] = yval->get( ipos );
+     133        6824 :     disti[2] = zval->get( ipos );
+     134        6824 :     values[1] = disti.modulo2(); der_i[1]=2*disti; der_i[2].zero();
+     135      189327 :     for(unsigned j=0; j<i; ++j) {
+     136      182503 :       unsigned jpos = ncols*task_index + wval->getRowIndex( task_index, j );
+     137      182503 :       double weightj = wval->get( jpos );
+     138      182503 :       if( weightj<epsilon ) continue ;
+     139      137009 :       distj[0] = xval->get( jpos );
+     140      137009 :       distj[1] = yval->get( jpos );
+     141      137009 :       distj[2] = zval->get( jpos );
+     142      137009 :       values[2] = distj.modulo2(); der_j[1].zero(); der_j[2]=2*distj;
+     143      137009 :       der_i[3] = ( disti - distj ); values[3] = der_i[3].modulo2();
+     144      137009 :       der_i[3] = 2*der_i[3]; der_j[3] = -der_i[3];
+     145             :       // Compute angle between bonds
+     146      137009 :       values[0] = angle.compute( disti, distj, der_i[0], der_j[0] );
+     147             :       // Compute product of weights
+     148      137009 :       double weightij = weighti*weightj;
+     149             :       // Now compute all symmetry functions
+     150      414532 :       for(unsigned n=0; n<functions.size(); ++n) {
+     151      277523 :         unsigned ostrn = getConstPntrToComponent(n)->getPositionInStream();
+     152      277523 :         double nonweight = functions[n].evaluate( values ); myvals.addValue( ostrn, nonweight*weightij );
+     153      277523 :         if( doNotCalculateDerivatives() ) continue;
+     154             : 
+     155      567230 :         for(unsigned m=0; m<functions[n].getNumberOfArguments(); ++m) {
+     156      296550 :           double der = weightij*functions[n].evaluateDeriv( m, values );
+     157      296550 :           myvals.addDerivative( ostrn, ipos, der*der_i[m][0] );
+     158      296550 :           myvals.addDerivative( ostrn, matsize+ipos, der*der_i[m][1] );
+     159      296550 :           myvals.addDerivative( ostrn, 2*matsize+ipos, der*der_i[m][2] );
+     160      296550 :           myvals.addDerivative( ostrn, jpos, der*der_j[m][0] );
+     161      296550 :           myvals.addDerivative( ostrn, matsize+jpos, der*der_j[m][1] );
+     162      296550 :           myvals.addDerivative( ostrn, 2*matsize+jpos, der*der_j[m][2] );
+     163             :         }
+     164      270680 :         myvals.addDerivative( ostrn, 3*matsize+ipos, nonweight*weightj );
+     165      270680 :         myvals.addDerivative( ostrn, 3*matsize+jpos, nonweight*weighti );
+     166             :       }
+     167             :     }
+     168             :   }
+     169         472 :   if( doNotCalculateDerivatives() ) return ;
+     170             : 
+     171             :   // And update the elements that have derivatives
+     172             :   // Needs a separate loop here as there may be forces from j
+     173        8320 :   for(unsigned i=0; i<nbonds; ++i) {
+     174        8192 :     unsigned ipos = ncols*task_index + wval->getRowIndex( task_index, i );
+     175        8192 :     double weighti = wval->get( ipos );
+     176        8192 :     if( weighti<epsilon ) continue ;
+     177             : 
+     178       16286 :     for(unsigned n=0; n<functions.size(); ++n) {
+     179       11416 :       unsigned ostrn = getConstPntrToComponent(n)->getPositionInStream();
+     180       11416 :       myvals.updateIndex( ostrn, ipos ); myvals.updateIndex( ostrn, matsize+ipos );
+     181       11416 :       myvals.updateIndex( ostrn, 2*matsize+ipos ); myvals.updateIndex( ostrn, 3*matsize+ipos );
+     182             :     }
+     183             :   }
+     184             : }
+     185             : 
+     186             : }
+     187             : }
+
+
+
+ + + + +
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 000000000..7190041fa --- /dev/null +++ b/coverage/symfunc/index-sort-f.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - symfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfuncHitTotalCoverage
Test:plumed test coverageLines:78686291.2 %
Date:2024-10-17 16:45:00Functions:516381.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
LocalCrystalinity.cpp +
100.0%
+
100.0 %35 / 3566.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
AtomicSMAC.cpp +
91.3%91.3%
+
91.3 %42 / 4666.7 %2 / 3
RadialTetra.cpp +
88.2%88.2%
+
88.2 %30 / 3466.7 %2 / 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
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
CoordinationNumbers.cpp +
98.6%98.6%
+
98.6 %68 / 6980.0 %4 / 5
ThreeBodyGFunctions.cpp +
98.9%98.9%
+
98.9 %94 / 9585.7 %6 / 7
Fccubic.cpp +
100.0%
+
100.0 %30 / 30100.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 000000000..1890a8486 --- /dev/null +++ b/coverage/symfunc/index-sort-l.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - symfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfuncHitTotalCoverage
Test:plumed test coverageLines:78686291.2 %
Date:2024-10-17 16:45:00Functions:516381.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
ThreeBodyGFunctions.cpp +
98.9%98.9%
+
98.9 %94 / 9585.7 %6 / 7
CylindricalHarmonic.cpp +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
Fccubic.cpp +
100.0%
+
100.0 %30 / 30100.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
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/index.html b/coverage/symfunc/index.html new file mode 100644 index 000000000..615c2d28d --- /dev/null +++ b/coverage/symfunc/index.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - symfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfuncHitTotalCoverage
Test:plumed test coverageLines:78686291.2 %
Date:2024-10-17 16:45:00Functions:516381.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 %30 / 30100.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 +
98.9%98.9%
+
98.9 %94 / 9585.7 %6 / 7
+
+
+ + + + +
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 000000000..164e70b0a --- /dev/null +++ b/coverage/tools/Angle.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d25ed84fe --- /dev/null +++ b/coverage/tools/Angle.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..62d4a219d --- /dev/null +++ b/coverage/tools/Angle.cpp.gcov.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..a09c95c53 --- /dev/null +++ b/coverage/tools/AtomNumber.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj696
_ZN4PLMD10AtomNumber9setSerialEj1539580
+
+
+ + + +
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 000000000..7e4ca7034 --- /dev/null +++ b/coverage/tools/AtomNumber.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj696
_ZN4PLMD10AtomNumber9setSerialEj1539580
+
+
+ + + +
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 000000000..ae3292aed --- /dev/null +++ b/coverage/tools/AtomNumber.h.gcov.html @@ -0,0 +1,228 @@ + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-10-17 16:45:00Functions: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    11855945 : AtomNumber::AtomNumber() {
+      75    11855897 :   index_=0;
+      76             : }
+      77             : 
+      78             : inline
+      79             : AtomNumber::AtomNumber(unsigned i) {
+      80             :   index_=i;
+      81             : }
+      82             : 
+      83             : inline
+      84             : unsigned AtomNumber::serial()const {
+      85     1164302 :   return index_+1;
+      86             : }
+      87             : 
+      88             : inline
+      89             : unsigned AtomNumber::index()const {
+      90    32376726 :   return index_;
+      91             : }
+      92             : 
+      93             : inline
+      94     1539580 : AtomNumber & AtomNumber::setSerial(unsigned i) {
+      95     1539580 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+      96     1539580 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+      97     1539580 :   index_=i-1;
+      98     1539580 :   return *this;
+      99             : }
+     100             : 
+     101             : inline
+     102             : AtomNumber & AtomNumber::setIndex(unsigned i) {
+     103          56 :   index_=i;
+     104             :   return *this;
+     105             : }
+     106             : 
+     107             : inline
+     108         696 : AtomNumber AtomNumber::serial(unsigned i) {
+     109         696 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+     110         696 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+     111         696 :   return AtomNumber(i-1);
+     112             : }
+     113             : 
+     114             : inline
+     115             : AtomNumber AtomNumber::index(unsigned i) {
+     116             :   return AtomNumber(i);
+     117             : }
+     118             : 
+     119             : inline
+     120             : bool operator<(const AtomNumber&a,const AtomNumber&b) {
+     121   378470091 :   return a.index_<b.index_;
+     122             : }
+     123             : 
+     124             : inline
+     125             : bool operator>(const AtomNumber&a,const AtomNumber&b) {
+     126     7680099 :   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   170528100 :   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 000000000..0ad76a7f8 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..c7560925b --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..ba47a7ae7 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.gcov.html @@ -0,0 +1,363 @@ + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..489f33484 --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..a72b1d6bf --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..d66127217 --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.gcov.html @@ -0,0 +1,196 @@ + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..7eafc91e5 --- /dev/null +++ b/coverage/tools/CheckInRange.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZNK4PLMD12CheckInRange5checkERKSt6vectorIdSaIdEE139130
+
+
+ + + +
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 000000000..8196387b9 --- /dev/null +++ b/coverage/tools/CheckInRange.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12CheckInRange9setBoundsERKjRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EESD_RS9_43
_ZNK4PLMD12CheckInRange5checkERKSt6vectorIdSaIdEE139130
_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 000000000..a0092ded4 --- /dev/null +++ b/coverage/tools/CheckInRange.cpp.gcov.html @@ -0,0 +1,164 @@ + + + + + + + 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-10-17 16:45:00Functions: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      139130 : bool CheckInRange::check( const std::vector<double>& vals ) const {
+      81      191478 :   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 000000000..ce7255a11 --- /dev/null +++ b/coverage/tools/CheckInRange.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c30adfc7b --- /dev/null +++ b/coverage/tools/CheckInRange.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..00cc9361e --- /dev/null +++ b/coverage/tools/CheckInRange.h.gcov.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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         224 : 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 000000000..c92811a62 --- /dev/null +++ b/coverage/tools/Citations.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9CitationsE1773
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4684
_ZNK4PLMD9Citations5emptyEv32745
_ZN4PLMD9Citations5clearEv32800
+
+
+ + + +
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 000000000..98a675997 --- /dev/null +++ b/coverage/tools/Citations.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4684
_ZN4PLMD9Citations5clearEv32800
_ZN4PLMDlsERSoRKNS_9CitationsE1773
_ZNK4PLMD9Citations5emptyEv32745
+
+
+ + + +
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 000000000..a66aba791 --- /dev/null +++ b/coverage/tools/Citations.cpp.gcov.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions: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        4684 : std::string Citations::cite(const std::string & item) {
+      30             :   unsigned i;
+      31        9007 :   for(i=0; i<items.size(); ++i) if(items[i]==item) break;
+      32        4684 :   if(i==items.size()) items.push_back(item);
+      33        4684 :   plumed_assert(i<items.size());
+      34             :   std::string ret;
+      35        4684 :   Tools::convert(i+1,ret);
+      36        9368 :   ret="["+ret+"]";
+      37        4684 :   return ret;
+      38             : }
+      39             : 
+      40        1773 : std::ostream & operator<<(std::ostream &log,const Citations&cit) {
+      41        4388 :   for(unsigned i=0; i<cit.items.size(); ++i)
+      42        5230 :     log<<"  ["<<i+1<<"] "<<cit.items[i]<<"\n";
+      43        1773 :   return log;
+      44             : }
+      45             : 
+      46       32800 : void Citations::clear() {
+      47       32800 :   items.clear();
+      48       32800 : }
+      49             : 
+      50       32745 : bool Citations::empty()const {
+      51       32745 :   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 000000000..aa11091c1 --- /dev/null +++ b/coverage/tools/Citations.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Citations.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..7846278b3 --- /dev/null +++ b/coverage/tools/Citations.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Citations.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..54478d3a2 --- /dev/null +++ b/coverage/tools/Citations.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + LCOV - plumed test coverage - tools/Citations.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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      806680 : 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 000000000..8315b1e6f --- /dev/null +++ b/coverage/tools/Communicator.cpp.func-sort-c.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-10-17 16:45:00Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatoraSERKS0_0
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv24
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1227
_ZN4PLMD12Communicator8Get_commEv1877
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2389
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5850
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7635
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14986
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15394
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15394
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv79605
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv97984
_ZN4PLMD12CommunicatorD0Ev1619116
_ZN4PLMD12CommunicatorC2Ev1622345
_ZN4PLMD12CommunicatorD2Ev1622345
_ZNK4PLMD12Communicator8Get_sizeEv2971978
_ZN4PLMD12Communicator3SumENS0_4DataE4531013
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4774646
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv5202175
_ZNK4PLMD12Communicator7BarrierEv5208094
_ZN4PLMD12Communicator5BcastENS0_4DataEi5535312
_ZNK4PLMD12Communicator8Get_rankEv7770005
_ZN4PLMD12Communicator11initializedEv27727211
+
+
+ + + +
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 000000000..4d462ecf6 --- /dev/null +++ b/coverage/tools/Communicator.cpp.func.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-10-17 16:45:00Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv24
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4774646
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv97984
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv79605
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv5202175
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator11initializedEv27727211
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator3SumENS0_4DataE4531013
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15394
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator5BcastENS0_4DataEi5535312
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15394
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14986
_ZN4PLMD12Communicator8Get_commEv1877
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2389
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1227
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5850
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatorC2Ev1622345
_ZN4PLMD12CommunicatorD0Ev1619116
_ZN4PLMD12CommunicatorD2Ev1622345
_ZN4PLMD12CommunicatoraSERKS0_0
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7635
_ZNK4PLMD12Communicator7BarrierEv5208094
_ZNK4PLMD12Communicator8Get_rankEv7770005
_ZNK4PLMD12Communicator8Get_sizeEv2971978
+
+
+ + + +
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 000000000..c704416e8 --- /dev/null +++ b/coverage/tools/Communicator.cpp.gcov.html @@ -0,0 +1,394 @@ + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-10-17 16:45:00Functions: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     1622345 : Communicator::Communicator()
+      40             : #ifdef __PLUMED_HAS_MPI
+      41     1622345 :   : communicator(MPI_COMM_SELF)
+      42             : #endif
+      43             : {
+      44     1622345 : }
+      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     7770005 : int Communicator::Get_rank()const {
+      60     7770005 :   int r=0;
+      61             : #ifdef __PLUMED_HAS_MPI
+      62     7770005 :   if(initialized()) MPI_Comm_rank(communicator,&r);
+      63             : #endif
+      64     7770005 :   return r;
+      65             : }
+      66             : 
+      67     2971978 : int Communicator::Get_size()const {
+      68     2971978 :   int s=1;
+      69             : #ifdef __PLUMED_HAS_MPI
+      70     2971978 :   if(initialized()) MPI_Comm_size(communicator,&s);
+      71             : #endif
+      72     2971978 :   return s;
+      73             : }
+      74             : 
+      75        2389 : void Communicator::Set_comm(MPI_Comm c) {
+      76             : #ifdef __PLUMED_HAS_MPI
+      77        2389 :   if(initialized()) {
+      78        1769 :     if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      79        1769 :     if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
+      80             :   }
+      81             : #else
+      82             :   (void) c;
+      83             : #endif
+      84        2389 : }
+      85             : 
+      86     3241461 : Communicator::~Communicator() {
+      87             : #ifdef __PLUMED_HAS_MPI
+      88     1622345 :   if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      89             : #endif
+      90     3241461 : }
+      91             : 
+      92        1227 : void Communicator::Set_comm(const TypesafePtr & val) {
+      93             : #ifdef __PLUMED_HAS_MPI
+      94        1227 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+      95        2454 :   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        1227 : }
+     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     5535312 : void Communicator::Bcast(Data data,int root) {
+     126             : #if defined(__PLUMED_HAS_MPI)
+     127     5535312 :   if(initialized()) MPI_Bcast(data.pointer,data.size,data.type,root,communicator);
+     128             : #else
+     129             :   (void) data;
+     130             :   (void) root;
+     131             : #endif
+     132     5535312 : }
+     133             : 
+     134     4531013 : void Communicator::Sum(Data data) {
+     135             : #if defined(__PLUMED_HAS_MPI)
+     136     4531013 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_SUM,communicator);
+     137             : #else
+     138             :   (void) data;
+     139             : #endif
+     140     4531013 : }
+     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       15394 : Communicator::Request Communicator::Isend(ConstData data,int source,int tag) {
+     167             :   Request req;
+     168             : #ifdef __PLUMED_HAS_MPI
+     169       15394 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     170       15394 :   void*s=const_cast<void*>((const void*)data.pointer);
+     171       15394 :   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       15394 :   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       15394 : void Communicator::Recv(Data data,int source,int tag,Status&status) {
+     228             : #ifdef __PLUMED_HAS_MPI
+     229       15394 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     230       15394 :   if(&status==&StatusIgnore) MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,MPI_STATUS_IGNORE);
+     231        7635 :   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       15394 : }
+     240             : 
+     241     5208094 : void Communicator::Barrier()const {
+     242             : #ifdef __PLUMED_HAS_MPI
+     243     5208094 :   if(initialized()) MPI_Barrier(communicator);
+     244             : #endif
+     245     5208094 : }
+     246             : 
+     247        1877 : MPI_Comm & Communicator::Get_comm() {
+     248        1877 :   return communicator;
+     249             : }
+     250             : 
+     251    27727211 : bool Communicator::initialized() {
+     252             : #if defined(__PLUMED_HAS_MPI)
+     253    27727211 :   int flag=0;
+     254    27727211 :   MPI_Initialized(&flag);
+     255    27727211 :   if(flag) return true;
+     256    18171004 :   else return false;
+     257             : #endif
+     258             :   return false;
+     259             : }
+     260             : 
+     261       14986 : void Communicator::Request::wait(Status&s) {
+     262             : #ifdef __PLUMED_HAS_MPI
+     263       14986 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     264       14986 :   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       14986 : }
+     271             : 
+     272             : #ifdef __PLUMED_HAS_MPI
+     273           0 : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_FLOAT;}
+     274     4774646 : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_DOUBLE;}
+     275       97984 : template<> MPI_Datatype Communicator::getMPIType<int>()   { return MPI_INT;}
+     276         295 : template<> MPI_Datatype Communicator::getMPIType<char>()   { return MPI_CHAR;}
+     277       79605 : template<> MPI_Datatype Communicator::getMPIType<unsigned>()   { return MPI_UNSIGNED;}
+     278          24 : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_UNSIGNED;}
+     279     5202175 : 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        7635 : int Communicator::Status::Get_count(MPI_Datatype type)const {
+     306             :   int i;
+     307             : #ifdef __PLUMED_HAS_MPI
+     308        7635 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     309        7635 :   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        7635 :   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 000000000..b76d322c2 --- /dev/null +++ b/coverage/tools/Communicator.h.func-sort-c.html @@ -0,0 +1,312 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZN4PLMD12Communicator3SumISt6vectorINS_13TensorGenericILj3ELj3EEESaIS4_EEEEvRT_16
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE24
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i24
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator5IsendINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator9ConstDataC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator9AllgatherIiSt6vectorIiSaIiEEEEvRKT_RT0_131
_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_i431
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator9AllgatherIdSt6vectorIdSaIdEEEEvRKT_RT0_565
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator3SumIjEEvPT_i601
_ZN4PLMD12Communicator3SumIjEEvRT_1084
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_1535
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE2246
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_4804
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE4806
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7634
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7634
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7634
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7634
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7634
_ZN4PLMD12Communicator3SumISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEEvRT_11179
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator10AllgathervIjjEEvPKT_iPT0_PKiS8_18459
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumINS_13TensorGenericILj3ELj3EEEEEvRT_20641
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_39935
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE40281
_ZN4PLMD12Communicator5BcastIiEEvRT_i52127
_ZN4PLMD12Communicator3SumIdEEvPT_i88362
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i279099
_ZN4PLMD12Communicator3SumIdEEvRT_2034363
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2313608
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2598078
_ZN4PLMD12Communicator5BcastImEEvRT_i5202175
+
+
+ + + +
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 000000000..d5abe3ccf --- /dev/null +++ b/coverage/tools/Communicator.h.func.html @@ -0,0 +1,312 @@ + + + + + + + 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-10-17 16:45:00Functions: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_2313608
_ZN4PLMD12Communicator3SumISt6vectorIfSaIfEEEEvRT_0
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_1535
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_39935
_ZN4PLMD12Communicator3SumIdEEvPT_i88362
_ZN4PLMD12Communicator3SumIdEEvRT_2034363
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumIiEEvRT_204
_ZN4PLMD12Communicator3SumIjEEvPT_i601
_ZN4PLMD12Communicator3SumIjEEvRT_1084
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE24
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2598078
_ZN4PLMD12Communicator4DataC2IfEERSt6vectorIT_SaIS4_EE0
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE2246
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE40281
_ZN4PLMD12Communicator4DataC2IyEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7634
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7634
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i134
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i24
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i279099
_ZN4PLMD12Communicator5BcastISt6vectorIfSaIfEEEEvRT_i0
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator5BcastISt6vectorIySaIyEEEEvRT_i2
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator5BcastIiEEvRT_i52127
_ZN4PLMD12Communicator5BcastIjEEvRT_i431
_ZN4PLMD12Communicator5BcastImEEvRT_i5202175
_ZN4PLMD12Communicator5IsendINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7634
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7634
_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_countIiEEiv7634
+
+
+ + + +
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 000000000..b147706aa --- /dev/null +++ b/coverage/tools/Communicator.h.gcov.html @@ -0,0 +1,328 @@ + + + + + + + LCOV - plumed test coverage - tools/Communicator.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404393.0 %
Date:2024-10-17 16:45:00Functions: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     2918284 :     template <typename T> Data(T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+      73             : /// Init from reference
+      74    14582186 :     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     2651828 :     template <typename T> explicit Data(std::vector<T>&v) {
+      85     2651999 :       Data d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+      86     2651828 :     }
+      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        7634 :     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      108444 :   template <class T> void Sum(T*buf,int count) {Sum(Data(buf,count));}
+     182             : /// Wrapper for MPI_Allreduce with MPI_SUM (reference)
+     183     4422565 :   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     5535303 :   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       15268 :   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       15268 :   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 000000000..04a01433e --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..1102593a7 --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..8c6a47389 --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.gcov.html @@ -0,0 +1,142 @@ + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..f780870be --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader14isPlumedGlobalEv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenC2EPKv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenD2Ev0
_ZN4PLMD8DLLoader9installedEv42
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZNK4PLMD8DLLoader10getHandlesEv55044
_ZN4PLMD8DLLoaderC2Ev812028
_ZN4PLMD8DLLoaderD2Ev812028
+
+
+ + + +
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 000000000..c23a0342f --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-10-17 16:45:00Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader14isPlumedGlobalEv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenC2EPKv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenD2Ev0
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8DLLoader9installedEv42
_ZN4PLMD8DLLoaderC2Ev812028
_ZN4PLMD8DLLoaderD2Ev812028
_ZNK4PLMD8DLLoader10getHandlesEv55044
+
+
+ + + +
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 000000000..5669b958f --- /dev/null +++ b/coverage/tools/DLLoader.cpp.gcov.html @@ -0,0 +1,216 @@ + + + + + + + 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-10-17 16:45:00Functions: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      812028 : DLLoader::~DLLoader() {
+      59      812028 :   auto debug=std::getenv("PLUMED_LOAD_DEBUG");
+      60             : #ifdef __PLUMED_HAS_DLOPEN
+      61      812028 :   if(debug) std::fprintf(stderr,"delete dlloader\n");
+      62      812079 :   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      812028 :   if(debug) std::fprintf(stderr,"end delete dlloader\n");
+      70             : #endif
+      71      812028 : }
+      72             : 
+      73      812028 : DLLoader::DLLoader() {
+      74             :   // do nothing
+      75      812028 : }
+      76             : 
+      77       55044 : const std::vector<void*> & DLLoader::getHandles() const noexcept {
+      78       55044 :   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/ERMSD.cpp.func-sort-c.html b/coverage/tools/ERMSD.cpp.func-sort-c.html new file mode 100644 index 000000000..94b6a7c33 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..7542ae009 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..70b71a8ce --- /dev/null +++ b/coverage/tools/ERMSD.cpp.gcov.html @@ -0,0 +1,379 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..2998fa8fb --- /dev/null +++ b/coverage/tools/ERMSD.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..31fa9e43e --- /dev/null +++ b/coverage/tools/ERMSD.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3b95f7f5d --- /dev/null +++ b/coverage/tools/ERMSD.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..dbf4ff21f --- /dev/null +++ b/coverage/tools/Exception.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9Exception5stackEv4
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE11
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE55
_ZN4PLMD9ExceptionlsERKNS0_8LocationE55
_ZN4PLMD9ExceptionC2Ev140
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE397
+
+
+ + + +
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 000000000..d1be1ac52 --- /dev/null +++ b/coverage/tools/Exception.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-10-17 16:45:00Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE55
_ZN4PLMD9ExceptionC2Ev140
_ZN4PLMD9ExceptionlsERKNS0_8LocationE55
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE11
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE397
_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 000000000..9a6771de0 --- /dev/null +++ b/coverage/tools/Exception.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-10-17 16:45:00Functions: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          55 : std::string simplify(const std::string & path)
+      41             : {
+      42             :   // using vector in place of stack
+      43             :   std::vector<std::string> v;
+      44          55 :   int n = path.length();
+      45             :   std::string ans;
+      46         179 :   for (int i = 0; i < n; i++) {
+      47         124 :     std::string dir = "";
+      48             :     // forming the current directory.
+      49        1095 :     while (i < n && path[i] != '/') {
+      50         971 :       dir += path[i];
+      51         971 :       i++;
+      52             :     }
+      53             : 
+      54             :     // if ".." , we pop.
+      55         124 :     if (dir == "..") {
+      56           4 :       if (!v.empty())
+      57             :         v.pop_back();
+      58             :     }
+      59         240 :     else if (dir == "." || dir == "") {
+      60             :       // do nothing (added for better understanding.)
+      61             :     }
+      62             :     else {
+      63             :       // push the current directory into the vector.
+      64         119 :       v.push_back(dir);
+      65             :     }
+      66             :   }
+      67             : 
+      68             :   // forming the ans
+      69             :   bool first=true;
+      70         170 :   for (const auto & i : v) {
+      71         115 :     if(!first) ans += "/";
+      72             :     first=false;
+      73             :     ans += i;
+      74             :   }
+      75             : 
+      76             :   // vector is empty
+      77          55 :   if (ans == "")
+      78           0 :     return "/";
+      79             : 
+      80             :   return ans;
+      81          55 : }
+      82             : 
+      83             : }
+      84             : 
+      85         140 : Exception::Exception()
+      86             : {
+      87             :   callstack.fill(nullptr);
+      88             : #ifdef __PLUMED_HAS_EXECINFO
+      89         140 :   callstack_n = backtrace(&callstack[0], callstack.size()-1);
+      90         140 :   const char* env=std::getenv("PLUMED_STACK_TRACE");
+      91         140 :   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         140 : }
+      98             : 
+      99         397 : Exception& Exception::operator<<(const std::string&msg)
+     100             : {
+     101         397 :   if(msg.length()>0) {
+     102         397 :     if(note) this->msg +="\n";
+     103         397 :     this->msg +=msg;
+     104         397 :     note=false;
+     105             :   }
+     106         397 :   return *this;
+     107             : }
+     108             : 
+     109          55 : Exception& Exception::operator<<(const Location&loc)
+     110             : {
+     111          55 :   if(loc.file) {
+     112             :     const std::size_t clinelen=1000;
+     113             :     char cline[clinelen];
+     114          55 :     std::snprintf(cline,clinelen,"%u",loc.line);
+     115          55 :     this->msg += "\n(";
+     116             :     try {
+     117         110 :       this->msg += simplify(loc.file);
+     118           0 :     } catch(...) {
+     119             :       // ignore
+     120           0 :     }
+     121             :     this->msg += ":";
+     122             :     this->msg += cline;
+     123             :     this->msg += ")";
+     124          55 :     if(loc.pretty && loc.pretty[0]) {
+     125             :       this->msg += " ";
+     126          55 :       this->msg += loc.pretty;
+     127             :     }
+     128             :   }
+     129          55 :   note=true;
+     130          55 :   return *this;
+     131             : }
+     132             : 
+     133          11 : Exception& Exception::operator<<(const Assertion&as)
+     134             : {
+     135          11 :   if(as.assertion) {
+     136          11 :     this->msg += "\n+++ assertion failed: ";
+     137          11 :     this->msg += as.assertion;
+     138             :   }
+     139          11 :   note=true;
+     140          11 :   return *this;
+     141             : }
+     142             : 
+     143           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 000000000..cc5abd3c5 --- /dev/null +++ b/coverage/tools/Exception.h.func-sort-c.html @@ -0,0 +1,628 @@ + + + + + + + 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-10-17 16:45:00Functions:3413924.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
_ZN4PLMD9ExceptionlsIA108_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA10_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA110_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA111_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA113_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA115_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA116_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA118_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA119_cEERS0_RKT_0
_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
_ZN4PLMD9ExceptionlsIA21_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA22_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_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
_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
_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
_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
_ZN4PLMD9ExceptionlsIlEERS0_RKT_0
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA2_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA35_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA43_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA56_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA83_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA89_cEERS0_RKT_1
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_2
_ZN4PLMD9ExceptionlsIA104_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA16_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA78_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA79_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA94_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA31_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA3_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_6
_ZN4PLMD9ExceptionlsIA39_cEERS0_RKT_6
_ZN4PLMD9ExceptionlsIA50_cEERS0_RKT_6
_ZN4PLMD9ExceptionlsIA66_cEERS0_RKT_7
_ZN4PLMD9ExceptionlsIA57_cEERS0_RKT_8
_ZN4PLMD9ExceptionlsISt17basic_string_viewIcSt11char_traitsIcEEEERS0_RKT_10
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_15
_ZN4PLMD9ExceptionlsIA20_cEERS0_RKT_22
_ZN4PLMD9ExceptionlsIjEERS0_RKT_22
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_24
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_24
_ZN4PLMD9ExceptionlsIA23_cEERS0_RKT_28
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZN4PLMD9ExceptionlsImEERS0_RKT_60
_ZN4PLMD9ExceptionC2ERKS0_70
_ZNK4PLMD9Exception4whatEv121
_ZN4PLMD9ExceptionD2Ev144
+
+
+ + + +
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 000000000..4131271e2 --- /dev/null +++ b/coverage/tools/Exception.h.func.html @@ -0,0 +1,628 @@ + + + + + + + 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-10-17 16:45:00Functions:3413924.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_2
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZN4PLMD9ExceptionC2ERKS0_70
_ZN4PLMD9ExceptionD0Ev0
_ZN4PLMD9ExceptionD2Ev144
_ZN4PLMD9ExceptionlsIA100_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA102_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA103_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA104_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA108_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA10_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA110_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA111_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA113_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA115_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA116_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA118_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA119_cEERS0_RKT_0
_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
_ZN4PLMD9ExceptionlsIA16_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA171_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA17_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_24
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_24
_ZN4PLMD9ExceptionlsIA20_cEERS0_RKT_22
_ZN4PLMD9ExceptionlsIA21_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA22_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA23_cEERS0_RKT_28
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_6
_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_6
_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_6
_ZN4PLMD9ExceptionlsIA51_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA52_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA53_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA54_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA55_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA56_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA57_cEERS0_RKT_8
_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_2
_ZN4PLMD9ExceptionlsIA79_cEERS0_RKT_2
_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_15
_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_22
_ZN4PLMD9ExceptionlsIlEERS0_RKT_0
_ZN4PLMD9ExceptionlsImEERS0_RKT_60
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZNK4PLMD9Exception4whatEv121
+
+
+ + + +
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 000000000..377d1bd22 --- /dev/null +++ b/coverage/tools/Exception.h.gcov.html @@ -0,0 +1,479 @@ + + + + + + + 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-10-17 16:45:00Functions:3413924.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          54 :     explicit Location(const char*file,unsigned line,const char* pretty=nullptr):
+     182          54 :       file(file),
+     183          54 :       line(line),
+     184          54 :       pretty(pretty)
+     185             :     {}
+     186             :   };
+     187             : 
+     188             : /// Auxiliary containing the failed assertion.
+     189             : /// Typically used from the macros below.
+     190             :   class Assertion {
+     191             :   public:
+     192             :     const char*assertion;
+     193          10 :     explicit Assertion(const char*assertion=nullptr):
+     194          10 :       assertion(assertion)
+     195             :     {}
+     196             :   };
+     197             : 
+     198             : /// Auxiliary class used to throw exceptions.
+     199             : /// It just defines <<= operator so that:
+     200             : /// - exceptions can be thrown calling std::throw_with_nested
+     201             : ///   with a "throw like" syntax
+     202             : /// - precedence is the same as the throw operator
+     203             : /// (see https://en.cppreference.com/w/cpp/language/operator_precedence)
+     204             :   class Throw {
+     205             :   public:
+     206             :     template <typename E>
+     207           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          70 :   Exception(const Exception & e):
+     231          70 :     msg(e.msg),
+     232          70 :     note(e.note),
+     233          70 :     callstack(e.callstack),
+     234          70 :     callstack_n(e.callstack_n),
+     235          70 :     stackTrace(e.stackTrace)
+     236             :   {
+     237          70 :   }
+     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         121 :   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         144 :   ~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         267 :   Exception& operator<<(const T & x) {
+     288         267 :     stream<<x;
+     289         267 :     (*this)<<stream.str();
+     290         267 :     stream.str("");
+     291         267 :     return *this;
+     292             :   }
+     293             : };
+     294             : 
+     295             : /// Class representing a generic error
+     296         143 : class ExceptionError :
+     297             :   public Exception {
+     298             : public:
+     299           1 :   using Exception::Exception;
+     300             :   template<typename T>
+     301             :   ExceptionError& operator<<(const T & x) {
+     302          89 :     *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         111 : class ExceptionTypeError :
+     321             :   public Exception {
+     322             : public:
+     323           0 :   using Exception::Exception;
+     324             :   template<typename T>
+     325             :   ExceptionTypeError& operator<<(const T & x) {
+     326         107 :     *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 000000000..13a7710d0 --- /dev/null +++ b/coverage/tools/FileBase.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-10-17 16:45:00Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase5closeEv1017
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2019
_ZN4PLMD8FileBase4linkERNS_6ActionE4310
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE5338
_ZN4PLMD8FileBase5flushEv5681
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev6150
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7345
_ZN4PLMD8FileBase4linkEP8_IO_FILE21179
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE812233
_ZN4PLMD8FileBase6isOpenEv814296
_ZN4PLMD8FileBaseC2Ev833684
_ZN4PLMD8FileBaseD2Ev833684
_ZNK4PLMD8FileBasecvbEv31252080
+
+
+ + + +
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 000000000..56d8635ec --- /dev/null +++ b/coverage/tools/FileBase.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-10-17 16:45:00Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7345
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase4linkEP8_IO_FILE21179
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE5338
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE812233
_ZN4PLMD8FileBase4linkERNS_6ActionE4310
_ZN4PLMD8FileBase5closeEv1017
_ZN4PLMD8FileBase5flushEv5681
_ZN4PLMD8FileBase6isOpenEv814296
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2019
_ZN4PLMD8FileBaseC2Ev833684
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBaseD2Ev833684
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev6150
_ZNK4PLMD8FileBasecvbEv31252080
+
+
+ + + +
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 000000000..ff49c527f --- /dev/null +++ b/coverage/tools/FileBase.cpp.gcov.html @@ -0,0 +1,251 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-10-17 16:45:00Functions: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       21179 : FileBase& FileBase::link(FILE*fp) {
+      43       21179 :   plumed_massert(!this->fp,"cannot link an already open file");
+      44       21179 :   this->fp=fp;
+      45       21179 :   cloned=true;
+      46       21179 :   return *this;
+      47             : }
+      48             : 
+      49        5681 : FileBase& FileBase::flush() {
+      50        5681 :   if(fp) fflush(fp);
+      51        5681 :   return *this;
+      52             : }
+      53             : 
+      54      812233 : FileBase& FileBase::link(Communicator&comm) {
+      55      812233 :   plumed_massert(!fp,"cannot link an already open file");
+      56      812233 :   this->comm=&comm;
+      57      812233 :   return *this;
+      58             : }
+      59             : 
+      60        5338 : FileBase& FileBase::link(PlumedMain&plumed) {
+      61        5338 :   plumed_massert(!fp,"cannot link an already open file");
+      62        5338 :   this->plumed=&plumed;
+      63        5338 :   link(plumed.comm);
+      64        5338 :   return *this;
+      65             : }
+      66             : 
+      67        4310 : FileBase& FileBase::link(Action&action) {
+      68        4310 :   plumed_massert(!fp,"cannot link an already open file");
+      69        4310 :   this->action=&action;
+      70        4310 :   link(action.plumed);
+      71        4310 :   return *this;
+      72             : }
+      73             : 
+      74        2019 : bool FileBase::FileExist(const std::string& path) {
+      75             :   bool do_exist=false;
+      76        4038 :   this->path=appendSuffix(path,getSuffix());
+      77        2019 :   mode="r";
+      78             :   // first try with suffix
+      79        2019 :   FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      80             : // call fclose when ff goes out of scope
+      81        1520 :   auto deleter=[](auto f) { if(f) std::fclose(f); };
+      82             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(ff,deleter);
+      83             : 
+      84        2019 :   if(!ff) {
+      85             :     this->path=path;
+      86             :     // then try without suffic
+      87         499 :     ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      88             :     mode="r";
+      89             :   }
+      90        2019 :   if(ff) do_exist=true;
+      91        2019 :   if(comm) comm->Barrier();
+      92        2019 :   return do_exist;
+      93             : }
+      94             : 
+      95      814296 : bool FileBase::isOpen() {
+      96             :   bool isopen=false;
+      97      814296 :   if(fp) isopen=true;
+      98      814296 :   return isopen;
+      99             : }
+     100             : 
+     101        1017 : void        FileBase::close() {
+     102        1017 :   plumed_assert(!cloned);
+     103        1017 :   eof=false;
+     104        1017 :   err=false;
+     105        1017 :   if(fp)   std::fclose(fp);
+     106             : #ifdef __PLUMED_HAS_ZLIB
+     107        1017 :   if(gzfp) gzclose(gzFile(gzfp));
+     108             : #endif
+     109        1017 :   fp=NULL;
+     110        1017 :   gzfp=NULL;
+     111        1017 : }
+     112             : 
+     113      833684 : FileBase::FileBase():
+     114      833684 :   fp(NULL),
+     115      833684 :   gzfp(NULL),
+     116      833684 :   comm(NULL),
+     117      833684 :   plumed(NULL),
+     118      833684 :   action(NULL),
+     119      833684 :   cloned(false),
+     120      833684 :   eof(false),
+     121      833684 :   err(false),
+     122      833684 :   heavyFlush(false),
+     123      833684 :   enforcedSuffix_(false)
+     124             : {
+     125      833684 : }
+     126             : 
+     127      833684 : FileBase::~FileBase()
+     128             : {
+     129      833684 :   if(plumed) plumed->eraseFile(*this);
+     130      833684 :   if(!cloned && fp)   std::fclose(fp);
+     131             : #ifdef __PLUMED_HAS_ZLIB
+     132      833684 :   if(!cloned && gzfp) gzclose(gzFile(gzfp));
+     133             : #endif
+     134      833684 : }
+     135             : 
+     136    31252080 : FileBase::operator bool()const {
+     137    31252080 :   return !eof;
+     138             : }
+     139             : 
+     140        7345 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) {
+     141        7345 :   if(path=="/dev/null") return path; // do not append a suffix to /dev/null
+     142        7170 :   std::string ret=path;
+     143        7170 :   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        7170 :   if(ext.length()>0) {
+     154        5057 :     int l=path.length()-(ext.length()+1);
+     155        5057 :     plumed_assert(l>=0);
+     156        5057 :     ret.resize(l);
+     157             :   }
+     158             :   ret+=suffix;
+     159       12227 :   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        6150 : std::string FileBase::getSuffix()const {
+     170        6150 :   if(enforcedSuffix_) return enforcedSuffix;
+     171        5886 :   if(plumed) return plumed->getSuffix();
+     172         683 :   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 000000000..79c448901 --- /dev/null +++ b/coverage/tools/FileBase.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d5e0bd49d --- /dev/null +++ b/coverage/tools/FileBase.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..8bef94a83 --- /dev/null +++ b/coverage/tools/FileBase.h.gcov.html @@ -0,0 +1,228 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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    18145736 :   class FieldBase {
+      48             : // everything is public to simplify usage
+      49             :   public:
+      50             :     std::string name;
+      51             :     std::string value;
+      52             :     bool constant;
+      53    16856431 :     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         871 :   return path;
+     138             : }
+     139             : 
+     140             : inline
+     141             : std::string FileBase::getMode()const {
+     142         220 :   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 000000000..a6daba7a4 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_12
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_96
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_19471
_ZN4PLMD11ForwardDeclINS_10PlumedMain15DeprecatedAtomsEEC2IJRS1_EEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1619116
+
+
+ + + +
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 000000000..e3decf272 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_10PlumedMain15DeprecatedAtomsEEC2IJRS1_EEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1619116
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_96
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_19471
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_806680
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_12
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_806680
+
+
+ + + +
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 000000000..fd4afd646 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.gcov.html @@ -0,0 +1,131 @@ + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions: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     3250647 : 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     8898815 : ForwardDecl<T>::ForwardDecl(Args &&...args):
+      49     8092135 :   std::unique_ptr<T>(std::make_unique<T>(std::forward<Args>(args)...))
+      50     8898815 : {}
+      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 000000000..7fbaa4e7d --- /dev/null +++ b/coverage/tools/Grid.cpp.func-sort-c.html @@ -0,0 +1,712 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2dd9fa550 --- /dev/null +++ b/coverage/tools/Grid.cpp.func.html @@ -0,0 +1,712 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1ab83ce3b --- /dev/null +++ b/coverage/tools/Grid.cpp.gcov.html @@ -0,0 +1,1189 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..14ab934bf --- /dev/null +++ b/coverage/tools/Grid.h.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d0a0c1e77 --- /dev/null +++ b/coverage/tools/Grid.h.func.html @@ -0,0 +1,172 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..990780ca2 --- /dev/null +++ b/coverage/tools/Grid.h.gcov.html @@ -0,0 +1,695 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..13d8446eb --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7011859.3 %
Date:2024-10-17 16:45:00Functions: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
_ZN4PLMD13HistogramBeadC2Ev260467
_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 000000000..2bd5a8bfa --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7011859.3 %
Date:2024-10-17 16:45:00Functions: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
_ZN4PLMD13HistogramBeadC2Ev260467
_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 000000000..1fcdf9ba4 --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.gcov.html @@ -0,0 +1,341 @@ + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7011859.3 %
Date:2024-10-17 16:45:00Functions: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      260467 : HistogramBead::HistogramBead():
+      94      260467 :   init(false),
+      95      260467 :   lowb(0.0),
+      96      260467 :   highb(0.0),
+      97      260467 :   width(0.0),
+      98      260467 :   cutoff(std::numeric_limits<double>::max()),
+      99      260467 :   type(gaussian),
+     100      260467 :   periodicity(unset),
+     101      260467 :   min(0.0),
+     102      260467 :   max(0.0),
+     103      260467 :   max_minus_min(0.0),
+     104      260467 :   inv_max_minus_min(0.0)
+     105             : {
+     106      260467 : }
+     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 000000000..63b8cae18 --- /dev/null +++ b/coverage/tools/HistogramBead.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..cdd3b5836 --- /dev/null +++ b/coverage/tools/HistogramBead.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..084917971 --- /dev/null +++ b/coverage/tools/HistogramBead.h.gcov.html @@ -0,0 +1,190 @@ + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-10-17 16:45:00Functions: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 000000000..7bc0448be --- /dev/null +++ b/coverage/tools/IFile.cpp.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-10-17 16:45:00Functions: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
_ZN4PLMD5IFileD0Ev349
_ZN4PLMD5IFile10allowNoEOLEv1028
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1524
_ZN4PLMD5IFile18allowIgnoredFieldsEv5790
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFileC1Ev11806
_ZN4PLMD5IFileD1Ev11806
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1101908
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1137909
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1138013
_ZN4PLMD5IFile9scanFieldEv1568480
_ZN4PLMD5IFile12advanceFieldEv1574911
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1729344
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2466976
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7518069
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE16611749
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_16618115
_ZN4PLMD5IFile6llreadEPcm113782645
+
+
+ + + +
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 000000000..5158a74b7 --- /dev/null +++ b/coverage/tools/IFile.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-10-17 16:45:00Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1137909
_ZN4PLMD5IFile10allowNoEOLEv1028
_ZN4PLMD5IFile12advanceFieldEv1574911
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1138013
_ZN4PLMD5IFile18allowIgnoredFieldsEv5790
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1524
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFile6llreadEPcm113782645
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1729344
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1101908
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_16618115
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7518069
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2466976
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx0
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy14
_ZN4PLMD5IFile9scanFieldEv1568480
_ZN4PLMD5IFileC1Ev11806
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD0Ev349
_ZN4PLMD5IFileD1Ev11806
_ZN4PLMD5IFileD2Ev0
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE16611749
+
+
+ + + +
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 000000000..eb0d0dca8 --- /dev/null +++ b/coverage/tools/IFile.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-10-17 16:45:00Functions: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   113782645 : size_t IFile::llread(char*ptr,size_t s) {
+      42   113782645 :   plumed_assert(fp);
+      43             :   size_t r;
+      44   113782645 :   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   113779123 :     if(std::feof(fp))   eof=true;
+      56   113779123 :     if(std::ferror(fp)) err=true;
+      57             :   }
+      58   113782645 :   return r;
+      59             : }
+      60             : 
+      61     1574911 : IFile& IFile::advanceField() {
+      62     1574911 :   plumed_assert(!inMiddleOfField);
+      63             :   std::string line;
+      64             :   bool done=false;
+      65     3151656 :   while(!done) {
+      66     1583187 :     getline(line);
+      67             : // using explicit conversion not to confuse cppcheck 1.86
+      68     1583187 :     if(!bool(*this)) {return *this;}
+      69     1576745 :     std::vector<std::string> words=Tools::getWords(line);
+      70     3153297 :     if(words.size()>=2 && words[0]=="#!" && words[1]=="FIELDS") {
+      71         743 :       fields.clear();
+      72        4925 :       for(unsigned i=2; i<words.size(); i++) {
+      73             :         Field field;
+      74             :         field.name=words[i];
+      75        4182 :         fields.push_back(field);
+      76             :       }
+      77     1597724 :     } else if(words.size()==4 && words[0]=="#!" && words[1]=="SET") {
+      78             :       Field field;
+      79             :       field.name=words[2];
+      80             :       field.value=words[3];
+      81        3275 :       field.constant=true;
+      82        3275 :       fields.push_back(field);
+      83             :     } else {
+      84             :       unsigned nf=0;
+      85    18108584 :       for(unsigned i=0; i<fields.size(); i++) if(!fields[i].constant) nf++;
+      86     1572727 :       Tools::trimComments(line);
+      87     3145454 :       words=Tools::getWords(line);
+      88     1572727 :       if( words.size()==nf ) {
+      89             :         unsigned j=0;
+      90    18053957 :         for(unsigned i=0; i<fields.size(); i++) {
+      91    16485488 :           if(fields[i].constant) continue;
+      92     7616869 :           fields[i].value=words[j];
+      93     7616869 :           fields[i].read=false;
+      94     7616869 :           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     1576745 :   }
+     102     1568469 :   inMiddleOfField=true;
+     103     1568469 :   return *this;
+     104             : }
+     105             : 
+     106        1524 : IFile& IFile::open(const std::string&path) {
+     107        1524 :   plumed_massert(!cloned,"file "+path+" appears to be cloned");
+     108        1524 :   eof=false;
+     109        1524 :   err=false;
+     110        1524 :   fp=NULL;
+     111        1524 :   gzfp=NULL;
+     112        1524 :   bool do_exist=FileExist(path);
+     113        1526 :   plumed_massert(do_exist,"file " + path + " cannot be found");
+     114        1523 :   fp=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+     115        3046 :   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        1523 :   if(plumed) plumed->insertFile(*this);
+     123        1523 :   return *this;
+     124             : }
+     125             : 
+     126     1138013 : IFile& IFile::scanFieldList(std::vector<std::string>&s) {
+     127     1138013 :   if(!inMiddleOfField) advanceField();
+     128             : // using explicit conversion not to confuse cppcheck 1.86
+     129     1138013 :   if(!bool(*this)) return *this;
+     130             :   s.clear();
+     131     9190324 :   for(unsigned i=0; i<fields.size(); i++)
+     132     8052387 :     s.push_back(fields[i].name);
+     133             :   return *this;
+     134             : }
+     135             : 
+     136     1137909 : bool IFile::FieldExist(const std::string& s) {
+     137             :   std::vector<std::string> slist;
+     138     1137909 :   scanFieldList(slist);
+     139     1137909 :   int mycount = (int) std::count(slist.begin(), slist.end(), s);
+     140     1137909 :   if(mycount>0) return true;
+     141     1114836 :   else return false;
+     142     1137909 : }
+     143             : 
+     144    16618115 : IFile& IFile::scanField(const std::string&name,std::string&str) {
+     145    16618115 :   if(!inMiddleOfField) advanceField();
+     146             : // using explicit conversion not to confuse cppcheck 1.86
+     147    16618115 :   if(!bool(*this)) return *this;
+     148    16611749 :   unsigned i=findField(name);
+     149    16611749 :   str=fields[i].value;
+     150    16611749 :   fields[i].read=true;
+     151    16611749 :   return *this;
+     152             : }
+     153             : 
+     154     7518069 : IFile& IFile::scanField(const std::string&name,double &x) {
+     155             :   std::string str;
+     156     7518069 :   scanField(name,str);
+     157     7518069 :   if(*this) Tools::convert(str,x);
+     158     7518069 :   return *this;
+     159             : }
+     160             : 
+     161     2466976 : IFile& IFile::scanField(const std::string&name,int &x) {
+     162             :   std::string str;
+     163     2466976 :   scanField(name,str);
+     164     2466976 :   if(*this) Tools::convert(str,x);
+     165     2466976 :   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     1101908 : IFile& IFile::scanField(Value* val) {
+     204     1101908 :   double ff=std::numeric_limits<double>::quiet_NaN(); // this is to be sure a NaN value is replaced upon failure
+     205     1101908 :   scanField(  val->getName(), ff );
+     206     1101908 :   val->set( ff );
+     207     2203816 :   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     1098599 :     val->setNotPeriodic();
+     214             :   }
+     215     1101908 :   return *this;
+     216             : }
+     217             : 
+     218     1568480 : IFile& IFile::scanField() {
+     219     1568480 :   if(!ignoreFields) {
+     220    16351279 :     for(unsigned i=0; i<fields.size(); i++) {
+     221    14997119 :       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     1568480 :   inMiddleOfField=false;
+     225     1568480 :   return *this;
+     226             : }
+     227             : 
+     228       11806 : IFile::IFile():
+     229       11806 :   inMiddleOfField(false),
+     230       11806 :   ignoreFields(false),
+     231       11806 :   noEOL(false)
+     232             : {
+     233       11806 : }
+     234             : 
+     235       12155 : IFile::~IFile() {
+     236       11806 :   if(inMiddleOfField) std::cerr<<"WARNING: IFile closed in the middle of reading. seems strange!\n";
+     237       12155 : }
+     238             : 
+     239     1729344 : IFile& IFile::getline(std::string &str) {
+     240     1729344 :   char tmp=0;
+     241             :   str="";
+     242             :   fpos_t pos;
+     243     1729344 :   fgetpos(fp,&pos);
+     244   113782592 :   while(llread(&tmp,1)==1 && tmp && tmp!='\n' && tmp!='\r' && !eof && !err) {
+     245   112053248 :     str+=tmp;
+     246             :   }
+     247     1729344 :   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     1729344 :   if(eof && noEOL) {
+     252        1014 :     if(str.length()>0) eof=false;
+     253     1728330 :   } else if(eof || err || tmp!='\n') {
+     254        6481 :     eof = true;
+     255             :     str="";
+     256        6481 :     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     1729344 :   return *this;
+     266             : }
+     267             : 
+     268    16611749 : unsigned IFile::findField(const std::string&name)const {
+     269             :   unsigned i;
+     270   106730333 :   for(i=0; i<fields.size(); i++) if(fields[i].name==name) break;
+     271    16611749 :   if(i>=fields.size()) {
+     272           0 :     plumed_merror("file " + getPath() + ": field " + name + " cannot be found");
+     273             :   }
+     274    16611749 :   return i;
+     275             : }
+     276             : 
+     277        6136 : void IFile::reset(bool reset) {
+     278        6136 :   eof = reset;
+     279        6136 :   err = reset;
+     280        6136 :   if(!reset && fp) clearerr(fp);
+     281             : #ifdef __PLUMED_HAS_ZLIB
+     282        6136 :   if(!reset && gzfp) gzclearerr(gzFile(gzfp));
+     283             : #endif
+     284        6136 :   return;
+     285             : }
+     286             : 
+     287        5790 : void IFile::allowIgnoredFields() {
+     288        5790 :   ignoreFields=true;
+     289        5790 : }
+     290             : 
+     291        1028 : void IFile::allowNoEOL() {
+     292        1028 :   noEOL=true;
+     293        1028 : }
+     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 000000000..5faddc668 --- /dev/null +++ b/coverage/tools/IFile.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..86cac9686 --- /dev/null +++ b/coverage/tools/IFile.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..add07e51d --- /dev/null +++ b/coverage/tools/IFile.h.gcov.html @@ -0,0 +1,193 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-10-17 16:45:00Functions: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       19388 :   class Field:
+      45             :     public FieldBase {
+      46             :   public:
+      47             :     bool read;
+      48        7457 :     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 000000000..f35b6c370 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9022240.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..e062237f3 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9022240.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..5a9ad966e --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.gcov.html @@ -0,0 +1,531 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9022240.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..d282cef77 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..cd518b2a4 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..42a0a0b22 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.gcov.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..515640b45 --- /dev/null +++ b/coverage/tools/Keywords.cpp.func-sort-c.html @@ -0,0 +1,264 @@ + + + + + + + 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:23742855.4 %
Date:2024-10-17 16:45:00Functions:374877.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD8Keywords21removeOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE108
_ZNK4PLMD8Keywords9print_vimEv438
_ZNK4PLMD8Keywords17getNeededKeywordsB5cxx11Ev560
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev876
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE922
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_1322
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5044
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev5684
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6007
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7330
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7956
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13948
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_25281
_ZN4PLMD8Keywords14setDisplayNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32101
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33150
_ZN4PLMD8Keywords19addActionNameSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE44003
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE44141
_ZN4PLMD8Keywords19setValueDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE54915
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE58621
_ZNK4PLMD8Keywords14getDisplayNameB5cxx11Ev69369
_ZN4PLMD8Keywords11needsActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE76774
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej76929
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb83853
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_133967
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_260588
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE291619
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE300900
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_436090
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_445966
_ZNK4PLMD8Keywords3getB5cxx11Ej551402
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_990514
_ZNK4PLMD8Keywords4sizeEv1297879
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1809241
_ZNK4PLMD8Keywords8getStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1814285
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2134480
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2178621
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3268380
+
+
+ + + +
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 000000000..993d91ee0 --- /dev/null +++ b/coverage/tools/Keywords.cpp.func.html @@ -0,0 +1,264 @@ + + + + + + + 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:23742855.4 %
Date:2024-10-17 16:45:00Functions:374877.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords11needsActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE76774
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_1322
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7330
_ZN4PLMD8Keywords14setDisplayNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32101
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_133967
_ZN4PLMD8Keywords19addActionNameSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE44003
_ZN4PLMD8Keywords19setValueDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE54915
_ZN4PLMD8Keywords21removeOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE108
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33150
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_990514
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_436090
_ZN4PLMD8Keywords3addERKS0_0
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE44141
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13948
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE922
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2134480
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_445966
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_260588
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej76929
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev876
_ZNK4PLMD8Keywords14getDisplayNameB5cxx11Ev69369
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7956
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_25281
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb83853
_ZNK4PLMD8Keywords17getNeededKeywordsB5cxx11Ev560
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev5684
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5044
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE300900
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE58621
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6007
_ZNK4PLMD8Keywords3getB5cxx11Ej551402
_ZNK4PLMD8Keywords4sizeEv1297879
_ZNK4PLMD8Keywords5printEP8_IO_FILE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1809241
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3268380
_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_traitsIcESaIcEEE1814285
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE291619
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2178621
_ZNK4PLMD8Keywords9print_vimEv438
+
+
+ + + +
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 000000000..fc4d808b4 --- /dev/null +++ b/coverage/tools/Keywords.cpp.gcov.html @@ -0,0 +1,795 @@ + + + + + + + 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:23742855.4 %
Date:2024-10-17 16:45:00Functions:374877.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Keywords.h"
+      23             : #include "Log.h"
+      24             : #include "Tools.h"
+      25             : #include <iostream>
+      26             : #include <iomanip>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30     2134480 : Keywords::KeyType::KeyType( const std::string& type ) {
+      31     2134480 :   if( type=="compulsory" ) {
+      32      566713 :     style=compulsory;
+      33     1567767 :   } else if( type=="flag" ) {
+      34      447288 :     style=flag;
+      35     1120479 :   } else if( type=="optional" ) {
+      36      677816 :     style=optional;
+      37      442663 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      38      218386 :     style=atoms;
+      39      224277 :   } else if( type=="hidden" ) {
+      40      224277 :     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     2134480 : }
+      47             : 
+      48         922 : void Keywords::KeyType::setStyle( const std::string& type ) {
+      49         922 :   if( type=="compulsory" ) {
+      50         435 :     style=compulsory;
+      51         487 :   } else if( type=="flag" ) {
+      52           0 :     style=flag;
+      53         487 :   } else if( type=="optional" ) {
+      54          25 :     style=optional;
+      55         462 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      56         462 :     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         922 : }
+      65             : 
+      66     1814285 : std::string Keywords::getStyle( const std::string & k ) const {
+      67           0 :   plumed_massert( types.count(k), "Did not find keyword " + k );
+      68     1814285 :   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      260588 : void Keywords::reserve( const std::string & t, const std::string & k, const std::string & d ) {
+     121      260588 :   plumed_assert( !exists(k) && !reserved(k) );
+     122      260588 :   std::string fd, lowkey=k;
+     123             :   // Convert to lower case
+     124     2716076 :   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      411514 :     std::size_t num=lowkey.find_first_of("_");
+     128      411514 :     if( num==std::string::npos ) break;
+     129      150926 :     lowkey.erase( lowkey.begin() + num, lowkey.begin() + num + 1 );
+     130      150926 :   }
+     131      260588 :   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      260588 :   } else if( t=="numbered" ) {
+     140       35808 :     fd = d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     141       17904 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     142       35808 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("optional")) );
+     143             :   } else {
+     144             :     fd = d;
+     145      243683 :     if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     146      242684 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     147      485368 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     148      243683 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     149             :   }
+     150      260588 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     151      260588 :   reserved_keys.push_back(k);
+     152      260588 : }
+     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       44141 : void Keywords::use( const std::string & k ) {
+     168       44141 :   plumed_massert( reserved(k), "the " + k + " keyword is not reserved");
+     169      260022 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     170      215881 :     if(reserved_keys[i]==k) keys.push_back( reserved_keys[i] );
+     171             :   }
+     172       44141 : }
+     173             : 
+     174        7330 : void Keywords::reset_style( const std::string & k, const std::string & style ) {
+     175        7330 :   plumed_massert( exists(k) || reserved(k), "no " + k + " keyword" );
+     176        7330 :   if( style=="numbered" ) { allowmultiple[k]=true; return; }
+     177         922 :   (types.find(k)->second).setStyle(style);
+     178         922 :   if( (types.find(k)->second).isVessel() ) allowmultiple[k]=true;
+     179        1384 :   if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,style) );
+     180             : }
+     181             : 
+     182      990514 : void Keywords::add( const std::string & t, const std::string & k, const std::string & d ) {
+     183     2971542 :   plumed_massert( !exists(k) && t!="flag" && !reserved(k) && t!="vessel", "keyword " + k + " has already been registered");
+     184             :   std::string fd;
+     185      990514 :   if( t=="numbered" ) {
+     186       39420 :     fd=d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     187       19710 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     188       39420 :     types.insert( std::pair<std::string,KeyType>(k, KeyType("optional")) );
+     189             :   } else {
+     190             :     fd=d;
+     191      970804 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     192     1941608 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     193     1188191 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     194             :   }
+     195     1038653 :   if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     196      990514 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     197      990514 :   keys.push_back(k);
+     198      990514 : }
+     199             : 
+     200      436090 : void Keywords::add( const std::string & t, const std::string & k, const std::string &  def, const std::string & d ) {
+     201      872501 :   plumed_assert( !exists(k) && !reserved(k) &&  (t=="compulsory" || t=="hidden" )); // An optional keyword can't have a default
+     202      436090 :   types.insert(  std::pair<std::string,KeyType>(k, KeyType(t)) );
+     203      872180 :   documentation.insert( std::pair<std::string,std::string>(k,"( default=" + def + " ) " + d) );
+     204      436090 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     205      436090 :   numdefs.insert( std::pair<std::string,std::string>(k,def) );
+     206      436090 :   keys.push_back(k);
+     207      436090 : }
+     208             : 
+     209      445966 : void Keywords::addFlag( const std::string & k, const bool def, const std::string & d ) {
+     210      445966 :   plumed_massert( !exists(k) && !reserved(k), "keyword " + k + " has already been registered");
+     211      445966 :   std::string defstr; plumed_massert( !def, "the second argument to addFlag must be false " + k );
+     212             :   defstr="( default=off ) ";
+     213      891932 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     214      891932 :   documentation.insert( std::pair<std::string,std::string>(k,defstr + d) );
+     215      445966 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     216           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     217      445966 :   keys.push_back(k);
+     218      445966 : }
+     219             : 
+     220       13948 : void Keywords::remove( const std::string & k ) {
+     221             :   bool found=false; unsigned j=0, n=0;
+     222             : 
+     223             :   while(true) {
+     224      139843 :     for(j=0; j<keys.size(); j++) if(keys[j]==k)break;
+     225      119360 :     for(n=0; n<reserved_keys.size(); n++) if(reserved_keys[n]==k)break;
+     226       28895 :     if(j<keys.size()) {
+     227       13753 :       keys.erase(keys.begin()+j);
+     228             :       found=true;
+     229       15142 :     } else if(n<reserved_keys.size()) {
+     230        1194 :       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             :   // Remove any output comonents that this keyword creates
+     237       27710 :   for(const auto& dkey : ckey ) {
+     238       13762 :     if( dkey.second==k ) removeOutputComponent( dkey.first );
+     239             :   }
+     240       13948 :   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
+     241       13948 : }
+     242             : 
+     243      291619 : bool Keywords::numbered( const std::string & k ) const {
+     244      583238 :   if( style( k,"atoms") ) return true;
+     245           0 :   plumed_massert( allowmultiple.count(k), "Did not find keyword " + k );
+     246      247882 :   return allowmultiple.find(k)->second;
+     247             : }
+     248             : 
+     249     1809241 : bool Keywords::style( const std::string & k, const std::string & t ) const {
+     250     1809241 :   if( getStyle(k)==t ) return true;
+     251             :   return false;
+     252             : }
+     253             : 
+     254     1297879 : unsigned Keywords::size() const {
+     255     1297879 :   return keys.size();
+     256             : }
+     257             : 
+     258       76929 : std::string Keywords::getKeyword( const unsigned i ) const {
+     259       76929 :   plumed_assert( i<size() );
+     260       76929 :   return keys[i];
+     261             : }
+     262             : 
+     263     3268380 : bool Keywords::exists( const std::string & k ) const {
+     264    28587866 :   for(unsigned i=0; i<keys.size(); ++i) {
+     265    26102984 :     if( keys[i]==k ) return true;
+     266             :   }
+     267             :   return false;
+     268             : }
+     269             : 
+     270     2178621 : bool Keywords::reserved( const std::string & k ) const {
+     271     4498868 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     272     2364388 :     if( reserved_keys[i]==k ) return true;
+     273             :   }
+     274             :   return false;
+     275             : }
+     276             : 
+     277           0 : void Keywords::print_template(const std::string& actionname, bool include_optional) const {
+     278             :   unsigned nkeys=0;
+     279             :   std::printf("%s",actionname.c_str());
+     280           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     281           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     282             :   }
+     283           0 :   if( nkeys>0 ) {
+     284           0 :     std::string prevtag="start";
+     285           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     286           0 :       if( (types.find(keys[i])->second).isAtomList() ) {
+     287           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     288           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second ) break;
+     289           0 :         if( (atomtags.find(keys[i])->second).find("residues")!=std::string::npos) std::printf(" %s=<residue selection>", keys[i].c_str() );
+     290             :         else std::printf(" %s=<atom selection>", keys[i].c_str() );
+     291           0 :         prevtag=atomtags.find(keys[i])->second;
+     292             :       }
+     293             :     }
+     294             :   }
+     295             :   nkeys=0;
+     296           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     297           0 :     if ( include_optional || \
+     298           0 :          (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     299             :   }
+     300           0 :   if( nkeys>0 ) {
+     301           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     302           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) {
+     303             :         std::string def;
+     304           0 :         if( getDefaultValue( keys[i], def) ) {
+     305             :           std::printf(" %s=%s ", keys[i].c_str(), def.c_str() );
+     306             :         } else {
+     307             :           std::printf(" %s=    ", keys[i].c_str() );
+     308             :         }
+     309           0 :       } else if (include_optional) {
+     310             :         // TG no defaults for optional keywords?
+     311             :         std::printf(" [%s]", keys[i].c_str() );
+     312             :       }
+     313             :     }
+     314             :   }
+     315             :   std::printf("\n");
+     316             :   std::flush(std::cout);
+     317           0 : }
+     318             : 
+     319         438 : void Keywords::print_vim() const {
+     320        5482 :   for(unsigned i=0; i<keys.size(); ++i) {
+     321        5044 :     if( (types.find(keys[i])->second).isFlag() ) {
+     322             :       std::printf( ",flag:%s", keys[i].c_str() );
+     323             :     } else {
+     324        4044 :       if( allowmultiple.find(keys[i])->second ) std::printf(",numbered:%s",keys[i].c_str() );
+     325             :       else std::printf(",option:%s",keys[i].c_str() );
+     326             :     }
+     327             :   }
+     328         438 :   std::fprintf(stdout, "\n%s", getHelpString().c_str() );
+     329         438 : }
+     330             : 
+     331           0 : void Keywords::print_html() const {
+     332             : 
+     333             : // This is the part that outputs the details of the components
+     334           0 :   if( cnames.size()>0 ) {
+     335             :     unsigned ndef=0;
+     336           0 :     for(unsigned i=0; i<cnames.size(); ++i) {
+     337           0 :       if(ckey.find(cnames[i])->second=="default") ndef++;
+     338             :     }
+     339             : 
+     340           0 :     if( ndef>0 ) {
+     341           0 :       std::cout<<"\\par Description of components\n\n";
+     342           0 :       std::cout<<cstring<<"\n\n";
+     343           0 :       std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     344             :       std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     345             :       unsigned nndef=0;
+     346           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     347             :         //plumed_assert( ckey.find(cnames[i])->second=="default" );
+     348           0 :         if( ckey.find(cnames[i])->second!="default" ) { nndef++; continue; }
+     349             :         std::printf("<tr>\n");
+     350             :         std::printf("<td width=15%%> <b> %s </b></td>\n",cnames[i].c_str() );
+     351             :         std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     352             :         std::printf("</tr>\n");
+     353             :       }
+     354           0 :       std::cout<<"</table>\n\n";
+     355           0 :       if( nndef>0 ) {
+     356           0 :         std::cout<<"In addition the following quantities can be calculated by employing the keywords listed below"<<std::endl;
+     357           0 :         std::cout<<"\n\n";
+     358           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     359             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     360           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     361           0 :           if( ckey.find(cnames[i])->second!="default") {
+     362             :             std::printf("<tr>\n");
+     363             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     364             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     365             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     366             :             std::printf("</tr>\n");
+     367             :           }
+     368             :         }
+     369           0 :         std::cout<<"</table>\n\n";
+     370             :       }
+     371             :     } else {
+     372             :       unsigned nregs=0;
+     373           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     374           0 :         if( exists(ckey.find(cnames[i])->second) ) nregs++;
+     375             :       }
+     376           0 :       if( nregs>0 ) {
+     377           0 :         std::cout<<"\\par Description of components\n\n";
+     378           0 :         std::cout<<cstring<<"\n\n";
+     379           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     380             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     381           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     382           0 :           if( exists(ckey.find(cnames[i])->second) ) {
+     383             :             std::printf("<tr>\n");
+     384             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     385             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     386             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     387             :             std::printf("</tr>\n");
+     388             :           }
+     389             :         }
+     390           0 :         std::cout<<"</table>\n\n";
+     391             :       }
+     392             :     }
+     393             :   }
+     394             : 
+     395             :   unsigned nkeys=0;
+     396           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     397           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     398             :   }
+     399           0 :   if( nkeys>0 ) {
+     400           0 :     if(isaction && isatoms) std::cout<<"\\par The atoms involved can be specified using\n\n";
+     401           0 :     else if(isaction) std::cout<<"\\par The data to analyze can be the output from another analysis algorithm\n\n";
+     402           0 :     else std::cout<<"\\par The input trajectory is specified using one of the following\n\n";
+     403           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     404           0 :     std::string prevtag="start"; unsigned counter=0;
+     405           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     406           0 :       if ( (types.find(keys[i])->second).isAtomList() ) {
+     407           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     408           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second && isaction ) {
+     409           0 :           std::cout<<"</table>\n\n";
+     410           0 :           if( isatoms ) std::cout<<"\\par Or alternatively by using\n\n";
+     411           0 :           else if( counter==0 ) { std::cout<<"\\par Alternatively data can be collected from the trajectory using \n\n"; counter++; }
+     412           0 :           else std::cout<<"\\par Lastly data collected in a previous analysis action can be reanalyzed by using the keyword \n\n";
+     413           0 :           std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     414             :         }
+     415           0 :         print_html_item( keys[i] );
+     416           0 :         prevtag=atomtags.find(keys[i])->second;
+     417             :       }
+     418             :     }
+     419           0 :     std::cout<<"</table>\n\n";
+     420             :   }
+     421             :   nkeys=0;
+     422           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     423           0 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     424             :   }
+     425           0 :   if( nkeys>0 ) {
+     426           0 :     if(isaction) std::cout<< "\\par Compulsory keywords\n\n";
+     427           0 :     else std::cout<<"\\par The following must be present\n\n";
+     428           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     429           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     430           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) print_html_item( keys[i] );
+     431             :     }
+     432           0 :     std::cout<<"</table>\n\n";
+     433             :   }
+     434             :   nkeys=0;
+     435           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     436           0 :     if ( (types.find(keys[i])->second).isFlag() || (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     437             :   }
+     438           0 :   if( nkeys>0 ) {
+     439           0 :     if(isaction) std::cout<<"\\par Options\n\n";
+     440           0 :     else std::cout<<"\\par The following options are available\n\n";
+     441           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     442           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     443           0 :       if ( (types.find(keys[i])->second).isFlag() ) print_html_item( keys[i] );
+     444             :     }
+     445           0 :     std::cout<<"\n";
+     446             :   }
+     447             :   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() ) nkeys++;
+     450             :   }
+     451           0 :   if( nkeys>0 ) {
+     452           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     453           0 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) print_html_item( keys[i] );
+     454             :     }
+     455             :   }
+     456           0 :   std::cout<<"</table>\n\n";
+     457           0 : }
+     458             : 
+     459           0 : void Keywords::print_spelling() const {
+     460           0 :   for(unsigned i=0; i<keys.size(); ++i) std::printf("%s\n", keys[i].c_str() );
+     461           0 :   for(unsigned i=0; i<cnames.size(); ++i) std::printf("%s\n",cnames[i].c_str() );
+     462           0 : }
+     463             : 
+     464        7956 : std::string Keywords::getKeywordDocs( const std::string& key ) const {
+     465        7956 :   bool killdot=( (documentation.find(key)->second).find("\\f$")!=std::string::npos ); // Check for latex
+     466        7956 :   std::vector<std::string> w=Tools::getWords( documentation.find(key)->second );
+     467       15912 :   std::stringstream sstr; sstr<<std::setw(23)<<key<<" - ";
+     468        7956 :   unsigned nl=0; std::string blank=" ";
+     469      190534 :   for(unsigned i=0; i<w.size(); ++i) {
+     470      183064 :     nl+=w[i].length() + 1;
+     471      183064 :     if( nl>60 ) {
+     472       39774 :       sstr<<"\n"<<std::setw(23)<<blank<<"   "<<w[i]<<" "; nl=0;
+     473      169806 :     } else sstr<<w[i]<<" ";
+     474      183064 :     if( killdot && w[i].find(".")!=std::string::npos ) break; // If there is latex only write up to first dot
+     475             :   }
+     476       15912 :   sstr<<"\n"; return sstr.str();
+     477        7956 : }
+     478             : 
+     479         876 : std::string Keywords::getHelpString() const {
+     480             :   std::string helpstr; unsigned nkeys=0;
+     481       10964 :   for(unsigned i=0; i<keys.size(); ++i) {
+     482       10088 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     483             :   }
+     484         876 :   if( nkeys>0 ) {
+     485             :     helpstr += "The input trajectory can be in any of the following formats: \n\n";
+     486        5124 :     for(unsigned i=0; i<keys.size(); ++i) {
+     487        5480 :       if ( (types.find(keys[i])->second).isAtomList() ) helpstr += getKeywordDocs( keys[i] );
+     488             :     }
+     489             :   }
+     490             :   nkeys=0;
+     491       10964 :   for(unsigned i=0; i<keys.size(); ++i) {
+     492       10088 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     493             :   }
+     494             :   unsigned ncompulsory=nkeys;
+     495         876 :   if( nkeys>0 ) {
+     496             :     helpstr += "\nThe following arguments are compulsory: \n\n";
+     497        8884 :     for(unsigned i=0; i<keys.size(); ++i) {
+     498       10468 :       if ( (types.find(keys[i])->second).isCompulsory() ) helpstr += getKeywordDocs( keys[i] );
+     499             :     }
+     500             :   }
+     501             :   nkeys=0;
+     502       10964 :   for(unsigned i=0; i<keys.size(); ++i) {
+     503       10088 :     if ( (types.find(keys[i])->second).isFlag() ) nkeys++;
+     504             :   }
+     505         876 :   if( nkeys>0 ) {
+     506         702 :     if(ncompulsory>0) helpstr += "\nIn addition you may use the following options: \n\n";
+     507             :     else helpstr += "\nThe following options are available\n\n";
+     508        9656 :     for(unsigned i=0; i<keys.size(); ++i) {
+     509       10954 :       if ( (types.find(keys[i])->second).isFlag() ) helpstr += getKeywordDocs( keys[i] ).c_str();
+     510             :     }
+     511             :   }
+     512             :   nkeys=0;
+     513       10964 :   for(unsigned i=0; i<keys.size(); ++i) {
+     514       17132 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     515             :   }
+     516         876 :   if( nkeys>0 ) {
+     517        9412 :     for(unsigned i=0; i<keys.size(); ++i) {
+     518       17484 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) helpstr += getKeywordDocs( keys[i] );
+     519             :     }
+     520             :     helpstr += "\n";
+     521             :   }
+     522         876 :   return helpstr;
+     523             : }
+     524             : 
+     525           0 : void Keywords::print( Log& log ) const {
+     526           0 :   log.printf("%s", getHelpString().c_str() );
+     527           0 : }
+     528             : 
+     529           0 : void Keywords::print( FILE* out ) const {
+     530           0 :   fprintf( out,"%s", getHelpString().c_str() );
+     531           0 : }
+     532             : 
+     533           0 : std::string Keywords::getTooltip( const std::string& name ) const {
+     534           0 :   std::size_t dd=name.find_first_of("0123456789"); std::string kname=name.substr(0,dd);
+     535           0 :   if( !exists(kname) ) return "<b> could not find this keyword </b>";
+     536           0 :   std::string mystring, docstr = documentation.find(kname)->second;
+     537           0 :   if( types.find(kname)->second.isCompulsory() ) {
+     538             :     mystring += "<b>compulsory keyword ";
+     539           0 :     if( docstr.find("default")!=std::string::npos ) {
+     540           0 :       std::size_t bra = docstr.find_first_of(")"); mystring += docstr.substr(0,bra+1); docstr = docstr.substr(bra+1);
+     541             :     }
+     542             :     mystring += "</b>\n";
+     543             :   }
+     544           0 :   std::vector<std::string> w=Tools::getWords( docstr ); unsigned nl=0;
+     545           0 :   for(unsigned i=0; i<w.size(); ++i) {
+     546           0 :     nl+=w[i].length() + 1;
+     547           0 :     if( nl>80 ) { mystring += w[i] + "\n"; nl=0; }
+     548           0 :     else { mystring += w[i] + " "; }
+     549           0 :     if( w[i].find(".")!=std::string::npos ) break; // Only write up the the first dot
+     550             :   }
+     551             :   return mystring;
+     552           0 : }
+     553             : 
+     554           0 : void Keywords::print_html_item( const std::string& key ) const {
+     555             :   std::printf("<tr>\n");
+     556             :   std::printf("<td width=15%%> <b> %s </b></td>\n",key.c_str() );
+     557             :   std::printf("<td> %s </td>\n",(documentation.find(key)->second).c_str() );
+     558             :   std::printf("</tr>\n");
+     559           0 : }
+     560             : 
+     561      551402 : std::string Keywords::get( const unsigned k ) const {
+     562      551402 :   plumed_assert( k<size() );
+     563      551402 :   return keys[k];
+     564             : }
+     565             : 
+     566       83853 : bool Keywords::getLogicalDefault(const std::string & key, bool& def ) const {
+     567       83853 :   if( booldefs.find(key)!=booldefs.end() ) {
+     568       83853 :     def=booldefs.find(key)->second;
+     569       83853 :     return true;
+     570             :   } else {
+     571             :     return false;
+     572             :   }
+     573             : }
+     574             : 
+     575       25281 : bool Keywords::getDefaultValue(const std::string & key, std::string& def ) const {
+     576       36579 :   plumed_assert( style(key,"compulsory") || style(key,"hidden") );
+     577             : 
+     578       25281 :   if( numdefs.find(key)!=numdefs.end() ) {
+     579       19633 :     def=numdefs.find(key)->second;
+     580       19633 :     return true;
+     581             :   } else {
+     582             :     return false;
+     583             :   }
+     584             : }
+     585             : 
+     586           0 : void Keywords::destroyData() {
+     587           0 :   keys.clear(); reserved_keys.clear(); types.clear();
+     588             :   allowmultiple.clear(); documentation.clear();
+     589             :   booldefs.clear(); numdefs.clear(); atomtags.clear();
+     590             :   ckey.clear(); cdocs.clear(); ckey.clear();
+     591           0 : }
+     592             : 
+     593       33150 : void Keywords::setComponentsIntroduction( const std::string& instr ) {
+     594       33150 :   cstring = instr;
+     595       33150 : }
+     596             : 
+     597      133967 : void Keywords::addOutputComponent( const std::string& name, const std::string& key, const std::string& descr ) {
+     598      133967 :   plumed_assert( !outputComponentExists(name) );
+     599      133967 :   plumed_massert( name!=".#!value", name + " is reserved for storing description of value" );
+     600      133967 :   plumed_massert( name.find("-")==std::string::npos,"dash is reseved character in component names" );
+     601             : 
+     602      133967 :   std::size_t num2=name.find_first_of("_");
+     603      133967 :   if( num2!=std::string::npos ) {
+     604         644 :     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");
+     605         644 :     plumed_massert( num2==0, "underscore is reserved character in component names that has special meaning");
+     606             :   }
+     607      133967 :   if( key=="default" ) {
+     608             :     cstring = "By default this Action calculates the following quantities. These quantities can "
+     609             :               "be referenced elsewhere in the input by using this Action's label followed by a "
+     610      100144 :               "dot and the name of the quantity required from the list below.";
+     611             :   }
+     612             : 
+     613      133967 :   ckey.insert( std::pair<std::string,std::string>(name,key) );
+     614      133967 :   cdocs.insert( std::pair<std::string,std::string>(name,descr) );
+     615      133967 :   cnames.push_back(name);
+     616      133967 : }
+     617             : 
+     618         108 : void Keywords::removeOutputComponent( const std::string& name ) {
+     619             :   unsigned j=0;
+     620             :   while(true) {
+     621         762 :     for(j=0; j<cnames.size(); j++) if(cnames[j]==name)break;
+     622         216 :     if(j<cnames.size()) cnames.erase(cnames.begin()+j);
+     623             :     else break;
+     624             :   }
+     625             :   cdocs.erase(name);
+     626         108 : }
+     627             : 
+     628       54915 : void Keywords::setValueDescription( const std::string& descr ) {
+     629      109830 :   if( !outputComponentExists(".#!value") ) {
+     630       47928 :     ckey.insert( std::pair<std::string,std::string>(".#!value","default") );
+     631       47928 :     cdocs.insert( std::pair<std::string,std::string>(".#!value",descr) );
+     632       95856 :     cnames.push_back(".#!value");
+     633       13974 :   } else cdocs[".#!value"] = descr;
+     634       54915 : }
+     635             : 
+     636      300900 : bool Keywords::outputComponentExists( const std::string& name ) const {
+     637      300900 :   if( cstring.find("customize")!=std::string::npos ) return true;
+     638             : 
+     639             :   std::string sname;
+     640      296433 :   std::size_t num=name.find_first_of("-");
+     641      296433 :   std::size_t num2=name.find_last_of("_");
+     642             : 
+     643      298899 :   if( num2!=std::string::npos ) sname=name.substr(num2);
+     644      320952 :   else if( num!=std::string::npos ) sname=name.substr(0,num);
+     645             :   else sname=name;
+     646             : 
+     647     1044721 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     648      861618 :     if( sname==cnames[i] ) return true;
+     649             :   }
+     650             :   return false;
+     651             : }
+     652             : 
+     653       58621 : std::string Keywords::getOutputComponentFlag( const std::string& name ) const {
+     654       58621 :   return ckey.find(name)->second;
+     655             : }
+     656             : 
+     657        6007 : std::string Keywords::getOutputComponentDescription( const std::string& name ) const {
+     658        6007 :   std::string checkname = name; std::size_t hyp=name.find_first_of("-");
+     659        6009 :   if( hyp!=std::string::npos ) checkname = name.substr(0,hyp);
+     660             : 
+     661             :   bool found=false;
+     662       21134 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     663       15127 :     if( checkname==cnames[i] ) found=true;
+     664             :   }
+     665        6007 :   if( !found ) {
+     666           3 :     if( name==".#!value" ) return "the value calculated by this action";
+     667           0 :     if( outputComponentExists( name ) ) plumed_merror("cannot find description for component " + name + " that allegedly exists. Gareth Tribello might know what the fuck that is about.");
+     668           0 :     plumed_merror("could not find output component named " + name );
+     669             :   }
+     670        6004 :   return cdocs.find(checkname)->second;
+     671             : }
+     672             : 
+     673           0 : void Keywords::removeComponent( const std::string& name ) {
+     674             :   bool found=false;
+     675             : 
+     676             :   while(true) {
+     677             :     unsigned j;
+     678           0 :     for(j=0; j<cnames.size(); j++) if(cnames[j]==name)break;
+     679           0 :     if(j<cnames.size()) {
+     680           0 :       cnames.erase(cnames.begin()+j);
+     681             :       found=true;
+     682             :     } else break;
+     683           0 :   }
+     684             :   // Delete documentation, type and so on from the description
+     685             :   cdocs.erase(name); ckey.erase(name);
+     686           0 :   plumed_massert(found,"You are trying to remove " + name + " a component that isn't there");
+     687           0 : }
+     688             : 
+     689        5684 : std::vector<std::string> Keywords::getOutputComponents() const {
+     690        5684 :   return cnames;
+     691             : }
+     692             : 
+     693        5044 : std::string Keywords::getKeywordDescription( const std::string& key ) const {
+     694       10088 :   plumed_assert( exists( key ) ); return documentation.find(key)->second;
+     695             : }
+     696             : 
+     697       76774 : void Keywords::needsAction( const std::string& name ) {
+     698       76774 :   if( std::find(neededActions.begin(), neededActions.end(), name )!=neededActions.end() ) return;
+     699       76127 :   neededActions.push_back( name );
+     700             : }
+     701             : 
+     702         560 : const std::vector<std::string>& Keywords::getNeededKeywords() const {
+     703         560 :   return neededActions;
+     704             : }
+     705             : 
+     706       44003 : void Keywords::addActionNameSuffix( const std::string& suffix ) {
+     707       44003 :   if( std::find(actionNameSuffixes.begin(), actionNameSuffixes.end(), suffix )!=actionNameSuffixes.end() ) return;
+     708       44003 :   actionNameSuffixes.push_back( suffix );
+     709             : }
+     710             : 
+     711       32101 : void Keywords::setDisplayName( const std::string& name ) {
+     712       32101 :   thisactname = name;
+     713       32101 : }
+     714             : 
+     715       69369 : std::string Keywords::getDisplayName() const {
+     716       69369 :   return thisactname;
+     717             : }
+     718             : 
+     719             : }
+
+
+
+ + + + +
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 000000000..7600e1bca --- /dev/null +++ b/coverage/tools/Keywords.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Keywords.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131681.2 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev185612
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev1814285
+
+
+ + + +
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 000000000..d0b7a4b52 --- /dev/null +++ b/coverage/tools/Keywords.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Keywords.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131681.2 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev185612
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev1814285
+
+
+ + + +
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 000000000..da68b9d21 --- /dev/null +++ b/coverage/tools/Keywords.h.gcov.html @@ -0,0 +1,282 @@ + + + + + + + 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-10-17 16:45:00Functions: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       18312 :     bool isCompulsory() const { return (style==compulsory); }
+      44       24086 :     bool isFlag() const { return (style==flag); }
+      45       18830 :     bool isOptional() const { return (style==optional); }
+      46     1229310 :     bool isAtomList() const { return (style==atoms); }
+      47       13664 :     bool isVessel() const { return (style==vessel); }
+      48     1814285 :     std::string toString() const {
+      49     1814285 :       if(style==compulsory) return "compulsory";
+      50      618068 :       else if(style==optional) return "optional";
+      51      312767 :       else if(style==atoms) return "atoms";
+      52      651108 :       else if(style==flag) return "flag";
+      53      108075 :       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             :   friend class ActionRegister;
+      62             : private:
+      63             : /// Is this an action or driver (this bool affects what style==atoms does in print)
+      64             :   bool isaction;
+      65             : /// This allows us to overwrite the behavior of the atoms type in analysis actions
+      66             :   bool isatoms;
+      67             : /// The name of the action that has this set of keywords
+      68             :   std::string thisactname;
+      69             : /// The names of the allowed keywords
+      70             :   std::vector<std::string> keys;
+      71             : /// The names of the reserved keywords
+      72             :   std::vector<std::string> reserved_keys;
+      73             : /// Whether the keyword is compulsory, optional...
+      74             :   std::map<std::string,KeyType> types;
+      75             : /// Do we allow stuff like key1, key2 etc
+      76             :   std::map<std::string,bool> allowmultiple;
+      77             : /// The documentation for the keywords
+      78             :   std::map<std::string,std::string> documentation;
+      79             : /// The default values for the flags (are they on or of)
+      80             :   std::map<std::string,bool> booldefs;
+      81             : /// The default values (if there are default values) for compulsory keywords
+      82             :   std::map<std::string,std::string> numdefs;
+      83             : /// The tags for atoms - we use this so the manual can differentiate between different ways of specifying atoms
+      84             :   std::map<std::string,std::string> atomtags;
+      85             : /// The string that should be printed out to describe how the components work for this particular action
+      86             :   std::string cstring;
+      87             : /// The names of all the possible components for an action
+      88             :   std::vector<std::string> cnames;
+      89             : /// The keyword that turns on a particular component
+      90             :   std::map<std::string,std::string> ckey;
+      91             : /// The documentation for a particular component
+      92             :   std::map<std::string,std::string> cdocs;
+      93             : /// The list of actions that are needed by this action
+      94             :   std::vector<std::string> neededActions;
+      95             : /// List of suffixes that can be used with this action
+      96             :   std::vector<std::string> actionNameSuffixes;
+      97             : /// Print the documentation for the jth keyword in html
+      98             :   void print_html_item( const std::string& ) const;
+      99             : public:
+     100             : /// Constructor
+     101      185612 :   Keywords() : isaction(true), isatoms(true) {}
+     102             : ///
+     103       10602 :   void isDriver() { isaction=false; }
+     104             : ///
+     105             :   void isAnalysis() { isatoms=false; }
+     106             : /// find out whether flag key is on or off by default.
+     107             :   bool getLogicalDefault(const std::string & key, bool& def ) const ;
+     108             : /// Get the value of the default for the keyword named key
+     109             :   bool getDefaultValue(const std::string & key, std::string& def ) const ;
+     110             : /// Return the number of defined keywords
+     111             :   unsigned size() const;
+     112             : /// Check if numbered keywords are allowed for this action
+     113             :   bool numbered( const std::string & k ) const ;
+     114             : /// Return the ith keyword
+     115             :   std::string getKeyword( const unsigned i ) const ;
+     116             : /// Get the documentation for a particular keyword
+     117             :   std::string getKeywordDocs( const std::string& key ) const ;
+     118             : /// Print the documentation to the log file (used by PLMD::Action::error)
+     119             :   void print( Log& log ) const ;
+     120             : /// Print the documentation to a file (use by PLUMED::CLTool::readCommandLineArgs)
+     121             :   void print( FILE* out ) const ;
+     122             : /// Get the help string
+     123             :   std::string getHelpString() const ;
+     124             : /// Print a file containing the list of keywords for a particular action (used for spell checking)
+     125             :   void print_spelling() const ;
+     126             : /// Reserve a keyword
+     127             :   void reserve( const std::string & t, const std::string & k, const std::string & d );
+     128             : /// Reserve a flag
+     129             :   void reserveFlag( const std::string & k, const bool def, const std::string & d );
+     130             : /// Use one of the reserved keywords
+     131             :   void use( const std::string  & k );
+     132             : /// Get the ith keyword
+     133             :   std::string get( const unsigned k ) const ;
+     134             : /// Add a new keyword of type t with name k and description d
+     135             :   void add( const std::string & t, const std::string & k, const std::string & d );
+     136             : /// Add a new compulsory keyword (t must equal compulsory) with name k, default value def and description d
+     137             :   void add( const std::string & t, const std::string & k, const std::string & def, const std::string & d );
+     138             : /// 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
+     139             :   void addFlag( const std::string & k, const bool def, const std::string & d );
+     140             : /// Remove the keyword with name k
+     141             :   void remove( const std::string & k );
+     142             : /// Check if there is a keyword with name k
+     143             :   bool exists( const std::string & k ) const ;
+     144             : /// Check the keyword k has been reserved
+     145             :   bool reserved( const std::string & k ) const ;
+     146             : /// Get the type for the keyword with string k
+     147             :   std::string getStyle( const std::string & k ) const ;
+     148             : /// Check if the keyword with name k has style t
+     149             :   bool style( const std::string & k, const std::string & t ) const ;
+     150             : /// Print an html version of the documentation
+     151             :   void print_html() const ;
+     152             : /// Print keywords in form readable by vim
+     153             :   void print_vim() const ;
+     154             : /// Print the template version for the documentation
+     155             :   void print_template( const std::string& actionname, bool include_optional) const ;
+     156             : /// Change the style of a keyword
+     157             :   void reset_style( const std::string & k, const std::string & style );
+     158             : /// Add keywords from one keyword object to another
+     159             :   void add( const Keywords& keys );
+     160             : /// Copy the keywords data
+     161             :   void copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
+     162             :                  std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+     163             :                  std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+     164             :                  std::map<std::string,std::string>& cd ) const ;
+     165             : /// Clear everything from the keywords object.
+     166             : /// Not actually needed if your Keywords object is going out of scope.
+     167             :   void destroyData();
+     168             : /// Set the text that introduces how the components for this action are introduced
+     169             :   void setComponentsIntroduction( const std::string& instr );
+     170             : /// Add the description of the value
+     171             :   void setValueDescription( const std::string& descr );
+     172             : /// Add a potential component which can be output by this particular action
+     173             :   void addOutputComponent( const std::string& name, const std::string& key, const std::string& descr );
+     174             : /// Remove a component that can be output by this particular action
+     175             :   void removeOutputComponent( const std::string& name );
+     176             : /// Has a component with this name been added?
+     177             :   bool outputComponentExists( const std::string& name ) const ;
+     178             : /// Get the flag that forces this component to be calculated
+     179             :   std::string getOutputComponentFlag( const std::string& name ) const ;
+     180             : /// Get the description of this component
+     181             :   std::string getOutputComponentDescription( const std::string& name ) const ;
+     182             : /// Get the full list of output components
+     183             :   std::vector<std::string> getOutputComponents() const ;
+     184             : /// Get the description of a particular keyword
+     185             :   std::string getKeywordDescription( const std::string& name ) const ;
+     186             : /// Remove a component with a particular name from the keywords
+     187             :   void removeComponent( const std::string& name );
+     188             : /// Reference to keys
+     189           0 :   std::vector<std::string> getKeys() const { return keys; }
+     190             : /// Get the description of a particular keyword
+     191             :   std::string getTooltip( const std::string& name ) const ;
+     192             : /// Note that another actions is required to create this shortcut
+     193             :   void needsAction( const std::string& name );
+     194             : /// Add a suffix to the list of action name suffixes to test for
+     195             :   void addActionNameSuffix( const std::string& suffix );
+     196             : /// Get the list of keywords that are needed by this action
+     197             :   const std::vector<std::string>& getNeededKeywords() const ;
+     198             : /// Return the name of the action that has this set of keywords
+     199             :   std::string getDisplayName() const ;
+     200             : /// Set the display name
+     201             :   void setDisplayName( const std::string& name );
+     202             : };
+     203             : 
+     204             : }
+     205             : 
+     206             : #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 000000000..fac309848 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-10-17 16:45:00Functions: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_13TensorGenericILj3ELj3EEE19980
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE19981
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_34723
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE54698
+
+
+ + + +
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 000000000..26cf39373 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-10-17 16:45:00Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16LatticeReduction10isReduced2ERKNS_13VectorGenericILj3EEES4_S4_0
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE19981
_ZN4PLMD16LatticeReduction10reduceSlowERNS_13TensorGenericILj3ELj3EEE1
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE54698
_ZN4PLMD16LatticeReduction6reduceERNS_13TensorGenericILj3ELj3EEE19980
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_34723
_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 000000000..8a0be9b00 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.gcov.html @@ -0,0 +1,291 @@ + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-10-17 16:45:00Functions: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       54698 : void LatticeReduction::sort(Vector v[3]) {
+      32             :   const double onePlusEpsilon=(1.0+epsilon);
+      33             :   double m[3];
+      34       54698 :   m[0]=modulo2(v[0]);
+      35       54698 :   m[1]=modulo2(v[1]);
+      36       54698 :   m[2]=modulo2(v[2]);
+      37      382886 :   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       54698 :   plumed_assert(m[0]<=m[1]*onePlusEpsilon);
+      42       54698 :   plumed_assert(m[1]<=m[2]*onePlusEpsilon);
+      43       54698 : }
+      44             : 
+      45       34723 : void LatticeReduction::reduce(Vector&a,Vector&b) {
+      46             :   const double onePlusEpsilon=(1.0+epsilon);
+      47       34723 :   double ma=modulo2(a);
+      48       34723 :   double mb=modulo2(b);
+      49             :   unsigned counter=0;
+      50             :   while(true) {
+      51       35284 :     if(mb>ma) {
+      52             :       std::swap(a,b);
+      53             :       std::swap(ma,mb);
+      54             :     }
+      55       35284 :     a-=b*floor(dotProduct(a,b)/mb+0.5);
+      56       35284 :     ma=modulo2(a);
+      57       35284 :     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       34723 : }
+      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       19980 : void LatticeReduction::reduce(Tensor&t) {
+     112       19980 :   reduceFast(t);
+     113       19980 : }
+     114             : 
+     115       19981 : void LatticeReduction::reduceFast(Tensor&t) {
+     116             :   const double onePlusEpsilon=(1.0+epsilon);
+     117       79924 :   Vector v[3];
+     118       19981 :   v[0]=t.getRow(0);
+     119       19981 :   v[1]=t.getRow(1);
+     120       19981 :   v[2]=t.getRow(2);
+     121             :   unsigned counter=0;
+     122             :   while(true) {
+     123       34716 :     sort(v);
+     124       34716 :     reduce(v[0],v[1]);
+     125       34716 :     double b11=modulo2(v[0]);
+     126       34716 :     double b22=modulo2(v[1]);
+     127       34716 :     double b12=dotProduct(v[0],v[1]);
+     128       34716 :     double b13=dotProduct(v[0],v[2]);
+     129       34716 :     double b23=dotProduct(v[1],v[2]);
+     130       34716 :     double z=b11*b22-b12*b12;
+     131       34716 :     double y2=-(b11*b23-b12*b13)/z;
+     132       34716 :     double y1=-(b22*b13-b12*b23)/z;
+     133       34716 :     int x1min=floor(y1);
+     134       34716 :     int x1max=x1min+1;
+     135       34716 :     int x2min=floor(y2);
+     136       34716 :     int x2max=x2min+1;
+     137             :     bool first=true;
+     138             :     double mbest,mtrial;
+     139       34716 :     Vector trial,best;
+     140      104148 :     for(int x1=x1min; x1<=x1max; x1++)
+     141      208296 :       for(int x2=x2min; x2<=x2max; x2++) {
+     142      138864 :         trial=v[2]+x2*v[1]+x1*v[0];
+     143      138864 :         mtrial=modulo2(trial);
+     144      138864 :         if(first || mtrial<mbest) {
+     145             :           mbest=mtrial;
+     146       41811 :           best=trial;
+     147             :           first=false;
+     148             :         }
+     149             :       }
+     150       34716 :     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       19981 :   sort(v);
+     156       19981 :   t.setRow(0,v[0]);
+     157       19981 :   t.setRow(1,v[1]);
+     158       19981 :   t.setRow(2,v[2]);
+     159       19981 : }
+     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 000000000..83cc42978 --- /dev/null +++ b/coverage/tools/LeptonCall.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10LeptonCall3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EEPNS_6ActionERKb3077
_ZNK4PLMD10LeptonCall8evaluateERKSt6vectorIdSaIdEE22964653
_ZNK4PLMD10LeptonCall13evaluateDerivERKjRKSt6vectorIdSaIdEE32187986
+
+
+ + + +
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 000000000..19db25691 --- /dev/null +++ b/coverage/tools/LeptonCall.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10LeptonCall3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EEPNS_6ActionERKb3077
_ZNK4PLMD10LeptonCall13evaluateDerivERKjRKSt6vectorIdSaIdEE32187986
_ZNK4PLMD10LeptonCall8evaluateERKSt6vectorIdSaIdEE22964653
+
+
+ + + +
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 000000000..5954592cb --- /dev/null +++ b/coverage/tools/LeptonCall.cpp.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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-10-17 16:45:00Functions: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        3077 : void LeptonCall::set(const std::string & func, const std::vector<std::string>& var, Action* action, const bool& a ) {
+      28        3077 :   unsigned nth=OpenMP::getNumThreads(); expression.resize(nth); expression_deriv.resize(var.size());
+      29             :   // Resize the expression for the derivatives
+      30        8057 :   for(unsigned i=0; i<expression_deriv.size(); ++i) expression_deriv[i].resize(OpenMP::getNumThreads());
+      31        3077 :   allow_extra_args=a; nargs=var.size();
+      32             : 
+      33        3077 :   lepton_ref.resize(nth*nargs,nullptr);
+      34        3077 :   lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(lepton::Constants()); unsigned nt=0;
+      35        3077 :   if( action ) action->log<<"  function as parsed by lepton: "<<pe<<"\n";
+      36        9231 :   for(auto & e : expression) {
+      37        6154 :     e=pe.createCompiledExpression();
+      38       16114 :     for(unsigned j=0; j<var.size(); ++j) {
+      39             :       try {
+      40        9960 :         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        6154 :     nt++;
+      47             :   }
+      48        8013 :   for(auto & p : expression[0].getVariables()) {
+      49        4936 :     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        3077 :   if( action ) action->log<<"  derivatives as computed by lepton:\n";
+      55        3077 :   lepton_ref_deriv.resize(nth*nargs*nargs,nullptr);
+      56        8057 :   for(unsigned i=0; i<var.size(); i++) {
+      57        9960 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(var[i]).optimize(lepton::Constants()); nt=0; if( action ) action->log<<"    "<<pe<<"\n";
+      58       14940 :     for(auto & e : expression_deriv[i]) {
+      59        9960 :       e=pe.createCompiledExpression();
+      60       28876 :       for(unsigned j=0; j<var.size(); ++j) {
+      61             :         try {
+      62       18916 :           lepton_ref_deriv[i*OpenMP::getNumThreads()*var.size() + nt*var.size()+j]=&const_cast<lepton::CompiledExpression*>(&expression_deriv[i][nt])->getVariableReference(var[j]);
+      63        6110 :         } 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        6110 :         }
+      67             :       }
+      68        9960 :       nt++;
+      69             :     }
+      70             :   }
+      71        3077 : }
+      72             : 
+      73    22964653 : double LeptonCall::evaluate( const std::vector<double>& args ) const {
+      74             :   plumed_dbg_assert( allow_extra_args || args.size()==nargs );
+      75    22964653 :   const unsigned t=OpenMP::getThreadNum(), tbas=t*nargs;
+      76    67579945 :   for(unsigned i=0; i<nargs; ++i) {
+      77    44615292 :     if( lepton_ref[tbas+i] ) *lepton_ref[tbas+i] = args[i];
+      78             :   }
+      79    22964653 :   return expression[t].evaluate();
+      80             : }
+      81             : 
+      82    32187986 : 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    32187986 :   const unsigned t=OpenMP::getThreadNum(), dbas = ider*OpenMP::getNumThreads()*nargs + t*nargs;
+      85   106817008 :   for(unsigned j=0; j<nargs; j++) {
+      86    74629022 :     if(lepton_ref_deriv[dbas+j] ) *lepton_ref_deriv[dbas+j] = args[j];
+      87             :   }
+      88    32187986 :   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 000000000..162ebb24f --- /dev/null +++ b/coverage/tools/LeptonCall.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8cc8f690b --- /dev/null +++ b/coverage/tools/LeptonCall.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8082c1c6c --- /dev/null +++ b/coverage/tools/LeptonCall.h.gcov.html @@ -0,0 +1,134 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..82d5d3fbf --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9LinkCells9getCutoffEv513
_ZN4PLMD9LinkCells9setCutoffERKd654
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE654
_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 000000000..1c8eddff9 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE11969
_ZN4PLMD9LinkCells9setCutoffERKd654
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE654
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE1446143
_ZNK4PLMD9LinkCells12getMaxInCellEv11750
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE262786
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_262786
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_1183357
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_3375
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE1183357
_ZNK4PLMD9LinkCells9getCutoffEv513
+
+
+ + + +
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 000000000..43b0158f2 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.gcov.html @@ -0,0 +1,258 @@ + + + + + + + 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-10-17 16:45:00Functions: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         654 : LinkCells::LinkCells( Communicator& cc ) :
+      29         654 :   comm(cc),
+      30         654 :   cutoffwasset(false),
+      31         654 :   link_cutoff(0.0),
+      32         654 :   ncells(3),
+      33        1308 :   nstride(3)
+      34             : {
+      35         654 : }
+      36             : 
+      37         654 : void LinkCells::setCutoff( const double& lcut ) {
+      38         654 :   cutoffwasset=true; link_cutoff=lcut;
+      39         654 : }
+      40             : 
+      41         513 : double LinkCells::getCutoff() const {
+      42         513 :   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 000000000..a08f978b1 --- /dev/null +++ b/coverage/tools/LinkCells.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/LinkCells.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d8a33ad6a --- /dev/null +++ b/coverage/tools/LinkCells.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/LinkCells.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..eb4614a85 --- /dev/null +++ b/coverage/tools/LinkCells.h.gcov.html @@ -0,0 +1,177 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..89dc9f491 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func-sort-c.html @@ -0,0 +1,284 @@ + + + + + + + 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-10-17 16:45:00Functions:5353100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd11743380
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd11743380
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd11743380
_ZN4PLMD12LoopUnrollerILj4EE4_dotEPKdS3_12203712
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd50271319
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd58803861
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd58803865
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd58803865
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd58807865
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd58807865
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd73442619
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd206692573
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd206692573
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_264273073
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_264273073
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd724490000
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd724490000
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd1106293625
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd1106293625
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1957307872
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1957307872
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd2014562474
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd2014562474
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd2515086763
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd2515086763
+
+
+ + + +
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 000000000..6a8d4c0b9 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func.html @@ -0,0 +1,284 @@ + + + + + + + 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-10-17 16:45:00Functions:5353100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd11743380
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd11743380
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd11743380
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd1489986
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd2014562474
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_264273073
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd2515086763
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd206692573
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1957307872
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd1106293625
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd724490000
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd2014562474
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_264273073
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd2515086763
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd206692573
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1957307872
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd1106293625
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd724490000
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj4EE4_dotEPKdS3_12203712
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd50271319
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd73442619
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd58807865
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd58807865
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd58803861
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd58803865
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd60102394
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd81596234
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd250728
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd49152217
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd58803865
+
+
+ + + +
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 000000000..4cd226056 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.gcov.html @@ -0,0 +1,236 @@ + + + + + + + LCOV - plumed test coverage - tools/LoopUnroller.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LoopUnroller.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-10-17 16:45:00Functions: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  1857640024 : void LoopUnroller<n>::_zero(double*d) {
+      78  1133150024 :   LoopUnroller<n-1>::_zero(d);
+      79  1857640024 :   d[n-1]=0.0;
+      80  1857640024 : }
+      81             : 
+      82             : template<>
+      83             : inline
+      84             : void LoopUnroller<1>::_zero(double*d) {
+      85   725054522 :   d[0]=0.0;
+      86             : }
+      87             : 
+      88             : template<unsigned n>
+      89  4389739312 : void LoopUnroller<n>::_add(double*d,const double*a) {
+      90  2375176838 :   LoopUnroller<n-1>::_add(d,a);
+      91  4389739312 :   d[n-1]+=a[n-1];
+      92  4389739312 : }
+      93             : 
+      94             : template<>
+      95             : inline
+      96             : void LoopUnroller<1>::_add(double*d,const double*a) {
+      97  2014562474 :   d[0]+=a[0];
+      98             : }
+      99             : 
+     100             : template<unsigned n>
+     101  4210648148 : void LoopUnroller<n>::_sub(double*d,const double*a) {
+     102  2253340276 :   LoopUnroller<n-1>::_sub(d,a);
+     103  4210648148 :   d[n-1]-=a[n-1];
+     104  4210648148 : }
+     105             : 
+     106             : template<>
+     107             : inline
+     108             : void LoopUnroller<1>::_sub(double*d,const double*a) {
+     109  1957307872 :   d[0]-=a[0];
+     110             : }
+     111             : 
+     112             : template<unsigned n>
+     113  5519750930 : void LoopUnroller<n>::_mul(double*d,const double s) {
+     114  3004664167 :   LoopUnroller<n-1>::_mul(d,s);
+     115  5519750930 :   d[n-1]*=s;
+     116  5519750930 : }
+     117             : 
+     118             : template<>
+     119             : inline
+     120             : void LoopUnroller<1>::_mul(double*d,const double s) {
+     121  2515086763 :   d[0]*=s;
+     122             : }
+     123             : 
+     124             : template<unsigned n>
+     125   414889514 : void LoopUnroller<n>::_neg(double*d,const double*a ) {
+     126   208196941 :   LoopUnroller<n-1>::_neg(d,a);
+     127   414889514 :   d[n-1]=-a[n-1];
+     128   414889514 : }
+     129             : 
+     130             : template<>
+     131             : inline
+     132             : void LoopUnroller<1>::_neg(double*d,const double*a) {
+     133   206692573 :   d[0]=-a[0];
+     134             : }
+     135             : 
+     136             : template<unsigned n>
+     137  2213706352 : double LoopUnroller<n>::_sum2(const double*d) {
+     138  2213706352 :   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  1106293625 :   return d[0]*d[0];
+     145             : }
+     146             : 
+     147             : template<unsigned n>
+     148   540749858 : double LoopUnroller<n>::_dot(const double*d,const double*v) {
+     149   540749858 :   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   264273073 :   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 000000000..1675dcd9a --- /dev/null +++ b/coverage/tools/Matrix.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:12113987.1 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logdetIdEEiRKNS_6MatrixIT_EERd0
_ZN4PLMD12pseudoInvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE1
_ZN4PLMD6MatrixIdEmLERKd125
_ZN4PLMD8choleskyIdEEvRKNS_6MatrixIT_EERS3_446
_ZN4PLMD9transposeIdEEvRKNS_6MatrixIT_EERS3_730
_ZN4PLMD7diagMatIdEEiRKNS_6MatrixIT_EERSt6vectorIdSaIdEERNS1_IdEE14055
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EES5_RS3_16490
_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 000000000..5bb682b43 --- /dev/null +++ b/coverage/tools/Matrix.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:12113987.1 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_16490
_ZN4PLMD6InvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE25702
_ZN4PLMD6MatrixIdEmLERKd125
_ZN4PLMD6logdetIdEEiRKNS_6MatrixIT_EERd0
_ZN4PLMD7diagMatIdEEiRKNS_6MatrixIT_EERSt6vectorIdSaIdEERNS1_IdEE14055
_ZN4PLMD8choleskyIdEEvRKNS_6MatrixIT_EERS3_446
_ZN4PLMD9transposeIdEEvRKNS_6MatrixIT_EERS3_730
_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 000000000..527b2e906 --- /dev/null +++ b/coverage/tools/Matrix.h.gcov.html @@ -0,0 +1,490 @@ + + + + + + + LCOV - plumed test coverage - tools/Matrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Matrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12113987.1 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #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    36866819 : 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    36863484 :   explicit Matrix(const unsigned nr=0, const unsigned nc=0 )  : sz(nr*nc), rw(nr), cl(nc), data(nr*nc) {}
+      91         272 :   Matrix(const Matrix<T>& t) : sz(t.sz), rw(t.rw), cl(t.cl), data(t.data) {}
+      92             :   /// Resize the matrix
+      93         899 :   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     3019033 :   inline unsigned nrows() const { return rw; }
+      96             :   /// Return the number of columns
+      97    11458232 :   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  2015393449 :   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   601299290 :   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     4829318 :     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         125 :   Matrix<T> operator*=(const T& v) {
+     132       55038 :     for(unsigned i=0; i<sz; ++i) { data[i]*=v; }
+     133         125 :     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       16490 : template <typename T> void mult( const Matrix<T>& A, const Matrix<T>& B, Matrix<T>& C ) {
+     169       16490 :   plumed_assert(A.cl==B.rw);
+     170       16490 :   if( A.rw !=C.rw  || B.cl !=C.cl ) { C.resize( A.rw, B.cl ); } C=static_cast<T>( 0 );
+     171  2012861479 :   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       16490 : }
+     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         730 : template <typename T> void transpose( const Matrix<T>& A, Matrix<T>& AT ) {
+     189         730 :   if( A.rw!=AT.cl || A.cl!=AT.rw ) AT.resize( A.cl, A.rw );
+     190       52990 :   for(unsigned i=0; i<A.cl; ++i) for(unsigned j=0; j<A.rw; ++j) AT(i,j)=A(j,i);
+     191         730 : }
+     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 000000000..9d16bfdd2 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-10-17 16:45:00Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowC2ERS3_j30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjEixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2822610
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2822610
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2822610
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j3523551
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowixEj3523551
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj3523551
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j36028234
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj36028234
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj36028234
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowC2ERS8_j41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowixEj41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjEixEj41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j48481086
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj48481086
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj48481086
+
+
+ + + +
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 000000000..832d79abf --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-10-17 16:45:00Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2822610
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2822610
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2822610
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j36028234
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj36028234
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j3523551
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj36028234
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j48481086
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj48481086
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj48481086
_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_rowixEj3523551
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj3523551
+
+
+ + + +
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 000000000..0b811cc6c --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html @@ -0,0 +1,214 @@ + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-10-17 16:45:00Functions: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     3523551 : MatrixSquareBracketsAccess<T,C,I,J>::Const_row::Const_row(const MatrixSquareBracketsAccess&t,I i):
+     101     3523551 :   t(t),i(i) {}
+     102             : 
+     103             : template<class T,class C,class I,class J>
+     104   129092119 : MatrixSquareBracketsAccess<T,C,I,J>::Row::Row(MatrixSquareBracketsAccess&t,I i):
+     105   129092119 :   t(t),i(i) {}
+     106             : 
+     107             : template<class T,class C,class I,class J>
+     108     3523551 : 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     3523551 :   return (*static_cast<const T*>(&t))(i,j);
+     113             : }
+     114             : 
+     115             : template<class T,class C,class I,class J>
+     116   129092119 : 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   129092119 :   return (*static_cast<T*>(&t))(i,j);
+     121             : }
+     122             : 
+     123             : template<class T,class C,class I,class J>
+     124   129092119 : typename MatrixSquareBracketsAccess<T,C,I,J>::Row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i) {
+     125   129092119 :   return Row(*this,i);
+     126             : }
+     127             : 
+     128             : template<class T,class C,class I,class J>
+     129     3523551 : typename MatrixSquareBracketsAccess<T,C,I,J>::Const_row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i)const {
+     130     3523551 :   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 000000000..c770f7bbd --- /dev/null +++ b/coverage/tools/MergeVectorTools.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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_EE49755
_ZN4PLMD16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS3_EEEEvPKPKT_mRS2_INS6_10value_typeESaISB_EE49755
+
+
+ + + +
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 000000000..34c8eda1a --- /dev/null +++ b/coverage/tools/MergeVectorTools.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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_EE49755
_ZN4PLMD16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS3_EEEEvPKPKT_mRS2_INS6_10value_typeESaISB_EE49755
+
+
+ + + +
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 000000000..7b3ebf733 --- /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-10-17 16:45:00Functions: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       49755 : 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      135651 :     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             :     // TODO: revert "typename C::value_type" to "auto": nvc++ and icpc seems to do not deduce automatically the return type
+      55             :     const typename C::value_type & top() const { return *fwdIt; }
+      56             :     void next() { ++fwdIt;};
+      57             :   };
+      58             : 
+      59             :   // preprocessing
+      60             :   {
+      61       49755 :     std::size_t maxsize=0;
+      62      190189 :     for(unsigned i=0; i<size; i++) {
+      63             :       // find the largest
+      64      191247 :       maxsize=std::max(maxsize,vecs[i]->size());
+      65             :     }
+      66             :     // this is just to decrease the number of reallocations on push_back
+      67       49755 :     result.reserve(maxsize);
+      68             :     // if vectors are empty we are done
+      69       49755 :     if(maxsize==0) return;
+      70             :   }
+      71             : 
+      72             :   // start
+      73             :   // heap containing the ranges to be pushed
+      74             :   // avoid allocations when it's small
+      75             :   gch::small_vector<Entry,32> heap;
+      76             : 
+      77             :   {
+      78      185398 :     for(unsigned i=0; i<size; i++) {
+      79      138725 :       if(!vecs[i]->empty()) {
+      80             :         // add entry at the end of the array
+      81      135651 :         heap.emplace_back(Entry(*vecs[i]));
+      82             :       }
+      83             :     }
+      84             :     // make a sorted heap
+      85       46673 :     std::make_heap(std::begin(heap),std::end(heap));
+      86             :   }
+      87             : 
+      88             :   // first iteration, to avoid an extra "if" in main iteration
+      89             :   // explanations are below
+      90             :   {
+      91       46673 :     std::pop_heap(std::begin(heap), std::end(heap));
+      92             :     auto & tmp=heap.back();
+      93       46673 :     const auto val=tmp.top();
+      94             :     // here, we append inconditionally
+      95       46673 :     result.push_back(val);
+      96             :     tmp.next();
+      97       46673 :     if(tmp.empty()) heap.pop_back();
+      98       44128 :     else std::push_heap(std::begin(heap), std::end(heap));
+      99             :   }
+     100             : 
+     101     2515279 :   while(!heap.empty()) {
+     102             :     // move entry with the smallest element to the back of the array
+     103     2468606 :     std::pop_heap(std::begin(heap), std::end(heap));
+     104             :     // entry
+     105             :     auto & tmp=heap.back();
+     106             :     // element
+     107     2468606 :     const auto val=tmp.top();
+     108             :     // if the element is larger than the current largest element,
+     109             :     // push it to result
+     110     2468606 :     if(val > result.back()) result.push_back(val);
+     111             :     // move forward the used entry
+     112             :     tmp.next();
+     113             :     // if this entry is exhausted, remove it from the array
+     114     2468606 :     if(tmp.empty()) heap.pop_back();
+     115             :     // otherwise, sort again the array
+     116     2335500 :     else std::push_heap(std::begin(heap), std::end(heap));
+     117             :   }
+     118             : }
+     119             : 
+     120             : template<typename T, typename = void>
+     121             : struct has_size_and_data : std::false_type {};
+     122             : 
+     123             : template<typename T>
+     124             : struct has_size_and_data<T, std::void_t<decltype(std::declval<T>().size()), decltype(std::declval<T>().data())>> : std::true_type {};
+     125             : 
+     126             : template<class C, class D>
+     127       49755 : auto mergeSortedVectors(C& vecs, std::vector<D> & result) -> typename std::enable_if<has_size_and_data<C>::value, void>::type {
+     128       49755 :   mergeSortedVectors(vecs.data(),vecs.size(),result);
+     129       49755 : }
+     130             : 
+     131             : }
+     132             : }
+     133             : 
+     134             : #endif
+     135             : 
+
+
+
+ + + + +
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 000000000..44e6cb208 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828398.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..3b9b8fccb --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828398.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..b74642ef0 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.gcov.html @@ -0,0 +1,271 @@ + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828398.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..2aa6a92ff --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..92f215c5f --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..5a7925d71 --- /dev/null +++ b/coverage/tools/MinimiseBase.h.gcov.html @@ -0,0 +1,191 @@ + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..c23285743 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE631
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE3540
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_4565
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_9943
+
+
+ + + +
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 000000000..6d83c8756 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-10-17 16:45:00Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE631
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_9943
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_4565
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE3540
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32
+
+
+ + + +
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 000000000..a95d61007 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.gcov.html @@ -0,0 +1,663 @@ + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-10-17 16:45:00Functions: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          32 : unsigned MolDataClass::numberOfAtomsPerResidueInBackbone( const std::string& type ) {
+      30          32 :   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        9943 : bool MolDataClass::allowedResidue( const std::string& type, const std::string& residuename ) {
+      37        9943 :   if( type=="protein" ) {
+      38        7836 :     if(residuename=="ALA") return true;
+      39        7520 :     else if(residuename=="ARG") return true;
+      40        7520 :     else if(residuename=="ASN") return true;
+      41        7520 :     else if(residuename=="ASP") return true;
+      42        7508 :     else if(residuename=="CYS") return true;
+      43        7508 :     else if(residuename=="GLN") return true;
+      44        7508 :     else if(residuename=="GLU") return true;
+      45        7496 :     else if(residuename=="GLY") return true;
+      46        7486 :     else if(residuename=="HIS") return true;
+      47        7486 :     else if(residuename=="ILE") return true;
+      48        7482 :     else if(residuename=="LEU") return true;
+      49        7482 :     else if(residuename=="LYS") return true;
+      50        7476 :     else if(residuename=="MET") return true;
+      51        7476 :     else if(residuename=="PHE") return true;
+      52        7470 :     else if(residuename=="PRO") return true;
+      53        7463 :     else if(residuename=="SER") return true;
+      54        7459 :     else if(residuename=="THR") return true;
+      55        7429 :     else if(residuename=="TRP") return true;
+      56        7415 :     else if(residuename=="TYR") return true;
+      57        7409 :     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        3540 : void MolDataClass::getBackboneForResidue( const std::string& type, const unsigned& residuenum, const PDB& mypdb, std::vector<AtomNumber>& atoms ) {
+     164        3540 :   std::string residuename=mypdb.getResidueName( residuenum );
+     165        3540 :   plumed_massert( MolDataClass::allowedResidue( type, residuename ), "residue " + residuename + " unrecognized for molecule type " + type );
+     166        3540 :   if( type=="protein" ) {
+     167        3540 :     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        3540 :     } else if( residuename=="ACE") {
+     175           0 :       atoms.resize(1);
+     176           0 :       atoms[0]=mypdb.getNamedAtomFromResidue("C",residuenum);
+     177        7080 :     } else if( residuename=="NME"||residuename=="NH2") {
+     178           0 :       atoms.resize(1);
+     179           0 :       atoms[0]=mypdb.getNamedAtomFromResidue("N",residuenum);
+     180             :     } else {
+     181        3540 :       atoms.resize(5);
+     182        3540 :       atoms[0]=mypdb.getNamedAtomFromResidue("N",residuenum);
+     183        3540 :       atoms[1]=mypdb.getNamedAtomFromResidue("CA",residuenum);
+     184        3540 :       atoms[2]=mypdb.getNamedAtomFromResidue("CB",residuenum);
+     185        3540 :       atoms[3]=mypdb.getNamedAtomFromResidue("C",residuenum);
+     186        3540 :       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        3540 : }
+     201             : 
+     202        4565 : bool MolDataClass::isTerminalGroup( const std::string& type, const std::string& residuename ) {
+     203        4565 :   if( type=="protein" ) {
+     204        4565 :     if( residuename=="ACE" ) return true;
+     205        4127 :     else if( residuename=="NME" ) return true;
+     206        3689 :     else if( residuename=="NH2" ) return true;
+     207        3689 :     else return false;
+     208             :   } else {
+     209           0 :     plumed_merror(type + " is not a valid molecule type");
+     210             :   }
+     211             :   return false;
+     212             : }
+     213             : 
+     214         631 : void MolDataClass::specialSymbol( const std::string& type, const std::string& symbol, const PDB& mypdb, std::vector<AtomNumber>& numbers ) {
+     215         861 :   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         631 :     numbers.resize(0);
+     222             : 
+     223             : // special cases:
+     224         631 :     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         630 :     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         628 :     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         627 :     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         626 :     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         625 :     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         624 :     if(dash==std::string::npos) plumed_error() << "Unrecognized symbol "<<symbol;
+     289             : 
+     290         624 :     std::size_t firstunderscore=symbol.find_first_of('_',dash+1);
+     291         624 :     std::size_t firstnum=symbol.find_first_of("0123456789",dash+1);
+     292         624 :     std::string name=symbol.substr(0,dash);
+     293             :     unsigned resnum;
+     294             :     std::string resname;
+     295             :     std::string chainid;
+     296         624 :     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         618 :     } else if(firstnum==dash+1) {
+     300        1216 :       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         624 :     resname= mypdb.getResidueName(resnum,chainid);
+     308         624 :     Tools::stripLeadingAndTrailingBlanks(resname);
+     309        1248 :     if(allowedResidue("protein",resname)) {
+     310         208 :       if( name=="phi" && !isTerminalGroup("protein",resname) ) {
+     311         118 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum-1,chainid));
+     312         118 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     313         118 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     314         118 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     315         175 :       } else if( name=="psi" && !isTerminalGroup("protein",resname) ) {
+     316         170 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     317         170 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     318         170 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     319         170 :         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 000000000..1cac69605 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:4646100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue6resizeERKmS2_S2_S2_S2_36
_ZN4PLMD10MultiValueC2ERKmS2_S2_S2_S2_344869
_ZN4PLMD10MultiValue8clearAllEv6810512
_ZN4PLMD10MultiValue16clearDerivativesERKj128147747
+
+
+ + + +
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 000000000..045e19003 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:4646100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue16clearDerivativesERKj128147747
_ZN4PLMD10MultiValue6resizeERKmS2_S2_S2_S2_36
_ZN4PLMD10MultiValue8clearAllEv6810512
_ZN4PLMD10MultiValueC2ERKmS2_S2_S2_S2_344869
+
+
+ + + +
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 000000000..22f6b87f2 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.gcov.html @@ -0,0 +1,176 @@ + + + + + + + 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:4646100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiValue.h"
+      23             : #include "Tools.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27      344869 : MultiValue::MultiValue( const size_t& nvals, const size_t& nder, const size_t& nmat, const size_t& maxcol, const size_t& nbook ):
+      28      344869 :   task_index(0),
+      29      344869 :   task2_index(0),
+      30      344869 :   values(nvals),
+      31      344869 :   nderivatives(nder),
+      32      344869 :   derivatives(nvals*nder),
+      33      344869 :   hasderiv(nvals*nder,false),
+      34      344869 :   tmpval(0),
+      35      344869 :   nactive(nvals),
+      36      344869 :   active_list(nvals*nder),
+      37      344869 :   tmpder(nder),
+      38      344869 :   atLeastOneSet(false),
+      39      344869 :   vector_call(false),
+      40      344869 :   nindices(0),
+      41      344869 :   nsplit(0),
+      42      344869 :   nmatrix_cols(maxcol),
+      43      344869 :   matrix_row_stash(nmat*maxcol,0),
+      44      344869 :   matrix_force_stash(nder*nmat),
+      45      344869 :   matrix_bookeeping(nbook,0),
+      46      344869 :   matrix_row_nderivatives(nmat,0),
+      47      344869 :   matrix_row_derivative_indices(nmat)
+      48             : {
+      49      388633 :   for(unsigned i=0; i<nmat; ++i) matrix_row_derivative_indices[i].resize( nder );
+      50             :   // This is crap that will be deleted in future
+      51      344869 :   std::vector<unsigned> myind( nder );
+      52    99768807 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      53      344869 : }
+      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 ); std::vector<unsigned> myind( nder );
+      63        6840 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      64          36 : }
+      65             : 
+      66     6810512 : void MultiValue::clearAll() {
+      67    36576302 :   for(unsigned i=0; i<values.size(); ++i) values[i]=0;
+      68             :   // Clear matrix row
+      69             :   std::fill( matrix_row_stash.begin(), matrix_row_stash.end(), 0 );
+      70             :   // Clear matrix derivative indices
+      71             :   std::fill( matrix_row_nderivatives.begin(), matrix_row_nderivatives.end(), 0 );
+      72             :   // Clear matrix forces
+      73             :   std::fill(matrix_force_stash.begin(),matrix_force_stash.end(),0);
+      74     6810512 :   if( !atLeastOneSet ) return;
+      75    29403410 :   for(unsigned i=0; i<values.size(); ++i) clearDerivatives(i);
+      76     5521277 :   atLeastOneSet=false;
+      77             : }
+      78             : 
+      79   128147747 : void MultiValue::clearDerivatives( const unsigned& ival ) {
+      80   128147747 :   values[ival]=0;
+      81   128147747 :   if( !atLeastOneSet ) return;
+      82    69072184 :   unsigned base=ival*nderivatives;
+      83   626107740 :   for(unsigned i=0; i<nactive[ival]; ++i) {
+      84   557035556 :     unsigned k = base+active_list[base+i]; derivatives[k]=0.; hasderiv[k]=false;
+      85             :   }
+      86    69072184 :   nactive[ival]=0;
+      87             : #ifndef NDEBUG
+      88             :   for(unsigned i=0; i<nderivatives; ++i) {
+      89             :     if( hasderiv[base+i] ) {
+      90             :       std::string num1, num2;
+      91             :       Tools::convert(ival,num1); Tools::convert(i,num2);
+      92             :       plumed_merror("FAILING TO CLEAR VALUE " + num1 + " DERIVATIVE " + num2 + " IS PROBLEMATIC");
+      93             :     }
+      94             :     // As this is debugging code we hard code an escape here otherwise this check is really expensive
+      95             :     if( i>1000 ) return;
+      96             :   }
+      97             : #endif
+      98             : }
+      99             : 
+     100             : }
+
+
+
+ + + + +
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 000000000..1d0705fd0 --- /dev/null +++ b/coverage/tools/MultiValue.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - tools/MultiValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue19resizeTemporyVectorERKj490140
_ZN4PLMD10MultiValue18stashMatrixElementERKjS2_S2_RKd8598870
_ZN4PLMD10MultiValue13addDerivativeERKmS2_RKd1064975746
_ZN4PLMD10MultiValue11updateIndexERKmS2_1951191120
+
+
+ + + +
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 000000000..28c83af60 --- /dev/null +++ b/coverage/tools/MultiValue.h.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - tools/MultiValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKmS2_1951191120
_ZN4PLMD10MultiValue13addDerivativeERKmS2_RKd1064975746
_ZN4PLMD10MultiValue18stashMatrixElementERKjS2_S2_RKd8598870
_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 000000000..2eca3c4ea --- /dev/null +++ b/coverage/tools/MultiValue.h.gcov.html @@ -0,0 +1,436 @@ + + + + + + + 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-10-17 16:45:00Functions: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 "Vector.h"
+      27             : #include "Tensor.h"
+      28             : #include <vector>
+      29             : #include <cstddef>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class MultiValue {
+      34             :   friend class ActionWithVector;
+      35             : private:
+      36             : /// The index of the task we are currently performing
+      37             :   std::size_t task_index, task2_index;
+      38             : /// Values of quantities
+      39             :   std::vector<double> values;
+      40             : /// Number of derivatives per value
+      41             :   unsigned nderivatives;
+      42             : /// Derivatives
+      43             :   std::vector<double> derivatives;
+      44             : /// Matrix asserting which values have derivatives
+      45             :   std::vector<bool> hasderiv;
+      46             : /// Tempory value
+      47             :   double tmpval;
+      48             : /// Lists of active variables
+      49             :   std::vector<unsigned> nactive, active_list;
+      50             : /// Tempory vector of derivatives (used for calculating quotients
+      51             :   std::vector<double> tmpder;
+      52             : /// Logical to check if any derivatives were set
+      53             :   bool atLeastOneSet;
+      54             : /// Are we in this for a call on vectors
+      55             :   bool vector_call;
+      56             :   unsigned nindices, nsplit;
+      57             : /// This allows us to store matrix elements
+      58             :   unsigned nmatrix_cols;
+      59             :   std::vector<double> matrix_row_stash;
+      60             :   std::vector<double> matrix_force_stash;
+      61             :   std::vector<unsigned> matrix_bookeeping;
+      62             : /// These are used to store the indices that have derivatives wrt to at least one
+      63             : /// of the elements in a matrix
+      64             :   std::vector<unsigned> matrix_row_nderivatives;
+      65             :   std::vector<std::vector<unsigned> > matrix_row_derivative_indices;
+      66             : /// This is a fudge to save on vector resizing in MultiColvar
+      67             :   std::vector<unsigned> indices;
+      68             :   std::vector<Vector> tmp_atoms;
+      69             :   std::vector<std::vector<Vector> > tmp_atom_der;
+      70             :   std::vector<Tensor> tmp_atom_virial;
+      71             :   std::vector<std::vector<double> > tmp_vectors;
+      72             : public:
+      73       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 );
+      74          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 );
+      75             : /// Set the task index prior to the loop
+      76             :   void setTaskIndex( const std::size_t& tindex );
+      77             : ///
+      78             :   std::size_t getTaskIndex() const ;
+      79             : ///
+      80             :   void setSecondTaskIndex( const std::size_t& tindex );
+      81             : /// Get the task index
+      82             :   std::size_t getSecondTaskIndex() const ;
+      83             : ///
+      84             :   void setSplitIndex( const std::size_t& nat );
+      85             :   std::size_t getSplitIndex() const ;
+      86             : ///
+      87             :   void setNumberOfIndices( const std::size_t& nat );
+      88             :   std::size_t getNumberOfIndices() const ;
+      89             : ///
+      90             :   std::vector<unsigned>& getIndices();
+      91             :   std::vector<Vector>& getAtomVector();
+      92             : /// Get the number of values in the stash
+      93             :   unsigned getNumberOfValues() const ;
+      94             : /// Get the number of derivatives in the stash
+      95             :   unsigned getNumberOfDerivatives() const ;
+      96             : /// Get references to some memory. These vectors allow us to
+      97             : /// avoid doing lots of resizing of vectors in MultiColvarTemplate
+      98             :   std::vector<Vector>& getFirstAtomVector();
+      99             :   std::vector<std::vector<Vector> >& getFirstAtomDerivativeVector();
+     100             :   const std::vector<std::vector<Vector> >& getConstFirstAtomDerivativeVector() const ;
+     101             :   std::vector<Tensor>& getFirstAtomVirialVector();
+     102             :   void resizeTemporyVector(const unsigned& n );
+     103             :   std::vector<double>& getTemporyVector(const unsigned& ind );
+     104             : ///
+     105             :   bool inVectorCall() const ;
+     106             : /// Set value numbered
+     107             :   void setValue( const std::size_t&,  const double& );
+     108             : /// Add value numbered
+     109             :   void addValue( const std::size_t&,  const double& );
+     110             : /// Add derivative
+     111             :   void addDerivative( const std::size_t&, const std::size_t&, const double& );
+     112             : /// Set the value of the derivative
+     113             :   void setDerivative( const std::size_t& ival, const std::size_t& jder, const double& der);
+     114             : /// Return the ith value
+     115             :   double get( const std::size_t& ) const ;
+     116             : /// Return a derivative value
+     117             :   double getDerivative( const std::size_t&, const std::size_t& ) const ;
+     118             : /// Clear all values
+     119             :   void clearAll();
+     120             : /// Clear the derivatives
+     121             :   void clearDerivatives( const unsigned& );
+     122             : /// Clear a value
+     123             :   void clear( const unsigned& );
+     124             : /// Functions for accessing active list
+     125             :   bool updateComplete();
+     126             :   void emptyActiveMembers();
+     127             :   void putIndexInActiveArray( const unsigned & );
+     128             :   void updateIndex( const unsigned& );
+     129             : ///
+     130             :   void updateIndex( const std::size_t&, const std::size_t& );
+     131             : ///
+     132             :   unsigned getActiveIndex( const std::size_t&, const std::size_t& ) const ;
+     133             : ///
+     134             :   void clearActiveMembers( const std::size_t& ival );
+     135             : ///
+     136             :   unsigned getNumberActive( const std::size_t& ival ) const ;
+     137             : ///
+     138             :   unsigned getActiveIndex( const unsigned& ) const ;
+     139             : /// Get the matrix bookeeping array
+     140             :   const std::vector<unsigned> & getMatrixBookeeping() const ;
+     141             :   void stashMatrixElement( const unsigned& nmat, const unsigned& rowstart, const unsigned& jcol, const double& val );
+     142             :   double getStashedMatrixElement( const unsigned& nmat, const unsigned& jcol ) const ;
+     143             : /// Get the bookeeping stuff for the derivatives wrt to rows of matrix
+     144             :   void setNumberOfMatrixRowDerivatives( const unsigned& nmat, const unsigned& nind );
+     145             :   unsigned getNumberOfMatrixRowDerivatives( const unsigned& nmat ) const ;
+     146             :   std::vector<unsigned>& getMatrixRowDerivativeIndices( const unsigned& nmat );
+     147             : /// Stash the forces on the matrix
+     148             :   void addMatrixForce( const unsigned& imat, const unsigned& jind, const double& f );
+     149             :   double getStashedMatrixForce( const unsigned& imat, const unsigned& jind ) const ;
+     150             : };
+     151             : 
+     152             : inline
+     153             : unsigned MultiValue::getNumberOfValues() const {
+     154             :   return values.size();
+     155             : }
+     156             : 
+     157             : inline
+     158             : unsigned MultiValue::getNumberOfDerivatives() const {
+     159      163849 :   return nderivatives; //derivatives.ncols();
+     160             : }
+     161             : 
+     162             : inline
+     163             : double MultiValue::get( const std::size_t& ival ) const {
+     164             :   plumed_dbg_assert( ival<=values.size() );
+     165   291523266 :   return values[ival];
+     166             : }
+     167             : 
+     168             : inline
+     169             : void MultiValue::setValue( const std::size_t& ival,  const double& val) {
+     170             :   plumed_dbg_assert( ival<=values.size() );
+     171    25017068 :   values[ival]=val;
+     172             : }
+     173             : 
+     174             : inline
+     175             : void MultiValue::addValue( const std::size_t& ival,  const double& val) {
+     176             :   plumed_dbg_assert( ival<=values.size() );
+     177   187549828 :   values[ival]+=val;
+     178             : }
+     179             : 
+     180             : inline
+     181  1064975746 : void MultiValue::addDerivative( const std::size_t& ival, const std::size_t& jder, const double& der) {
+     182  1064975746 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     183  1064975746 :   hasderiv[nderivatives*ival+jder]=true; derivatives[nderivatives*ival+jder] += der;
+     184  1064975746 : }
+     185             : 
+     186             : inline
+     187             : void MultiValue::setDerivative( const std::size_t& ival, const std::size_t& jder, const double& der) {
+     188             :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     189             :   hasderiv[nderivatives*ival+jder]=true; derivatives[nderivatives*ival+jder]=der;
+     190             : }
+     191             : 
+     192             : 
+     193             : inline
+     194             : double MultiValue::getDerivative( const std::size_t& ival, const std::size_t& jder ) const {
+     195             :   plumed_dbg_assert( ival<values.size() && jder<nderivatives );
+     196   888496226 :   return derivatives[nderivatives*ival+jder];
+     197             : }
+     198             : 
+     199             : inline
+     200  1951191120 : void MultiValue::updateIndex( const std::size_t& ival, const std::size_t& jder ) {
+     201             :   plumed_dbg_assert( ival<values.size() && jder<nderivatives );
+     202             : #ifdef DNDEBUG
+     203             :   for(unsigned i=0; i<nactive[ival]; ++i) plumed_dbg_assert( active_list[nderivatives*ival+nactive[ival]]!=jder );
+     204             : #endif
+     205  1951191120 :   if( hasderiv[nderivatives*ival+jder] ) {
+     206             :     plumed_dbg_assert( nactive[ival]<nderivatives);
+     207   557035706 :     active_list[nderivatives*ival+nactive[ival]]=jder;
+     208   557035706 :     nactive[ival]++;
+     209             :   }
+     210  1951191120 : }
+     211             : 
+     212             : inline
+     213             : unsigned MultiValue::getNumberActive( const std::size_t& ival ) const {
+     214             :   plumed_dbg_assert( ival<nactive.size() );
+     215  1299330336 :   return nactive[ival];
+     216             : }
+     217             : 
+     218             : inline
+     219             : unsigned MultiValue::getActiveIndex( const std::size_t& ival, const std::size_t& ind ) const {
+     220             :   plumed_dbg_assert( ind<nactive[ival] );
+     221  1100607420 :   return active_list[nderivatives*ival+ind];
+     222             : }
+     223             : 
+     224             : inline
+     225             : void MultiValue::setSplitIndex( const std::size_t& nat ) {
+     226      663993 :   nsplit = nat;
+     227             : }
+     228             : 
+     229             : inline
+     230             : std::size_t MultiValue::getSplitIndex() const {
+     231   246931070 :   return nsplit;
+     232             : }
+     233             : 
+     234             : inline
+     235             : void MultiValue::setNumberOfIndices( const std::size_t& nat ) {
+     236      405876 :   nindices = nat;
+     237             : }
+     238             : 
+     239             : inline
+     240             : std::size_t MultiValue::getNumberOfIndices() const {
+     241    28540953 :   return nindices;
+     242             : }
+     243             : 
+     244             : 
+     245             : inline
+     246             : bool MultiValue::inVectorCall() const {
+     247             :   return (matrix_row_nderivatives.size()>0 && vector_call);
+     248             : }
+     249             : 
+     250             : inline
+     251             : void MultiValue::clearActiveMembers( const std::size_t& ival ) {
+     252             :   nactive[ival]=0;
+     253             : }
+     254             : 
+     255             : inline
+     256             : void MultiValue::setTaskIndex( const std::size_t& tindex ) {
+     257    98355224 :   task_index = tindex;
+     258             : }
+     259             : 
+     260             : inline
+     261             : std::size_t MultiValue::getTaskIndex() const {
+     262    17449808 :   return task_index;
+     263             : }
+     264             : 
+     265             : inline
+     266             : void MultiValue::setSecondTaskIndex( const std::size_t& tindex ) {
+     267    88130811 :   task2_index = tindex;
+     268             : }
+     269             : 
+     270             : inline
+     271             : std::size_t MultiValue::getSecondTaskIndex() const {
+     272     6403164 :   return task2_index;
+     273             : }
+     274             : 
+     275             : inline
+     276             : std::vector<unsigned>& MultiValue::getIndices() {
+     277     1379763 :   return indices;
+     278             : }
+     279             : 
+     280             : inline
+     281             : std::vector<Vector>& MultiValue::getAtomVector() {
+     282      405876 :   return tmp_atoms;
+     283             : }
+     284             : 
+     285             : inline
+     286             : std::vector<Vector>& MultiValue::getFirstAtomVector() {
+     287      670728 :   return tmp_atoms;
+     288             : }
+     289             : 
+     290             : inline
+     291             : std::vector<std::vector<Vector> >& MultiValue::getFirstAtomDerivativeVector() {
+     292     1076604 :   return tmp_atom_der;
+     293             : }
+     294             : 
+     295             : inline
+     296             : const std::vector<std::vector<Vector> >& MultiValue::getConstFirstAtomDerivativeVector() const {
+     297             :   return tmp_atom_der;
+     298             : }
+     299             : 
+     300             : inline
+     301             : std::vector<Tensor>& MultiValue::getFirstAtomVirialVector() {
+     302      490140 :   return tmp_atom_virial;
+     303             : }
+     304             : 
+     305             : inline
+     306     8598870 : void MultiValue::stashMatrixElement( const unsigned& nmat, const unsigned& rowstart, const unsigned& jcol, const double& val ) {
+     307             :   plumed_dbg_assert( jcol<nmatrix_cols && rowstart + matrix_bookeeping[rowstart]<matrix_bookeeping.size() && nmatrix_cols*nmat + matrix_bookeeping[rowstart]<matrix_row_stash.size() );
+     308     8598870 :   matrix_bookeeping[rowstart]++; matrix_bookeeping[rowstart + matrix_bookeeping[rowstart]]=jcol; matrix_row_stash[ nmatrix_cols*nmat + jcol] = val;
+     309     8598870 : }
+     310             : 
+     311             : inline
+     312             : double MultiValue::getStashedMatrixElement( const unsigned& nmat, const unsigned& jcol ) const {
+     313             :   plumed_dbg_assert( nmatrix_cols*nmat + jcol<matrix_row_stash.size() );
+     314     7206015 :   return matrix_row_stash[ nmatrix_cols*nmat + jcol ];
+     315             : }
+     316             : 
+     317             : inline
+     318             : const std::vector<unsigned> & MultiValue::getMatrixBookeeping() const {
+     319             :   return matrix_bookeeping;
+     320             : }
+     321             : 
+     322             : inline
+     323             : void MultiValue::setNumberOfMatrixRowDerivatives( const unsigned& nmat, const unsigned& nind ) {
+     324             :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() && nind<=matrix_row_derivative_indices[nmat].size() );
+     325    12992400 :   matrix_row_nderivatives[nmat]=nind;
+     326             : }
+     327             : 
+     328             : inline
+     329             : unsigned MultiValue::getNumberOfMatrixRowDerivatives( const unsigned& nmat ) const {
+     330   108296955 :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() ); return matrix_row_nderivatives[nmat];
+     331             : }
+     332             : 
+     333             : inline
+     334             : std::vector<unsigned>& MultiValue::getMatrixRowDerivativeIndices( const unsigned& nmat ) {
+     335     1978950 :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() ); return matrix_row_derivative_indices[nmat];
+     336             : }
+     337             : 
+     338             : inline
+     339             : void MultiValue::addMatrixForce( const unsigned& imat, const unsigned& jind, const double& f ) {
+     340    19244157 :   matrix_force_stash[imat*nderivatives + jind]+=f;
+     341             : }
+     342             : 
+     343             : inline
+     344             : double MultiValue::getStashedMatrixForce( const unsigned& imat, const unsigned& jind ) const {
+     345   842633458 :   return matrix_force_stash[imat*nderivatives + jind];
+     346             : }
+     347             : 
+     348             : inline
+     349      490140 : void MultiValue::resizeTemporyVector(const unsigned& n ) {
+     350      490140 :   if( n>tmp_vectors.size() ) tmp_vectors.resize(n);
+     351      490140 : }
+     352             : 
+     353             : inline
+     354             : std::vector<double>& MultiValue::getTemporyVector(const unsigned& ind ) {
+     355             :   plumed_dbg_assert( ind<tmp_vectors.size() );
+     356             :   return tmp_vectors[ind];
+     357             : }
+     358             : 
+     359             : }
+     360             : #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 000000000..b96ec7802 --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZNK4PLMD12NeighborList4sizeEv23715485
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZN4PLMD12NeighborList12getIndexPairEj234387479
_ZNK4PLMD12NeighborList12getClosePairEj265911560
+
+
+ + + +
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 000000000..562dca54b --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZNK4PLMD12NeighborList12getClosePairEj265911560
_ZNK4PLMD12NeighborList13getLastUpdateEv24
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZNK4PLMD12NeighborList4sizeEv23715485
_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 000000000..91266c6cc --- /dev/null +++ b/coverage/tools/NeighborList.cpp.gcov.html @@ -0,0 +1,370 @@ + + + + + + + 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-10-17 16:45:00Functions: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    23715485 : unsigned NeighborList::size() const {
+     268    23715485 :   return neighbors_.size();
+     269             : }
+     270             : 
+     271   265911560 : NeighborList::pairIDs NeighborList::getClosePair(const unsigned i) const {
+     272   265911560 :   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 000000000..ad4dde8a9 --- /dev/null +++ b/coverage/tools/NeighborList.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5cc323091 --- /dev/null +++ b/coverage/tools/NeighborList.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3282bf3e2 --- /dev/null +++ b/coverage/tools/NeighborList.h.gcov.html @@ -0,0 +1,188 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..386975a5a --- /dev/null +++ b/coverage/tools/OFile.cpp.func-sort-c.html @@ -0,0 +1,192 @@ + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21022792.5 %
Date:2024-10-17 16:45:00Functions: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_3759
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4131
_ZNK4PLMD5OFile12checkRestartEv4131
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE6709
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd7274
_ZN4PLMD5OFile5flushEv9403
_ZN4PLMD5OFileC1Ev15193
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28070
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE806680
_ZN4PLMD5OFileC2Ev806685
_ZN4PLMD5OFile8fmtFieldEv827749
_ZN4PLMD5OFile10printFieldEv3841520
_ZN4PLMD5OFile7llwriteEPKcm6064709
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6140690
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14310056
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15803900
_ZN4PLMD5OFile6printfEPKcz25083013
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_38566022
+
+
+ + + +
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 000000000..8c114569b --- /dev/null +++ b/coverage/tools/OFile.cpp.func.html @@ -0,0 +1,192 @@ + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21022792.5 %
Date:2024-10-17 16:45:00Functions:283093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3759
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd7274
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_38566022
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15803900
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6140690
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx0
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEy47
_ZN4PLMD5OFile10printFieldEv3841520
_ZN4PLMD5OFile11clearFieldsEv3202
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE806680
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5OFile14enforceRestartEv11
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE194
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE6709
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28070
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4131
_ZN4PLMD5OFile5flushEv9403
_ZN4PLMD5OFile6printfEPKcz25083013
_ZN4PLMD5OFile6rewindEv135
_ZN4PLMD5OFile7llwriteEPKcm6064709
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14310056
_ZN4PLMD5OFile8fmtFieldEv827749
_ZN4PLMD5OFileC1Ev15193
_ZN4PLMD5OFileC2Ev806685
_ZNK4PLMD5OFile12checkRestartEv4131
+
+
+ + + +
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 000000000..3333cc048 --- /dev/null +++ b/coverage/tools/OFile.cpp.gcov.html @@ -0,0 +1,512 @@ + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21022792.5 %
Date:2024-10-17 16:45:00Functions: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     6064709 : size_t OFile::llwrite(const char*ptr,size_t s) {
+      47             :   size_t r;
+      48     6064709 :   if(linked) return linked->llwrite(ptr,s);
+      49     6064657 :   if(! (comm && comm->Get_rank()>0)) {
+      50     5184999 :     if(!fp) plumed_merror("writing on uninitialized File");
+      51     5184999 :     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     5183736 :       r=std::fwrite(ptr,1,s,fp);
+      59             :     }
+      60             :   }
+      61     6064657 :   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     5202117 :     comm->Barrier();
+      69     5202117 :     comm->Bcast(r,0);
+      70             :   }
+      71             : 
+      72     6064657 :   return r;
+      73             : }
+      74             : 
+      75      821878 : OFile::OFile():
+      76      821878 :   linked(NULL),
+      77      821878 :   fieldChanged(false),
+      78      821878 :   backstring("bck"),
+      79      821878 :   enforceRestart_(false),
+      80      821878 :   enforceBackup_(false)
+      81             : {
+      82      821878 :   fmtField();
+      83      821878 :   buflen=1;
+      84      821878 :   actual_buffer_length=0;
+      85      821878 :   buffer.resize(buflen);
+      86             : // these are set to zero to avoid valgrind errors
+      87     1643756 :   for(int i=0; i<buflen; ++i) buffer[i]=0;
+      88             : // these are set to zero to avoid valgrind errors
+      89      821878 :   buffer_string.resize(1000,0);
+      90      821878 : }
+      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      806680 : OFile& OFile::setLinePrefix(const std::string&l) {
+     100      806680 :   linePrefix=l;
+     101      806680 :   return *this;
+     102             : }
+     103             : 
+     104    25083013 : int OFile::printf(const char*fmt,...) {
+     105             :   va_list arg;
+     106    25083013 :   va_start(arg, fmt);
+     107    25083013 :   int r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     108    25083013 :   va_end(arg);
+     109    25083013 :   if(r>=buflen-actual_buffer_length) {
+     110             :     int newlen=buflen;
+     111       55211 :     while(newlen<=r+actual_buffer_length) newlen*=2;
+     112       18404 :     std::vector<char> newbuf(newlen);
+     113       18404 :     std::memmove(newbuf.data(),buffer.data(),buflen);
+     114    13873683 :     for(int k=buflen; k<newlen; k++) newbuf[k]=0;
+     115             :     std::swap(buffer,newbuf);
+     116       18404 :     buflen=newlen;
+     117             :     va_list arg;
+     118       18404 :     va_start(arg, fmt);
+     119       18404 :     r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     120       18404 :     va_end(arg);
+     121             :   }
+     122    25083013 :   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    25083013 :   char*psearch=p1+actual_buffer_length;
+     129    25083013 :   actual_buffer_length+=r;
+     130    30562280 :   while((p2=std::strchr(psearch,'\n'))) {
+     131     5479267 :     if(linePrefix.length()>0) llwrite(linePrefix.c_str(),linePrefix.length());
+     132     5479267 :     llwrite(p1,p2-p1+1);
+     133     5479267 :     actual_buffer_length-=(p2-p1)+1;
+     134     5479267 :     p1=p2+1;
+     135             :     psearch=p1;
+     136             :   };
+     137    25083013 :   if(buffer.data()!=p1) std::memmove(buffer.data(),p1,actual_buffer_length);
+     138    25083013 :   return r;
+     139             : }
+     140             : 
+     141       28070 : OFile& OFile::addConstantField(const std::string&name) {
+     142             :   Field f;
+     143             :   f.name=name;
+     144       28070 :   const_fields.push_back(f);
+     145       28070 :   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    14310056 : OFile& OFile::fmtField(const std::string&fmt) {
+     157    14310056 :   this->fieldFmt=fmt;
+     158    14310056 :   return *this;
+     159             : }
+     160             : 
+     161      827749 : OFile& OFile::fmtField() {
+     162      827749 :   this->fieldFmt="%23.16lg";
+     163      827749 :   return *this;
+     164             : }
+     165             : 
+     166    15803900 : 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    15803900 :   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    15803900 :   printField(name,buffer_string.data());
+     173    15803900 :   return *this;
+     174             : }
+     175             : 
+     176     6140690 : OFile& OFile::printField(const std::string&name,int v) {
+     177             :   std::snprintf(buffer_string.data(),buffer_string.size()," %d",v);
+     178     6140690 :   printField(name,buffer_string.data());
+     179     6140690 :   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    38566022 : OFile& OFile::printField(const std::string&name,const std::string & v) {
+     213             :   unsigned i;
+     214   201367806 :   for(i=0; i<const_fields.size(); i++) if(const_fields[i].name==name) break;
+     215    38566022 :   if(i>=const_fields.size()) {
+     216             :     Field field;
+     217             :     field.name=name;
+     218             :     field.value=v;
+     219    16820904 :     fields.push_back(field);
+     220             :   } else {
+     221    21745118 :     if(const_fields[i].value!=v) fieldChanged=true;
+     222             :     const_fields[i].value=v;
+     223             :   }
+     224    38566022 :   return *this;
+     225             : }
+     226             : 
+     227        6709 : OFile& OFile::setupPrintValue( Value *val ) {
+     228        6709 :   if( val->isPeriodic() ) {
+     229         510 :     addConstantField("min_" + val->getName() );
+     230        1020 :     addConstantField("max_" + val->getName() );
+     231             :   }
+     232        6709 :   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     3841520 : OFile& OFile::printField() {
+     246             :   bool reprint=false;
+     247     3841520 :   if(fieldChanged || fields.size()!=previous_fields.size()) {
+     248             :     reprint=true;
+     249    20067536 :   } else for(unsigned i=0; i<fields.size(); i++) {
+     250    16232293 :       if( previous_fields[i].name!=fields[i].name ||
+     251    16232291 :           (fields[i].constant && fields[i].value!=previous_fields[i].value) ) {
+     252             :         reprint=true;
+     253             :         break;
+     254             :       }
+     255             :     }
+     256     3841520 :   if(reprint) {
+     257        6277 :     printf("#! FIELDS");
+     258      594892 :     for(unsigned i=0; i<fields.size(); i++) printf(" %s",fields[i].name.c_str());
+     259        6277 :     printf("\n");
+     260       34283 :     for(unsigned i=0; i<const_fields.size(); i++) {
+     261       28006 :       printf("#! SET %s %s",const_fields[i].name.c_str(),const_fields[i].value.c_str());
+     262       28006 :       printf("\n");
+     263             :     }
+     264             :   }
+     265    20662424 :   for(unsigned i=0; i<fields.size(); i++) printf("%s",fields[i].value.c_str());
+     266     3841520 :   printf("\n");
+     267     3841520 :   previous_fields=fields;
+     268     3841520 :   fields.clear();
+     269     3841520 :   fieldChanged=false;
+     270     3841520 :   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        3759 : void OFile::backupFile( const std::string& bstring, const std::string& fname ) {
+     294        3759 :   if(fname=="/dev/null") return;
+     295        3605 :   int maxbackup=100;
+     296        3605 :   if(std::getenv("PLUMED_MAXBACKUP")) Tools::convert(std::getenv("PLUMED_MAXBACKUP"),maxbackup);
+     297        3605 :   if(maxbackup>0 && (!comm || comm->Get_rank()==0)) {
+     298        3040 :     FILE* ff=std::fopen(const_cast<char*>(fname.c_str()),"r");
+     299        3040 :     if(ff) {
+     300             :       // no exception here
+     301         122 :       std::fclose(ff);
+     302             :       std::string backup;
+     303         122 :       size_t found=fname.find_last_of("/\\");
+     304         122 :       std::string directory=fname.substr(0,found+1);
+     305         122 :       std::string file=fname.substr(found+1);
+     306         122 :       for(int i=0;; i++) {
+     307             :         std::string num;
+     308         171 :         Tools::convert(i,num);
+     309         171 :         if(i>maxbackup) plumed_merror("cannot backup file "+file+" maximum number of backup is "+num+"\n");
+     310         342 :         backup=directory+bstring +"."+num+"."+file;
+     311         171 :         FILE* fff=std::fopen(backup.c_str(),"r");
+     312             :         // no exception here
+     313         171 :         if(!fff) break;
+     314          49 :         else std::fclose(fff);
+     315          49 :       }
+     316         122 :       int check=rename(fname.c_str(),backup.c_str());
+     317         122 :       plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     318             :     }
+     319             :   }
+     320             : }
+     321             : 
+     322        4131 : OFile& OFile::open(const std::string&path) {
+     323        4131 :   plumed_assert(!cloned);
+     324        4131 :   eof=false;
+     325        4131 :   err=false;
+     326        4131 :   fp=NULL;
+     327        4131 :   gzfp=NULL;
+     328        4131 :   this->path=path;
+     329        8262 :   this->path=appendSuffix(path,getSuffix());
+     330        4131 :   if(checkRestart()) {
+     331         372 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"a");
+     332         372 :     mode="a";
+     333         744 :     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        3759 :     backupFile( backstring, this->path );
+     342        3759 :     if(comm)comm->Barrier();
+     343        3759 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"w");
+     344        3759 :     mode="w";
+     345        7518 :     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        4131 :   if(plumed) plumed->insertFile(*this);
+     354        4131 :   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        9403 : FileBase& OFile::flush() {
+     391        9403 :   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        5497 :     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        5497 :     if(gzfp) gzflush(gzFile(gzfp),Z_FULL_FLUSH);
+     410             : #endif
+     411             :   }
+     412        9403 :   return *this;
+     413             : }
+     414             : 
+     415        4131 : bool OFile::checkRestart()const {
+     416        4131 :   if(enforceRestart_) return true;
+     417        4120 :   else if(enforceBackup_) return false;
+     418        2976 :   else if(action) return action->getRestart();
+     419         344 :   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 000000000..9c6639b7e --- /dev/null +++ b/coverage/tools/OFile.h.func-sort-c.html @@ -0,0 +1,504 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZN4PLMDlsIA49_cEERNS_5OFileES3_RKT_55
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_65
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_103
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_107
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_158
_ZN4PLMDlsIA6_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_168
_ZN4PLMDlsIA83_cEERNS_5OFileES3_RKT_184
_ZN4PLMDlsIA73_cEERNS_5OFileES3_RKT_199
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_206
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_209
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_236
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_291
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_292
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_703
_ZN4PLMDlsIA51_cEERNS_5OFileES3_RKT_1092
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_1106
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1158
_ZN4PLMDlsIA10_cEERNS_5OFileES3_RKT_1290
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_1293
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1296
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1301
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1313
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1550
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1644
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1773
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_1909
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1915
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_2191
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_2256
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_2500
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2585
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2862
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_3088
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_3231
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_8083
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_10342
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIA4_cEERNS_5OFileES3_RKT_45204
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_45552
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46744
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47756
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_51545
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52492
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91822
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_217594
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_404001
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_517324
+
+
+ + + +
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 000000000..044a3fd25 --- /dev/null +++ b/coverage/tools/OFile.h.func.html @@ -0,0 +1,504 @@ + + + + + + + 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-10-17 16:45:00Functions: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_1290
_ZN4PLMDlsIA110_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_1106
_ZN4PLMDlsIA120_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA127_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA129_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1158
_ZN4PLMDlsIA134_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1550
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_2500
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52492
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_2256
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_1909
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46744
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_291
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2585
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_107
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1915
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA26_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_158
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1313
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_703
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_517324
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_292
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_65
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_3231
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_236
_ZN4PLMDlsIA37_cEERNS_5OFileES3_RKT_17
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_3088
_ZN4PLMDlsIA39_cEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1644
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_168
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_2191
_ZN4PLMDlsIA42_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_36
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1301
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_103
_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_51545
_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_199
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_1293
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_10342
_ZN4PLMDlsIA77_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA78_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA79_cEERNS_5OFileES3_RKT_21
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2862
_ZN4PLMDlsIA81_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA82_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA83_cEERNS_5OFileES3_RKT_184
_ZN4PLMDlsIA85_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA88_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47756
_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_8083
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1773
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1296
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_217594
_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_404001
_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 000000000..8cb7e75e7 --- /dev/null +++ b/coverage/tools/OFile.h.gcov.html @@ -0,0 +1,362 @@ + + + + + + + LCOV - plumed test coverage - tools/OFile.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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    51803683 :   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     1772250 : OFile& operator<<(OFile&of,const T &t) {
+     277     1772250 :   of.oss<<t;
+     278     1772250 :   of.printf("%s",of.oss.str().c_str());
+     279     1772250 :   of.oss.str("");
+     280     1772250 :   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 000000000..e97f79df0 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP13setNumThreadsEj1
_ZN4PLMD6OpenMP16getCachelineSizeEv354380
_ZN4PLMD6OpenMP13getNumThreadsEv35068230
_ZN4PLMD6OpenMP12getThreadNumEv61693272
+
+
+ + + +
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 000000000..a589f632b --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP12getThreadNumEv61693272
_ZN4PLMD6OpenMP13getNumThreadsEv35068230
_ZN4PLMD6OpenMP13setNumThreadsEj1
_ZN4PLMD6OpenMP16getCachelineSizeEv354380
+
+
+ + + +
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 000000000..a3f6a6e74 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-10-17 16:45:00Functions: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      354380 : unsigned getCachelineSize() {
+      54      354380 :   if(!OpenMPVars::get().cache_set) {
+      55         962 :     if(std::getenv("PLUMED_CACHELINE_SIZE")) {
+      56           1 :       Tools::convert(std::getenv("PLUMED_CACHELINE_SIZE"),OpenMPVars::get().cacheline_size);
+      57             :     }
+      58         962 :     OpenMPVars::get().cache_set = true;
+      59             :   }
+      60      354380 :   return OpenMPVars::get().cacheline_size;
+      61             : }
+      62             : 
+      63    35068230 : unsigned getNumThreads() {
+      64    35068230 :   if(!OpenMPVars::get().nt_env_set) {
+      65         962 :     if(std::getenv("PLUMED_NUM_THREADS")) {
+      66         962 :       Tools::convert(std::getenv("PLUMED_NUM_THREADS"),OpenMPVars::get().num_threads);
+      67             :     }
+      68         962 :     OpenMPVars::get().nt_env_set = true;
+      69             :   }
+      70    35068230 :   return OpenMPVars::get().num_threads;
+      71             : }
+      72             : 
+      73    61693272 : unsigned getThreadNum() {
+      74             : #if defined(_OPENMP)
+      75    61693272 :   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 000000000..3bc87e407 --- /dev/null +++ b/coverage/tools/OpenMP.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjRKSt6vectorIT_SaIS3_EE1350
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j353089
+
+
+ + + +
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 000000000..8dce2ae83 --- /dev/null +++ b/coverage/tools/OpenMP.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j353089
_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 000000000..1d4e3f7cd --- /dev/null +++ b/coverage/tools/OpenMP.h.gcov.html @@ -0,0 +1,148 @@ + + + + + + + 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-10-17 16:45:00Functions: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      353089 : 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      353089 :   unsigned m=n*sizeof(T)/(2*getCachelineSize());
+      51      353089 :   unsigned numThreads=getNumThreads();
+      52      353089 :   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      353089 :   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 000000000..d900d049d --- /dev/null +++ b/coverage/tools/PDB.cpp.func-sort-c.html @@ -0,0 +1,248 @@ + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22041852.6 %
Date:2024-10-17 16:45:00Functions: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_189
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE268
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd434
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE1038
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEE2148
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2368
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd4559
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE4601
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj6198
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj7956
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11759
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj17700
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE35470
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49952
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_59906
_ZNK4PLMD3PDB7getBetaEv152222
_ZNK4PLMD3PDB12getOccupancyEv153889
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE166219
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE180036
_ZNK4PLMD3PDB14getAtomNumbersEv314591
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6941325
_ZNK4PLMD3PDB12getPositionsEv23575319
_ZNK4PLMD3PDB4sizeEv233313745
+
+
+ + + +
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 000000000..a40fcff75 --- /dev/null +++ b/coverage/tools/PDB.cpp.func.html @@ -0,0 +1,248 @@ + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22041852.6 %
Date:2024-10-17 16:45:00Functions: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_FILEbd4559
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd434
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE4601
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj6198
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6941325
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE1038
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_189
_ZNK4PLMD3PDB12getOccupancyEv153889
_ZNK4PLMD3PDB12getPositionsEv23575319
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE268
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_59906
_ZNK4PLMD3PDB14getAtomNumbersEv314591
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE180036
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj7956
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49952
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11759
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev0
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEE2148
_ZNK4PLMD3PDB16getAtomBlockEndsEv6
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE166219
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE35470
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv3
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj17700
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2368
_ZNK4PLMD3PDB4sizeEv233313745
_ZNK4PLMD3PDB7getBetaEv152222
_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 000000000..4187dffd4 --- /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:22041852.6 %
Date:2024-10-17 16:45:00Functions: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      153889 : const std::vector<double> & PDB::getOccupancy()const {
+     211      153889 :   return occupancy;
+     212             : }
+     213             : 
+     214      152222 : const std::vector<double> & PDB::getBeta()const {
+     215      152222 :   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      314591 : const std::vector<AtomNumber> & PDB::getAtomNumbers()const {
+     246      314591 :   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     6941325 : std::string PDB::getAtomName(AtomNumber a)const {
+     262             :   const auto p=number2index.find(a);
+     263     6941325 :   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     6941325 :   } else return atomsymb[p->second];
+     267             : }
+     268             : 
+     269      166219 : unsigned PDB::getResidueNumber(AtomNumber a)const {
+     270             :   const auto p=number2index.find(a);
+     271      166219 :   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      166219 :   } else return residue[p->second];
+     275             : }
+     276             : 
+     277      180036 : std::string PDB::getResidueName(AtomNumber a) const {
+     278             :   const auto p=number2index.find(a);
+     279      180036 :   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      180036 :   } else return residuenames[p->second];
+     283             : }
+     284             : 
+     285   233313745 : unsigned PDB::size()const {
+     286   233313745 :   return positions.size();
+     287             : }
+     288             : 
+     289        4559 : bool PDB::readFromFilepointer(FILE *fp,bool naturalUnits,double scale) {
+     290             :   //cerr<<file<<endl;
+     291             :   bool file_is_alive=false;
+     292        4559 :   if(naturalUnits) scale=1.0;
+     293             :   std::string line;
+     294             :   fpos_t pos; bool between_ters=true;
+     295      457317 :   while(Tools::getline(fp,line)) {
+     296             :     //cerr<<line<<"\n";
+     297      456813 :     fgetpos (fp,&pos);
+     298     3319432 :     while(line.length()<80) line.push_back(' ');
+     299      456813 :     std::string record=line.substr(0,6);
+     300      456813 :     std::string serial=line.substr(6,5);
+     301      456813 :     std::string atomname=line.substr(12,4);
+     302      456813 :     std::string residuename=line.substr(17,3);
+     303      456813 :     std::string chainID=line.substr(21,1);
+     304      456813 :     std::string resnum=line.substr(22,4);
+     305      456813 :     std::string x=line.substr(30,8);
+     306      456813 :     std::string y=line.substr(38,8);
+     307      456813 :     std::string z=line.substr(46,8);
+     308      456813 :     std::string occ=line.substr(54,6);
+     309      456813 :     std::string bet=line.substr(60,6);
+     310      456813 :     std::string BoxX=line.substr(6,9);
+     311      456813 :     std::string BoxY=line.substr(15,9);
+     312      456813 :     std::string BoxZ=line.substr(24,9);
+     313      456813 :     std::string BoxA=line.substr(33,7);
+     314      456813 :     std::string BoxB=line.substr(40,7);
+     315      456813 :     std::string BoxG=line.substr(47,7);
+     316      456813 :     Tools::trim(record);
+     317      456813 :     if(record=="TER") { between_ters=false; block_ends.push_back( positions.size() ); }
+     318      456813 :     if(record=="END") { file_is_alive=true;  break;}
+     319      452899 :     if(record=="ENDMDL") { file_is_alive=true;  break;}
+     320      452758 :     if(record=="REMARK") {
+     321        9202 :       std::vector<std::string> v1;  v1=Tools::getWords(line.substr(6));
+     322        4601 :       addRemark( v1 );
+     323        4601 :     }
+     324      452758 :     if(record=="CRYST1") {
+     325          77 :       Tools::convert(BoxX,BoxXYZ[0]);
+     326          77 :       Tools::convert(BoxY,BoxXYZ[1]);
+     327          77 :       Tools::convert(BoxZ,BoxXYZ[2]);
+     328          77 :       Tools::convert(BoxA,BoxABG[0]);
+     329          77 :       Tools::convert(BoxB,BoxABG[1]);
+     330          77 :       Tools::convert(BoxG,BoxABG[2]);
+     331          77 :       BoxXYZ*=scale;
+     332          77 :       double cosA=std::cos(BoxABG[0]*pi/180.);
+     333          77 :       double cosB=std::cos(BoxABG[1]*pi/180.);
+     334          77 :       double cosG=std::cos(BoxABG[2]*pi/180.);
+     335          77 :       double sinG=std::sin(BoxABG[2]*pi/180.);
+     336         308 :       for (unsigned i=0; i<3; i++) {Box[i][0]=0.; Box[i][1]=0.; Box[i][2]=0.;}
+     337          77 :       Box[0][0]=BoxXYZ[0];
+     338          77 :       Box[1][0]=BoxXYZ[1]*cosG;
+     339          77 :       Box[1][1]=BoxXYZ[1]*sinG;
+     340          77 :       Box[2][0]=BoxXYZ[2]*cosB;
+     341          77 :       Box[2][1]=(BoxXYZ[2]*BoxXYZ[1]*cosA-Box[2][0]*Box[1][0])/Box[1][1];
+     342          77 :       Box[2][2]=std::sqrt(BoxXYZ[2]*BoxXYZ[2]-Box[2][0]*Box[2][0]-Box[2][1]*Box[2][1]);
+     343             :     }
+     344      458625 :     if(record=="ATOM" || record=="HETATM") {
+     345             :       between_ters=true;
+     346             :       AtomNumber a;
+     347      446891 :       unsigned resno=0; // GB: when resnum string is not present, we set res number to zero
+     348             :       double o,b;
+     349      446891 :       Vector p;
+     350             :       {
+     351             :         int result;
+     352      446891 :         auto trimmed=serial;
+     353      446891 :         Tools::trim(trimmed);
+     354      446953 :         while(trimmed.length()<5) trimmed = std::string(" ") + trimmed;
+     355      446891 :         const char* errmsg = h36::hy36decode(5, trimmed.c_str(),trimmed.length(), &result);
+     356      446891 :         if(errmsg) {
+     357           0 :           std::string msg(errmsg);
+     358           0 :           plumed_merror(msg);
+     359             :         }
+     360      446891 :         a.setSerial(result);
+     361             :       }
+     362             : 
+     363             :       // allow skipping residue number
+     364             :       {
+     365      446891 :         auto trimmed=resnum;
+     366      446891 :         Tools::trim(trimmed);
+     367      446891 :         if(trimmed.length()>0) {
+     368             :           int result;
+     369      446891 :           while(trimmed.length()<4) trimmed = std::string(" ") + trimmed;
+     370      446891 :           const char* errmsg = h36::hy36decode(4, trimmed.c_str(),trimmed.length(), &result);
+     371      446891 :           if(errmsg) {
+     372           0 :             std::string msg(errmsg);
+     373           0 :             plumed_merror(msg);
+     374             :           }
+     375      446891 :           resno=result;
+     376             :         }
+     377             :       }
+     378             : 
+     379      446891 :       Tools::convert(occ,o);
+     380      446891 :       Tools::convert(bet,b);
+     381      446891 :       Tools::convert(x,p[0]);
+     382      446891 :       Tools::convert(y,p[1]);
+     383      446891 :       Tools::convert(z,p[2]);
+     384             :       // scale into nm
+     385      446891 :       p*=scale;
+     386      446891 :       numbers.push_back(a);
+     387      446891 :       number2index[a]=positions.size();
+     388      446891 :       std::size_t startpos=atomname.find_first_not_of(" \t");
+     389      446891 :       std::size_t endpos=atomname.find_last_not_of(" \t");
+     390      446891 :       atomsymb.push_back( atomname.substr(startpos, endpos-startpos+1) );
+     391      446891 :       residue.push_back(resno);
+     392      446891 :       chain.push_back(chainID);
+     393      446891 :       occupancy.push_back(o);
+     394      446891 :       beta.push_back(b);
+     395      446891 :       positions.push_back(p);
+     396      446891 :       residuenames.push_back(residuename);
+     397             :     }
+     398             :   }
+     399        4559 :   if( between_ters ) block_ends.push_back( positions.size() );
+     400        4559 :   return file_is_alive;
+     401             : }
+     402             : 
+     403         434 : bool PDB::read(const std::string&file,bool naturalUnits,double scale) {
+     404         434 :   FILE* fp=std::fopen(file.c_str(),"r");
+     405         434 :   if(!fp) return false;
+     406             : // call fclose when exiting this function
+     407         433 :   auto deleter=[](auto f) { std::fclose(f); };
+     408             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     409         433 :   readFromFilepointer(fp,naturalUnits,scale);
+     410             :   return true;
+     411             : }
+     412             : 
+     413         268 : void PDB::getChainNames( std::vector<std::string>& chains ) const {
+     414         268 :   chains.resize(0);
+     415         268 :   chains.push_back( chain[0] );
+     416      549268 :   for(unsigned i=1; i<size(); ++i) {
+     417      549000 :     if( chains[chains.size()-1]!=chain[i] ) chains.push_back( chain[i] );
+     418             :   }
+     419         268 : }
+     420             : 
+     421       11759 : void PDB::getResidueRange( const std::string& chainname, unsigned& res_start, unsigned& res_end, std::string& errmsg ) const {
+     422             :   bool inres=false, foundchain=false;
+     423    30698369 :   for(unsigned i=0; i<size(); ++i) {
+     424    30686610 :     if( chain[i]==chainname ) {
+     425    26688832 :       if(!inres) {
+     426       11759 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     427       11759 :         res_start=residue[i];
+     428             :       }
+     429             :       inres=true; foundchain=true;
+     430     3997778 :     } else if( inres && chain[i]!=chainname ) {
+     431             :       inres=false;
+     432       11221 :       res_end=residue[i-1];
+     433             :     }
+     434             :   }
+     435       11759 :   if(inres) res_end=residue[size()-1];
+     436       11759 : }
+     437             : 
+     438         189 : void PDB::getAtomRange( const std::string& chainname, AtomNumber& a_start, AtomNumber& a_end, std::string& errmsg ) const {
+     439             :   bool inres=false, foundchain=false;
+     440      495957 :   for(unsigned i=0; i<size(); ++i) {
+     441      495768 :     if( chain[i]==chainname ) {
+     442      102298 :       if(!inres) {
+     443         189 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     444         189 :         a_start=numbers[i];
+     445             :       }
+     446             :       inres=true; foundchain=true;
+     447      393470 :     } else if( inres && chain[i]!=chainname ) {
+     448             :       inres=false;
+     449          93 :       a_end=numbers[i-1];
+     450             :     }
+     451             :   }
+     452         189 :   if(inres) a_end=numbers[size()-1];
+     453         189 : }
+     454             : 
+     455        7956 : std::string PDB::getResidueName( const unsigned& resnum ) const {
+     456     9758352 :   for(unsigned i=0; i<size(); ++i) {
+     457     9758352 :     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       49952 : std::string PDB::getResidueName(const unsigned& resnum,const std::string& chainid ) const {
+     464    64916447 :   for(unsigned i=0; i<size(); ++i) {
+     465    64966579 :     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       17700 : AtomNumber PDB::getNamedAtomFromResidue( const std::string& aname, const unsigned& resnum ) const {
+     473    21799572 :   for(unsigned i=0; i<size(); ++i) {
+     474    21799572 :     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        2368 : AtomNumber PDB::getNamedAtomFromResidueAndChain( const std::string& aname, const unsigned& resnum, const std::string& chainid ) const {
+     481     1087296 :   for(unsigned i=0; i<size(); ++i) {
+     482     1089664 :     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       35470 : std::vector<AtomNumber> PDB::getAtomsInResidue(const unsigned& resnum,const std::string& chainid)const {
+     489             :   std::vector<AtomNumber> tmp;
+     490    95754470 :   for(unsigned i=0; i<size(); ++i) {
+     491    96261470 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) tmp.push_back(numbers[i]);
+     492             :   }
+     493       35470 :   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       35470 :   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        6198 : std::string PDB::getChainID(const unsigned& resnumber) const {
+     512     7587064 :   for(unsigned i=0; i<size(); ++i) {
+     513     7587064 :     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       59906 : bool PDB::allowedResidue( const std::string& type, const std::string& residuename ) const {
+     631       59906 :   if( type=="protein" ) {
+     632       59906 :     if(residuename=="ALA") return true;
+     633       56756 :     else if(residuename=="ARG") return true;
+     634       53172 :     else if(residuename=="ASN") return true;
+     635       50100 :     else if(residuename=="ASP") return true;
+     636       47412 :     else if(residuename=="CYS") return true;
+     637       47204 :     else if(residuename=="GLN") return true;
+     638       42844 :     else if(residuename=="GLU") return true;
+     639       40828 :     else if(residuename=="GLY") return true;
+     640       38036 :     else if(residuename=="HIS") return true;
+     641       38036 :     else if(residuename=="ILE") return true;
+     642       34436 :     else if(residuename=="LEU") return true;
+     643       28052 :     else if(residuename=="LYS") return true;
+     644       23732 :     else if(residuename=="MET") return true;
+     645       21412 :     else if(residuename=="PHE") return true;
+     646       17188 :     else if(residuename=="PRO") return true;
+     647       14020 :     else if(residuename=="SER") return true;
+     648       11810 :     else if(residuename=="THR") return true;
+     649        9740 :     else if(residuename=="TRP") return true;
+     650        9740 :     else if(residuename=="TYR") return true;
+     651        7532 :     else if(residuename=="VAL") return true;
+     652             : // Terminal groups
+     653        3010 :     else if(residuename=="ACE") return true;
+     654        3010 :     else if(residuename=="NME") return true;
+     655        3010 :     else if(residuename=="NH2") return true;
+     656             : // Alternative residue names in common force fields
+     657        3010 :     else if(residuename=="GLH") return true; // neutral GLU
+     658        3010 :     else if(residuename=="ASH") return true; // neutral ASP
+     659        3010 :     else if(residuename=="HID") return true; // HIS-D amber
+     660        3010 :     else if(residuename=="HSD") return true; // HIS-D charmm
+     661        3010 :     else if(residuename=="HIE") return true; // HIS-E amber
+     662        2402 :     else if(residuename=="HSE") return true; // HIS-E charmm
+     663        2402 :     else if(residuename=="HIP") return true; // HIS-P amber
+     664        2402 :     else if(residuename=="HSP") return true; // HIS-P charmm
+     665        2402 :     else if(residuename=="CYX") return true; // disulfide bridge CYS
+     666             : // Weird amino acids
+     667        2402 :     else if(residuename=="NLE") return true;
+     668        2402 :     else if(residuename=="SFO") return true;
+     669        2402 :     else return false;
+     670           0 :   } else if( type=="dna" ) {
+     671           0 :     if(residuename=="A") return true;
+     672           0 :     else if(residuename=="A5") return true;
+     673           0 :     else if(residuename=="A3") return true;
+     674           0 :     else if(residuename=="AN") return true;
+     675           0 :     else if(residuename=="G") return true;
+     676           0 :     else if(residuename=="G5") return true;
+     677           0 :     else if(residuename=="G3") return true;
+     678           0 :     else if(residuename=="GN") return true;
+     679           0 :     else if(residuename=="T") return true;
+     680           0 :     else if(residuename=="T5") return true;
+     681           0 :     else if(residuename=="T3") return true;
+     682           0 :     else if(residuename=="TN") return true;
+     683           0 :     else if(residuename=="C") return true;
+     684           0 :     else if(residuename=="C5") return true;
+     685           0 :     else if(residuename=="C3") return true;
+     686           0 :     else if(residuename=="CN") return true;
+     687           0 :     else if(residuename=="DA") return true;
+     688           0 :     else if(residuename=="DA5") return true;
+     689           0 :     else if(residuename=="DA3") return true;
+     690           0 :     else if(residuename=="DAN") return true;
+     691           0 :     else if(residuename=="DG") return true;
+     692           0 :     else if(residuename=="DG5") return true;
+     693           0 :     else if(residuename=="DG3") return true;
+     694           0 :     else if(residuename=="DGN") return true;
+     695           0 :     else if(residuename=="DT") return true;
+     696           0 :     else if(residuename=="DT5") return true;
+     697           0 :     else if(residuename=="DT3") return true;
+     698           0 :     else if(residuename=="DTN") return true;
+     699           0 :     else if(residuename=="DC") return true;
+     700           0 :     else if(residuename=="DC5") return true;
+     701           0 :     else if(residuename=="DC3") return true;
+     702           0 :     else if(residuename=="DCN") return true;
+     703           0 :     else return false;
+     704           0 :   } else if( type=="rna" ) {
+     705           0 :     if(residuename=="A") return true;
+     706           0 :     else if(residuename=="A5") return true;
+     707           0 :     else if(residuename=="A3") return true;
+     708           0 :     else if(residuename=="AN") return true;
+     709           0 :     else if(residuename=="G") return true;
+     710           0 :     else if(residuename=="G5") return true;
+     711           0 :     else if(residuename=="G3") return true;
+     712           0 :     else if(residuename=="GN") return true;
+     713           0 :     else if(residuename=="U") return true;
+     714           0 :     else if(residuename=="U5") return true;
+     715           0 :     else if(residuename=="U3") return true;
+     716           0 :     else if(residuename=="UN") return true;
+     717           0 :     else if(residuename=="C") return true;
+     718           0 :     else if(residuename=="C5") return true;
+     719           0 :     else if(residuename=="C3") return true;
+     720           0 :     else if(residuename=="CN") return true;
+     721           0 :     else if(residuename=="RA") return true;
+     722           0 :     else if(residuename=="RA5") return true;
+     723           0 :     else if(residuename=="RA3") return true;
+     724           0 :     else if(residuename=="RAN") return true;
+     725           0 :     else if(residuename=="RG") return true;
+     726           0 :     else if(residuename=="RG5") return true;
+     727           0 :     else if(residuename=="RG3") return true;
+     728           0 :     else if(residuename=="RGN") return true;
+     729           0 :     else if(residuename=="RU") return true;
+     730           0 :     else if(residuename=="RU5") return true;
+     731           0 :     else if(residuename=="RU3") return true;
+     732           0 :     else if(residuename=="RUN") return true;
+     733           0 :     else if(residuename=="RC") return true;
+     734           0 :     else if(residuename=="RC5") return true;
+     735           0 :     else if(residuename=="RC3") return true;
+     736           0 :     else if(residuename=="RCN") return true;
+     737           0 :     else return false;
+     738           0 :   } else if( type=="water" ) {
+     739           0 :     if(residuename=="SOL") return true;
+     740           0 :     if(residuename=="WAT") return true;
+     741           0 :     return false;
+     742           0 :   } else if( type=="ion" ) {
+     743           0 :     if(residuename=="IB+") return true;
+     744           0 :     if(residuename=="CA") return true;
+     745           0 :     if(residuename=="CL") return true;
+     746           0 :     if(residuename=="NA") return true;
+     747           0 :     if(residuename=="MG") return true;
+     748           0 :     if(residuename=="K") return true;
+     749           0 :     if(residuename=="RB") return true;
+     750           0 :     if(residuename=="CS") return true;
+     751           0 :     if(residuename=="LI") return true;
+     752           0 :     if(residuename=="ZN") return true;
+     753           0 :     return false;
+     754             :   }
+     755             :   return false;
+     756             : }
+     757             : 
+     758             : }
+     759             : 
+
+
+
+ + + + +
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 000000000..56e0efcf7 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc13isOrthorombicEv8569
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_NS_3gch12small_vectorINS_13VectorGenericILj3EEELj6ESaIS4_EEE19978
_ZN4PLMD3PbcC2Ev26462
_ZNK4PLMD3Pbc6getBoxEv28686
_ZNK4PLMD3Pbc9getInvBoxEv45429
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE90725
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE201929
_ZNK4PLMD3Pbc5applyENS_12mdMemoryViewILm18446744073709551615ELm3EEEj405876
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj405876
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1958610
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi558281117
+
+
+ + + +
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 000000000..d35d57db5 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-10-17 16:45:00Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE90725
_ZN4PLMD3PbcC2Ev26462
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_NS_3gch12small_vectorINS_13VectorGenericILj3EEELj6ESaIS4_EEE19978
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1958610
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE201929
_ZNK4PLMD3Pbc13isOrthorombicEv8569
_ZNK4PLMD3Pbc5applyENS_12mdMemoryViewILm18446744073709551615ELm3EEEj405876
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj405876
_ZNK4PLMD3Pbc6getBoxEv28686
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi558281117
_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 000000000..047c92194 --- /dev/null +++ b/coverage/tools/Pbc.cpp.gcov.html @@ -0,0 +1,367 @@ + + + + + + + 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-10-17 16:45:00Functions: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       26462 : Pbc::Pbc():
+      33      396930 :   type(unset)
+      34             : {
+      35       26462 :   box.zero();
+      36       26462 :   invBox.zero();
+      37       26462 : }
+      38             : 
+      39       19978 : 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      299670 :   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      799120 :   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      539406 :         const int ishift[3]= {l,m,n};
+      51      539406 :         Vector dshift(l,m,n);
+      52             : 
+      53             : // count how many components are != 0
+      54             :         unsigned count=0;
+      55     2157624 :         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      618710 :         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      359604 :         Vector cosdir=matmul(reduced,transpose(reduced),dshift);
+      66      359604 :         double dp=dotProduct(dshift,cosdir);
+      67      359604 :         double ref=modulo2(dshift)*modulo2(cosdir);
+      68      359604 :         if(std::fabs(ref-dp*dp)<small) continue;
+      69             : 
+      70             : // here we start pruning depending on the sign of the scaled coordinate
+      71     4204500 :         for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) {
+      72             : 
+      73     2242400 :               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     8969600 :               for(int s=0; s<3; s++) if(ishift[s]*block[s]>0) skip=true;
+      78     2533342 :               if(skip) continue;
+      79             :               skip=true;
+      80     3065040 :               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     2298780 :                 if(((1-ishift[s]*ishift[s])*block[s])*cosdir[s]<-small) skip=false;
+      84             :               }
+      85      766260 :               if(skip)continue;
+      86             : 
+      87             : // if we arrive to this point, shift is eligible and is added to the list
+      88      950636 :               shifts[i][j][k].push_back(matmul(transpose(reduced),dshift));
+      89             :             }
+      90             :       }
+      91       19978 : }
+      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       90725 : void Pbc::setBox(const Tensor&b) {
+     116       90725 :   box=b;
+     117             : // detect type:
+     118             :   const double epsilon=1e-28;
+     119             : 
+     120       90725 :   type=unset;
+     121       90725 :   double det=box.determinant();
+     122       90725 :   if(det*det<epsilon) return;
+     123             : 
+     124             :   bool cxy=false;
+     125             :   bool cxz=false;
+     126             :   bool cyz=false;
+     127       88680 :   if(box(0,1)*box(0,1)<epsilon && box(1,0)*box(1,0)<epsilon) cxy=true;
+     128       88680 :   if(box(0,2)*box(0,2)<epsilon && box(2,0)*box(2,0)<epsilon) cxz=true;
+     129       88680 :   if(box(1,2)*box(1,2)<epsilon && box(2,1)*box(2,1)<epsilon) cyz=true;
+     130             : 
+     131       88680 :   invBox=box.inverse();
+     132             : 
+     133       88680 :   if(cxy && cxz && cyz) type=orthorombic;
+     134       19978 :   else type=generic;
+     135             : 
+     136       88680 :   if(type==orthorombic) {
+     137       68702 :     reduced=box;
+     138       68702 :     invReduced=inverse(reduced);
+     139      274808 :     for(unsigned i=0; i<3; i++) {
+     140      206106 :       diag[i]=box[i][i];
+     141      206106 :       hdiag[i]=0.5*box[i][i];
+     142      206106 :       mdiag[i]=-0.5*box[i][i];
+     143             :     }
+     144             :   } else {
+     145       19978 :     reduced=box;
+     146       19978 :     LatticeReduction::reduce(reduced);
+     147       19978 :     invReduced=inverse(reduced);
+     148       19978 :     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   558281117 : Vector Pbc::distance(const Vector&v1,const Vector&v2,int*nshifts)const {
+     223   558281117 :   Vector d=delta(v1,v2);
+     224   558281117 :   if(type==unset) {
+     225             :     // do nothing
+     226   532625263 :   } 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  1937606964 :     for(int i=0; i<3; i++) d[i]=Tools::pbc(d[i]*invBox(i,i))*box(i,i);
+     234             : #endif
+     235    48223522 :   } else if(type==generic) {
+     236    48223522 :     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   192894088 :       for(int i=0; i<3; i++) {
+     245   144670566 :         s[i]=Tools::pbc(s[i]);
+     246             :       }
+     247    48223522 :       d=matmul(s,reduced);
+     248             : // check if shifts have to be attempted:
+     249    48223522 :       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   558281117 :   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        8569 : bool Pbc::isOrthorombic()const {
+     280        8569 :   return type==orthorombic;
+     281             : }
+     282             : 
+     283       28686 : const Tensor& Pbc::getBox()const {
+     284       28686 :   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 000000000..94a006ce3 --- /dev/null +++ b/coverage/tools/Pbc.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Pbc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..4efd8594a --- /dev/null +++ b/coverage/tools/Pbc.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Pbc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..e4cd84c6a --- /dev/null +++ b/coverage/tools/Pbc.h.gcov.html @@ -0,0 +1,224 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..969769823 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253865.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..30ea896fb --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253865.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..6c0ea1a13 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.gcov.html @@ -0,0 +1,208 @@ + + + + + + + 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:253865.8 %
Date:2024-10-17 16:45:00Functions: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             : 
+      86             :     // String must be null terminated.
+      87             :     // This is to ensure null termination without the penalty of dynamic allocation.
+      88             :     // It's a tiny optimization: it just removes one extra allocation when cmd() is called with a key
+      89             :     // longer than the buffer for SSO (typically 15 chars)
+      90             :     // It's included here only because PlumedHandle is used in benchmarks.
+      91             :     constexpr unsigned key_buffer_size=64;
+      92             :     // no allocation - on stack
+      93             :     char key_buffer_char[key_buffer_size];
+      94             :     std::string key_buffer_string;
+      95             :     const char* key_buffer=nullptr;
+      96             : 
+      97         222 :     if(key.length()<key_buffer_size) {
+      98             :       // in this case, the string_view fits in the local buffer
+      99         222 :       std::size_t nchars=key.copy(key_buffer_char,key_buffer_size-1);
+     100         222 :       key_buffer_char[nchars]='\0'; // ensure null termination
+     101             :       key_buffer=key_buffer_char;
+     102             :     } else {
+     103             :       // in this case, the string_view does not fit in the local buffer
+     104             :       // hence we allocate a new std::string
+     105             :       key_buffer_string=key;
+     106             :       key_buffer=key_buffer_string.c_str();
+     107             :     }
+     108             :     // in both cases, key_buffer is pointing to a proper null terminated copy
+     109             : 
+     110         222 :     plumed_cmd(plumed_v2c(loaded),key_buffer,safe);
+     111             : 
+     112           0 :   } else plumed_error() << "should never arrive here (either one or the other should work)";
+     113        1476 : }
+     114             : 
+     115           0 : PlumedHandle::PlumedHandle(PlumedHandle && other) noexcept:
+     116             :   local(std::move(other.local)),
+     117           0 :   loaded(other.loaded)
+     118             : {
+     119           0 :   other.loaded=nullptr;
+     120           0 : }
+     121             : 
+     122           0 : PlumedHandle & PlumedHandle::operator=(PlumedHandle && other) noexcept {
+     123           0 :   if(this!=&other) {
+     124           0 :     if(loaded) plumed_finalize(plumed_v2c(loaded));
+     125             :     local=std::move(other.local);
+     126           0 :     loaded=other.loaded;
+     127           0 :     other.loaded=nullptr;
+     128             :   }
+     129           0 :   return *this;
+     130             : }
+     131             : 
+     132             : }
+
+
+
+ + + + +
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 000000000..680e1551e --- /dev/null +++ b/coverage/tools/RMSD.cpp.func-sort-c.html @@ -0,0 +1,392 @@ + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55673575.6 %
Date:2024-10-17 16:45:00Functions: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
_ZN4PLMD4RMSD5clearEv11988
_ZN4PLMD4RMSD11setDisplaceERKSt6vectorIdSaIdEEb13173
_ZN4PLMD4RMSD3setERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb13173
_ZN4PLMD4RMSD8setAlignERKSt6vectorIdSaIdEEbb13173
_ZN4PLMD12RMSDCoreData28doCoreCalcWithCloseStructureEbbRKNS_13TensorGenericILj3ELj3EEES4_RSt5arrayIS5_IS2_Lm3EELm3EE45192
_ZN4PLMD4RMSD27calculateWithCloseStructureERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RKNS_13TensorGenericILj3ELj3EEESC_RSt5arrayISD_ISA_Lm3EELm3EEb45192
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb45192
_ZN4PLMD4RMSDC2Ev46865
_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_traitsIcESaIcEEE58365
_ZN4PLMD4RMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE58381
_ZN4PLMD12RMSDCoreData10doCoreCalcEbbb58656
_ZNK4PLMD4RMSD12getReferenceEv101427
_ZN4PLMD12RMSDCoreData22getDDistanceDPositionsEv102546
_ZN4PLMD12RMSDCoreData11getDistanceEb103848
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b197608
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b366914
_ZNK4PLMD4RMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_b564764
+
+
+ + + +
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 000000000..129a84236 --- /dev/null +++ b/coverage/tools/RMSD.cpp.func.html @@ -0,0 +1,392 @@ + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55673575.6 %
Date:2024-10-17 16:45:00Functions: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
_ZN4PLMD4RMSD11setDisplaceERKSt6vectorIdSaIdEEb13173
_ZN4PLMD4RMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE58381
_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_traitsIcESaIcEEEbb13173
_ZN4PLMD4RMSD5clearEv11988
_ZN4PLMD4RMSD7setTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE58365
_ZN4PLMD4RMSD8calc_RotERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEEb672
_ZN4PLMD4RMSD8getAlignEv0
_ZN4PLMD4RMSD8setAlignERKSt6vectorIdSaIdEEbb13173
_ZN4PLMD4RMSD9calc_SOMAERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_b0
_ZN4PLMD4RMSD9getMethodB5cxx11Ev5
_ZN4PLMD4RMSDC2Ev46865
_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_b197608
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b112
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b366914
_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_b564764
+
+
+ + + +
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 000000000..f0e6018a7 --- /dev/null +++ b/coverage/tools/RMSD.cpp.gcov.html @@ -0,0 +1,1548 @@ + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55673575.6 %
Date:2024-10-17 16:45:00Functions: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       46865 : 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       13173 : 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       13173 :   setReference(reference); // this by default remove the com and assumes uniform weights
+      46       13173 :   setAlign(align, normalize_weights, remove_center); // this recalculates the com with weights. If remove_center=false then it restore the center back
+      47       13173 :   setDisplace(displace, normalize_weights);  // this is does not affect any calculation of the weights
+      48       13173 :   setType(mytype);
+      49             : 
+      50       13173 : }
+      51             : 
+      52       58365 : void RMSD::setType(const std::string & mytype) {
+      53             : 
+      54       58365 :   alignmentMethod=SIMPLE; // initialize with the simplest case: no rotation
+      55       58365 :   if (mytype=="SIMPLE") {
+      56          39 :     alignmentMethod=SIMPLE;
+      57             :   }
+      58       58326 :   else if (mytype=="OPTIMAL") {
+      59       47031 :     alignmentMethod=OPTIMAL;
+      60             :   }
+      61       11295 :   else if (mytype=="OPTIMAL-FAST") {
+      62       11295 :     alignmentMethod=OPTIMAL_FAST;
+      63             :   }
+      64           0 :   else plumed_merror("unknown RMSD type" + mytype);
+      65             : 
+      66       58365 : }
+      67             : 
+      68       11988 : void RMSD::clear() {
+      69             :   reference.clear();
+      70       11988 :   reference_center.zero();
+      71       11988 :   reference_center_is_calculated=false;
+      72       11988 :   reference_center_is_removed=false;
+      73             :   align.clear();
+      74             :   displace.clear();
+      75       11988 :   positions_center.zero();
+      76       11988 :   positions_center_is_calculated=false;
+      77       11988 :   positions_center_is_removed=false;
+      78       11988 : }
+      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       58381 : void RMSD::setReference(const std::vector<Vector> & reference) {
+      94       58381 :   unsigned n=reference.size();
+      95       58381 :   this->reference=reference;
+      96       58381 :   plumed_massert(align.empty(),"you should first clear() an RMSD object, then set a new reference");
+      97       58381 :   plumed_massert(displace.empty(),"you should first clear() an RMSD object, then set a new reference");
+      98       58381 :   align.resize(n,1.0/n);
+      99       58381 :   displace.resize(n,1.0/n);
+     100      842400 :   for(unsigned i=0; i<n; i++) reference_center+=this->reference[i]*align[i];
+     101             :   #pragma omp simd
+     102      784019 :   for(unsigned i=0; i<n; i++) this->reference[i]-=reference_center;
+     103       58381 :   reference_center_is_calculated=true;
+     104       58381 :   reference_center_is_removed=true;
+     105       58381 : }
+     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       13173 : void RMSD::setAlign(const std::vector<double> & align, bool normalize_weights, bool remove_center) {
+     113       13173 :   unsigned n=reference.size();
+     114       13173 :   plumed_massert(this->align.size()==align.size(),"mismatch in dimension of align/displace arrays");
+     115       13173 :   this->align=align;
+     116       13173 :   if(normalize_weights) {
+     117             :     double w=0.0;
+     118       26258 :     #pragma omp simd reduction(+:w)
+     119      195783 :     for(unsigned i=0; i<n; i++) w+=this->align[i];
+     120       13129 :     if(w>epsilon) {
+     121       13127 :       double inv=1.0/w;
+     122             :       #pragma omp simd
+     123      195753 :       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       13173 :   if(reference_center_is_removed) {
+     134       13173 :     plumed_massert(reference_center_is_calculated," seems that the reference center has been removed but not calculated and stored!");
+     135       13173 :     addCenter(reference,reference_center);
+     136             :   }
+     137       13173 :   reference_center=calculateCenter(reference,this->align);
+     138       13173 :   reference_center_is_calculated=true;
+     139       13173 :   if(remove_center) {
+     140       13168 :     removeCenter(reference,reference_center);
+     141       13168 :     reference_center_is_removed=true;
+     142             :   } else {
+     143           5 :     reference_center_is_removed=false;
+     144             :   }
+     145       13173 : }
+     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       13173 : void RMSD::setDisplace(const std::vector<double> & displace, bool normalize_weights) {
+     153       13173 :   unsigned n=reference.size();
+     154       13173 :   plumed_massert(this->displace.size()==displace.size(),"mismatch in dimension of align/displace arrays");
+     155       13173 :   this->displace=displace;
+     156       13173 :   if(normalize_weights) {
+     157             :     double w=0.0;
+     158       26258 :     #pragma omp simd reduction(+:w)
+     159      195783 :     for(unsigned i=0; i<n; i++) w+=this->displace[i];
+     160       13129 :     if(w>epsilon) {
+     161       13127 :       double inv=1.0/w;
+     162             :       #pragma omp simd
+     163      195753 :       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       13173 : }
+     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      564764 : double RMSD::calculate(const std::vector<Vector> & positions,std::vector<Vector> &derivatives, bool squared)const {
+     178             : 
+     179             :   double ret=0.;
+     180             : 
+     181      564764 :   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      197610 :   } case OPTIMAL_FAST : {
+     188             :     // this is calling the fastest option:
+     189      197610 :     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      367026 :   } case OPTIMAL : {
+     194             :     // this is the fast routine but in the "safe" mode, which gives less numerical error:
+     195      367026 :     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      564764 :   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      564636 : 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      564636 :   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      564636 :   Tensor rr01;
+     438             : 
+     439      564636 :   derivatives.resize(n);
+     440             : 
+     441      564636 :   Vector cpositions;
+     442             : 
+     443             : // first expensive loop: compute centers
+     444    22872434 :   for(unsigned iat=0; iat<n; iat++) {
+     445    22307798 :     double w=align[iat];
+     446    22307798 :     cpositions+=positions[iat]*w;
+     447             :   }
+     448             : 
+     449             : // second expensive loop: compute second moments wrt centers
+     450    22872434 :   for(unsigned iat=0; iat<n; iat++) {
+     451    22307798 :     double w=align[iat];
+     452    22307798 :     rr00+=dotProduct(positions[iat]-cpositions,positions[iat]-cpositions)*w;
+     453    22305622 :     rr11+=dotProduct(reference[iat],reference[iat])*w;
+     454    22307798 :     rr01+=Tensor(positions[iat]-cpositions,reference[iat])*w;
+     455             :   }
+     456             : 
+     457      564636 :   Tensor4d m;
+     458             : 
+     459      564636 :   m[0][0]=2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
+     460      564636 :   m[1][1]=2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
+     461      564636 :   m[2][2]=2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
+     462      564636 :   m[3][3]=2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
+     463      564636 :   m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
+     464      564636 :   m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
+     465      564636 :   m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
+     466      564636 :   m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
+     467      564636 :   m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
+     468      564636 :   m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
+     469      564636 :   m[1][0] = m[0][1];
+     470      564636 :   m[2][0] = m[0][2];
+     471      564636 :   m[2][1] = m[1][2];
+     472      564636 :   m[3][0] = m[0][3];
+     473      564636 :   m[3][1] = m[1][3];
+     474      564636 :   m[3][2] = m[2][3];
+     475             : 
+     476    11857356 :   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      564636 :   Vector4d q;
+     498             : 
+     499     2823180 :   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      564522 :     VectorGeneric<1> eigenvals;
+     523      564522 :     TensorGeneric<1,4> eigenvecs;
+     524      564522 :     diagMatSym(m, eigenvals, eigenvecs );
+     525      564522 :     dist=eigenvals[0]+rr00+rr11;
+     526      564522 :     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      564636 :   Tensor rotation;
+     534      564636 :   rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
+     535      564636 :   rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
+     536      564636 :   rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
+     537      564636 :   rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
+     538      564636 :   rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
+     539      564636 :   rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
+     540      564636 :   rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
+     541      564636 :   rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
+     542      564636 :   rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);
+     543             : 
+     544             : 
+     545      564636 :   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      564522 :   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      564636 :   Tensor ddist_drotation;
+     570      564636 :   Vector ddist_dcpositions;
+     571             : 
+     572             : // third expensive loop: derivatives
+     573    22872434 :   for(unsigned iat=0; iat<n; iat++) {
+     574    22307798 :     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    22305622 :       derivatives[iat]= prefactor*align[iat]*d;
+     579     5224640 :       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      564636 :   if(!squared) {
+     603       93898 :     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      564636 :   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 000000000..372c3d40b --- /dev/null +++ b/coverage/tools/RMSD.h.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - tools/RMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData18setPositionsCenterENS_13VectorGenericILj3EEE0
_ZN4PLMD12RMSDCoreData19calcReferenceCenterEv0
_ZN4PLMD4RMSD17getMatrixFromDRotERKNS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEERKjSB_900
_ZN4PLMD4RMSD15calculateCenterERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE13173
_ZN4PLMD4RMSD9addCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_13173
_ZN4PLMD4RMSD12removeCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_26341
_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 000000000..d12a673dc --- /dev/null +++ b/coverage/tools/RMSD.h.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - tools/RMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-10-17 16:45:00Functions: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_26341
_ZN4PLMD4RMSD15calculateCenterERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE13173
_ZN4PLMD4RMSD17getMatrixFromDRotERKNS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEERKjSB_900
_ZN4PLMD4RMSD9addCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_13173
+
+
+ + + +
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 000000000..2dcca204a --- /dev/null +++ b/coverage/tools/RMSD.h.gcov.html @@ -0,0 +1,452 @@ + + + + + + + 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-10-17 16:45:00Functions: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       13173 :   Vector calculateCenter(const std::vector<Vector> &p,const std::vector<double> &w) {
+      84       13173 :     plumed_massert(p.size()==w.size(),"mismatch in dimension of position/align arrays while calculating the center");
+      85       13173 :     unsigned n; n=p.size();
+      86       13173 :     Vector c; c.zero();
+      87      209488 :     for(unsigned i=0; i<n; i++)c+=p[i]*w[i];
+      88       13173 :     return c;
+      89             :   };
+      90             : // removes the center for the position provided
+      91       26341 :   void removeCenter(std::vector<Vector> &p, const Vector &c) {
+      92       26341 :     unsigned n; n=p.size();
+      93      418946 :     for(unsigned i=0; i<n; i++)p[i]-=c;
+      94       26341 :   };
+      95             : // add center
+      96       13173 :   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 000000000..511fd6ec2 --- /dev/null +++ b/coverage/tools/Random.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - tools/Random.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-10-17 16:45:00Functions: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_traitsIcESaIcEEE808809
_ZN4PLMD6Random7setSeedEi809849
_ZN4PLMD6Random8GaussianEv1219087
_ZN4PLMD6Random7RandU01Ev1552997
_ZN4PLMD6Random3U01Ev5567742
+
+
+ + + +
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 000000000..cd62b52f6 --- /dev/null +++ b/coverage/tools/Random.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - tools/Random.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-10-17 16:45:00Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Random10fromStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD6Random13ReadStateFullERSi0
_ZN4PLMD6Random3U01Ev5567742
_ZN4PLMD6Random4U01dEv2
_ZN4PLMD6Random7RandU01Ev1552997
_ZN4PLMD6Random7ShuffleERSt6vectorIjSaIjEE2
_ZN4PLMD6Random7setSeedEi809849
_ZN4PLMD6Random8GaussianEv1219087
_ZN4PLMD6RandomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE808809
_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 000000000..1a4bdf324 --- /dev/null +++ b/coverage/tools/Random.cpp.gcov.html @@ -0,0 +1,245 @@ + + + + + + + LCOV - plumed test coverage - tools/Random.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-10-17 16:45:00Functions: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      808809 : Random::Random(const std::string & name):
+      39      808809 :   switchGaussian(false),
+      40      808809 :   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      808809 :   name(&name!=&noname?name:"noname")
+      47             : {
+      48      808809 :   iy=0;
+      49    26690697 :   for(unsigned i=0; i<NTAB; i++) iv[i]=0;
+      50      808809 :   setSeed(0);
+      51      808809 : }
+      52             : 
+      53      809849 : void Random::setSeed(int idum_) {
+      54      809849 :   if(idum_>0) idum_=-idum_;
+      55      809849 :   idum=idum_;
+      56      809849 :   incPrec=false;
+      57      809849 : }
+      58             : 
+      59     1552997 : double Random::RandU01 ()
+      60             : {
+      61     1552997 :   if (incPrec)
+      62           1 :     return U01d();
+      63             :   else
+      64     1552996 :     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     5567742 : double Random::U01() {
+      77             :   int j,k;
+      78             :   double temp;
+      79     5567742 :   if (idum <= 0 || !iy) {
+      80        1634 :     if (-idum < 1) idum=1;
+      81         795 :     else idum = -idum;
+      82       66994 :     for (j=NTAB+7; j>=0; j--) {
+      83       65360 :       k=idum/IQ;
+      84       65360 :       idum=IA*(idum-k*IQ)-IR*k;
+      85       65360 :       if (idum < 0) idum += IM;
+      86       65360 :       if (j < NTAB) iv[j] = idum;
+      87             :     }
+      88        1634 :     iy=iv[0];
+      89             :   }
+      90     5567742 :   k=idum/IQ;
+      91     5567742 :   idum=IA*(idum-k*IQ)-IR*k;
+      92     5567742 :   if (idum < 0) idum += IM;
+      93     5567742 :   j=iy/NDIV;
+      94     5567742 :   iy=iv[j];
+      95     5567742 :   iv[j] = idum;
+      96     5567742 :   if ((temp=AM*iy) > RNMX) return RNMX;
+      97     5567742 :   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      775824 :     v1=2.0*RandU01()-1.0;
+     150      775824 :     v2=2.0*RandU01()-1.0;
+     151      775824 :     rsq=v1*v1+v2*v2;
+     152      775824 :     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 000000000..9c9bc6169 --- /dev/null +++ b/coverage/tools/Random.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Random.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..50b54e91d --- /dev/null +++ b/coverage/tools/Random.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Random.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..0794435af --- /dev/null +++ b/coverage/tools/Random.h.gcov.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage - tools/Random.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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      808744 : 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 000000000..455d6e672 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4874a5d18 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..909b259eb --- /dev/null +++ b/coverage/tools/RootFindingBase.h.gcov.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-10-17 16:45:00Functions: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           6 :   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 000000000..684f43c0a --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9StopwatchE1298
_ZNK4PLMD9Stopwatch3logERSo1298
_ZN4PLMD9StopwatchD2Ev806704
+
+
+ + + +
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 000000000..83d780003 --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9StopwatchD2Ev806704
_ZN4PLMDlsERSoRKNS_9StopwatchE1298
_ZNK4PLMD9Stopwatch3logERSo1298
+
+
+ + + +
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 000000000..fc04e37c7 --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.gcov.html @@ -0,0 +1,154 @@ + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-10-17 16:45:00Functions: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        1298 : std::ostream& operator<<(std::ostream&os,const Stopwatch&sw) {
+      36        1298 :   return sw.log(os);
+      37             : }
+      38             : 
+      39      806704 : Stopwatch::~Stopwatch() {
+      40      806704 :   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        9645 :     for(auto & w : watches) {
+      45        8350 :       if(w.second.state==Watch::State::paused) w.second.start().stop();
+      46             :     }
+      47        1295 :     *mylog << *this;
+      48             :   }
+      49      806704 : }
+      50             : 
+      51        1298 : std::ostream& Stopwatch::log(std::ostream&os)const {
+      52             :   const std::size_t bufferlen=1000;
+      53             :   char buffer[bufferlen];
+      54        1298 :   buffer[0]=0;
+      55       53218 :   for(unsigned i=0; i<40; i++) os<<" ";
+      56        1298 :   os<<"      Cycles        Total      Average      Minimum      Maximum\n";
+      57             : 
+      58             :   std::vector<std::string> names;
+      59        9654 :   for(const auto & it : watches) names.emplace_back(it.first);
+      60        1298 :   std::sort(names.begin(),names.end());
+      61             : 
+      62             :   const double frac=1.0/1000000000.0;
+      63             : 
+      64        9654 :   for(const auto & name : names) {
+      65        8356 :     const Watch&t(watches.find(name)->second);
+      66             :     os<<name;
+      67      206861 :     for(unsigned i=name.length(); i<40; i++) os<<" ";
+      68        8356 :     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        8356 :     os<<buffer;
+      70             :   }
+      71        1298 :   return os;
+      72        1298 : }
+      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 000000000..c6bae96a2 --- /dev/null +++ b/coverage/tools/Stopwatch.h.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions: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_traitsIcEE1329166
_ZN4PLMDL20StopwatchEmptyStringEv1329168
_ZN4PLMD9Stopwatch9startStopERKSt17basic_string_viewIcSt11char_traitsIcEE1699022
_ZN4PLMD9Stopwatch5Watch4stopEv1700312
_ZN4PLMD9Stopwatch5Watch5pauseEv3029325
_ZN4PLMD9Stopwatch7HandlerD2Ev8541747
+
+
+ + + +
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 000000000..bc179f3ed --- /dev/null +++ b/coverage/tools/Stopwatch.h.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-10-17 16:45:00Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch10startPauseERKSt17basic_string_viewIcSt11char_traitsIcEE1329166
_ZN4PLMD9Stopwatch4stopERKSt17basic_string_viewIcSt11char_traitsIcEE4
_ZN4PLMD9Stopwatch5Watch4stopEv1700312
_ZN4PLMD9Stopwatch5Watch5pauseEv3029325
_ZN4PLMD9Stopwatch5pauseERKSt17basic_string_viewIcSt11char_traitsIcEE1
_ZN4PLMD9Stopwatch5startERKSt17basic_string_viewIcSt11char_traitsIcEE8
_ZN4PLMD9Stopwatch7HandlerD2Ev8541747
_ZN4PLMD9Stopwatch7HandleraSEOS1_5075
_ZN4PLMD9Stopwatch9startStopERKSt17basic_string_viewIcSt11char_traitsIcEE1699022
_ZN4PLMD9StopwatchaSEOS0_0
_ZN4PLMDL20StopwatchEmptyStringEv1329168
+
+
+ + + +
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 000000000..d8e10bd7d --- /dev/null +++ b/coverage/tools/Stopwatch.h.gcov.html @@ -0,0 +1,542 @@ + + + + + + + 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-10-17 16:45:00Functions: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     1329168 : inline static const std::string & StopwatchEmptyString() noexcept {
+     172     1329168 :   const static std::string s;
+     173     1329168 :   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       13722 :   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      806689 :   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     3028188 :   watch(watch),
+     308     3028188 :   stop(stop)
+     309             : {
+     310             :   watch->start();
+     311             : }
+     312             : 
+     313             : inline
+     314     8541747 : Stopwatch::Handler::~Handler() {
+     315     8541747 :   if(watch) {
+     316     3028188 :     if(stop) watch->stop();
+     317     1329166 :     else watch->pause();
+     318             :   }
+     319     8541747 : }
+     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     1699022 : Stopwatch::Handler Stopwatch::startStop(const std::string_view&name) {
+     341     1699022 :   return watches[name].startStop();
+     342             : }
+     343             : 
+     344             : inline
+     345     1329166 : Stopwatch::Handler Stopwatch::startPause(const std::string_view&name) {
+     346     1329166 :   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     3029482 :   state=State::started;
+     390     3029482 :   running++;
+     391     3029482 :   lastStart=std::chrono::high_resolution_clock::now();
+     392             :   return *this;
+     393             : }
+     394             : 
+     395             : inline
+     396     1700312 : Stopwatch::Watch & Stopwatch::Watch::stop() {
+     397     1700312 :   pause();
+     398     1700312 :   state=State::stopped;
+     399     1700312 :   cycles++;
+     400     1700312 :   total+=lap;
+     401     1700312 :   if(lap>max)max=lap;
+     402     1700312 :   if(min>lap || cycles==1)min=lap;
+     403     1700312 :   lastLap=lap;
+     404     1700312 :   lap=0;
+     405     1700312 :   return *this;
+     406             : }
+     407             : 
+     408             : inline
+     409     3029325 : Stopwatch::Watch & Stopwatch::Watch::pause() {
+     410     3029325 :   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     3029325 :   plumed_assert(running>0) << "Non matching start/pause or start/stop commands in a Stopwatch";
+     415     3029325 :   running--;
+     416             : // notice: with exception safety the following might be converted to a plain error.
+     417             : // I leave it like this for now:
+     418     3029325 :   if(running!=0) return *this;
+     419     3029274 :   auto t=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-lastStart);
+     420     3029274 :   lap+=t.count();
+     421     3029274 :   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 000000000..371c13cb3 --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:638475.0 %
Date:2024-10-17 16:45:00Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10Subprocess4contEv16
_ZN4PLMD10Subprocess5flushEv16
_ZN4PLMD10Subprocess7HandlerC2EPS0_16
_ZN4PLMD10Subprocess7HandlerD2Ev16
_ZN4PLMD13SubprocessPid4contEv16
_ZN4PLMD10Subprocess4stopEv18
_ZN4PLMD13SubprocessPid4stopEv18
_ZN4PLMDL26SubprocessPidGetenvSignalsEv34
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE44
_ZN4PLMD10Subprocess9availableEv122
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10030
_ZN4PLMD10SubprocessD2Ev10030
_ZN4PLMD13SubprocessPidC2Ei10030
_ZN4PLMD13SubprocessPidD2Ev10030
+
+
+ + + +
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 000000000..55c40b71a --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:638475.0 %
Date:2024-10-17 16:45:00Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess4contEv16
_ZN4PLMD10Subprocess4stopEv18
_ZN4PLMD10Subprocess5flushEv16
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandlerC2EPS0_16
_ZN4PLMD10Subprocess7HandlerD2Ev16
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE44
_ZN4PLMD10Subprocess9availableEv122
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10030
_ZN4PLMD10SubprocessD2Ev10030
_ZN4PLMD13SubprocessPid4contEv16
_ZN4PLMD13SubprocessPid4stopEv18
_ZN4PLMD13SubprocessPidC2Ei10030
_ZN4PLMD13SubprocessPidD2Ev10030
_ZN4PLMDL26SubprocessPidGetenvSignalsEv34
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.gcov.html b/coverage/tools/Subprocess.cpp.gcov.html new file mode 100644 index 000000000..37628a6dd --- /dev/null +++ b/coverage/tools/Subprocess.cpp.gcov.html @@ -0,0 +1,268 @@ + + + + + + + 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:638475.0 %
Date:2024-10-17 16:45:00Functions:141687.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Subprocess.h"
+      23             : #include "Exception.h"
+      24             : #include "Tools.h"
+      25             : #ifdef __PLUMED_HAS_SUBPROCESS
+      26             : #include <unistd.h>
+      27             : #include <csignal>
+      28             : #include <sys/wait.h>
+      29             : #endif
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /// Retrieve PLUMED_ENABLE_SIGNALS.
+      34             : /// Inline static so that it can store a static variable (for quicker access)
+      35             : /// without adding a unique global symbol to a library including this header file.
+      36          34 : inline static bool SubprocessPidGetenvSignals() noexcept {
+      37          34 :   static const bool res=std::getenv("PLUMED_ENABLE_SIGNALS");
+      38          34 :   return res;
+      39             : }
+      40             : 
+      41             : /// Small utility class, used to avoid inclusion of unistd.h> in a header file.
+      42             : class SubprocessPid {
+      43             : #ifdef __PLUMED_HAS_SUBPROCESS
+      44             : public:
+      45             :   const pid_t pid;
+      46       10030 :   explicit SubprocessPid(pid_t pid):
+      47       10030 :     pid(pid)
+      48             :   {
+      49       10030 :     plumed_assert(pid!=0 && pid!=-1);
+      50       10030 :   }
+      51          18 :   void stop() noexcept {
+      52             :     // Signals give problems with MPI on Travis.
+      53             :     // I disable them for now.
+      54          18 :     if(SubprocessPidGetenvSignals()) kill(pid,SIGSTOP);
+      55          18 :   }
+      56          16 :   void cont() noexcept {
+      57             :     // Signals give problems with MPI on Travis.
+      58             :     // I disable them for now.
+      59          16 :     if(SubprocessPidGetenvSignals()) kill(pid,SIGCONT);
+      60          16 :   }
+      61       10030 :   ~SubprocessPid() {
+      62             :     // the destructor implies we do not need the subprocess anymore, so SIGKILL
+      63             :     // is the fastest exit.
+      64             :     // if we want to gracefully kill the process with a delay, it would be cleaner
+      65             :     // to have another member function
+      66       10030 :     kill(pid,SIGKILL);
+      67             :     // Wait for the child process to terminate
+      68             :     // This is anyway required to avoid leaks
+      69             :     int status;
+      70       10030 :     waitpid(pid, &status, 0);
+      71       10030 :   }
+      72             : #endif
+      73             : };
+      74             : 
+      75       10030 : Subprocess::Subprocess(const std::string & cmd) {
+      76             : #ifdef __PLUMED_HAS_SUBPROCESS
+      77       10030 :   char* arr [] = {
+      78             :     // const_cast are necessary here due to the declaration of execv
+      79             :     const_cast<char*>("/bin/sh"),
+      80             :     const_cast<char*>("-c"),
+      81             :     const_cast<char*>(cmd.c_str()),
+      82             :     nullptr
+      83       10030 :   };
+      84             :   int cp[2];
+      85             :   int pc[2];
+      86       10030 :   if(pipe(pc)<0) plumed_error()<<"error creating parent to child pipe";
+      87       10030 :   if(pipe(cp)<0) plumed_error()<<"error creating child to parent pipe";
+      88       10030 :   pid_t pid=fork();
+      89       10030 :   switch(pid) {
+      90           0 :   case -1:
+      91           0 :     plumed_error()<<"error forking";
+      92             :     break;
+      93             : // CHILD:
+      94           0 :   case 0:
+      95             :   {
+      96           0 :     if(close(1)<0) plumed_error()<<"error closing file";
+      97           0 :     if(dup(cp[1])<0) plumed_error()<<"error duplicating file";
+      98           0 :     if(close(0)<0) plumed_error()<<"error closing file";
+      99           0 :     if(dup(pc[0])<0) plumed_error()<<"error duplicating file";
+     100           0 :     if(close(pc[1])<0) plumed_error()<<"error closing file";
+     101           0 :     if(close(cp[0])<0) plumed_error()<<"error closing file";
+     102           0 :     auto err=execv(arr[0],arr);
+     103           0 :     plumed_error()<<"error in script file " << cmd << ", execv returned "<<err;
+     104             :   }
+     105             : // PARENT::
+     106       10030 :   default:
+     107       10030 :     this->pid=Tools::make_unique<SubprocessPid>(pid);
+     108       10030 :     if(close(pc[0])<0) plumed_error()<<"error closing file";
+     109       10030 :     if(close(cp[1])<0) plumed_error()<<"error closing file";
+     110       10030 :     fpc=pc[1];
+     111       10030 :     fcp=cp[0];
+     112       10030 :     fppc=fdopen(fpc,"w");
+     113       10030 :     parent_to_child.link(fppc);
+     114       10030 :     fpcp=fdopen(fcp,"r");
+     115       10030 :     child_to_parent.link(fpcp);
+     116             :   }
+     117             : #else
+     118             :   plumed_error()<<"Subprocess not supported";
+     119             : #endif
+     120       10030 : }
+     121             : 
+     122       10030 : Subprocess::~Subprocess() {
+     123             : #ifdef __PLUMED_HAS_SUBPROCESS
+     124             : // close files:
+     125       10030 :   fclose(fppc);
+     126       10030 :   fclose(fpcp);
+     127             : // fclose also closes the underlying descriptors,
+     128             : // so this is not needed:
+     129       10030 :   close(fpc);
+     130       10030 :   close(fcp);
+     131             : // after closing the communication, the subprocess is killed
+     132             : // in pid's destructor
+     133             : #endif
+     134       10030 : }
+     135             : 
+     136         122 : bool Subprocess::available() noexcept {
+     137             : #ifdef __PLUMED_HAS_SUBPROCESS
+     138         122 :   return true;
+     139             : #else
+     140             :   return false;
+     141             : #endif
+     142             : }
+     143             : 
+     144          18 : void Subprocess::stop() noexcept {
+     145             : #ifdef __PLUMED_HAS_SUBPROCESS
+     146          18 :   pid->stop();
+     147             : #endif
+     148          18 : }
+     149             : 
+     150          16 : void Subprocess::cont() noexcept {
+     151             : #ifdef __PLUMED_HAS_SUBPROCESS
+     152          16 :   pid->cont();
+     153             : #endif
+     154          16 : }
+     155             : 
+     156          16 : void Subprocess::flush() {
+     157          16 :   parent_to_child.flush();
+     158          16 : }
+     159             : 
+     160          44 : Subprocess & Subprocess::getline(std::string & line) {
+     161          44 :   child_to_parent.getline(line);
+     162          44 :   if(!child_to_parent) plumed_error() <<"error reading subprocess";
+     163          44 :   return (*this);
+     164             : }
+     165             : 
+     166          16 : Subprocess::Handler::Handler(Subprocess *sp) noexcept:
+     167          16 :   sp(sp)
+     168             : {
+     169          16 :   sp->cont();
+     170          16 : }
+     171             : 
+     172          16 : Subprocess::Handler::~Handler() {
+     173          16 :   if(sp) sp->stop();
+     174          16 : }
+     175             : 
+     176           0 : Subprocess::Handler::Handler(Handler && handler) noexcept :
+     177           0 :   sp(handler.sp)
+     178             : {
+     179           0 :   handler.sp=nullptr;
+     180           0 : }
+     181             : 
+     182           0 : Subprocess::Handler & Subprocess::Handler::operator=(Handler && handler) noexcept {
+     183           0 :   if(this!=&handler) {
+     184           0 :     if(sp) sp->stop();
+     185           0 :     sp=handler.sp;
+     186           0 :     handler.sp=nullptr;
+     187             :   }
+     188           0 :   return *this;
+     189             : }
+     190             : 
+     191             : 
+     192             : }
+
+
+
+ + + + +
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 000000000..d975215d4 --- /dev/null +++ b/coverage/tools/Subprocess.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_16
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_16
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.func.html b/coverage/tools/Subprocess.h.func.html new file mode 100644 index 000000000..63a69a355 --- /dev/null +++ b/coverage/tools/Subprocess.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_16
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_16
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.gcov.html b/coverage/tools/Subprocess.h.gcov.html new file mode 100644 index 000000000..6097a0a06 --- /dev/null +++ b/coverage/tools/Subprocess.h.gcov.html @@ -0,0 +1,218 @@ + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-10-17 16:45:00Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Subprocess_h
+      23             : #define __PLUMED_tools_Subprocess_h
+      24             : 
+      25             : #include "OFile.h"
+      26             : #include "IFile.h"
+      27             : #include <string>
+      28             : #include <cstdio>
+      29             : #include <memory>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /// Small class to avoid including unistd.h here
+      34             : class SubprocessPid;
+      35             : 
+      36             : /**
+      37             : Class managing a subprocess.
+      38             : 
+      39             : The subprocess is launched and one can interact with it through a pipe.
+      40             : 
+      41             : In order not to consume resources, it might be possible to use this syntax:
+      42             : 
+      43             : \verbatim
+      44             : // at construction:
+      45             : Subprocess sp;
+      46             : sp.stop();
+      47             : 
+      48             : // when needed
+      49             : {
+      50             :   auto h=sp.contStop();
+      51             :   sp<<"command\n";
+      52             :   sp.flush();
+      53             :   sp.getline(answer);
+      54             : }
+      55             : // when h goes out of scope, subprocess is stopped again.
+      56             : // If an exception is raised in the block, the subprocess is stopped as well.
+      57             : \endverbatim
+      58             : 
+      59             : \warning
+      60             : Currently `stop` and `cont` are giving problems with some MPI implementation,
+      61             : In addition, notice that the stop signal is only sent to the child process and
+      62             : not to the subsequently spawn processes, so it might not work as intended.
+      63             : This feature is left here but is probably no a good idea to use it.
+      64             : It can be enabled with `export PLUMED_ENABLE_SIGNALS=1`.
+      65             : 
+      66             : */
+      67             : class Subprocess {
+      68             :   /// Process ID.
+      69             :   /// We store this rather than pid_t to avoid including <unistd.h> in this header file.
+      70             :   /// This remains nullptr in the child process.
+      71             :   std::unique_ptr<SubprocessPid> pid;
+      72             :   /// File descriptor, parent to child
+      73             :   int fpc=0;
+      74             :   /// File descriptor, child to parent
+      75             :   int fcp=0;
+      76             :   /// File pointer, parent to child
+      77             :   FILE* fppc=NULL;
+      78             :   /// File pointer, child to parent
+      79             :   FILE* fpcp=NULL;
+      80             :   /// PLUMED file object, parent to child.
+      81             :   /// Used to simplify formatting
+      82             :   OFile parent_to_child;
+      83             :   /// PLUMED file object, child to parent.
+      84             :   /// Used to simplify formatting
+      85             :   IFile child_to_parent;
+      86             : public:
+      87             :   /// Class used to cont/stop a Subprocess in an exception safe manner.
+      88             :   class Handler {
+      89             :     Subprocess* sp=nullptr;
+      90             :     /// Private constructor.
+      91             :     /// Only to be called by Subprocess::contStop()
+      92             :     explicit Handler(Subprocess* sp) noexcept;
+      93             :     friend class Subprocess;
+      94             :   public:
+      95             :     /// Default constructor
+      96             :     Handler() = default;
+      97             :     /// Destructor stops the subprocess.
+      98             :     ~Handler();
+      99             :     /// Default copy constructor is deleted (not copyable)
+     100             :     Handler(const Handler &) = delete;
+     101             :     /// Default copy assignment is deleted (not copyable)
+     102             :     Handler & operator=(const Handler & handler) = delete;
+     103             :     /// Move constructor.
+     104             :     Handler(Handler &&) noexcept;
+     105             :     /// Move assignment.
+     106             :     Handler & operator=(Handler && handler) noexcept;
+     107             :   };
+     108             : /// Constructor with a command line.
+     109             :   explicit Subprocess(const std::string & cmd);
+     110             : /// Destructor
+     111             :   ~Subprocess();
+     112             : /// Flush communication to process.
+     113             :   void flush();
+     114             : /// Check if subprocess facilities are available.
+     115             : /// If it returns false, any call to Subprocess constructor will raise an exception.
+     116             :   static bool available() noexcept;
+     117             : /// Get a line from the subprocess.
+     118             :   Subprocess & getline(std::string &);
+     119             : /// Write something to the subprocess.
+     120             :   template <class T> friend Subprocess& operator<<(Subprocess& ep,const T &t);
+     121             : /// Send a SIGCONT to the subprocess.
+     122             : /// Better used through contStop() method.
+     123             :   void cont() noexcept;
+     124             : /// Send a SIGSTOP to the subprocess.
+     125             : /// Better used through contStop() method.
+     126             :   void stop() noexcept;
+     127             : /// Returns a handler to temporarily resume the process.
+     128             :   Handler contStop() noexcept {
+     129          16 :     return Handler(this);
+     130             :   }
+     131             : };
+     132             : 
+     133             : template <class T>
+     134          32 : Subprocess& operator<<(Subprocess& ep,const T &t) {
+     135          32 :   ep.parent_to_child<<t;
+     136          32 :   return ep;
+     137             : }
+     138             : 
+     139             : }
+     140             : 
+     141             : #endif
+     142             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func-sort-c.html b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html new file mode 100644 index 000000000..e820e5a6f --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,496 @@ + + + + + + + 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-10-17 16:45:00Functions: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
_ZN4PLMD16switchContainers10smapSwitchC2Edddii15
_ZN4PLMD16switchContainers11cubicSwitchC2Edd15
_ZN4PLMD16switchContainers11cubicSwitchD0Ev15
_ZNK4PLMD16switchContainers10smapSwitch19specificDescriptionB5cxx11Ev15
_ZNK4PLMD16switchContainers11cubicSwitch19specificDescriptionB5cxx11Ev15
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EEC2Eddd16
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE19specificDescriptionB5cxx11Ev16
_ZNK4PLMD16switchContainers12leptonSwitch19specificDescriptionB5cxx11Ev18
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD16switchContainers12leptonSwitchC2EdddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZNK4PLMD17SwitchingFunction6get_r0Ev32
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKS2_44
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE10doRationalEdRddiid52
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE8functionEdRd52
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EEC2Edddii55
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE19specificDescriptionB5cxx11Ev55
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE12calculateSqrEdRd60
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE12calculateSqrEdRd60
_ZN4PLMD16switchContainers14gaussianSwitchC2Eddd66
_ZN4PLMD17SwitchingFunction3setEiidd74
_ZN4PLMD16switchContainers17exponentialSwitchC2Eddd75
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE19specificDescriptionB5cxx11Ev113
_ZN4PLMD16switchContainers18fastGaussianSwitchC2Eddd114
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EEC2Edddii132
_ZNK4PLMD16switchContainers10baseSwitch19specificDescriptionB5cxx11Ev150
_ZN4PLMD16switchContainers10baseSwitch12setupStretchEv216
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE19specificDescriptionB5cxx11Ev244
_ZN4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EEC2Eddd263
_ZN4PLMD16switchContainers20fixedRationalFactoryILi6ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi264
_ZN4PLMD16switchContainers20fixedRationalFactoryILi10ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi266
_ZN4PLMD16switchContainers20fixedRationalFactoryILi8ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi266
_ZN4PLMD16switchContainers20fixedRationalFactoryILi12ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi282
_ZN4PLMD16switchContainers15rationalFactoryEdddii472
_ZNK4PLMD16switchContainers13nativeqSwitch19specificDescriptionB5cxx11Ev572
_ZNK4PLMD16switchContainers10baseSwitch11descriptionB5cxx11Ev1204
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1204
_ZNK4PLMD16switchContainers10baseSwitch6get_r0Ev1236
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1283
_ZN4PLMD16switchContainers10baseSwitchC2EdddSt17basic_string_viewIcSt11char_traitsIcEE1356
_ZN4PLMD16switchContainers10baseSwitchD2Ev1356
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE10doRationalILi12EEEddRdd1382
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE8functionEdRd1382
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE12calculateSqrEdRd1428
_ZNK4PLMD16switchContainers10tanhSwitch8functionEdRd12718
_ZNK4PLMD16switchContainers11cubicSwitch8functionEdRd127256
_ZNK4PLMD16switchContainers13nativeqSwitch9calculateEdRd146632
_ZNK4PLMD16switchContainers14gaussianSwitch8functionEdRd279640
_ZNK4PLMD16switchContainers13cosinusSwitch8functionEdRd522111
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE10doRationalEdRddiid2113979
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE8functionEdRd2113979
_ZNK4PLMD16switchContainers17exponentialSwitch8functionEdRd2404247
_ZNK4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EE12calculateSqrEdRd3128712
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE12calculateSqrEdRd3408239
_ZNK4PLMD16switchContainers12leptonSwitch9calculateEdRd5877796
_ZNK4PLMD16switchContainers12leptonSwitch12funcAndDerivclEd6515285
_ZNK4PLMD16switchContainers12leptonSwitch12calculateSqrEdRd7125890
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE12calculateSqrEdRd8345710
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE8functionEdRd16111416
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE10doRationalEdRddiid16111468
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE8functionEdRd16153550
_ZNK4PLMD16switchContainers10smapSwitch8functionEdRd21911326
_ZNK4PLMD16switchContainers10baseSwitch12calculateSqrEdRd31818564
_ZNK4PLMD16switchContainers18fastGaussianSwitch12calculateSqrEdRd38317812
_ZNK4PLMD16switchContainers10baseSwitch9get_dmax2Ev49030642
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev49030642
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd92146473
_ZNK4PLMD17SwitchingFunction9calculateEdRd127737259
_ZNK4PLMD16switchContainers10baseSwitch9calculateEdRd162817906
_ZNK4PLMD16switchContainers10baseSwitch8get_dmaxEv536580542
_ZNK4PLMD17SwitchingFunction8get_dmaxEv536580542
+
+
+ + + +
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 000000000..b847bd342 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func.html @@ -0,0 +1,496 @@ + + + + + + + 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-10-17 16:45:00Functions:8210677.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16switchContainers10baseSwitch12setupStretchEv216
_ZN4PLMD16switchContainers10baseSwitch13removeStretchEv0
_ZN4PLMD16switchContainers10baseSwitchC2EdddSt17basic_string_viewIcSt11char_traitsIcEE1356
_ZN4PLMD16switchContainers10baseSwitchD0Ev0
_ZN4PLMD16switchContainers10baseSwitchD2Ev1356
_ZN4PLMD16switchContainers10smapSwitchC2Edddii15
_ZN4PLMD16switchContainers10tanhSwitchC2Eddd4
_ZN4PLMD16switchContainers11cubicSwitchC2Edd15
_ZN4PLMD16switchContainers11cubicSwitchD0Ev15
_ZN4PLMD16switchContainers11cubicSwitchD2Ev0
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKS2_44
_ZN4PLMD16switchContainers12leptonSwitchC2EdddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD16switchContainers13cosinusSwitchC2Eddd3
_ZN4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EEC2Eddd0
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE10doRationalILi12EEEddRdd1382
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EEC2Eddd16
_ZN4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EEC2Eddd0
_ZN4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EEC2Eddd1
_ZN4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EEC2Eddd263
_ZN4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EEC2Eddd2
_ZN4PLMD16switchContainers14gaussianSwitchC2Eddd66
_ZN4PLMD16switchContainers15rationalFactoryEdddii472
_ZN4PLMD16switchContainers17exponentialSwitchC2Eddd75
_ZN4PLMD16switchContainers18fastGaussianSwitchC2Eddd114
_ZN4PLMD16switchContainers20fixedRationalFactoryILi0ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi0
_ZN4PLMD16switchContainers20fixedRationalFactoryILi10ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi266
_ZN4PLMD16switchContainers20fixedRationalFactoryILi12ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi282
_ZN4PLMD16switchContainers20fixedRationalFactoryILi2ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi0
_ZN4PLMD16switchContainers20fixedRationalFactoryILi4ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi1
_ZN4PLMD16switchContainers20fixedRationalFactoryILi6ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi264
_ZN4PLMD16switchContainers20fixedRationalFactoryILi8ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi266
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE10doRationalEdRddiid52
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EEC2Edddii3
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE10doRationalEdRddiid2113979
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EEC2Edddii132
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE10doRationalEdRddiid16111468
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EEC2Edddii55
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE10doRationalEdRddiid0
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EEC2Edddii0
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1283
_ZN4PLMD17SwitchingFunction3setEiidd74
_ZNK4PLMD16switchContainers10baseSwitch11descriptionB5cxx11Ev1204
_ZNK4PLMD16switchContainers10baseSwitch12calculateSqrEdRd31818564
_ZNK4PLMD16switchContainers10baseSwitch19specificDescriptionB5cxx11Ev150
_ZNK4PLMD16switchContainers10baseSwitch6get_d0Ev8
_ZNK4PLMD16switchContainers10baseSwitch6get_r0Ev1236
_ZNK4PLMD16switchContainers10baseSwitch8get_dmaxEv536580542
_ZNK4PLMD16switchContainers10baseSwitch9calculateEdRd162817906
_ZNK4PLMD16switchContainers10baseSwitch9get_dmax2Ev49030642
_ZNK4PLMD16switchContainers10smapSwitch19specificDescriptionB5cxx11Ev15
_ZNK4PLMD16switchContainers10smapSwitch8functionEdRd21911326
_ZNK4PLMD16switchContainers10tanhSwitch8functionEdRd12718
_ZNK4PLMD16switchContainers11cubicSwitch19specificDescriptionB5cxx11Ev15
_ZNK4PLMD16switchContainers11cubicSwitch8functionEdRd127256
_ZNK4PLMD16switchContainers12leptonSwitch12calculateSqrEdRd7125890
_ZNK4PLMD16switchContainers12leptonSwitch12funcAndDerivclEd6515285
_ZNK4PLMD16switchContainers12leptonSwitch19specificDescriptionB5cxx11Ev18
_ZNK4PLMD16switchContainers12leptonSwitch8functionEdRd0
_ZNK4PLMD16switchContainers12leptonSwitch9calculateEdRd5877796
_ZNK4PLMD16switchContainers13cosinusSwitch8functionEdRd522111
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE19specificDescriptionB5cxx11Ev16
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE8functionEdRd1382
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE12calculateSqrEdRd1428
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE19specificDescriptionB5cxx11Ev1
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE12calculateSqrEdRd8345710
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE19specificDescriptionB5cxx11Ev244
_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_12rationalFormE0EE19specificDescriptionB5cxx11Ev55
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE8functionEdRd16111416
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE8functionEdRd0
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1204
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd92146473
_ZNK4PLMD17SwitchingFunction6get_d0Ev8
_ZNK4PLMD17SwitchingFunction6get_r0Ev32
_ZNK4PLMD17SwitchingFunction8get_dmaxEv536580542
_ZNK4PLMD17SwitchingFunction9calculateEdRd127737259
_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 000000000..8312f7edb --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.gcov.html @@ -0,0 +1,1039 @@ + + + + + + + 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-10-17 16:45:00Functions: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        1356 : baseSwitch::baseSwitch(double D0,double DMAX, double R0, std::string_view name)
+     180        1356 :   : d0(D0),
+     181        1356 :     dmax(DMAX),
+     182        1356 :     dmax_2([](const double d) {
+     183        1356 :   if(d<std::sqrt(std::numeric_limits<double>::max())) {
+     184         244 :     return  d*d;
+     185             :   } else {
+     186             :     return std::numeric_limits<double>::max();
+     187             :   }
+     188             : }(dmax)),
+     189        1356 : invr0(1.0/R0),
+     190        1356 : invr0_2(invr0*invr0),
+     191        1600 : mytype(name) {}
+     192             : 
+     193        1356 : baseSwitch::~baseSwitch()=default;
+     194             : 
+     195   162817906 : double baseSwitch::calculate(const double distance, double& dfunc) const {
+     196             :   double res = 0.0;//RVO!
+     197   162817906 :   dfunc = 0.0;
+     198   162817906 :   if(distance <= dmax) {
+     199             :     res = 1.0;
+     200   156000375 :     const double rdist = (distance-d0)*invr0;
+     201   156000375 :     if(rdist > 0.0) {
+     202    59637678 :       res = function(rdist,dfunc);
+     203             :       //the following comments came from the original
+     204             :       // this is for the chain rule (derivative of rdist):
+     205    59637678 :       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    59637678 :       dfunc /= distance;
+     213             :     }
+     214   156000375 :     res=res*stretch+shift;
+     215   156000375 :     dfunc*=stretch;
+     216             :   }
+     217   162817906 :   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        1236 : double baseSwitch::get_r0() const {return 1.0/invr0;}
+     226   536580542 : double baseSwitch::get_dmax() const {return dmax;}
+     227    49030642 : double baseSwitch::get_dmax2() const {return dmax_2;}
+     228        1204 : std::string baseSwitch::description() const {
+     229        1204 :   std::ostringstream ostr;
+     230        1204 :   ostr<<get_r0()
+     231             :       <<".  Using "
+     232             :       << mytype
+     233        2408 :       <<" switching function with parameters d0="<< d0
+     234        2408 :       << specificDescription();
+     235        1204 :   return ostr.str();
+     236        1204 : }
+     237         150 : std::string baseSwitch::specificDescription() const {return "";}
+     238         216 : void baseSwitch::setupStretch() {
+     239         216 :   if(dmax!=std::numeric_limits<double>::max()) {
+     240         216 :     stretch=1.0;
+     241         216 :     shift=0.0;
+     242             :     double dummy;
+     243         216 :     double s0=calculate(0.0,dummy);
+     244         216 :     double sd=calculate(dmax,dummy);
+     245         216 :     stretch=1.0/(s0-sd);
+     246         216 :     shift=-sd*stretch;
+     247             :   }
+     248         216 : }
+     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         263 :   std::string specificDescription() const override {
+     256         263 :     std::ostringstream ostr;
+     257         263 :     ostr << " nn=" << N << " mm=" <<N*2;
+     258         263 :     return ostr.str();
+     259         263 :   }
+     260             : public:
+     261         282 :   fixedRational(double D0,double DMAX, double R0)
+     262         282 :     :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         171 :   std::string specificDescription() const override {
+     317         171 :     std::ostringstream ostr;
+     318         171 :     ostr << " nn=" << nn << " mm=" <<mm;
+     319         171 :     return ostr.str();
+     320         171 :   }
+     321             : public:
+     322         190 :   rational(double D0,double DMAX, double R0, int N, int M)
+     323             :     :baseSwitch(D0,DMAX,R0,"rational"),
+     324         190 :      nn(N),
+     325          89 :      mm([](int m,int n) {if (m==0) {return n*2;} else {return m;}}(M,N)),
+     326         190 :   preRes(static_cast<double>(nn)/mm),
+     327         190 :   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         190 :   preSecDev ((nn * (mm * mm - 3.0* mm * (-1 + nn ) + nn *(-3 + 2* nn )))/(6.0* mm )),
+     330         190 :   nnf(nn/2),
+     331         190 :   mmf(mm/2),
+     332         190 :   preDfuncF(0.5*nnf*(nnf-mmf)/static_cast<double>(mmf)),
+     333         190 :   preSecDevF((nnf* (mmf*mmf - 3.0* mmf* (-1 + nnf) + nnf*(-3 + 2* nnf)))/(6.0* mmf)) {}
+     334             : 
+     335    18225499 :   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    16111520 :       if(!((rdist > lessThanOne) && (rdist < moreThanOne))) {
+     348    16111508 :         const double rNdist=Tools::fastpow(rdist,N-1);
+     349    16111508 :         const double rMdist=Tools::fastpow(rdist,M-1);
+     350    16111508 :         const double num = 1.0-rNdist*rdist;
+     351    16111508 :         const double iden = 1.0/(1.0-rMdist*rdist);
+     352    16111508 :         result = num*iden;
+     353    16111508 :         dfunc = ((M*result*rMdist)-(N*rNdist))*iden;
+     354    16111508 :       } 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    18225499 :     return result;
+     362             :   }
+     363    18225447 :   inline double function(double rdist,double&dfunc) const override {
+     364             :     //preRes and preDfunc are passed already set
+     365    18225447 :     dfunc=preDfunc;
+     366    18225447 :     double result = doRational(rdist,dfunc,preSecDev,nn,mm,preRes);
+     367    18225447 :     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        1079 : 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        1079 :     if (N==EXP) {
+     398         282 :       return PLMD::Tools::make_unique<switchContainers::fixedRational<EXP>>(D0,DMAX,R0);
+     399             :     } else {
+     400         797 :       return fixedRationalFactory<EXP-2>(D0,DMAX,R0,N);
+     401             :     }
+     402             :   }
+     403             : }
+     404             : 
+     405             : std::unique_ptr<baseSwitch>
+     406         472 : rationalFactory(double D0,double DMAX, double R0, int N, int M) {
+     407         472 :   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         472 :   if(((2*N)==M || M == 0) && fast && N<=highestPrecompiledPower) {
+     412         282 :     auto tmp = fixedRationalFactory<highestPrecompiledPower>(D0,DMAX,R0,N);
+     413         282 :     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         190 :   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          58 :   if(fast) {
+     430             :     //fast rational
+     431             :     return PLMD::Tools::make_unique<switchContainers::rational<
+     432          55 :            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         114 :   fastGaussianSwitch(double /*D0*/, double DMAX, double /*R0*/)
+     466         114 :     :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          15 :   std::string specificDescription() const override {
+     519          15 :     std::ostringstream ostr;
+     520          15 :     ostr<<" dmax="<<dmax;
+     521          15 :     return ostr.str();
+     522          15 :   }
+     523             : public:
+     524          15 :   cubicSwitch(double D0, double DMAX)
+     525          15 :     :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          15 :   }
+     531          15 :   ~cubicSwitch()=default;
+     532             : protected:
+     533      127256 :   inline double function(const double rdist,double&dfunc) const override {
+     534      127256 :     const double tmp1 = rdist - 1.0;
+     535      127256 :     const double tmp2 = 1.0+2.0*rdist;
+     536             :     //double result = tmp1*tmp1*tmp2;
+     537      127256 :     dfunc = 2*tmp1*tmp2 + 2*tmp1*tmp1;
+     538      127256 :     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        1283 : void SwitchingFunction::set(const std::string & definition,std::string& errormsg) {
+     829        1283 :   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        1283 :   if( data.size()<1 ) {
+     838             :     errormsg="missing all input for switching function";
+     839             :     return;
+     840             :   }
+     841        1283 :   std::string name=data[0];
+     842             :   data.erase(data.begin());
+     843        1283 :   double r0=0.0;
+     844        1283 :   double d0=0.0;
+     845        1283 :   double dmax=std::numeric_limits<double>::max();
+     846        1283 :   init=true;
+     847        1711 :   CHECKandPARSE(data,"D_0",d0,errormsg);
+     848        1623 :   CHECKandPARSE(data,"D_MAX",dmax,errormsg);
+     849             : 
+     850        1283 :   bool dostretch=false;
+     851        1283 :   Tools::parseFlag(data,"STRETCH",dostretch); // this is ignored now
+     852        1283 :   dostretch=true;
+     853        1283 :   bool dontstretch=false;
+     854        1283 :   Tools::parseFlag(data,"NOSTRETCH",dontstretch); // this is ignored now
+     855        1283 :   if(dontstretch)
+     856         169 :     dostretch=false;
+     857        1283 :   if(name=="CUBIC") {
+     858             :     //cubic is the only switch type that only uses d0 and dmax
+     859          15 :     function = PLMD::Tools::make_unique<switchContainers::cubicSwitch>(d0,dmax);
+     860             :   } else {
+     861        2536 :     REQUIREDPARSE(data,"R_0",r0,errormsg);
+     862        1268 :     if(name=="RATIONAL") {
+     863         398 :       int nn=6;
+     864         398 :       int mm=0;
+     865         642 :       CHECKandPARSE(data,"NN",nn,errormsg);
+     866         636 :       CHECKandPARSE(data,"MM",mm,errormsg);
+     867         796 :       function = switchContainers::rationalFactory(d0,dmax,r0,nn,mm);
+     868         870 :     } 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         855 :     } 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         283 :     } else if(name=="EXP") {
+     889          75 :       function = PLMD::Tools::make_unique<switchContainers::exponentialSwitch>(d0,dmax,r0);
+     890         208 :     } else if(name=="GAUSSIAN") {
+     891         180 :       if ( r0==1.0 && d0==0.0 ) {
+     892         114 :         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        1281 :   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        1281 :   if(dostretch && dmax!=std::numeric_limits<double>::max()) {
+     917         142 :     function->setupStretch();
+     918             :   }
+     919        1283 : }
+     920             : 
+     921        1204 : 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        1204 :   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   127737259 : double SwitchingFunction::calculate(double distance,double&dfunc)const {
+     932   127737259 :   plumed_massert(init,"you are trying to use an unset SwitchingFunction");
+     933   127737259 :   double result=function->calculate(distance,dfunc);
+     934   127737259 :   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   536580542 : double SwitchingFunction::get_dmax() const {
+     956   536580542 :   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 000000000..e85fae692 --- /dev/null +++ b/coverage/tools/SwitchingFunction.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a6e42b56c --- /dev/null +++ b/coverage/tools/SwitchingFunction.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..bd6542bb1 --- /dev/null +++ b/coverage/tools/SwitchingFunction.h.gcov.html @@ -0,0 +1,194 @@ + + + + + + + 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-10-17 16:45:00Functions: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        2447 : 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 000000000..090f7dff6 --- /dev/null +++ b/coverage/tools/Tensor.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions: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_623761
+
+
+ + + +
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 000000000..bfb662f71 --- /dev/null +++ b/coverage/tools/Tensor.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions: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_623761
+
+
+ + + +
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 000000000..e1d4fcef4 --- /dev/null +++ b/coverage/tools/Tensor.cpp.gcov.html @@ -0,0 +1,115 @@ + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions: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      623761 : 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      623761 :   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      623761 : }
+      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 000000000..287b0c89f --- /dev/null +++ b/coverage/tools/Tensor.h.func-sort-c.html @@ -0,0 +1,348 @@ + + + + + + + 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-10-17 16:45:00Functions: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_d37375
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZN4PLMD10diagMatSymILj4ELj4EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE58770
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE79542
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj109170
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv177723
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv177893
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv250728
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv271524
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE359604
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD10diagMatSymILj4ELj1EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE564522
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev564522
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE857865
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv930534
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev1489986
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1783263
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1820416
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE2610220
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_2930747
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3535518
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4309662
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv4873057
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_5176479
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE5607189
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_5754135
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_11518410
_ZNK4PLMD13TensorGenericILj4ELj4EE6getColEj12203712
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13274158
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev47477459
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj48814848
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_49152217
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_55998693
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_60102394
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE60626943
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj61391211
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d81591209
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd81596234
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_101528362
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE107285387
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj281867316
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj4999899893
+
+
+ + + +
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 000000000..b2f78fb99 --- /dev/null +++ b/coverage/tools/Tensor.h.func.html @@ -0,0 +1,348 @@ + + + + + + + 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-10-17 16:45:00Functions: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_EEE564522
_ZN4PLMD10diagMatSymILj4ELj4EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE58770
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE2610220
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev564522
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4309662
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv930534
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE79542
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1783263
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13274158
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_101528362
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev47477459
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_11518410
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJffffffffEEEdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj281867316
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_49152217
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd81596234
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_60102394
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev1489986
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj61391211
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE107285387
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE60626943
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE5607189
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE359604
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_5176479
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_5754135
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE857865
_ZN4PLMDdvILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d37375
_ZN4PLMDlsILj3ELj3EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDlsILj4ELj4EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1820416
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d81591209
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_55998693
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_2930747
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv271524
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj109170
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3535518
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv177893
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv4873057
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj4999899893
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv250728
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv177723
_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 000000000..5f9e60f4a --- /dev/null +++ b/coverage/tools/Tensor.h.gcov.html @@ -0,0 +1,650 @@ + + + + + + + LCOV - plumed test coverage - tools/Tensor.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14615196.7 %
Date:2024-10-17 16:45:00Functions: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   103665690 : void TensorGeneric<n,m>::auxiliaryConstructor(double first,Args... arg)
+     216             : {
+     217   103665690 :   d[n*m-(sizeof...(Args))-1]=first;
+     218    92147280 :   auxiliaryConstructor(arg...);
+     219   103665690 : }
+     220             : 
+     221             : template <unsigned n,unsigned m>
+     222             : template<typename... Args>
+     223    11518410 : 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    11518410 :   auxiliaryConstructor(first,arg...);
+     227    11518410 : }
+     228             : 
+     229             : template<unsigned n,unsigned m>
+     230    59785361 : TensorGeneric<n,m>::TensorGeneric() {
+     231    59785361 :   LoopUnroller<n*m>::_zero(d.data());
+     232    59785361 : }
+     233             : 
+     234             : template<unsigned n,unsigned m>
+     235   101528362 : TensorGeneric<n,m>::TensorGeneric(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     236  1319868706 :   for(unsigned i=0; i<n; i++)for(unsigned j=0; j<m; j++)d[i*m+j]=v1[i]*v2[j];
+     237   101528362 : }
+     238             : 
+     239             : template<unsigned n,unsigned m>
+     240      930534 : void TensorGeneric<n,m>::zero() {
+     241      930534 :   LoopUnroller<n*m>::_zero(d.data());
+     242      930534 : }
+     243             : 
+     244             : template<unsigned n,unsigned m>
+     245   351443373 : 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   351443373 :   return d[m*i+j];
+     251             : }
+     252             : 
+     253             : template<unsigned n,unsigned m>
+     254  5053333469 : 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  5053333469 :   return d[m*i+j];
+     260             : }
+     261             : 
+     262             : template<unsigned n,unsigned m>
+     263    60102394 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator +=(const TensorGeneric<n,m>& b) {
+     264    60102394 :   LoopUnroller<n*m>::_add(d.data(),b.d.data());
+     265    60102394 :   return *this;
+     266             : }
+     267             : 
+     268             : template<unsigned n,unsigned m>
+     269    49152217 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator -=(const TensorGeneric<n,m>& b) {
+     270    49152217 :   LoopUnroller<n*m>::_sub(d.data(),b.d.data());
+     271    49152217 :   return *this;
+     272             : }
+     273             : 
+     274             : template<unsigned n,unsigned m>
+     275    81596234 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator *=(double s) {
+     276    81596234 :   LoopUnroller<n*m>::_mul(d.data(),s);
+     277    81596234 :   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      177723 : TensorGeneric<n,m> TensorGeneric<n,m>::operator+()const {
+     288      177723 :   return *this;
+     289             : }
+     290             : 
+     291             : template<unsigned n,unsigned m>
+     292      250728 : TensorGeneric<n,m> TensorGeneric<n,m>::operator-()const {
+     293      250728 :   TensorGeneric<n,m> r;
+     294      250728 :   LoopUnroller<n*m>::_neg(r.d.data(),d.data());
+     295      250728 :   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     3074991 : TensorGeneric<n,m>& TensorGeneric<n,m>::setRow(unsigned i,const VectorGeneric<m> & r) {
+     306    12299964 :   for(unsigned j=0; j<m; ++j) (*this)(i,j)=r(j);
+     307     3074991 :   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     3535518 : VectorGeneric<m> TensorGeneric<n,m>::getRow(unsigned i)const {
+     319     3535518 :   VectorGeneric<m> v;
+     320    14142072 :   for(unsigned j=0; j<m; ++j) v(j)=(*this)(i,j);
+     321     3535518 :   return v;
+     322             : }
+     323             : 
+     324             : template<unsigned n,unsigned m>
+     325     2930747 : TensorGeneric<n,m> operator+(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     326     2930747 :   TensorGeneric<n,m> t(t1);
+     327     2930747 :   t+=t2;
+     328     2930747 :   return t;
+     329             : }
+     330             : 
+     331             : template<unsigned n,unsigned m>
+     332     1820416 : TensorGeneric<n,m> operator-(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     333     1820416 :   TensorGeneric<n,m> t(t1);
+     334     1820416 :   t-=t2;
+     335     1820416 :   return t;
+     336             : }
+     337             : 
+     338             : template<unsigned n,unsigned m>
+     339    81591209 : TensorGeneric<n,m> operator*(const TensorGeneric<n,m>&t1,double s) {
+     340    81591209 :   TensorGeneric<n,m> t(t1);
+     341    81591209 :   t*=s;
+     342    81591209 :   return t;
+     343             : }
+     344             : 
+     345             : template<unsigned n,unsigned m>
+     346    55998693 : TensorGeneric<n,m> operator*(double s,const TensorGeneric<n,m>&t1) {
+     347    55998693 :   return t1*s;
+     348             : }
+     349             : 
+     350             : template<unsigned n,unsigned m>
+     351       37375 : TensorGeneric<n,m> operator/(const TensorGeneric<n,m>&t1,double s) {
+     352       37375 :   return t1*(1.0/s);
+     353             : }
+     354             : 
+     355             : template<>
+     356             : inline
+     357      271524 : double TensorGeneric<3,3>::determinant()const {
+     358             :   return
+     359      271524 :     d[0]*d[4]*d[8]
+     360      271524 :     + d[1]*d[5]*d[6]
+     361      271524 :     + d[2]*d[3]*d[7]
+     362      271524 :     - d[0]*d[5]*d[7]
+     363      271524 :     - d[1]*d[3]*d[8]
+     364      271524 :     - d[2]*d[4]*d[6];
+     365             : }
+     366             : 
+     367             : template<unsigned n,unsigned m>
+     368             : inline
+     369    13274158 : TensorGeneric<n,n> TensorGeneric<n,m>::identity() {
+     370    13274158 :   TensorGeneric<n,n> t;
+     371    53096632 :   for(unsigned i=0; i<n; i++) t(i,i)=1.0;
+     372    13274158 :   return t;
+     373             : }
+     374             : 
+     375             : template<unsigned n,unsigned m>
+     376     4873057 : TensorGeneric<m,n> TensorGeneric<n,m>::transpose()const {
+     377     4873057 :   TensorGeneric<m,n> t;
+     378    63349741 :   for(unsigned i=0; i<m; i++)for(unsigned j=0; j<n; j++) t(i,j)=(*this)(j,i);
+     379     4873057 :   return t;
+     380             : }
+     381             : 
+     382             : template<>
+     383             : inline
+     384      177893 : TensorGeneric<3,3> TensorGeneric<3,3>::inverse()const {
+     385      177893 :   TensorGeneric t;
+     386      177893 :   double invdet=1.0/determinant();
+     387     2312609 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     388     1601037 :       t(j,i)=invdet*(   (*this)((i+1)%3,(j+1)%3)*(*this)((i+2)%3,(j+2)%3)
+     389     1601037 :                         -(*this)((i+1)%3,(j+2)%3)*(*this)((i+2)%3,(j+1)%3));
+     390      177893 :   return t;
+     391             : }
+     392             : 
+     393             : template<unsigned n,unsigned m,unsigned l>
+     394     5607189 : TensorGeneric<n,l> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b) {
+     395     5607189 :   TensorGeneric<n,l> t;
+     396   224287560 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<l; j++) for(unsigned k=0; k<m; k++) {
+     397   151394103 :         t(i,j)+=a(i,k)*b(k,j);
+     398             :       }
+     399     5607189 :   return t;
+     400             : }
+     401             : 
+     402             : template<unsigned n,unsigned m>
+     403    60626943 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const VectorGeneric<m>&b) {
+     404    60626943 :   VectorGeneric<n> t;
+     405   788150259 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(i,j)*b(j);
+     406    60626943 :   return t;
+     407             : }
+     408             : 
+     409             : template<unsigned n,unsigned m>
+     410   107670281 : VectorGeneric<n> matmul(const VectorGeneric<m>&a,const TensorGeneric<m,n>&b) {
+     411   107670281 :   VectorGeneric<n> t;
+     412  1400868335 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(j)*b(j,i);
+     413   107670281 :   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      359604 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b,const VectorGeneric<l>&c) {
+     428      359604 :   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       89147 :   return t.inverse();
+     449             : }
+     450             : 
+     451             : template<unsigned n,unsigned m>
+     452      857865 : TensorGeneric<n,m> transpose(const TensorGeneric<m,n>&t) {
+     453      857865 :   return t.transpose();
+     454             : }
+     455             : 
+     456             : template<unsigned n,unsigned m>
+     457     2610220 : TensorGeneric<n,m> extProduct(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     458     2610220 :   return TensorGeneric<n,m>(v1,v2);
+     459             : }
+     460             : 
+     461             : inline
+     462     5176479 : 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     5176479 :            -v2[2],   0.0, v2[0],
+     467     5176479 :            v2[1],-v2[0],   0.0);
+     468             : }
+     469             : 
+     470             : inline
+     471     5754135 : 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     5754135 :            v1[2],0.0,-v1[0],
+     476     5754135 :            -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      623758 : 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      623758 :   auto mat_copy=mat;
+     540             :   // documentation says this is size n (even if m<n)
+     541             :   std::array<double,n> evals_tmp;
+     542      623758 :   int nn=n;              // dimension of matrix
+     543      623758 :   double vl=0.0, vu=1.0; // ranges - not used
+     544      623758 :   int one=1,mm=m;        // minimum and maximum index
+     545      623758 :   double abstol=0.0;     // tolerance
+     546      623758 :   int mout=0;            // number of eigenvalues found (same as mm)
+     547      623758 :   int info=0;            // result
+     548      623758 :   int liwork=iwork.size();
+     549      623758 :   int lwork=work.size();
+     550      623758 :   TensorGenericAux::local_dsyevr("V", (n==m?"A":"I"), "U", &nn, const_cast<double*>(&mat_copy[0][0]), &nn, &vl, &vu, &one, &mm,
+     551      623758 :                                  &abstol, &mout, &evals_tmp[0], &evec[0][0], &nn,
+     552             :                                  isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     553      623758 :   if(info!=0) plumed_error()<<"Error diagonalizing matrix\n"
+     554             :                               <<"Matrix:\n"<<mat<<"\n"
+     555             :                               <<"Info: "<<info<<"\n";
+     556      623758 :   plumed_assert(mout==m);
+     557     1424758 :   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     1424758 :   for(unsigned i=0; i<m; ++i) {
+     563             :     unsigned j=0;
+     564      801593 :     for(j=0; j<n; j++) if(evec(i,j)*evec(i,j)>1e-14) break;
+     565     1395931 :     if(j<n) if(evec(i,j)<0.0) for(j=0; j<n; j++) evec(i,j)*=-1;
+     566             :   }
+     567      623758 : }
+     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 000000000..ef9c094cc --- /dev/null +++ b/coverage/tools/Tools.cpp.func-sort-c.html @@ -0,0 +1,300 @@ + + + + + + + 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-10-17 16:45:00Functions: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_202
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev202
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKSt9exception215
_ZN4PLMD12_GLOBAL__N_121process_one_exception6updateEv216
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools5ltrimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1080
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe1208
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4356
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9118
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13044
_ZN4PLMD5Tools12molfile_lockEv18968
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb19531
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE48254
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE72764
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_394754
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_548654
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i614907
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE1117614
_ZN4PLMD5Tools14getWordsSimpleERNS_3gch12small_vectorISt17basic_string_viewIcSt11char_traitsIcEELj2ESaIS6_EEES6_1346572
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1489657
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1612760
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_2415311
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2480516
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2480516
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2485982
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3319262
_ZN4PLMD5Tools8getWordsB5cxx11ESt17basic_string_viewIcSt11char_traitsIcEEPKcPiS6_RKb3540537
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3989194
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj3989194
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5106808
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc7128208
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14389256
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14389256
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14389256
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_437876410
+
+
+ + + +
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 000000000..09f3acdfe --- /dev/null +++ b/coverage/tools/Tools.cpp.func.html @@ -0,0 +1,300 @@ + + + + + + + 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-10-17 16:45:00Functions:525791.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_121process_one_exception6updateEv216
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclEPKc1
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKSt9exception215
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsINS0_21process_one_exceptionEEEvOT_202
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsIRNS0_21process_one_exceptionEEEvOT_14
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_394754
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14389256
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2485982
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5106808
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_93
_ZN4PLMD5Tools12convertToAnyIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToAnyIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2480516
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3989194
_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_traitsIcESaIcEEE1612760
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14389256
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb19531
_ZN4PLMD5Tools14getWordsSimpleERNS_3gch12small_vectorISt17basic_string_viewIcSt11char_traitsIcEELj2ESaIS6_EEES6_1346572
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE72764
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE1117614
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_548654
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14389256
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe1208
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2480516
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj3989194
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl3
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm93
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx85
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy54
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE48254
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_2415311
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev202
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4356
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9118
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1489657
_ZN4PLMD5Tools5ltrimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1080
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i614907
_ZN4PLMD5Tools7bessel0ERKd0
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3319262
_ZN4PLMD5Tools8getWordsB5cxx11ESt17basic_string_viewIcSt11char_traitsIcEEPKcPiS6_RKb3540537
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13044
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_437876410
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc7128208
+
+
+ + + +
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 000000000..cb7222abb --- /dev/null +++ b/coverage/tools/Tools.cpp.gcov.html @@ -0,0 +1,596 @@ + + + + + + + LCOV - plumed test coverage - tools/Tools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25829288.4 %
Date:2024-10-17 16:45:00Functions: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    21983489 : bool Tools::convertToAny(const std::string & str,T & t) {
+      37    41480996 :   std::istringstream istr(str.c_str());
+      38    21983489 :   bool ok=static_cast<bool>(istr>>t);
+      39    21983489 :   if(!ok) return false;
+      40             :   std::string remaining;
+      41    21940845 :   istr>>remaining;
+      42    21940845 :   return remaining.length()==0;
+      43    21983489 : }
+      44             : 
+      45     2480516 : bool Tools::convertNoexcept(const std::string & str,int & t) {
+      46     2480516 :   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     3989194 : bool Tools::convertNoexcept(const std::string & str,unsigned & t) {
+      58     3989194 :   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     1117614 : 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     1117614 :   bool r=convertToAny(str,i);
+      74     1117614 :   if(r) a.setSerial(i);
+      75     1117614 :   return r;
+      76             : }
+      77             : 
+      78             : template<class T>
+      79     6469945 : bool Tools::convertToInt(const std::string & str,T & t) {
+      80             :   // First try standard conversion
+      81     6469945 :   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    14390464 : bool Tools::convertToReal(const std::string & str,T & t) {
+     116    14390464 :   if(convertToAny(str,t)) return true;
+     117       68046 :   if(str=="PI" || str=="+PI" || str=="+pi" || str=="pi") {
+     118        8551 :     t=pi; return true;
+     119       17046 :   } else if(str=="-PI" || str=="-pi") {
+     120        8464 :     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    14389256 : bool Tools::convertNoexcept(const std::string & str,double & t) {
+     157    14389256 :   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      548654 : bool Tools::convertNoexcept(const std::string & str,std::string & t) {
+     165             :   t=str;
+     166      548654 :   return true;
+     167             : }
+     168             : 
+     169     3540537 : std::vector<std::string> Tools::getWords(std::string_view line,const char* separators,int * parlevel,const char* parenthesis, const bool& delete_parenthesis) {
+     170     3540537 :   plumed_massert(std::strlen(parenthesis)==1,"multiple parenthesis type not available");
+     171     3540537 :   plumed_massert(parenthesis[0]=='(' || parenthesis[0]=='[' || parenthesis[0]=='{',
+     172             :                  "only ( [ { allowed as parenthesis");
+     173     3540537 :   if(!separators) separators=" \t\n";
+     174     3540537 :   const std::string sep(separators);
+     175     3540537 :   char openpar=parenthesis[0];
+     176             :   char closepar;
+     177             :   if(openpar=='(') closepar=')';
+     178     3540537 :   if(openpar=='[') closepar=']';
+     179     3540537 :   if(openpar=='{') closepar='}';
+     180             :   std::vector<std::string> words;
+     181             :   std::string word;
+     182             :   int parenthesisLevel=0;
+     183     3540537 :   if(parlevel) parenthesisLevel=*parlevel;
+     184   290335739 :   for(unsigned i=0; i<line.length(); i++) {
+     185             :     bool found=false;
+     186             :     bool onParenthesis=false;
+     187   286795202 :     if( (line[i]==openpar || line[i]==closepar) && delete_parenthesis ) onParenthesis=true;
+     188   286795202 :     if(line[i]==closepar) {
+     189        4120 :       parenthesisLevel--;
+     190        4120 :       plumed_assert(parenthesisLevel>=0) << "Extra closed parenthesis in '" << line << "'";
+     191             :     }
+     192  1163875234 :     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   286795202 :     if(!(parenthesisLevel==0 && (found||onParenthesis))) word.push_back(line[i]);
+     195             :     //if(onParenthesis) word.push_back(' ');
+     196   286795202 :     if(line[i]==openpar) parenthesisLevel++;
+     197   286795202 :     if(found && word.length()>0) {
+     198    17606279 :       if(!parlevel) plumed_assert(parenthesisLevel==0) << "Unmatching parenthesis in '" << line << "'";
+     199    17606279 :       words.push_back(word);
+     200             :       word.clear();
+     201             :     }
+     202             :   }
+     203     3540537 :   if(word.length()>0) {
+     204     3418841 :     if(!parlevel) plumed_assert(parenthesisLevel==0) << "Unmatching parenthesis in '" << line << "'";
+     205     3418841 :     words.push_back(word);
+     206             :   }
+     207     3540537 :   if(parlevel) *parlevel=parenthesisLevel;
+     208     3540537 :   return words;
+     209           0 : }
+     210             : 
+     211     1346572 : void Tools::getWordsSimple(gch::small_vector<std::string_view> & words,std::string_view line) {
+     212             :   words.clear();
+     213     1346572 :   auto ptr=line.data();
+     214     1346572 :   std::size_t size=0;
+     215    14499630 :   for(unsigned i=0; i<line.length(); i++) {
+     216    13153058 :     const bool is_separator=(line[i]==' ');
+     217    13153058 :     if(!is_separator) {
+     218    13111442 :       size++;
+     219       41616 :     } else if(size==0) {
+     220           0 :       ptr++;
+     221             :     } else {
+     222             :       words.emplace_back(ptr,size);
+     223       41616 :       ptr=&line[i]+1;
+     224       41616 :       size=0;
+     225             :     }
+     226             :   }
+     227     1346572 :   if(size>0) {
+     228             :     words.emplace_back(ptr,size);
+     229             :   }
+     230     1346572 : }
+     231             : 
+     232       19531 : bool Tools::getParsedLine(IFile& ifile,std::vector<std::string> & words, bool trimcomments) {
+     233       19531 :   std::string line("");
+     234             :   words.clear();
+     235             :   bool stat;
+     236             :   bool inside=false;
+     237       19531 :   int parlevel=0;
+     238             :   bool mergenext=false;
+     239       39973 :   while((stat=ifile.getline(line))) {
+     240       38953 :     if(trimcomments) trimComments(line);
+     241       38953 :     trim(line);
+     242       38953 :     if(line.length()==0) continue;
+     243       32460 :     std::vector<std::string> w=getWords(line,NULL,&parlevel,"{",trimcomments);
+     244       32460 :     if(!w.empty()) {
+     245       46003 :       if(inside && *(w.begin())=="...") {
+     246             :         inside=false;
+     247        1268 :         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        1268 :         plumed_massert(w.size()<=2,"terminating \"...\" lines cannot consist of more than two words");
+     249        1268 :         w.clear(); if(!trimcomments) words.push_back("...");
+     250       30903 :       } else if(*(w.end()-1)=="...") {
+     251             :         inside=true;
+     252             :         w.erase(w.end()-1);
+     253             :       };
+     254             :       int i0=0;
+     255       32171 :       if(mergenext && words.size()>0 && w.size()>0) {
+     256         128 :         words[words.size()-1]+=" "+w[0];
+     257             :         i0=1;
+     258             :       }
+     259      118249 :       for(unsigned i=i0; i<w.size(); ++i) words.push_back(w[i]);
+     260             :     }
+     261       32460 :     mergenext=(parlevel>0);
+     262       32460 :     if(!inside)break;
+     263       13949 :     if(!trimcomments && parlevel==0) words.push_back("@newline");
+     264       13949 :     else if(!trimcomments) words[words.size()-1] += " @newline";
+     265       32460 :   }
+     266       19531 :   plumed_massert(parlevel==0,"non matching parenthesis");
+     267       19531 :   if(words.size()>0) return true;
+     268             :   return stat;
+     269             : }
+     270             : 
+     271             : 
+     272     3319262 : bool Tools::getline(FILE* fp,std::string & line) {
+     273             :   line="";
+     274             :   const int bufferlength=1024;
+     275             :   char buffer[bufferlength];
+     276             :   bool ret;
+     277  3402243550 :   for(int i=0; i<bufferlength; i++) buffer[i]='\0';
+     278     3319262 :   while((ret=fgets(buffer,bufferlength,fp))) {
+     279     3318162 :     line.append(buffer);
+     280     3318162 :     unsigned ss=std::strlen(buffer);
+     281     3318162 :     if(ss>0) if(buffer[ss-1]=='\n') break;
+     282             :   };
+     283     3319262 :   if(line.length()>0) if(*(line.end()-1)=='\n') line.erase(line.end()-1);
+     284     3319262 :   if(line.length()>0) if(*(line.end()-1)=='\r') line.erase(line.end()-1);
+     285     3319262 :   return ret;
+     286             : }
+     287             : 
+     288     1489657 : void Tools::trim(std::string & s) {
+     289     1489657 :   auto n=s.find_last_not_of(" \t");
+     290     1489657 :   if(n!=std::string::npos) s.resize(n+1);
+     291     1489657 : }
+     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     1612760 : void Tools::trimComments(std::string & s) {
+     302     1612760 :   auto n=s.find_first_of("#");
+     303     1612760 :   if(n!=std::string::npos) s.resize(n);
+     304     1612760 : }
+     305             : 
+     306     2415311 : bool Tools::caseInSensStringCompare(const std::string & str1, const std::string &str2)
+     307             : {
+     308     2415311 :   return ((str1.size() == str2.size()) && std::equal(str1.begin(), str1.end(), str2.begin(), [](char c1, char c2) {
+     309     7128208 :     return (c1 == c2 || std::toupper(c1) == std::toupper(c2));
+     310     2415311 :   }));
+     311             : }
+     312             : 
+     313      614907 : bool Tools::getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep) {
+     314             :   s.clear();
+     315     2515676 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     316     2415245 :     if((*p).length()==0) continue;
+     317     2415245 :     std::string x=(*p).substr(0,key.length());
+     318     2415245 :     if(caseInSensStringCompare(x,key)) {
+     319      514476 :       if((*p).length()==key.length())return false;
+     320      514475 :       std::string tmp=(*p).substr(key.length(),(*p).length());
+     321             :       line.erase(p);
+     322             :       s=tmp;
+     323      514475 :       const std::string multi("@replicas:");
+     324      514475 :       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       48254 : void Tools::interpretRanges(std::vector<std::string>&s) {
+     337             :   std::vector<std::string> news;
+     338      612215 :   for(const auto & p :s) {
+     339      563961 :     news.push_back(p);
+     340      563961 :     size_t dash=p.find("-");
+     341      564626 :     if(dash==std::string::npos) continue;
+     342             :     int first;
+     343        6066 :     if(!Tools::convertToAny(p.substr(0,dash),first)) continue;
+     344        2368 :     int stride=1;
+     345             :     int second;
+     346        2368 :     size_t colon=p.substr(dash+1).find(":");
+     347        2368 :     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        4606 :       if(!Tools::convertToAny(p.substr(dash+1),second)) continue;
+     352             :     }
+     353        2368 :     news.resize(news.size()-1);
+     354        2368 :     if(first<=second) {
+     355        2367 :       plumed_massert(stride>0,"interpreting ranges "+ p + ", stride should be positive");
+     356      566151 :       for(int i=first; i<=second; i+=stride) {
+     357             :         std::string ss;
+     358      563784 :         convert(i,ss);
+     359      563784 :         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       48254 :   s=news;
+     371       48254 : }
+     372             : 
+     373       72764 : void Tools::interpretLabel(std::vector<std::string>&s) {
+     374       72764 :   if(s.size()<2)return;
+     375       72425 :   std::string s0=s[0];
+     376       72425 :   unsigned l=s0.length();
+     377       72425 :   if(l<1) return;
+     378       72425 :   if(s0[l-1]==':') {
+     379             :     s[0]=s[1];
+     380      135806 :     s[1]="LABEL="+s0.substr(0,l-1);
+     381             :   }
+     382       72425 :   std::transform(s[0].begin(), s[0].end(), s[0].begin(), ::toupper);
+     383             : }
+     384             : 
+     385        9118 : std::vector<std::string> Tools::ls(const std::string&d) {
+     386             :   std::vector<std::string> result;
+     387      146410 :   for (auto const& dir_entry : std::filesystem::directory_iterator{d}) {
+     388      357168 :     result.push_back(dir_entry.path().filename());
+     389             :   }
+     390        9118 :   return result;
+     391           0 : }
+     392             : 
+     393        4356 : void Tools::stripLeadingAndTrailingBlanks( std::string& str ) {
+     394        4356 :   std::size_t first=str.find_first_not_of(' ');
+     395        4356 :   std::size_t last=str.find_last_not_of(' ');
+     396        8675 :   if( first<=last && first!=std::string::npos) str=str.substr(first,last+1);
+     397        4356 : }
+     398             : 
+     399       13044 : std::string Tools::extension(const std::string&s) {
+     400       13044 :   size_t n=s.find_last_of(".");
+     401             :   std::string ext;
+     402       13044 :   if(n!=std::string::npos && n+1<s.length() && n+5>=s.length()) {
+     403        9276 :     ext=s.substr(n+1);
+     404        9276 :     if(ext.find("/")!=std::string::npos) ext="";
+     405        9276 :     std::string base=s.substr(0,n);
+     406        9276 :     if(base.length()==0) ext="";
+     407        9276 :     if(base.length()>0 && base[base.length()-1]=='/') ext="";
+     408             :   }
+     409       13044 :   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   437876410 : bool Tools::startWith(const std::string & full,const std::string &start) {
+     423   437876410 :   return (full.substr(0,start.length())==start);
+     424             : }
+     425             : 
+     426      394754 : bool Tools::findKeyword(const std::vector<std::string>&line,const std::string&key) {
+     427      394754 :   const std::string search(key+"=");
+     428   433044672 :   for(const auto & p : line) {
+     429   432797995 :     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         216 :   void update() {
+     462         216 :     if(!first) msg+="\n\nThe above exception was the direct cause of the following exception:\n";
+     463         216 :     first=false;
+     464         216 :   }
+     465             : public:
+     466         202 :   process_one_exception(std::string & msg):
+     467         202 :     msg(msg)
+     468             :   {}
+     469         215 :   void operator()(const std::exception & e) {
+     470         215 :     update();
+     471         215 :     msg+=e.what();
+     472         215 :   }
+     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         216 : static void process_all_exceptions(T&& f) {
+     485             :   try {
+     486             :     // First throw the current exception
+     487         216 :     throw;
+     488         230 :   } 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         402 :   } catch(const std::exception &e) {
+     499             :     // If not nested, we end recursion
+     500         201 :     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         216 : }
+     511             : 
+     512             : }
+     513             : 
+     514         202 : std::string Tools::concatenateExceptionMessages() {
+     515             :   std::string msg;
+     516         202 :   process_all_exceptions(process_one_exception(msg));
+     517         202 :   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 000000000..41c95e8e1 --- /dev/null +++ b/coverage/tools/Tools.h.func-sort-c.html @@ -0,0 +1,296 @@ + + + + + + + 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-10-17 16:45:00Functions:515691.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_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
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_78
_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_961
_ZN4PLMD5Tools5parseIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i1080
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_1107
_ZN4PLMD5Tools10unique2rawINS_5ValueEEESt6vectorIPT_SaIS5_EERKS3_ISt10unique_ptrIS4_St14default_deleteIS4_EESaISB_EE1788
_ZN4PLMDL18dp2cutoffNoStretchEv5719
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5782
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5933
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_7065
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i7929
_ZN4PLMD5Tools22FastStringUnorderedMapIiEC2ESt16initializer_listISt4pairIKSt17basic_string_viewIcSt11char_traitsIcEEiEE10731
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEE4convESt17basic_string_viewIcSt11char_traitsIcEE13722
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE17265
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi17760
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19781
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_19781
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE28739
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32339
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_32339
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i33927
_ZN4PLMD5Tools16removeDuplicatesIjEEvRSt6vectorIT_SaIS3_EE74837
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi97415
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb98171
_ZN4PLMD5Tools11parseVectorIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi140300
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i310360
_ZN4PLMD5Tools22FastStringUnorderedMapIiE4convESt17basic_string_viewIcSt11char_traitsIcEE478028
_ZN4PLMD5Tools22FastStringUnorderedMapIiEixERKSt17basic_string_viewIcSt11char_traitsIcEE478028
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE778400
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_778400
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2474943
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEEixERKSt17basic_string_viewIcSt11char_traitsIcEE3028048
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6325149
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_6325149
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_14175048
_ZN4PLMD5Tools7fastpowEdi56252767
_ZN4PLMD5Tools3pbcEd1784362618
+
+
+ + + +
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 000000000..c54fcb0ae --- /dev/null +++ b/coverage/tools/Tools.h.func.html @@ -0,0 +1,296 @@ + + + + + + + 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-10-17 16:45:00Functions:515691.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_EEi97415
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi17760
_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_EEi140300
_ZN4PLMD5Tools11parseVectorIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE28739
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32339
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE778400
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6325149
_ZN4PLMD5Tools15convertNoexceptIlEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19781
_ZN4PLMD5Tools15convertNoexceptIxEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE17265
_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_traitsIcEE13722
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEEixERKSt17basic_string_viewIcSt11char_traitsIcEE3028048
_ZN4PLMD5Tools22FastStringUnorderedMapIiE4convESt17basic_string_viewIcSt11char_traitsIcEE478028
_ZN4PLMD5Tools22FastStringUnorderedMapIiEC2ESt16initializer_listISt4pairIKSt17basic_string_viewIcSt11char_traitsIcEEiEE10731
_ZN4PLMD5Tools22FastStringUnorderedMapIiEixERKSt17basic_string_viewIcSt11char_traitsIcEE478028
_ZN4PLMD5Tools3pbcEd1784362618
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i310360
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i33927
_ZN4PLMD5Tools5parseIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i1080
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i7929
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5933
_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_7065
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_14175048
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2474943
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_1107
_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_78
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_961
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_32339
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_778400
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_6325149
_ZN4PLMD5Tools7convertIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_19781
_ZN4PLMD5Tools7convertIxNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7fastpowEdi56252767
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb98171
_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 000000000..26250e43b --- /dev/null +++ b/coverage/tools/Tools.h.gcov.html @@ -0,0 +1,595 @@ + + + + + + + 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-10-17 16:45:00Functions:515691.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_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    23820685 :   static void convert(const T & t,U & u) {
+     151    23821725 :     plumed_assert(convertNoexcept(t,u)) <<"Error converting  "<<t;
+     152    23820684 :   }
+     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      152250 :     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      806704 :   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      491750 :     std::unique_ptr<const char[]> conv(std::string_view str) {
+     275      491750 :       auto p=std::make_unique<char[]>(str.size()+1);
+     276             :       std::memcpy(p.get(), str.data(), str.size()+1);
+     277      491750 :       return p;
+     278             :     }
+     279             : 
+     280             :   public:
+     281             : 
+     282             :     FastStringUnorderedMap() = default;
+     283       10731 :     FastStringUnorderedMap(std::initializer_list<std::pair<const std::string_view,T>> init) {
+     284      488759 :       for(const auto & c : init) {
+     285      478028 :         (*this)[c.first]=c.second;
+     286             :       }
+     287       10731 :     }
+     288             : 
+     289     3506076 :     T& operator[]( const std::string_view & key ) {
+     290             :       auto f=map.find(key);
+     291     3506076 :       if(f!=map.end()) return f->second;
+     292      983500 :       keys.push_back(conv(key));
+     293      491750 :       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         125 :       while (in_progress[key] > 0) {
+     327             :         // Wait if this command is already in progress.
+     328         102 :         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.section=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      359350 : bool Tools::parse(std::vector<std::string>&line,const std::string&key,T&val,int rep) {
+     390             :   std::string s;
+     391      718700 :   if(!getKey(line,key+"=",s,rep)) return false;
+     392      281175 :   if(s.length()>0 && !convertNoexcept(s,val))return false;
+     393             :   return true;
+     394             : }
+     395             : 
+     396             : template <class T>
+     397      255557 : bool Tools::parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep) {
+     398             :   std::string s;
+     399      511114 :   if(!getKey(line,key+"=",s,rep)) return false;
+     400             :   val.clear();
+     401      233300 :   std::vector<std::string> words=getWords(s,"\t\n ,");
+     402     4663016 :   for(unsigned i=0; i<words.size(); ++i) {
+     403             :     T v;
+     404     4429716 :     std::string s=words[i];
+     405     4429716 :     const std::string multi("@replicas:");
+     406     4429716 :     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     4429716 :     if(!convertNoexcept(s,v))return false;
+     413     4429716 :     val.push_back(v);
+     414             :   }
+     415             :   return true;
+     416      233300 : }
+     417             : 
+     418             : template<typename T>
+     419       92102 : void Tools::removeDuplicates(std::vector<T>& vec)
+     420             : {
+     421       92102 :   std::sort(vec.begin(), vec.end());
+     422       92102 :   vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
+     423       92102 : }
+     424             : 
+     425             : inline
+     426       98171 : bool Tools::parseFlag(std::vector<std::string>&line,const std::string&key,bool&val) {
+     427      696966 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     428      610719 :     if(key==*p) {
+     429       11924 :       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  1784362618 : 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  1784362618 :     const double y=x+offset;
+     448  1784362618 :     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     7155669 : bool Tools::convertNoexcept(T i,std::string & str) {
+     458     7155669 :   std::ostringstream ostr;
+     459      778400 :   ostr<<i;
+     460     7155669 :   str=ostr.str();
+     461     7155669 :   return true;
+     462     7155669 : }
+     463             : 
+     464             : inline
+     465    56252767 : double Tools::fastpow(double base, int exp)
+     466             : {
+     467    56252767 :   if(exp<0) {
+     468           0 :     exp=-exp;
+     469           0 :     base=1.0/base;
+     470             :   }
+     471             :   double result = 1.0;
+     472   289015368 :   while (exp)
+     473             :   {
+     474   199162409 :     if (exp & 1)
+     475   140896039 :       result *= base;
+     476   199162409 :     exp >>= 1;
+     477   199162409 :     base *= base;
+     478             :   }
+     479             : 
+     480    56252767 :   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
+
+
+
+ + + + +
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 000000000..980f189c3 --- /dev/null +++ b/coverage/tools/Torsion.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-10-17 16:45:00Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1294094
+
+
+ + + +
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 000000000..1b890247b --- /dev/null +++ b/coverage/tools/Torsion.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-10-17 16:45:00Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1294094
+
+
+ + + +
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 000000000..365ae1ca1 --- /dev/null +++ b/coverage/tools/Torsion.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-10-17 16:45:00Functions: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     1294094 : double Torsion::compute(const Vector& v1,const Vector& v2,const Vector& v3,Vector& d1,Vector& d2,Vector& d3)const {
+      40             : 
+      41     1294094 :   const double modv2(1./v2.modulo());
+      42     1294094 :   const Vector nv2(v2*modv2);
+      43     1294094 :   const Tensor dnv2_v2((Tensor::identity()-extProduct(nv2,nv2))*modv2);
+      44             : 
+      45     1294094 :   const Vector a(crossProduct(v2,v1));
+      46     1294094 :   const Tensor da_dv2(dcrossDv1(v2,v1));
+      47     1294094 :   const Tensor da_dv1(dcrossDv2(v2,v1));
+      48     1294094 :   const Vector b(crossProduct(v3,v2));
+      49     1294094 :   const Tensor db_dv3(dcrossDv1(v3,v2));
+      50     1294094 :   const Tensor db_dv2(dcrossDv2(v3,v2));
+      51     1294094 :   const double cosangle=dotProduct(a,b);
+      52     1294094 :   const Vector dcosangle_dv1=matmul(b,da_dv1);
+      53     1294094 :   const Vector dcosangle_dv2=matmul(b,da_dv2) + matmul(a,db_dv2);
+      54     1294094 :   const Vector dcosangle_dv3=matmul(a,db_dv3);
+      55             : 
+      56     1294094 :   const Vector cab(crossProduct(a,b));
+      57     1294094 :   const Tensor dcab_dv1(matmul(dcrossDv1(a,b),da_dv1));
+      58     1294094 :   const Tensor dcab_dv2(matmul(dcrossDv1(a,b),da_dv2) + matmul(dcrossDv2(a,b),db_dv2));
+      59     1294094 :   const Tensor dcab_dv3(matmul(dcrossDv2(a,b),db_dv3));
+      60             : 
+      61     1294094 :   const double sinangle=dotProduct(cab,nv2);
+      62     1294094 :   const Vector dsinangle_dv1=matmul(nv2,dcab_dv1);
+      63     1294094 :   const Vector dsinangle_dv2=matmul(nv2,dcab_dv2)+matmul(cab,dnv2_v2);
+      64     1294094 :   const Vector dsinangle_dv3=matmul(nv2,dcab_dv3);
+      65             : 
+      66     1294094 :   const double torsion=std::atan2(-sinangle,cosangle);
+      67             : // this is required since v1 and v3 are not normalized:
+      68     1294094 :   const double invR2=1.0/(cosangle*cosangle+sinangle*sinangle);
+      69             : 
+      70     1294094 :   d1= ( -dsinangle_dv1*cosangle + sinangle * dcosangle_dv1 ) *invR2;
+      71     1294094 :   d2= ( -dsinangle_dv2*cosangle + sinangle * dcosangle_dv2 ) *invR2;
+      72     1294094 :   d3= ( -dsinangle_dv3*cosangle + sinangle * dcosangle_dv3 ) *invR2;
+      73             : 
+      74     1294094 :   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 000000000..8e8807401 --- /dev/null +++ b/coverage/tools/Tree.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..778f95ed7 --- /dev/null +++ b/coverage/tools/Tree.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..ceb1ff34d --- /dev/null +++ b/coverage/tools/Tree.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a97304cdf --- /dev/null +++ b/coverage/tools/Tree.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..20b81d59b --- /dev/null +++ b/coverage/tools/Tree.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4ceeaac6f --- /dev/null +++ b/coverage/tools/Tree.h.gcov.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..5acfc0d7d --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev48
_ZN4PLMD11TypesafePtr11fromSafePtrEPv20092
_ZNK4PLMD11TypesafePtr4copyEv993725
+
+
+ + + +
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 000000000..15f59d663 --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-10-17 16:45:00Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr11fromSafePtrEPv20092
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev48
_ZNK4PLMD11TypesafePtr4copyEv993725
+
+
+ + + +
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 000000000..66c40a2e8 --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.gcov.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-10-17 16:45:00Functions: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       20092 : TypesafePtr TypesafePtr::fromSafePtr(void* safe) {
+      30             :   auto s=(plumed_safeptr_x*)safe;
+      31       20092 :   return TypesafePtr(const_cast<void*>(s->ptr), s->nelem, s->shape, s->flags);
+      32             : }
+      33             : 
+      34      993725 : TypesafePtr TypesafePtr::copy() const {
+      35      993725 :   auto passbyvalue=((flags>>25)&0x7)==1;
+      36      993725 :   if(passbyvalue) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object passed by value";
+      37      993725 :   auto forbidstore=flags&0x10000000;
+      38      993727 :   if(forbidstore) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object for which this was forbidden";
+      39             :   TypesafePtr ret;
+      40      993723 :   ret.ptr=ptr;
+      41      993723 :   ret.flags=flags;
+      42      993723 :   ret.nelem=nelem;
+      43      993723 :   ret.shape=shape;
+      44      993723 :   return ret;
+      45             : }
+      46             : 
+      47          48 : 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          48 :   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 000000000..a044bf701 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func-sort-c.html @@ -0,0 +1,312 @@ + + + + + + + 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:12313293.2 %
Date:2024-10-17 16:45:00Functions:446073.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_listINS0_8SizeLikeEE0
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listINS0_8SizeLikeEE0
_ZNK4PLMD11TypesafePtr3getIPiEET_St16initializer_listINS0_8SizeLikeEE0
_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_strB5cxx11Ev7
_ZNK4PLMD11TypesafePtr3getIPlEET_St16initializer_listINS0_8SizeLikeEE17
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr3setIlEEvT_149
_ZN4PLMD17typesafePtrSizeofIlEEmv166
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb166
_ZNK4PLMD11TypesafePtr3getIPKiEET_St16initializer_listINS0_8SizeLikeEE988
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb1010
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1743
_ZNK4PLMD11TypesafePtr10getCStringEv3156
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb3156
_ZNK4PLMD11TypesafePtr3getIPKPKcEET_St16initializer_listINS0_8SizeLikeEE5264
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb5264
_ZNK4PLMD11TypesafePtr3setIiEEvT_5687
_ZN4PLMD11TypesafePtrC2EimPKm6965
_ZNK4PLMD11TypesafePtr3setIdEEvT_7268
_ZN4PLMD11TypesafePtrC2EdmPKm7529
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv8055
_ZN4PLMD17typesafePtrSizeofIKcEEmv8345
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv24965
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb25953
_ZN4PLMD17typesafePtrSizeofIKiEEmv26000
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv217415
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listINS0_8SizeLikeEE257633
_ZN4PLMD11TypesafePtrC2ExmPKm264805
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv265887
_ZN4PLMD17typesafePtrSizeofIKxEEmv268744
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv268744
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb268744
_ZN4PLMD17typesafePtrSizeofIiEEmv271567
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb271574
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv354106
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listINS0_8SizeLikeEE395430
_ZN4PLMD17typesafePtrSizeofIdEEmv482912
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb483059
_ZN4PLMD17typesafePtrSizeofIKdEEmv757314
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb757591
_ZN4PLMD11TypesafePtraSEOS0_993723
_ZN4PLMD11TypesafePtr10init_shapeEPKm1422372
_ZN4PLMDL20typesafePtrSkipCheckEv1821533
+
+
+ + + +
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 000000000..304e27822 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func.html @@ -0,0 +1,312 @@ + + + + + + + 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:12313293.2 %
Date:2024-10-17 16:45:00Functions:446073.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr10init_shapeEPKm1422372
_ZN4PLMD11TypesafePtrC2EdmPKm7529
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD11TypesafePtrC2EimPKm6965
_ZN4PLMD11TypesafePtrC2EjmPKm4
_ZN4PLMD11TypesafePtrC2ExmPKm264805
_ZN4PLMD11TypesafePtraSEOS0_993723
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKcEEmv8345
_ZN4PLMD17typesafePtrSizeofIKdEEmv757314
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKiEEmv26000
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_ZN4PLMD17typesafePtrSizeofIKlEEmv0
_ZN4PLMD17typesafePtrSizeofIKxEEmv268744
_ZN4PLMD17typesafePtrSizeofIdEEmv482912
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZN4PLMD17typesafePtrSizeofIiEEmv271567
_ZN4PLMD17typesafePtrSizeofIlEEmv166
_ZN4PLMDL20typesafePtrSkipCheckEv1821533
_ZNK4PLMD11TypesafePtr10getCStringEv3156
_ZNK4PLMD11TypesafePtr3getIPKPKcEET_St16initializer_listINS0_8SizeLikeEE5264
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv354106
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listINS0_8SizeLikeEE395430
_ZNK4PLMD11TypesafePtr3getIPKfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPKfEET_St16initializer_listINS0_8SizeLikeEE0
_ZNK4PLMD11TypesafePtr3getIPKiEET_St16initializer_listINS0_8SizeLikeEE988
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv217415
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listINS0_8SizeLikeEE257633
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listINS0_8SizeLikeEE0
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv265887
_ZNK4PLMD11TypesafePtr3getIPiEET_St16initializer_listINS0_8SizeLikeEE0
_ZNK4PLMD11TypesafePtr3getIPlEET_St16initializer_listINS0_8SizeLikeEE17
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv8055
_ZNK4PLMD11TypesafePtr3getIfEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv24965
_ZNK4PLMD11TypesafePtr3getIjEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv268744
_ZNK4PLMD11TypesafePtr3setIdEEvT_7268
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr3setIiEEvT_5687
_ZNK4PLMD11TypesafePtr3setIlEEvT_149
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb1010
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb5264
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb3156
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb757591
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb25953
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1743
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb268744
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb483059
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb271574
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb166
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev7
+
+
+ + + +
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 000000000..99615b71b --- /dev/null +++ b/coverage/tools/TypesafePtr.h.gcov.html @@ -0,0 +1,501 @@ + + + + + + + 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:12313293.2 %
Date:2024-10-17 16:45:00Functions:446073.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             : #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 <limits>
+      38             : #include <initializer_list>
+      39             : #include <algorithm>
+      40             : 
+      41             : namespace PLMD {
+      42             : 
+      43     1821533 : static inline bool typesafePtrSkipCheck() {
+      44     1821533 :   static const bool ret=std::getenv("PLUMED_TYPESAFE_IGNORE");
+      45     1821533 :   return ret;
+      46             : }
+      47             : 
+      48             : template<class T>
+      49     1815049 : std::size_t typesafePtrSizeof() {
+      50     1815049 :   return sizeof(T);
+      51             : }
+      52             : 
+      53             : template<>
+      54             : inline
+      55             : std::size_t typesafePtrSizeof<void>() {
+      56             :   return 0;
+      57             : }
+      58             : 
+      59             : template<>
+      60             : inline
+      61             : std::size_t typesafePtrSizeof<const void>() {
+      62             :   return 0;
+      63             : }
+      64             : 
+      65             : /**
+      66             : \ingroup TOOLBOX
+      67             : Class to deal with propoagation of typesafe pointers.
+      68             : 
+      69             : */
+      70             : class TypesafePtr {
+      71             :   /// Small structure used to pass elements of a shape initializer_list
+      72             :   struct SizeLike {
+      73             :     std::size_t size;
+      74             :     SizeLike(short unsigned size): size(size) {}
+      75      653080 :     SizeLike(unsigned size): size(size) {}
+      76         988 :     SizeLike(long unsigned size): size(size) {}
+      77             :     SizeLike(long long unsigned size): size(size) {}
+      78             :     SizeLike(short size): size(std::size_t(size)) {}
+      79        5264 :     SizeLike(int size): size(std::size_t(size)) {}
+      80             :     SizeLike(long int size): size(std::size_t(size)) {}
+      81             :     SizeLike(long long int size): size(std::size_t(size)) {}
+      82             :   };
+      83             : 
+      84     1422372 :   inline void init_shape(const std::size_t* shape) {
+      85     1422372 :     this->shape[0]=0;
+      86     1422372 :     if(shape && *shape>0) {
+      87             :       std::size_t nelem_=1;
+      88             :       unsigned i=0;
+      89     1043499 :       for(i=0; i<this->shape.size(); i++) {
+      90     1043499 :         this->shape[i]=*shape;
+      91     1043499 :         if(*shape==0) break;
+      92      650459 :         nelem_*=*shape;
+      93      650459 :         shape++;
+      94             :       }
+      95      393040 :       plumed_assert(i<this->shape.size()); // check that last element is actually zero
+      96      393040 :       if(nelem==0) nelem=nelem_;
+      97      393040 :       plumed_assert(nelem==nelem_) << "Inconsistent shape/nelem";
+      98             :     }
+      99     1422372 :   }
+     100             : 
+     101             :   static std::string extra_msg();
+     102             : 
+     103             : public:
+     104             : 
+     105             :   TypesafePtr(void* ptr, std::size_t nelem, const std::size_t* shape, std::size_t flags):
+     106      407209 :     ptr(ptr),
+     107      407209 :     nelem(nelem),
+     108      407209 :     flags(flags)
+     109             :   {
+     110      407209 :     buffer[0]='\0';
+     111      407209 :     init_shape(shape);
+     112             :   }
+     113             : 
+     114             :   static const unsigned maxrank=4;
+     115             :   static TypesafePtr fromSafePtr(void* safe);
+     116             :   static TypesafePtr setNelemAndShape(const TypesafePtr &other, std::size_t nelem, const std::size_t* shape) {
+     117      386760 :     return TypesafePtr(other.ptr,nelem,shape,other.flags);
+     118             :   }
+     119             :   static TypesafePtr unchecked(const void* ptr) {
+     120             :     return TypesafePtr(const_cast<void*>(ptr),0,nullptr,0);
+     121             :   }
+     122             :   static constexpr unsigned short is_integral=3;
+     123             :   static constexpr unsigned short is_floating_point=4;
+     124             :   static constexpr unsigned short is_file=5;
+     125             : 
+     126     1800403 :   TypesafePtr() {
+     127     1800403 :     shape[0]=0;
+     128     1800403 :     buffer[0]='\0';
+     129             :   }
+     130             : 
+     131             :   TypesafePtr(std::nullptr_t)
+     132      294297 :   {
+     133      294297 :     shape[0]=0;
+     134      287341 :     buffer[0]='\0';
+     135             :   }
+     136             : 
+     137             : /// Macro that generate a constructor with given type and flags
+     138             : #define __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type,type_,flags_) \
+     139             :   TypesafePtr(type_*ptr, std::size_t nelem=0, const std::size_t* shape=nullptr) : \
+     140             :     ptr((void*)const_cast<type*>(ptr)), \
+     141             :     nelem(nelem), \
+     142             :     flags(flags_) \
+     143             :   { \
+     144             :     init_shape(shape); \
+     145             :     buffer[0]='\0'; \
+     146             :   }
+     147             : 
+     148             : /// Macro that uses __PLUMED_WRAPPER_TYPESAFEPTR_INNER to generate constructors with
+     149             : /// all possible pointer-const combinations
+     150             : #define __PLUMED_WRAPPER_TYPESAFEPTR(type, code,size) \
+     151             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type, type,             size | (0x10000*(code)) | (0x2000000*2)) \
+     152             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type, type const,       size | (0x10000*(code)) | (0x2000000*3)) \
+     153             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type*,            size | (0x10000*(code)) | (0x2000000*4)) \
+     154             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type*const,       size | (0x10000*(code)) | (0x2000000*5)) \
+     155             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type const*,      size | (0x10000*(code)) | (0x2000000*6)) \
+     156             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type const*const, size | (0x10000*(code)) | (0x2000000*7))
+     157             : 
+     158             : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
+     159             : #define __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_TYPESAFEPTR(type,code,0)
+     160             : 
+     161             : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
+     162             : /// In addition to generating constructors with all pointer types, it generates a constructor to
+     163             : /// allow pass-by-value
+     164             : #define __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(type,code) \
+     165             :   __PLUMED_WRAPPER_TYPESAFEPTR(type,code,sizeof(type)) \
+     166             :   TypesafePtr(type val, std::size_t nelem=0, const std::size_t* shape=nullptr): \
+     167             :       nelem(1), \
+     168             :       flags(sizeof(type) | (0x10000*(code)) | (0x2000000*1)) \
+     169             :     { \
+     170             :     plumed_assert(sizeof(type)<=32); \
+     171             :     ptr=&buffer[0]; \
+     172             :     flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+     173             :     std::memcpy(&buffer[0],&val,sizeof(type)); \
+     174             :     init_shape(shape); \
+     175             :   }
+     176             : 
+     177             : /// Here we create all the required instances
+     178             : /// 1: void
+     179             : /// 3: integral
+     180             : /// 4: floating
+     181             : /// 5: FILE
+     182             : /// 0x100: unsigned
+     183        1231 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(void,1)
+     184        2145 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
+     185             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(signed char,3)
+     186             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned char,0x100+3)
+     187             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(short,3)
+     188             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned short,0x100+3)
+     189      286255 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(int,3)
+     190         102 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned int,0x100+3)
+     191          94 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long,3)
+     192             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long,0x100+3)
+     193      264805 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long long,3)
+     194        3939 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long long,0x100+3)
+     195           0 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(float,4)
+     196      327338 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(double,4)
+     197             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long double,4)
+     198         993 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(FILE,5)
+     199             : 
+     200             :   ~TypesafePtr() {
+     201     3095693 :   }
+     202             : 
+     203             : 
+     204             :   TypesafePtr(const TypesafePtr&other) = delete;
+     205             : 
+     206             :   TypesafePtr & operator=(const TypesafePtr & other) = delete;
+     207             : 
+     208             :   TypesafePtr(TypesafePtr&&other):
+     209             :     buffer(other.buffer),
+     210             :     ptr(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr),
+     211             :     nelem(other.nelem),
+     212             :     shape(other.shape),
+     213             :     flags(other.flags)
+     214             :   {
+     215             :     other.ptr=nullptr;
+     216             :   }
+     217             : 
+     218             :   TypesafePtr copy() const;
+     219             : 
+     220      993723 :   TypesafePtr & operator=(TypesafePtr && other) {
+     221      993723 :     ptr=(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr);
+     222      993723 :     flags=other.flags;
+     223      993723 :     nelem=other.nelem;
+     224      993723 :     shape=other.shape;
+     225      993723 :     buffer=other.buffer;
+     226      993723 :     other.ptr=nullptr;
+     227      993723 :     return *this;
+     228             :   }
+     229             : 
+     230           7 :   std::string type_str() const {
+     231           7 :     auto type=(flags>>16)&0xff;
+     232           7 :     if(type==0) return "wildcard";
+     233           2 :     if(type==1) return "void";
+     234           0 :     if(type==2) return "integral";
+     235           0 :     if(type==3) return "integral";
+     236           5 :     if(type==4) return "floating point";
+     237           0 :     if(type==5) return "FILE";
+     238           0 :     return "unknown";
+     239             :   }
+     240             : 
+     241             : private:
+     242             : 
+     243             :   template<typename T>
+     244     1818377 :   T* get_priv(std::size_t nelem, const std::size_t* shape, bool byvalue) const {
+     245             : 
+     246     1818377 :     if(typesafePtrSkipCheck()) return (T*) ptr;
+     247             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     248     1818377 :     if(flags==0) return (T*) ptr; // no check
+     249     1816061 :     auto size=flags&0xffff;
+     250     1816061 :     auto type=(flags>>16)&0xff;
+     251             :     // auto unsi=(flags>>24)&0x1; // ignored
+     252     1817804 :     auto cons=(flags>>25)&0x7;
+     253             : 
+     254             :     // type=0: ignore check
+     255             :     // type>5: undefined yet
+     256     1816061 :     if(type!=0 && type<=5) {
+     257      574822 :       if(std::is_integral<T_noptr>::value && (type!=is_integral)) {
+     258          24 :         throw ExceptionTypeError() <<"This command expects an integer type. Received a " << type_str() << " instead"<<extra_msg();
+     259             :       }
+     260     1240228 :       if(std::is_floating_point<T_noptr>::value && (type!=is_floating_point)) {
+     261           4 :         throw ExceptionTypeError() <<"This command expects a floating point type. Received a " << type_str() << " instead"<<extra_msg();
+     262             :       }
+     263        1010 :       if(std::is_same<FILE,typename std::remove_const<T_noptr>::type>::value && (type!=is_file)) {
+     264           0 :         throw ExceptionTypeError() <<"This command expects a FILE. Received a " << type_str() << " instead"<<extra_msg();
+     265             :       }
+     266             :     }
+     267             : 
+     268     1816054 :     if(size>0 && typesafePtrSizeof<T_noptr>() >0 && typesafePtrSizeof<T_noptr>()!=size) {
+     269          24 :       throw ExceptionTypeError() << "This command expects a type with size " << typesafePtrSizeof<T_noptr>() << ". Received type has size " << size << " instead"<<extra_msg();
+     270             :     }
+     271             : 
+     272     1817791 :     if(!byvalue) if(cons==1) {
+     273           3 :         throw ExceptionTypeError() << "This command is trying to take the address of an argument that was passed by value"<<extra_msg();
+     274             :       }
+     275             : 
+     276             :     // cons==1 (by value) is here treated as cons==3 (const type*)
+     277     1812526 :     if(cons>0) {
+     278             :       if(!std::is_pointer<T>::value) {
+     279             :         if(std::is_void<T>::value) {
+     280        1743 :           if(cons==1) {
+     281           0 :             throw ExceptionTypeError() << "This command expects a void pointer. It received a value instead"<<extra_msg();
+     282             :           }
+     283             :         } else {
+     284     1810667 :           if(cons!=1 && cons!=2 && cons!=3) {
+     285           0 :             throw ExceptionTypeError() << "This command expects a pointer or a value. It received a pointer-to-pointer instead"<<extra_msg();
+     286             :           }
+     287             :         }
+     288             :         if(!std::is_const<T>::value) {
+     289      755655 :           if(cons==3) {
+     290           6 :             throw ExceptionTypeError() << "This command expects a modifiable pointer (T*). It received a non modifiable pointer instead (const T*)"<<extra_msg();
+     291      755653 :           } else if(cons==1) {
+     292           0 :             throw ExceptionTypeError() << "This command expects a modifiable pointer (T*). It received a value instead (T)"<<extra_msg();
+     293             :           }
+     294             :         }
+     295             :       } else {
+     296             :         if(!std::is_const<T>::value) {
+     297         116 :           if(cons==1) throw ExceptionTypeError() << "This command expects a pointer-to-pointer. It received a value intead"<<extra_msg();
+     298         116 :           if(cons==2 || cons==3) throw ExceptionTypeError() << "This command expects a pointer-to-pointer. It received a pointer intead"<<extra_msg();
+     299             :           if(!std::is_const<T_noptr>::value) {
+     300             :             if(cons!=4) throw ExceptionTypeError() << "This command expects a modifiable pointer-to-pointer (T**)"<<extra_msg();
+     301             :           } else {
+     302         116 :             if(cons!=6) throw ExceptionTypeError() << "This command expects a modifiable pointer to unmodifiable pointer (const T**)"<<extra_msg();
+     303             :           }
+     304             :         } else {
+     305             :           if(!std::is_const<T_noptr>::value) {
+     306             :             if(cons!=4 && cons!=5) throw ExceptionTypeError() << "This command expects T*const* pointer, and can only receive T**  or T*const* pointers"<<extra_msg();
+     307             :           }
+     308             :         }
+     309             :       }
+     310             :     }
+     311             :     // check full shape, if possible
+     312     1817788 :     if(shape && shape[0] && this->shape[0]) {
+     313     1296186 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     314     1296186 :         if(shape[i]==0 && this->shape[i]!=0) {
+     315          12 :           throw ExceptionTypeError() << "Incorrect number of axis (passed greater than requested)"<<extra_msg();
+     316             :         }
+     317     1296182 :         if(shape[i]!=0 && this->shape[i]==0) {
+     318          12 :           throw ExceptionTypeError() << "Incorrect number of axis (requested greater than passed)"<<extra_msg();
+     319             :         }
+     320     1296178 :         if(shape[i]==0) break;
+     321      861503 :         if((shape[i]>this->shape[i])) {
+     322          80 :           throw ExceptionTypeError() << "This command wants " << shape[i] << " elements on axis " << i <<" of this pointer, but " << this->shape[i] << " have been passed"<<extra_msg();
+     323             :         }
+     324      861483 :         if(i>0 && (shape[i]<this->shape[i])) {
+     325           8 :           throw ExceptionTypeError() << "This command wants " << shape[i] << " elements on axis " << i <<" of this pointer, but " << this->shape[i] << " have been passed"<<extra_msg();
+     326             :         }
+     327             :       }
+     328             :     }
+     329     1817758 :     if(nelem==0 && shape && shape[0]>0) {
+     330      527233 :       nelem=1;
+     331     1514979 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     332     1514979 :         if(shape[i]==0) break;
+     333      987746 :         nelem*=shape[i];
+     334             :       }
+     335             :     }
+     336             :     // check number of elements
+     337     1817758 :     if(nelem>0 && this->nelem>0) if(!(nelem<=this->nelem)) {
+     338           8 :         throw ExceptionTypeError() << "This command wants to access " << nelem << " from this pointer, but only " << this->nelem << " have been passed"<<extra_msg();
+     339             :       }
+     340     1817756 :     return (T*) ptr;
+     341             :   }
+     342             : 
+     343             : public:
+     344             : 
+     345             :   template<typename T>
+     346       13105 :   void set(T val) const {
+     347       13105 :     *get_priv<T>(0,nullptr,false)=val;
+     348       13105 :   }
+     349             : 
+     350             :   template<typename T>
+     351      837408 :   typename std::enable_if<std::is_pointer<T>::value,T>::type get() const {
+     352             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     353      841020 :     return get_priv<T_noptr>(0,nullptr,false);
+     354             :   }
+     355             : 
+     356             :   template<typename T>
+     357      301764 :   typename std::enable_if<!std::is_pointer<T>::value,T>::type get() const {
+     358      301764 :     return *get_priv<const T>(1,nullptr,true);
+     359             :   }
+     360             : 
+     361             :   // this will make sure that a null character is present
+     362        3156 :   const char* getCString() const {
+     363        3156 :     const char* ptr=get_priv<const char>(0,nullptr,false);
+     364        3156 :     if(!typesafePtrSkipCheck() && this->nelem>0 && this->nelem<std::numeric_limits<std::size_t>::max()) {
+     365             :       std::size_t i=0;
+     366       18736 :       for(; i<this->nelem; i++) if(ptr[i]==0) break;
+     367         615 :       if(i==this->nelem) throw ExceptionTypeError() << "PLUMED is expecting a null terminated string, but no null character was found";
+     368             :     }
+     369        3154 :     return ptr;
+     370             :   }
+     371             : 
+     372             :   template<typename T,typename I>
+     373             :   typename std::enable_if<std::is_integral<I>::value, T>::type get(I nelem) const {
+     374             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     375             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     376             :     return get_priv<T_noptr>(std::size_t(nelem),nullptr,false);
+     377             :   }
+     378             : 
+     379             :   template<typename T>
+     380      659332 :   T get(std::initializer_list<SizeLike> shape) const {
+     381             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     382      659332 :     plumed_assert(shape.size()<=maxrank);
+     383             :     std::array<std::size_t,maxrank+1> shape_;
+     384             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     385             :     unsigned j=0;
+     386     1911091 :     for(auto i : shape) {
+     387     1251759 :       shape_[j]=i.size;
+     388     1251759 :       j++;
+     389             :     }
+     390      659332 :     shape_[j]=0;
+     391      659332 :     return get_priv<T_noptr>(0,&shape_[0],false);
+     392             :   }
+     393             : 
+     394             :   operator bool() const noexcept {
+     395      727969 :     return ptr;
+     396             :   }
+     397             : 
+     398             :   void* getRaw() const noexcept {
+     399         222 :     return ptr;
+     400             :   }
+     401             : 
+     402             :   std::size_t getNelem() const noexcept {
+     403         222 :     return nelem;
+     404             :   }
+     405             : 
+     406             :   const std::size_t* getShape() const noexcept {
+     407             :     return shape.data();
+     408             :   }
+     409             : 
+     410             :   std::size_t getFlags() const noexcept {
+     411         222 :     return flags;
+     412             :   }
+     413             : 
+     414             : private:
+     415             :   std::array<char,32> buffer;
+     416             :   void* ptr=nullptr;
+     417             :   std::size_t nelem=0;
+     418             :   std::array<std::size_t,maxrank+1> shape; // make sure to initialize this!
+     419             :   std::size_t flags=0;
+     420             : };
+     421             : 
+     422             : }
+     423             : 
+     424             : 
+     425             : #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 000000000..69eb13fad --- /dev/null +++ b/coverage/tools/Units.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - tools/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-10-17 16:45:00Functions: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_traitsIcESaIcEEE13
_ZN4PLMD5Units9setEnergyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE35
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE64
_ZN4PLMD5Units7setMassEd953
_ZN4PLMD5Units9setChargeEd953
_ZN4PLMD5Units9setLengthEd953
_ZN4PLMD5UnitsC2Ev1616456
+
+
+ + + +
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 000000000..4f57082c8 --- /dev/null +++ b/coverage/tools/Units.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - tools/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-10-17 16:45:00Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Units7setMassERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD5Units7setMassEd953
_ZN4PLMD5Units7setTimeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13
_ZN4PLMD5Units7setTimeEd6
_ZN4PLMD5Units9setChargeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD5Units9setChargeEd953
_ZN4PLMD5Units9setEnergyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE35
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE64
_ZN4PLMD5Units9setLengthEd953
_ZN4PLMD5UnitsC2Ev1616456
+
+
+ + + +
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 000000000..5f32ac9ce --- /dev/null +++ b/coverage/tools/Units.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + LCOV - plumed test coverage - tools/Units.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-10-17 16:45:00Functions: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     1616456 : Units::Units():
+      28     1616456 :   energy(1.0),
+      29     1616456 :   energyString("kj/mol"),
+      30     1616456 :   length(1.0),
+      31     1616456 :   lengthString("nm"),
+      32     1616456 :   time(1.0),
+      33     1616456 :   timeString("ps"),
+      34     1616456 :   charge(1.0),
+      35     1616456 :   chargeString("e"),
+      36     1616456 :   mass(1.0),
+      37     1616456 :   massString("amu")
+      38             : {
+      39     1616456 : }
+      40             : 
+      41          35 : void Units::setEnergy(const std::string &s) {
+      42          35 :   energyString=s;
+      43          35 :   if(s=="kj/mol") {
+      44          21 :     energy=1.0;
+      45          14 :   } else if(s=="kcal/mol") {
+      46          11 :     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          35 : }
+      62             : 
+      63          64 : void Units::setLength(const std::string &s) {
+      64          64 :   lengthString=s;
+      65          64 :   if(s=="nm") {
+      66           2 :     length=1.0;
+      67          62 :   } else if(s=="A") {
+      68          53 :     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          64 : }
+      82             : 
+      83          13 : void Units::setTime(const std::string &s) {
+      84          13 :   timeString=s;
+      85          13 :   if(s=="ps") {
+      86           8 :     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          13 : }
+     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         953 : void Units::setLength(const double s) {
+     137         953 :   lengthString="";
+     138         953 :   length=s;
+     139         953 : }
+     140             : 
+     141           6 : void Units::setTime(const double s) {
+     142           6 :   timeString="";
+     143           6 :   time=s;
+     144           6 : }
+     145             : 
+     146         953 : void Units::setCharge(const double s) {
+     147         953 :   chargeString="";
+     148         953 :   charge=s;
+     149         953 : }
+     150             : 
+     151         953 : void Units::setMass(const double s) {
+     152         953 :   massString="";
+     153         953 :   mass=s;
+     154         953 : }
+     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 000000000..325e9b72f --- /dev/null +++ b/coverage/tools/Units.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Units.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3fddd66aa --- /dev/null +++ b/coverage/tools/Units.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Units.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..5d82e43b7 --- /dev/null +++ b/coverage/tools/Units.h.gcov.html @@ -0,0 +1,243 @@ + + + + + + + LCOV - plumed test coverage - tools/Units.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-10-17 16:45:00Functions: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    15923130 :   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 000000000..18d0b8128 --- /dev/null +++ b/coverage/tools/Vector.h.func-sort-c.html @@ -0,0 +1,344 @@ + + + + + + + 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:667094.3 %
Date:2024-10-17 16:45:00Functions:536877.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMDlsILj3EEERSoS1_RKNS_13VectorGenericIXT_EEE0
_ZN4PLMDmlILj5EEENS_13VectorGenericIXT_EEEdRKS2_0
_ZNK4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEdVEd57841
_ZN4PLMD13VectorGenericILj1EEC2Ev564522
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZN4PLMD13VectorGenericILj1EEixEj1129044
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_5453293
_ZN4PLMD10dotProductILj4EEEdRKNS_13VectorGenericIXT_EEES4_12203712
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_12827004
_ZN4PLMD13VectorGenericILj4EEC2Ev14070232
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_14990747
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_14990747
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_14997521
_ZN4PLMD13VectorGenericILj3EE4zeroEv24855371
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_30119685
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_30119685
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_30126459
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE34471352
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_45123980
_ZN4PLMD13VectorGenericILj4EEclEj48814848
_ZN4PLMD13VectorGenericILj4EEixEj52183123
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE203106997
_ZNK4PLMD13VectorGenericILj3EEngEv206441845
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_252069361
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d359166577
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
_ZNK4PLMD13VectorGenericILj3EE6moduloEv404864655
_ZN4PLMD13VectorGenericILj3EEC2Ev629836316
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d946890922
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_988692928
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev1105174523
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1318790905
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1364068188
_ZNK4PLMD13VectorGenericILj3EEclEj1520992692
_ZN4PLMD13VectorGenericILj3EEclEj1526763762
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1907036553
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1954460080
_ZNK4PLMD13VectorGenericILj3EEixEj2082524755
_ZN4PLMD13VectorGenericILj3EEixEj2237864468
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_2431363768
_ZN4PLMD13VectorGenericILj3EEmLEd2433432688
+
+
+ + + +
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 000000000..450c9ed99 --- /dev/null +++ b/coverage/tools/Vector.h.func.html @@ -0,0 +1,344 @@ + + + + + + + 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:667094.3 %
Date:2024-10-17 16:45:00Functions:536877.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_252069361
_ZN4PLMD10dotProductILj4EEEdRKNS_13VectorGenericIXT_EEES4_12203712
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_5453293
_ZN4PLMD13VectorGenericILj1EEC2Ev564522
_ZN4PLMD13VectorGenericILj1EEixEj1129044
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_45123980
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_30126459
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_30119685
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_14997521
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_14990747
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE4zeroEv24855371
_ZN4PLMD13VectorGenericILj3EEC2Ev629836316
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_30119685
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_14990747
_ZN4PLMD13VectorGenericILj3EEC2IJjjEEEdDpT_0
_ZN4PLMD13VectorGenericILj3EEclEj1526763762
_ZN4PLMD13VectorGenericILj3EEdVEd57841
_ZN4PLMD13VectorGenericILj3EEixEj2237864468
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1907036553
_ZN4PLMD13VectorGenericILj3EEmLEd2433432688
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1954460080
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_12827004
_ZN4PLMD13VectorGenericILj4EEC2Ev14070232
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_12827004
_ZN4PLMD13VectorGenericILj4EEclEj48814848
_ZN4PLMD13VectorGenericILj4EEixEj52183123
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EEC2Ev0
_ZN4PLMD13VectorGenericILj5EEC2IJddddEEEdDpT_0
_ZN4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj5EEmLEd0
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_988692928
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE34471352
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE203106997
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d359166577
_ZN4PLMDlsILj3EEERSoS1_RKNS_13VectorGenericIXT_EEE0
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1364068188
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d946890922
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_2431363768
_ZN4PLMDmlILj5EEENS_13VectorGenericIXT_EEEdRKS2_0
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1318790905
_ZNK4PLMD13VectorGenericILj3EE6moduloEv404864655
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev1105174523
_ZNK4PLMD13VectorGenericILj3EEclEj1520992692
_ZNK4PLMD13VectorGenericILj3EEixEj2082524755
_ZNK4PLMD13VectorGenericILj3EEngEv206441845
_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 000000000..9c3ff82c1 --- /dev/null +++ b/coverage/tools/Vector.h.gcov.html @@ -0,0 +1,419 @@ + + + + + + + LCOV - plumed test coverage - tools/Vector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:667094.3 %
Date:2024-10-17 16:45:00Functions:536877.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_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   186679956 : void VectorGeneric<n>::auxiliaryConstructor(double first,Args... arg)
+     164             : {
+     165   186679956 :   d[n-(sizeof...(Args))-1]=first;
+     166   128728972 :   auxiliaryConstructor(arg...);
+     167   186679956 : }
+     168             : 
+     169             : template <unsigned n>
+     170             : template<typename... Args>
+     171    57950984 : 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    57950984 :   auxiliaryConstructor(first,arg...);
+     175    57950984 : }
+     176             : 
+     177             : template <unsigned n>
+     178    24855371 : void VectorGeneric<n>::zero() {
+     179    24855371 :   LoopUnroller<n>::_zero(d.data());
+     180    24855371 : }
+     181             : 
+     182             : template <unsigned n>
+     183   644475074 : VectorGeneric<n>::VectorGeneric() {
+     184   643910552 :   LoopUnroller<n>::_zero(d.data());
+     185   644475074 : }
+     186             : 
+     187             : template <unsigned n>
+     188  2354825997 : double & VectorGeneric<n>::operator[](unsigned i) {
+     189  2354825997 :   return d[i];
+     190             : }
+     191             : 
+     192             : template <unsigned n>
+     193  2478901135 : const double & VectorGeneric<n>::operator[](unsigned i)const {
+     194  2478901135 :   return d[i];
+     195             : }
+     196             : 
+     197             : template <unsigned n>
+     198  1575578610 : double & VectorGeneric<n>::operator()(unsigned i) {
+     199  1575578610 :   return d[i];
+     200             : }
+     201             : 
+     202             : template <unsigned n>
+     203  1525611420 : const double & VectorGeneric<n>::operator()(unsigned i)const {
+     204  1525611420 :   return d[i];
+     205             : }
+     206             : 
+     207             : template <unsigned n>
+     208  1954460080 : VectorGeneric<n>& VectorGeneric<n>::operator +=(const VectorGeneric<n>& b) {
+     209  1954460080 :   LoopUnroller<n>::_add(d.data(),b.d.data());
+     210  1954460080 :   return *this;
+     211             : }
+     212             : 
+     213             : template <unsigned n>
+     214  1908155655 : VectorGeneric<n>& VectorGeneric<n>::operator -=(const VectorGeneric<n>& b) {
+     215  1908155655 :   LoopUnroller<n>::_sub(d.data(),b.d.data());
+     216  1908155655 :   return *this;
+     217             : }
+     218             : 
+     219             : template <unsigned n>
+     220  2433432688 : VectorGeneric<n>& VectorGeneric<n>::operator *=(double s) {
+     221  2433432688 :   LoopUnroller<n>::_mul(d.data(),s);
+     222  2433432688 :   return *this;
+     223             : }
+     224             : 
+     225             : template <unsigned n>
+     226       57841 : VectorGeneric<n>& VectorGeneric<n>::operator /=(double s) {
+     227       57841 :   LoopUnroller<n>::_mul(d.data(),1.0/s);
+     228       57841 :   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   206441845 : VectorGeneric<n> VectorGeneric<n>::operator -()const {
+     238   206441845 :   VectorGeneric<n> r;
+     239   206441845 :   LoopUnroller<n>::_neg(r.d.data(),d.data());
+     240   206441845 :   return r;
+     241             : }
+     242             : 
+     243             : template <unsigned n>
+     244  1318790905 : VectorGeneric<n> operator+(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     245  1318790905 :   VectorGeneric<n> v(v1);
+     246  1318790905 :   return v+=v2;
+     247             : }
+     248             : 
+     249             : template <unsigned n>
+     250  1365187290 : VectorGeneric<n> operator-(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     251  1365187290 :   VectorGeneric<n> v(v1);
+     252  1365187290 :   return v-=v2;
+     253             : }
+     254             : 
+     255             : template <unsigned n>
+     256  2431363768 : VectorGeneric<n> operator*(double s,const VectorGeneric<n>&v) {
+     257  2431363768 :   VectorGeneric<n> vv(v);
+     258  2431363768 :   return vv*=s;
+     259             : }
+     260             : 
+     261             : template <unsigned n>
+     262   946890922 : VectorGeneric<n> operator*(const VectorGeneric<n>&v,double s) {
+     263   946890922 :   return s*v;
+     264             : }
+     265             : 
+     266             : template <unsigned n>
+     267   359166577 : VectorGeneric<n> operator/(const VectorGeneric<n>&v,double s) {
+     268   359166577 :   return v*(1.0/s);
+     269             : }
+     270             : 
+     271             : template <unsigned n>
+     272   989812030 : VectorGeneric<n> delta(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     273   989812030 :   return v2-v1;
+     274             : }
+     275             : 
+     276             : template <unsigned n>
+     277  1106293625 : double VectorGeneric<n>::modulo2()const {
+     278  1106293625 :   return LoopUnroller<n>::_sum2(d.data());
+     279             : }
+     280             : 
+     281             : template <unsigned n>
+     282   264273073 : double dotProduct(const VectorGeneric<n>& v1,const VectorGeneric<n>& v2) {
+     283   264273073 :   return LoopUnroller<n>::_dot(v1.d.data(),v2.d.data());
+     284             : }
+     285             : 
+     286             : inline
+     287     5453293 : VectorGeneric<3> crossProduct(const VectorGeneric<3>& v1,const VectorGeneric<3>& v2) {
+     288             :   return VectorGeneric<3>(
+     289     5453293 :            v1[1]*v2[2]-v1[2]*v2[1],
+     290     5453293 :            v1[2]*v2[0]-v1[0]*v2[2],
+     291     5453293 :            v1[0]*v2[1]-v1[1]*v2[0]);
+     292             : }
+     293             : 
+     294             : template<unsigned n>
+     295   404864655 : double VectorGeneric<n>::modulo()const {
+     296   404864655 :   return sqrt(modulo2());
+     297             : }
+     298             : 
+     299             : template<unsigned n>
+     300   203106997 : double modulo2(const VectorGeneric<n>&v) {
+     301   203106997 :   return v.modulo2();
+     302             : }
+     303             : 
+     304             : template<unsigned n>
+     305    34471352 : double modulo(const VectorGeneric<n>&v) {
+     306    34471352 :   return v.modulo();
+     307             : }
+     308             : 
+     309             : template<unsigned n>
+     310           0 : std::ostream & operator<<(std::ostream &os, const VectorGeneric<n>& v) {
+     311           0 :   for(unsigned i=0; i<n-1; i++) os<<v(i)<<" ";
+     312           0 :   os<<v(n-1);
+     313           0 :   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 000000000..5c4a4f56a --- /dev/null +++ b/coverage/tools/h36.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - tools/h36.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8712768.5 %
Date:2024-10-17 16:45:00Functions: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_clEv239
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv239
_ZN4PLMD3h36L12digits_lowerEv8605
_ZN4PLMD3h3610hy36encodeEjiPc102253
_ZN4PLMD3h36L11encode_pureEPKcjjiPc102253
_ZN4PLMD3h36L12digits_upperEv110856
_ZN4PLMD3h3610hy36decodeEjPKcjPi893784
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi893784
+
+
+ + + +
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 000000000..a6d47aceb --- /dev/null +++ b/coverage/tools/h36.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - tools/h36.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8712768.5 %
Date:2024-10-17 16:45:00Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3h3610hy36decodeEjPKcjPi893784
_ZN4PLMD3h3610hy36encodeEjiPc102253
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi893784
_ZN4PLMD3h36L11encode_pureEPKcjjiPc102253
_ZN4PLMD3h36L12digits_lowerEv8605
_ZN4PLMD3h36L12digits_upperEv110856
_ZN4PLMD3h36L15fill_with_starsEjPc0
_ZN4PLMD3h36L17unsupported_widthEv0
_ZN4PLMD3h36L18value_out_of_rangeEv0
_ZN4PLMD3h36L22invalid_number_literalEv2
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE0_clEv239
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv239
+
+
+ + + +
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 000000000..5419bb45a --- /dev/null +++ b/coverage/tools/h36.cpp.gcov.html @@ -0,0 +1,411 @@ + + + + + + + LCOV - plumed test coverage - tools/h36.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8712768.5 %
Date:2024-10-17 16:45:00Functions: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      110856 : digits_upper() { return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+      62             : 
+      63             : static
+      64             : const char*
+      65        8605 : 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      893784 : 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     4915811 :   for(; i<s_size; i++) {
+     133     4022028 :     si = s[i];
+     134     4022028 :     if (si < 0 || si > 127) {
+     135           0 :       *result = 0;
+     136           0 :       return invalid_number_literal();
+     137             :     }
+     138     4022028 :     if (si == ' ') {
+     139     1208259 :       if (!have_non_blank) continue;
+     140           0 :       value *= digits_size;
+     141             :     }
+     142     2813769 :     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     2813769 :       dv = digits_values[si];
+     154     2813769 :       if (dv < 0 || dv >= digits_size) {
+     155           1 :         *result = 0;
+     156           1 :         return invalid_number_literal();
+     157             :       }
+     158     2813768 :       value *= digits_size;
+     159     2813768 :       value += dv;
+     160             :     }
+     161             :   }
+     162      893783 :   if (have_minus) value = -value;
+     163      893783 :   *result = value;
+     164      893783 :   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      893784 : hy36decode(unsigned width, const char* s, unsigned s_size, int* result)
+     261             : {
+     262         239 :   static const std::vector<int> digits_values_upper_vector([]() {
+     263         239 :     std::vector<int> ret(128U,-1);
+     264        8843 :     for(unsigned i=0; i<36U; i++) {
+     265        8604 :       int di = digits_upper()[i];
+     266        8604 :       if (di < 0 || di > 127) {
+     267           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     268             :       }
+     269        8604 :       ret[di] = i;
+     270             :     }
+     271         239 :     return ret;
+     272      893784 :   }());
+     273      893784 :   static const int* digits_values_upper=digits_values_upper_vector.data();
+     274         239 :   static const std::vector<int> digits_values_lower_vector([]() {
+     275         239 :     std::vector<int> ret(128U,-1);
+     276        8843 :     for(unsigned i=0; i<36U; i++) {
+     277        8604 :       int di = digits_lower()[i];
+     278        8604 :       if (di < 0 || di > 127) {
+     279           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     280             :       }
+     281        8604 :       ret[di] = i;
+     282             :     }
+     283         239 :     return ret;
+     284      893784 :   }());
+     285      893784 :   static const int* digits_values_lower=digits_values_lower_vector.data();
+     286             :   int di;
+     287             :   const char* errmsg;
+     288      893784 :   if (s_size == width) {
+     289      893784 :     di = s[0];
+     290      893784 :     if (di >= 0 && di <= 127) {
+     291      893784 :       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      893770 :       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      893770 :         errmsg = decode_pure(digits_values_upper, 10U, s, s_size, result);
+     319      893770 :         if (errmsg) return errmsg;
+     320      893770 :         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 000000000..afa735085 --- /dev/null +++ b/coverage/tools/index-sort-f.html @@ -0,0 +1,853 @@ + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5734711180.6 %
Date:2024-10-17 16:45:00Functions:1154157173.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Exception.h +
91.7%91.7%
+
91.7 %33 / 3624.5 %34 / 139
Grid.cpp +
69.4%69.4%
+
69.4 %420 / 60537.5 %60 / 160
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.6%52.6%
+
52.6 %220 / 41861.4 %27 / 44
DLLoader.cpp +
62.9%62.9%
+
62.9 %22 / 3562.5 %5 / 8
PlumedHandle.cpp +
65.8%65.8%
+
65.8 %25 / 3862.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 +
93.2%93.2%
+
93.2 %123 / 13273.3 %44 / 60
h36.cpp +
68.5%68.5%
+
68.5 %87 / 12775.0 %9 / 12
Keywords.cpp +
55.4%55.4%
+
55.4 %237 / 42877.1 %37 / 48
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 +
94.3%94.3%
+
94.3 %66 / 7077.9 %53 / 68
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 +
75.0%75.0%
+
75.0 %63 / 8487.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
MinimiseBase.h +
100.0%
+
100.0 %26 / 2688.9 %16 / 18
OFile.h +
100.0%
+
100.0 %6 / 688.9 %96 / 108
Matrix.h +
87.1%87.1%
+
87.1 %121 / 13990.0 %9 / 10
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Stopwatch.h +
81.5%81.5%
+
81.5 %53 / 6590.9 %10 / 11
Tools.h +
97.9%97.9%
+
97.9 %94 / 9691.1 %51 / 56
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
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Pbc.h +
83.3%83.3%
+
83.3 %5 / 6-0 / 0
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
LinkCells.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
Random.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
SwitchingFunction.h +
100.0%
+
100.0 %1 / 1-0 / 0
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
CheckInRange.h +
100.0%
+
100.0 %1 / 1-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
MergeVectorTools.h +
100.0%
+
100.0 %25 / 25100.0 %2 / 2
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
AtomNumber.h +
100.0%
+
100.0 %17 / 17100.0 %2 / 2
Keywords.h +
81.2%81.2%
+
81.2 %13 / 16100.0 %2 / 2
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
LeptonCall.cpp +
95.0%95.0%
+
95.0 %38 / 40100.0 %3 / 3
MultiValue.h +
100.0%
+
100.0 %43 / 43100.0 %4 / 4
CheckInRange.cpp +
77.5%77.5%
+
77.5 %31 / 40100.0 %4 / 4
OpenMP.cpp +
100.0%
+
100.0 %17 / 17100.0 %4 / 4
MultiValue.cpp +
100.0%
+
100.0 %46 / 46100.0 %4 / 4
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
MolDataClass.cpp +
85.1%85.1%
+
85.1 %406 / 477100.0 %5 / 5
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
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 000000000..1846a2284 --- /dev/null +++ b/coverage/tools/index-sort-l.html @@ -0,0 +1,853 @@ + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5734711180.6 %
Date:2024-10-17 16:45:00Functions:1154157173.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
PDB.cpp +
52.6%52.6%
+
52.6 %220 / 41861.4 %27 / 44
Keywords.cpp +
55.4%55.4%
+
55.4 %237 / 42877.1 %37 / 48
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 +
65.8%65.8%
+
65.8 %25 / 3862.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 +
75.0%75.0%
+
75.0 %63 / 8487.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 +
87.1%87.1%
+
87.1 %121 / 13990.0 %9 / 10
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 / 3624.5 %34 / 139
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
TypesafePtr.h +
93.2%93.2%
+
93.2 %123 / 13273.3 %44 / 60
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
Vector.h +
94.3%94.3%
+
94.3 %66 / 7077.9 %53 / 68
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 / 9691.1 %51 / 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
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
LinkCells.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
LeptonCall.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
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %13 / 13
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
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
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
MultiValue.cpp +
100.0%
+
100.0 %46 / 46100.0 %4 / 4
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 000000000..db7599e3e --- /dev/null +++ b/coverage/tools/index.html @@ -0,0 +1,853 @@ + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5734711180.6 %
Date:2024-10-17 16:45:00Functions:1154157173.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
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 / 3624.5 %34 / 139
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 +
55.4%55.4%
+
55.4 %237 / 42877.1 %37 / 48
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 +
87.1%87.1%
+
87.1 %121 / 13990.0 %9 / 10
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 +
100.0%
+
100.0 %46 / 46100.0 %4 / 4
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.6%52.6%
+
52.6 %220 / 41861.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 +
65.8%65.8%
+
65.8 %25 / 3862.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 +
75.0%75.0%
+
75.0 %63 / 8487.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 / 9691.1 %51 / 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 +
93.2%93.2%
+
93.2 %123 / 13273.3 %44 / 60
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 +
94.3%94.3%
+
94.3 %66 / 7077.9 %53 / 68
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 000000000..539da3092 --- /dev/null +++ b/coverage/valtools/Concatenate.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:848895.5 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools11ConcatenateC2ERKNS_13ActionOptionsE0
_ZN4PLMD8valtools11ConcatenateC1ERKNS_13ActionOptionsE176
_ZN4PLMD8valtools11Concatenate22getNumberOfDerivativesEv257
_ZN4PLMD8valtools11Concatenate16registerKeywordsERNS_8KeywordsE353
_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 000000000..e2fab304b --- /dev/null +++ b/coverage/valtools/Concatenate.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:848895.5 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools11Concatenate16registerKeywordsERNS_8KeywordsE353
_ZN4PLMD8valtools11Concatenate22getNumberOfDerivativesEv257
_ZN4PLMD8valtools11Concatenate5applyEv12070
_ZN4PLMD8valtools11Concatenate9calculateEv12191
_ZN4PLMD8valtools11ConcatenateC1ERKNS_13ActionOptionsE176
_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 000000000..7b7889250 --- /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:848895.5 %
Date:2024-10-17 16:45:00Functions: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         353 : void Concatenate::registerKeywords( Keywords& keys ) {
+      60         353 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      61        1059 :   keys.add("numbered","MATRIX","specify the matrices that you wish to join together into a single matrix"); keys.reset_style("MATRIX","compulsory");
+      62         353 :   keys.setValueDescription("the concatenated vector/matrix that was constructed from the input values");
+      63         353 : }
+      64             : 
+      65         176 : Concatenate::Concatenate(const ActionOptions& ao):
+      66             :   Action(ao),
+      67             :   ActionWithValue(ao),
+      68         176 :   ActionWithArguments(ao)
+      69             : {
+      70         176 :   if( getNumberOfArguments()>0 ) {
+      71         172 :     vectors=true; std::vector<unsigned> shape(1); shape[0]=0;
+      72         547 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      73         375 :       if( getPntrToArgument(i)->getRank()>1 ) error("cannot concatenate matrix with vectors");
+      74         375 :       getPntrToArgument(i)->buildDataStore(); shape[0] += getPntrToArgument(i)->getNumberOfValues();
+      75             :     }
+      76         172 :     log.printf("  creating vector with %d elements \n", shape[0] );
+      77         172 :     addValue( shape ); bool period=getPntrToArgument(0)->isPeriodic();
+      78         172 :     std::string min, max; if( period ) getPntrToArgument(0)->getDomain( min, max );
+      79         375 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+      80         203 :       if( period!=getPntrToArgument(i)->isPeriodic() ) error("periods of input arguments should match");
+      81         203 :       if( period ) {
+      82           0 :         std::string min0, max0; getPntrToArgument(i)->getDomain( min0, max0 );
+      83           0 :         if( min0!=min || max0!=max ) error("domains of input arguments should match");
+      84             :       }
+      85             :     }
+      86         172 :     if( period ) setPeriodic( min, max ); else setNotPeriodic();
+      87         172 :     getPntrToComponent(0)->buildDataStore();
+      88         172 :     if( getPntrToComponent(0)->getRank()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      89             :   } else {
+      90           4 :     unsigned nrows=0, ncols=0; std::vector<Value*> arglist; vectors=false;
+      91           7 :     for(unsigned i=1;; i++) {
+      92             :       unsigned nt_cols=0; unsigned size_b4 = arglist.size();
+      93          14 :       for(unsigned j=1;; j++) {
+      94          25 :         if( j==10 ) error("cannot combine more than 9 matrices");
+      95          50 :         std::vector<Value*> argn; parseArgumentList("MATRIX", i*10+j, argn);
+      96          25 :         if( argn.size()==0 ) break;
+      97          14 :         if( argn.size()>1 ) error("should only be one argument to each matrix keyword");
+      98          14 :         if( argn[0]->getRank()!=0 && argn[0]->getRank()!=2 ) error("input arguments for this action should be matrices");
+      99          14 :         argn[0]->buildDataStore(); arglist.push_back( argn[0] ); nt_cols++;
+     100          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() );
+     101          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() );
+     102          14 :       }
+     103          11 :       if( arglist.size()==size_b4 ) break;
+     104           7 :       if( i==1 ) ncols=nt_cols;
+     105           3 :       else if( nt_cols!=ncols ) error("should be joining same number of matrices in each row");
+     106           7 :       nrows++;
+     107           7 :     }
+     108             : 
+     109           4 :     std::vector<unsigned> shape(2); shape[0]=0; unsigned k=0;
+     110           4 :     row_starts.resize( arglist.size() ); col_starts.resize( arglist.size() );
+     111          11 :     for(unsigned i=0; i<nrows; ++i) {
+     112           7 :       unsigned cstart = 0, nr = 1; if( arglist[k]->getRank()==2 ) nr=arglist[k]->getShape()[0];
+     113          21 :       for(unsigned j=0; j<ncols; ++j) {
+     114          14 :         if( arglist[k]->getRank()==0 ) {
+     115           0 :           if( nr!=1 ) error("mismatched matrix sizes");
+     116          14 :         } else if( nrows>1 && arglist[k]->getShape()[0]!=nr ) error("mismatched matrix sizes");
+     117          14 :         row_starts[k] = shape[0]; col_starts[k] = cstart;
+     118          14 :         if( arglist[k]->getRank()==0 ) cstart += 1;
+     119          14 :         else cstart += arglist[k]->getShape()[1];
+     120          14 :         k++;
+     121             :       }
+     122           7 :       if( i==0 ) shape[1]=cstart;
+     123           3 :       else if( cstart!=shape[1] ) error("mismatched matrix sizes");
+     124           7 :       if( arglist[k-1]->getRank()==0 ) shape[0] += 1;
+     125           7 :       else shape[0] += arglist[k-1]->getShape()[0];
+     126             :     }
+     127             :     // Now request the arguments to make sure we store things we need
+     128           4 :     requestArguments(arglist); addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+     129           4 :     if( getPntrToComponent(0)->getRank()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     130             :   }
+     131         176 : }
+     132             : 
+     133       12191 : void Concatenate::calculate() {
+     134       12191 :   Value* myval = getPntrToComponent(0);
+     135       12191 :   if( vectors ) {
+     136             :     unsigned k=0;
+     137       61297 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     138       49158 :       Value* myarg=getPntrToArgument(i); unsigned nvals=myarg->getNumberOfValues();
+     139      404266 :       for(unsigned j=0; j<nvals; ++j) { myval->set( k, myarg->get(j) ); k++; }
+     140             :     }
+     141             :   } else {
+     142             :     // Retrieve the matrix from input
+     143          52 :     unsigned ncols = myval->getShape()[1];
+     144         258 :     for(unsigned k=0; k<getNumberOfArguments(); ++k) {
+     145             :       Value* argn = getPntrToArgument(k);
+     146         206 :       if( argn->getRank()==0 ) {
+     147           0 :         myval->set( ncols*row_starts[k]+col_starts[k], argn->get() );
+     148             :       } else {
+     149             :         std::vector<double> vals; std::vector<std::pair<unsigned,unsigned> > pairs;
+     150             :         bool symmetric=getPntrToArgument(k)->isSymmetric();
+     151         206 :         unsigned nedge=0; getPntrToArgument(k)->retrieveEdgeList( nedge, pairs, vals );
+     152        8946 :         for(unsigned l=0; l<nedge; ++l ) {
+     153        8740 :           unsigned i=pairs[l].first, j=pairs[l].second;
+     154        8740 :           myval->set( ncols*(row_starts[k]+i)+col_starts[k]+j, vals[l] );
+     155        8740 :           if( symmetric ) myval->set( ncols*(row_starts[k]+j)+col_starts[k]+i, vals[l] );
+     156             :         }
+     157             :       }
+     158             :     }
+     159             :   }
+     160       12191 : }
+     161             : 
+     162       12070 : void Concatenate::apply() {
+     163       12070 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return;
+     164             : 
+     165        5033 :   Value* val=getPntrToComponent(0);
+     166        5033 :   if( vectors ) {
+     167             :     unsigned k=0;
+     168       19923 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     169       14942 :       Value* myarg=getPntrToArgument(i); unsigned nvals=myarg->getNumberOfValues();
+     170      205938 :       for(unsigned j=0; j<nvals; ++j) { myarg->addForce( j, val->getForce(k) ); k++; }
+     171             :     }
+     172             :   } else {
+     173          52 :     unsigned ncols=val->getShape()[1];
+     174         258 :     for(unsigned k=0; k<getNumberOfArguments(); ++k) {
+     175             :       Value* argn=getPntrToArgument(k);
+     176         206 :       if( argn->getRank()==0 ) argn->addForce( 0, val->getForce(ncols*row_starts[k]+col_starts[k]) );
+     177             :       else {
+     178             :         unsigned val_ncols=val->getNumberOfColumns();
+     179             :         unsigned arg_ncols=argn->getNumberOfColumns();
+     180        1686 :         for(unsigned i=0; i<argn->getShape()[0]; ++i) {
+     181             :           unsigned ncol = argn->getRowLength(i);
+     182       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 );
+     183             :         }
+     184             :       }
+     185             :     }
+     186             :   }
+     187             : }
+     188             : 
+     189             : }
+     190             : }
+
+
+
+ + + + +
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 000000000..a52769304 --- /dev/null +++ b/coverage/valtools/Flatten.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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:2727100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools7FlattenC2ERKNS_13ActionOptionsE0
_ZN4PLMD8valtools7Flatten5applyEv7
_ZN4PLMD8valtools7Flatten9calculateEv9
_ZN4PLMD8valtools7FlattenC1ERKNS_13ActionOptionsE9
_ZN4PLMD8valtools7Flatten22getNumberOfDerivativesEv10
_ZN4PLMD8valtools7Flatten16registerKeywordsERNS_8KeywordsE20
+
+
+ + + +
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 000000000..cc46a6796 --- /dev/null +++ b/coverage/valtools/Flatten.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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:2727100.0 %
Date:2024-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools7Flatten16registerKeywordsERNS_8KeywordsE20
_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 000000000..3d3662927 --- /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:2727100.0 %
Date:2024-10-17 16:45:00Functions: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          20 : void Flatten::registerKeywords( Keywords& keys ) {
+      57          20 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      58          20 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      59          20 :   keys.setValueDescription("a vector containing all the elements of the input matrix");
+      60          20 : }
+      61             : 
+      62           9 : Flatten::Flatten(const ActionOptions& ao):
+      63             :   Action(ao),
+      64             :   ActionWithValue(ao),
+      65           9 :   ActionWithArguments(ao)
+      66             : {
+      67           9 :   if( getNumberOfArguments()!=1 ) error("should only be one argument for this action");
+      68           9 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("input to this action should be a matrix");
+      69           9 :   getPntrToArgument(0)->buildDataStore(true);
+      70           9 :   std::vector<unsigned> inshape( getPntrToArgument(0)->getShape() );
+      71           9 :   std::vector<unsigned> shape( 1 ); shape[0]=inshape[0]*inshape[1];
+      72           9 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      73           9 : }
+      74             : 
+      75           9 : void Flatten::calculate() {
+      76           9 :   Value* myval = getPntrToComponent(0); unsigned ss=getPntrToArgument(0)->getShape()[1];
+      77             :   std::vector<double> vals; std::vector<std::pair<unsigned,unsigned> > pairs;
+      78             :   bool symmetric=getPntrToArgument(0)->isSymmetric();
+      79           9 :   unsigned nedge=0; getPntrToArgument(0)->retrieveEdgeList( nedge, pairs, vals );
+      80        8139 :   for(unsigned l=0; l<nedge; ++l ) {
+      81        8130 :     unsigned i=pairs[l].first, j=pairs[l].second;
+      82        8130 :     myval->set( i*ss + j, vals[l] );
+      83        8130 :     if( symmetric ) myval->set( j*ss + i, vals[l] );
+      84             :   }
+      85           9 : }
+      86             : 
+      87           7 : void Flatten::apply() {
+      88           7 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return;
+      89             : 
+      90           3 :   Value* myval=getPntrToComponent(0); Value* myarg=getPntrToArgument(0);
+      91          22 :   unsigned nvals=myval->getNumberOfValues(); for(unsigned j=0; j<nvals; ++j) myarg->addForce( j, myval->getForce(j) );
+      92             : }
+      93             : 
+      94             : }
+      95             : }
+
+
+
+ + + + +
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 000000000..46dd0ab2a --- /dev/null +++ b/coverage/valtools/SelectComponents.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:313296.9 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools16SelectComponentsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8valtools16SelectComponentsC1ERKNS_13ActionOptionsE57
_ZN4PLMD8valtools16SelectComponents16registerKeywordsERNS_8KeywordsE69
+
+
+ + + +
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 000000000..87dfc8365 --- /dev/null +++ b/coverage/valtools/SelectComponents.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:313296.9 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools16SelectComponents16registerKeywordsERNS_8KeywordsE69
_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 000000000..79e2abb82 --- /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:313296.9 %
Date:2024-10-17 16:45:00Functions: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          69 : void SelectComponents::registerKeywords( Keywords& keys ) {
+      50          69 :   ActionShortcut::registerKeywords( keys );
+      51         138 :   keys.add("compulsory","ARG","the argument we are using to build the shortcut");
+      52         138 :   keys.add("compulsory","COMPONENTS","the components in the input value that you woul like to build a new vector from");
+      53         207 :   keys.needsAction("FLATTEN"); keys.needsAction("CONSTANT"); keys.needsAction("SELECT_WITH_MASK");
+      54          69 :   keys.setValueDescription("a vector containing the selected components");
+      55          69 : }
+      56             : 
+      57          57 : SelectComponents::SelectComponents(const ActionOptions& ao):
+      58             :   Action(ao),
+      59          57 :   ActionShortcut(ao)
+      60             : {
+      61         114 :   std::vector<std::string> argn; parseVector("ARG",argn); std::vector<Value*> theargs;
+      62          57 :   ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, theargs );
+      63          57 :   if( theargs.size()!=1 ) error("should only be one argument input to this action");
+      64             :   // Create an array that will eventually hold the mask
+      65          57 :   std::vector<double> mask( theargs[0]->getNumberOfValues(), 1 );
+      66         114 :   std::vector<std::string> elements; parseVector("COMPONENTS",elements);
+      67          57 :   if( theargs[0]->getRank()==1 ) {
+      68         189 :     for(unsigned i=0; i<elements.size(); ++i) { unsigned sel; Tools::convert( elements[i], sel ); mask[sel-1]=0; }
+      69           7 :   } else if( theargs[0]->getRank()==2 ) {
+      70          27 :     for(unsigned i=0; i<elements.size(); ++i) {
+      71          20 :       std::size_t dot = elements[i].find_first_of(".");
+      72          20 :       if( dot==std::string::npos ) error("found no dot in specification of required matrix element");
+      73          20 :       std::string istr=elements[i].substr(0,dot), jstr=elements[i].substr(dot+1);
+      74          20 :       unsigned ival, jval; Tools::convert( istr, ival ); Tools::convert( jstr, jval );
+      75          20 :       mask[(ival-1)*theargs[0]->getShape()[1] + jval - 1] = 0;
+      76             :     }
+      77          14 :     readInputLine( getShortcutLabel() + "_flat: FLATTEN ARG=" + theargs[0]->getName() );
+      78           0 :   } else error("input to this argument should be a vector/matrix");
+      79             :   // Now create the mask action
+      80          57 :   std::string mask_str; Tools::convert( mask[0], mask_str ); unsigned check_mask=mask[0];
+      81        1472 :   for(unsigned i=1; i<mask.size(); ++i) { std::string num; Tools::convert( mask[i], num ); mask_str += "," + num; check_mask +=mask[i]; }
+      82          57 :   if( mask.size()-check_mask!=elements.size() ) error("found repeated indexes in COMPONENTS");
+      83         114 :   readInputLine( getShortcutLabel() + "_mask: CONSTANT VALUES=" + mask_str );
+      84             :   // And finally create the selector
+      85         107 :   if( theargs[0]->getRank()==1 ) readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + theargs[0]->getName() + " MASK=" + getShortcutLabel() + "_mask");
+      86          14 :   else if( theargs[0]->getRank()==2 ) readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + getShortcutLabel() + "_flat MASK=" + getShortcutLabel() + "_mask");
+      87         114 : }
+      88             : 
+      89             : }
+      90             : }
+
+
+
+ + + + +
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 000000000..6335eddb6 --- /dev/null +++ b/coverage/valtools/SelectWithMask.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:9210488.5 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools14SelectWithMaskC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8valtools14SelectWithMask21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE18
_ZN4PLMD8valtools14SelectWithMaskC1ERKNS_13ActionOptionsE93
_ZN4PLMD8valtools14SelectWithMask22getNumberOfDerivativesEv98
_ZN4PLMD8valtools14SelectWithMask16registerKeywordsERNS_8KeywordsE178
_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 000000000..1a198f583 --- /dev/null +++ b/coverage/valtools/SelectWithMask.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:9210488.5 %
Date:2024-10-17 16:45:00Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools14SelectWithMask16registerKeywordsERNS_8KeywordsE178
_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 000000000..82831e5ee --- /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:9210488.5 %
Date:2024-10-17 16:45:00Functions: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         178 : void SelectWithMask::registerKeywords( Keywords& keys ) {
+      64         178 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      65         178 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      66         356 :   keys.add("optional","ROW_MASK","an array with ones in the rows of the matrix that you want to discard");
+      67         356 :   keys.add("optional","COLUMN_MASK","an array with ones in the columns of the matrix that you want to discard");
+      68         356 :   keys.add("compulsory","MASK","an array with ones in the components that you want to discard");
+      69         178 :   keys.setValueDescription("a vector/matrix of values that is obtained using a mask to select elements of interest");
+      70         178 : }
+      71             : 
+      72          93 : SelectWithMask::SelectWithMask(const ActionOptions& ao):
+      73             :   Action(ao),
+      74             :   ActionWithValue(ao),
+      75          93 :   ActionWithArguments(ao)
+      76             : {
+      77          93 :   if( getNumberOfArguments()!=1 ) error("should only be one argument for this action");
+      78          93 :   getPntrToArgument(0)->buildDataStore(); std::vector<unsigned> shape;
+      79          93 :   if( getPntrToArgument(0)->getRank()==1 ) {
+      80         136 :     std::vector<Value*> mask; parseArgumentList("MASK",mask);
+      81          68 :     if( mask.size()!=1 ) error("should only be one input for mask");
+      82          68 :     if( mask[0]->getNumberOfValues()!=getPntrToArgument(0)->getNumberOfValues() ) error("mismatch between size of mask and input vector");
+      83          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() );
+      84          68 :     std::vector<Value*> args( getArguments() ); args.push_back( mask[0] ); requestArguments( args );
+      85          68 :     shape.resize(1,0); if( (mask[0]->getPntrToAction())->getName()=="CONSTANT" ) shape[0]=getOutputVectorLength(mask[0]);
+      86          25 :   } else if( getPntrToArgument(0)->getRank()==2 ) {
+      87          75 :     std::vector<Value*> rmask, cmask; parseArgumentList("ROW_MASK",rmask); parseArgumentList("COLUMN_MASK",cmask);
+      88          25 :     if( rmask.size()==0 && cmask.size()==0 ) {
+      89           0 :       error("no mask elements have been specified");
+      90          25 :     } else if( cmask.size()==0 ) {
+      91         144 :       std::string con="0"; for(unsigned i=1; i<getPntrToArgument(0)->getShape()[1]; ++i) con += ",0";
+      92          22 :       plumed.readInputLine( getLabel() + "_colmask: CONSTANT VALUES=" + con ); std::vector<std::string> labs(1, getLabel() + "_colmask");
+      93          11 :       ActionWithArguments::interpretArgumentList( labs, plumed.getActionSet(), this, cmask );
+      94          25 :     } else if( rmask.size()==0 ) {
+      95          13 :       std::string con="0"; for(unsigned i=1; i<getPntrToArgument(0)->getShape()[0]; ++i) con += ",0";
+      96           2 :       plumed.readInputLine( getLabel() + "_rowmask: CONSTANT VALUES=" + con ); std::vector<std::string> labs(1, getLabel() + "_rowmask");
+      97           1 :       ActionWithArguments::interpretArgumentList( labs, plumed.getActionSet(), this, rmask );
+      98           1 :     }
+      99          25 :     shape.resize(2);
+     100          25 :     rmask[0]->buildDataStore(); shape[0] = getOutputVectorLength( rmask[0] );
+     101          25 :     cmask[0]->buildDataStore(); shape[1] = getOutputVectorLength( cmask[0] );
+     102          25 :     std::vector<Value*> args( getArguments() ); args.push_back( rmask[0] );
+     103          25 :     args.push_back( cmask[0] ); requestArguments( args );
+     104           0 :   } else error("input should be vector or matrix");
+     105             : 
+     106          93 :   addValue( shape ); getPntrToComponent(0)->buildDataStore();
+     107          93 :   if( getPntrToArgument(0)->isPeriodic() ) {
+     108           7 :     std::string min, max; getPntrToArgument(0)->getDomain( min, max ); setPeriodic( min, max );
+     109          86 :   } else setNotPeriodic();
+     110          93 :   if( getPntrToComponent(0)->getRank()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     111          93 : }
+     112             : 
+     113       10693 : unsigned SelectWithMask::getOutputVectorLength( const Value* mask ) const  {
+     114             :   unsigned l=0;
+     115      154139 :   for(unsigned i=0; i<mask->getNumberOfValues(); ++i) {
+     116      143446 :     if( fabs(mask->get(i))>0 ) continue;
+     117      133435 :     l++;
+     118             :   }
+     119       10693 :   return l;
+     120             : }
+     121             : 
+     122          18 : void SelectWithMask::getMatrixColumnTitles( std::vector<std::string>& argnames ) const {
+     123          18 :   std::vector<std::string> alltitles; (getPntrToArgument(0)->getPntrToAction())->getMatrixColumnTitles( alltitles );
+     124         103 :   for(unsigned i=0; i<alltitles.size(); ++i) {
+     125          85 :     if( fabs(getPntrToArgument(2)->get(i))>0 ) continue;
+     126          51 :     argnames.push_back( alltitles[i] );
+     127             :   }
+     128          18 : }
+     129             : 
+     130       10551 : void SelectWithMask::prepare() {
+     131       10551 :   Value* arg = getPntrToArgument(0); Value* out = getPntrToComponent(0);
+     132       10551 :   if( arg->getRank()==1 ) {
+     133             :     Value* mask = getPntrToArgument(1);
+     134       10516 :     std::vector<unsigned> shape(1); shape[0]=getOutputVectorLength( mask );
+     135       10516 :     if( out->getNumberOfValues()!=shape[0] ) {
+     136          19 :       if( shape[0]==1 ) shape.resize(0);
+     137          19 :       out->setShape(shape);
+     138             :     }
+     139          35 :   } else if( arg->getRank()==2 ) {
+     140          35 :     std::vector<unsigned> outshape(2);
+     141          35 :     Value* rmask = getPntrToArgument(1); outshape[0] = getOutputVectorLength( rmask );
+     142          35 :     Value* cmask = getPntrToArgument(2); outshape[1] = getOutputVectorLength( cmask );
+     143          35 :     if( out->getShape()[0]!=outshape[0] || out->getShape()[1]!=outshape[1] ) {
+     144          20 :       out->setShape(outshape); out->reshapeMatrixStore( outshape[1] );
+     145             :     }
+     146             :   }
+     147       10551 : }
+     148             : 
+     149       10543 : void SelectWithMask::calculate() {
+     150       10543 :   Value* arg = getPntrToArgument(0); Value* out = getPntrToComponent(0);
+     151       10543 :   if( arg->getRank()==1 ) {
+     152             :     Value* mask = getPntrToArgument(1); unsigned n=0;
+     153      149144 :     for(unsigned i=0; i<mask->getNumberOfValues(); ++i) {
+     154      138632 :       if( fabs(mask->get(i))>0 ) continue;
+     155      131198 :       out->set(n, arg->get(i) ); n++;
+     156             :     }
+     157          31 :   } else if ( arg->getRank()==2 ) {
+     158          31 :     std::vector<unsigned> outshape( out->getShape() );
+     159          31 :     unsigned n = 0; std::vector<unsigned> inshape( arg->getShape() );
+     160             :     Value* rmask = getPntrToArgument(1); Value* cmask = getPntrToArgument(2);
+     161        1774 :     for(unsigned i=0; i<inshape[0]; ++i) {
+     162        1743 :       if( fabs(rmask->get(i))>0 ) continue;
+     163             :       unsigned m = 0;
+     164      378651 :       for(unsigned j=0; j<inshape[1]; ++j) {
+     165      377500 :         if( fabs(cmask->get(j))>0 ) continue;
+     166      189405 :         out->set( n*outshape[1] + m, arg->get(i*inshape[1] + j) );
+     167      189405 :         m++;
+     168             :       }
+     169        1151 :       n++;
+     170             :     }
+     171             :   }
+     172       10543 : }
+     173             : 
+     174       10505 : void SelectWithMask::apply() {
+     175       10505 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return ;
+     176             : 
+     177       10443 :   Value* arg = getPntrToArgument(0); Value* out = getPntrToComponent(0);
+     178       10443 :   if( arg->getRank()==1 ) {
+     179             :     unsigned n=0; Value* mask = getPntrToArgument(1);
+     180      145276 :     for(unsigned i=0; i<mask->getNumberOfValues(); ++i) {
+     181      134833 :       if( fabs(mask->get(i))>0 ) continue;
+     182      130680 :       arg->addForce(i, out->getForce(n) ); n++;
+     183             :     }
+     184           0 :   } else if( arg->getRank()==2 ) {
+     185             :     unsigned n = 0;
+     186           0 :     std::vector<unsigned> inshape( arg->getShape() );
+     187           0 :     std::vector<unsigned> outshape( out->getShape() );
+     188             :     Value* rmask = getPntrToArgument(1); Value* cmask = getPntrToArgument(2);
+     189           0 :     for(unsigned i=0; i<inshape[0]; ++i) {
+     190           0 :       if( fabs(rmask->get(i))>0 ) continue;
+     191             :       unsigned m = 0;
+     192           0 :       for(unsigned j=0; j<inshape[1]; ++j) {
+     193           0 :         if( fabs(cmask->get(j))>0 ) continue;
+     194           0 :         arg->addForce( i*inshape[1] + j, out->getForce(n*outshape[1] + m) );
+     195           0 :         m++;
+     196             :       }
+     197           0 :       n++;
+     198             :     }
+     199             :   }
+     200             : }
+     201             : 
+     202             : 
+     203             : 
+     204             : }
+     205             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/VStack.cpp.func-sort-c.html b/coverage/valtools/VStack.cpp.func-sort-c.html new file mode 100644 index 000000000..ef9c7255b --- /dev/null +++ b/coverage/valtools/VStack.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - valtools/VStack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - VStack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7070100.0 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools6VStackC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8valtools6VStack21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE23
_ZN4PLMD8valtools6VStackC1ERKNS_13ActionOptionsE139
_ZN4PLMD8valtools6VStack16registerKeywordsERNS_8KeywordsE254
_ZN4PLMD8valtools6VStack22getNumberOfDerivativesEv294
_ZN4PLMD8valtools6VStack7prepareEv3100
_ZNK4PLMD8valtools6VStack12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE214418
_ZNK4PLMD8valtools6VStack15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE214418
_ZNK4PLMD8valtools6VStack18getNumberOfColumnsEv1270505
_ZNK4PLMD8valtools6VStack11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE4073147
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/VStack.cpp.func.html b/coverage/valtools/VStack.cpp.func.html new file mode 100644 index 000000000..cc7eecfc0 --- /dev/null +++ b/coverage/valtools/VStack.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - valtools/VStack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - VStack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7070100.0 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools6VStack16registerKeywordsERNS_8KeywordsE254
_ZN4PLMD8valtools6VStack22getNumberOfDerivativesEv294
_ZN4PLMD8valtools6VStack7prepareEv3100
_ZN4PLMD8valtools6VStackC1ERKNS_13ActionOptionsE139
_ZN4PLMD8valtools6VStackC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8valtools6VStack11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE4073147
_ZNK4PLMD8valtools6VStack12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE214418
_ZNK4PLMD8valtools6VStack15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE214418
_ZNK4PLMD8valtools6VStack18getNumberOfColumnsEv1270505
_ZNK4PLMD8valtools6VStack21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE23
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/VStack.cpp.gcov.html b/coverage/valtools/VStack.cpp.gcov.html new file mode 100644 index 000000000..246258a5b --- /dev/null +++ b/coverage/valtools/VStack.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + LCOV - plumed test coverage - valtools/VStack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - VStack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7070100.0 %
Date:2024-10-17 16:45:00Functions: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 "core/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 valtools {
+      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     1270505 :   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         254 : void VStack::registerKeywords( Keywords& keys ) {
+      63         254 :   ActionWithMatrix::registerKeywords( keys ); keys.use("ARG");
+      64         254 :   keys.setValueDescription("a matrix that contains the input vectors in its columns");
+      65         254 : }
+      66             : 
+      67         139 : VStack::VStack(const ActionOptions& ao):
+      68             :   Action(ao),
+      69         139 :   ActionWithMatrix(ao)
+      70             : {
+      71         139 :   if( getNumberOfArguments()==0 ) error("no arguments were specificed");
+      72         139 :   if( getPntrToArgument(0)->getRank()>1 ) error("all arguments should be vectors");
+      73             :   unsigned nvals=1; bool periodic=false; std::string smin, smax;
+      74         139 :   if( getPntrToArgument(0)->getRank()==1 ) nvals = getPntrToArgument(0)->getShape()[0];
+      75         139 :   if( getPntrToArgument(0)->isPeriodic() ) { periodic=true; getPntrToArgument(0)->getDomain( smin, smax ); }
+      76             : 
+      77        1228 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      78        1089 :     if( getPntrToArgument(i)->getRank()>1 || (getPntrToArgument(i)->getRank()==1 && getPntrToArgument(i)->hasDerivatives()) ) error("all arguments should be vectors");
+      79        1089 :     if( getPntrToArgument(i)->getRank()==0 ) {
+      80          41 :       if( nvals!=1 ) error("all input vector should have same number of elements");
+      81        1048 :     } else if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all input vector should have same number of elements");
+      82        1089 :     if( periodic ) {
+      83          51 :       if( !getPntrToArgument(i)->isPeriodic() ) error("one argument is periodic but " + getPntrToArgument(i)->getName() + " is not periodic");
+      84          51 :       std::string tmin, tmax; getPntrToArgument(i)->getDomain( tmin, tmax );
+      85          51 :       if( tmin!=smin || tmax!=smax ) error("domain of argument " + getPntrToArgument(i)->getName() + " is different from domain for all other arguments");
+      86        1038 :     } else if( getPntrToArgument(i)->isPeriodic() ) error("one argument is not periodic but " + getPntrToArgument(i)->getName() + " is periodic");
+      87             :   }
+      88             :   // And create a value to hold the matrix
+      89         139 :   std::vector<unsigned> shape(2); shape[0]=nvals; shape[1]=getNumberOfArguments(); addValue( shape );
+      90         139 :   if( periodic ) setPeriodic( smin, smax ); else setNotPeriodic();
+      91             :   // And store this value
+      92         139 :   getPntrToComponent(0)->buildDataStore(); getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      93             :   // Setup everything so we can build the store
+      94         139 :   done_in_chain=true; ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(0)->getPntrToAction() );
+      95         139 :   if( av ) {
+      96          99 :     const ActionWithVector* head0 = av->getFirstActionInChain();
+      97         996 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      98         928 :       ActionWithVector* avv=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+      99         928 :       if( !avv ) continue;
+     100         924 :       if( head0!=avv->getFirstActionInChain() ) { done_in_chain=false; break; }
+     101             :     }
+     102          40 :   } else done_in_chain=false;
+     103         139 :   unsigned nder = buildArgumentStore(0);
+     104             :   // This checks which values have been stored
+     105         139 :   stored.resize( getNumberOfArguments() ); std::string headstr=getFirstActionInChain()->getLabel();
+     106        1228 :   for(unsigned i=0; i<stored.size(); ++i) stored[i] = getPntrToArgument(i)->ignoreStoredValue( headstr );
+     107         139 : }
+     108             : 
+     109          23 : void VStack::getMatrixColumnTitles( std::vector<std::string>& argnames ) const {
+     110          60 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) {
+     111          37 :     if( (getPntrToArgument(j)->getPntrToAction())->getName()=="COLLECT" ) {
+     112          17 :       ActionWithArguments* aa = dynamic_cast<ActionWithArguments*>( getPntrToArgument(j)->getPntrToAction() );
+     113          17 :       plumed_assert( aa && aa->getNumberOfArguments()==1 ); argnames.push_back( (aa->getPntrToArgument(0))->getName() );
+     114          20 :     } else argnames.push_back( getPntrToArgument(j)->getName() );
+     115             :   }
+     116          23 : }
+     117             : 
+     118        3100 : void VStack::prepare() {
+     119        3100 :   ActionWithVector::prepare();
+     120        3100 :   if( getPntrToArgument(0)->getRank()==0 || getPntrToArgument(0)->getShape()[0]==getPntrToComponent(0)->getShape()[0] ) return ;
+     121          18 :   std::vector<unsigned> shape(2); shape[0] = getPntrToArgument(0)->getShape()[0]; shape[1] = getNumberOfArguments();
+     122          18 :   getPntrToComponent(0)->setShape(shape); getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     123             : }
+     124             : 
+     125      214418 : void VStack::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     126      214418 :   unsigned nargs = getNumberOfArguments(); unsigned nvals = getConstPntrToComponent(0)->getShape()[0];
+     127      214418 :   if( indices.size()!=nargs+1 ) indices.resize( nargs+1 );
+     128     4287565 :   for(unsigned i=0; i<nargs; ++i) indices[i+1] = nvals + i;
+     129             :   myvals.setSplitIndex( nargs + 1 );
+     130      214418 : }
+     131             : 
+     132     4073147 : void VStack::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     133     4073147 :   unsigned ind2 = index2; if( index2>=getConstPntrToComponent(0)->getShape()[0] ) ind2 = index2 - getConstPntrToComponent(0)->getShape()[0];
+     134     4073147 :   myvals.addValue( getConstPntrToComponent(0)->getPositionInStream(), getArgumentElement( ind2, index1, myvals ) );
+     135             : 
+     136     4073147 :   if( doNotCalculateDerivatives() ) return;
+     137     3692599 :   addDerivativeOnVectorArgument( stored[ind2], 0, ind2, index1, 1.0, myvals );
+     138             : }
+     139             : 
+     140      214418 : void VStack::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     141      214418 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     142             : 
+     143           3 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     144             :   std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) );
+     145           3 :   plumed_assert( nmat_ind<matrix_indices.size() );
+     146          12 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     147           9 :     bool found=false; ActionWithValue* iav = getPntrToArgument(i)->getPntrToAction();
+     148           9 :     for(unsigned j=0; j<i; ++j) {
+     149           6 :       if( iav==getPntrToArgument(j)->getPntrToAction() ) { found=true; break; }
+     150             :     }
+     151           9 :     if( found ) continue ;
+     152             : 
+     153             :     unsigned istrn = getPntrToArgument(i)->getPositionInStream();
+     154          48 :     for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     155          45 :       matrix_indices[nmat_ind] = myvals.getActiveIndex(istrn,k); nmat_ind++;
+     156             :     }
+     157             :   }
+     158             :   myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     159             : }
+     160             : 
+     161             : }
+     162             : }
+
+
+
+ + + + +
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 000000000..23f9d499c --- /dev/null +++ b/coverage/valtools/index-sort-f.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - valtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtoolsHitTotalCoverage
Test:plumed test coverageLines:30432194.7 %
Date:2024-10-17 16:45:00Functions:293485.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SelectComponents.cpp +
96.9%96.9%
+
96.9 %31 / 3266.7 %2 / 3
Flatten.cpp +
100.0%
+
100.0 %27 / 2783.3 %5 / 6
Concatenate.cpp +
95.5%95.5%
+
95.5 %84 / 8883.3 %5 / 6
SelectWithMask.cpp +
88.5%88.5%
+
88.5 %92 / 10488.9 %8 / 9
VStack.cpp +
100.0%
+
100.0 %70 / 7090.0 %9 / 10
+
+
+ + + + +
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 000000000..484fbb9f6 --- /dev/null +++ b/coverage/valtools/index-sort-l.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - valtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtoolsHitTotalCoverage
Test:plumed test coverageLines:30432194.7 %
Date:2024-10-17 16:45:00Functions:293485.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SelectWithMask.cpp +
88.5%88.5%
+
88.5 %92 / 10488.9 %8 / 9
Concatenate.cpp +
95.5%95.5%
+
95.5 %84 / 8883.3 %5 / 6
SelectComponents.cpp +
96.9%96.9%
+
96.9 %31 / 3266.7 %2 / 3
Flatten.cpp +
100.0%
+
100.0 %27 / 2783.3 %5 / 6
VStack.cpp +
100.0%
+
100.0 %70 / 7090.0 %9 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/index.html b/coverage/valtools/index.html new file mode 100644 index 000000000..05e43e5e3 --- /dev/null +++ b/coverage/valtools/index.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - valtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtoolsHitTotalCoverage
Test:plumed test coverageLines:30432194.7 %
Date:2024-10-17 16:45:00Functions:293485.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Concatenate.cpp +
95.5%95.5%
+
95.5 %84 / 8883.3 %5 / 6
Flatten.cpp +
100.0%
+
100.0 %27 / 2783.3 %5 / 6
SelectComponents.cpp +
96.9%96.9%
+
96.9 %31 / 3266.7 %2 / 3
SelectWithMask.cpp +
88.5%88.5%
+
88.5 %92 / 10488.9 %8 / 9
VStack.cpp +
100.0%
+
100.0 %70 / 7090.0 %9 / 10
+
+
+ + + + +
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 000000000..196589d26 --- /dev/null +++ b/coverage/vatom/ArgsToVatom.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom11ArgsToVatomC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom11ArgsToVatomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom11ArgsToVatom16registerKeywordsERNS_8KeywordsE20
_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 000000000..3f82c5d22 --- /dev/null +++ b/coverage/vatom/ArgsToVatom.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom11ArgsToVatom16registerKeywordsERNS_8KeywordsE20
_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 000000000..f6f7f7099 --- /dev/null +++ b/coverage/vatom/ArgsToVatom.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + 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-10-17 16:45:00Functions: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          20 : void ArgsToVatom::registerKeywords( Keywords& keys ) {
+      63          20 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys );
+      64          40 :   keys.add("compulsory","XPOS","the x position of the atom");
+      65          40 :   keys.add("compulsory","YPOS","the y position of the atom");
+      66          40 :   keys.add("compulsory","ZPOS","the z position of the atom");
+      67          40 :   keys.add("compulsory","MASS","the mass of the atom");
+      68          40 :   keys.add("compulsory","CHARGE","the charge of the atom");
+      69          40 :   keys.add("hidden","XBKP","x position to use in case PBC not set when using PHASES");
+      70          40 :   keys.add("hidden","YBKP","y position to use in case PBC not set when using PHASES");
+      71          40 :   keys.add("hidden","ZBKP","z position to use in case PBC not set when using PHASES");
+      72          40 :   keys.addFlag("FRACTIONAL",false,"the input arguments are calculated in fractional coordinates so you need to multiply by the cell");
+      73          40 :   keys.addOutputComponent("x","default","the x coordinate of the virtual atom");
+      74          40 :   keys.addOutputComponent("y","default","the y coordinate of the virtual atom");
+      75          40 :   keys.addOutputComponent("z","default","the z coordinate of the virtual atom");
+      76          40 :   keys.addOutputComponent("mass","default","the mass of the virtual atom");
+      77          40 :   keys.addOutputComponent("charge","default","the charge of the virtual atom");
+      78          20 : }
+      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 000000000..387e2b8aa --- /dev/null +++ b/coverage/vatom/Center.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:12212399.2 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE9576
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE17317
_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 000000000..7e1cfbd1e --- /dev/null +++ b/coverage/vatom/Center.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:12212399.2 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE17317
_ZN4PLMD5vatom6Center9calculateEv32946
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE9576
_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 000000000..0727cb40b --- /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:12212399.2 %
Date:2024-10-17 16:45:00Functions: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       17317 : void Center::registerKeywords(Keywords& keys) {
+     151       17317 :   ActionWithVirtualAtom::registerKeywords(keys);
+     152       50111 :   if( keys.getDisplayName()!="COM" ) keys.setDisplayName("CENTER");
+     153       34634 :   keys.add("optional","WEIGHTS","Center is computed as a weighted average.");
+     154       34634 :   keys.add("optional","SET_CHARGE","Set the charge of the virtual atom to a given value.");
+     155       34634 :   keys.add("optional","SET_MASS","Set the mass of the virtual atom to a given value.");
+     156       34634 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     157       34634 :   keys.addFlag("MASS",false,"If set center is mass weighted");
+     158       34634 :   keys.addFlag("PHASES",false,"Compute center using trigonometric phases");
+     159       17317 : }
+     160             : 
+     161        9576 : Center::Center(const ActionOptions&ao):
+     162             :   Action(ao),
+     163             :   ActionWithVirtualAtom(ao),
+     164        9576 :   isChargeSet_(false),
+     165        9576 :   isMassSet_(false),
+     166        9576 :   weight_mass(false),
+     167        9576 :   nopbc(false),
+     168        9576 :   first(true),
+     169        9576 :   phases(false)
+     170             : {
+     171             :   std::vector<AtomNumber> atoms;
+     172       19152 :   parseAtomList("ATOMS",atoms);
+     173        9576 :   if(atoms.size()==0) error("at least one atom should be specified");
+     174        9576 :   parseVector("WEIGHTS",weights);
+     175        9576 :   parseFlag("MASS",weight_mass);
+     176        9576 :   parseFlag("NOPBC",nopbc);
+     177        9576 :   parseFlag("PHASES",phases);
+     178       19152 :   double charge_=std::numeric_limits<double>::lowest(); parse("SET_CHARGE",charge_); setCharge(charge_);
+     179        9576 :   if(charge_!=std::numeric_limits<double>::lowest()) isChargeSet_=true;
+     180       19152 :   double mass_=-1; parse("SET_MASS",mass_); setMass(mass_);
+     181        9576 :   if(mass_>0.) isMassSet_=true;
+     182        9576 :   if(mass_==0.) error("SETMASS must be greater than 0");
+     183        9576 :   if( getName()=="COM") weight_mass=true;
+     184        9576 :   checkRead();
+     185        9576 :   log.printf("  of atoms:");
+     186       88601 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     187       79025 :     if(i%25==0) log<<"\n";
+     188       79025 :     log.printf(" %d",atoms[i].serial());
+     189             :   }
+     190        9576 :   log<<"\n";
+     191        9576 :   if(weight_mass) {
+     192        1840 :     log<<"  mass weighted\n";
+     193        1840 :     if(weights.size()!=0) error("WEIGHTS and MASS keywords cannot not be used simultaneously");
+     194             :   } else {
+     195        7736 :     if( weights.size()==0) {
+     196         693 :       log<<" using the geometric center\n";
+     197         693 :       weights.resize( atoms.size() );
+     198        3115 :       for(unsigned i=0; i<atoms.size(); i++) weights[i] = 1.;
+     199             :     } else {
+     200        7043 :       log<<" with weights:";
+     201        7044 :       if( weights.size()!=atoms.size() ) error("number of elements in weight vector does not match the number of atoms");
+     202       35274 :       for(unsigned i=0; i<weights.size(); ++i) {
+     203       28232 :         if(i%25==0) log<<"\n";
+     204       28232 :         log.printf(" %f",weights[i]);
+     205             :       }
+     206        7042 :       log.printf("\n");
+     207             :     }
+     208             :   }
+     209        9575 :   if(phases) {
+     210           4 :     log<<"  Phases will be used to take into account PBC\n";
+     211        9571 :   } else if(nopbc) {
+     212          47 :     log<<"  PBC will be ignored\n";
+     213             :   } else {
+     214        9524 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     215             :   }
+     216        9575 :   requestAtoms(atoms);
+     217        9577 : }
+     218             : 
+     219       32946 : void Center::calculate() {
+     220       32946 :   Vector pos;
+     221       32946 :   const bool dophases=(getPbc().isSet() ? phases : false);
+     222             : 
+     223       32946 :   if(!nopbc && !dophases) makeWhole();
+     224             : 
+     225       32946 :   if( first ) {
+     226       15376 :     if( weight_mass ) {
+     227      172257 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     228      164230 :         if(std::isnan(getMass(i))) {
+     229           0 :           error(
+     230             :             "You are trying to compute a CENTER or COM but masses are not known.\n"
+     231             :             "        If you are using plumed driver, please use the --mc option"
+     232             :           );
+     233             :         }
+     234             :       }
+     235             :     }
+     236             :     double mass(0.0);
+     237      209364 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) mass+=getMass(i);
+     238       15376 :     if( chargesWereSet && !isChargeSet_) {
+     239             :       double charge(0.0);
+     240      192732 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) charge+=getCharge(i);
+     241       13318 :       setCharge(charge);
+     242        2058 :     } else if( !isChargeSet_ ) {
+     243        2056 :       setCharge(0.0);
+     244             :     }
+     245       15376 :     if(!isMassSet_) setMass(mass);
+     246             : 
+     247       15376 :     if( weight_mass ) {
+     248        8027 :       weights.resize( getNumberOfAtoms() );
+     249      172257 :       for(unsigned i=0; i<weights.size(); i++) weights[i] = getMass(i) / mass;
+     250             :     } else {
+     251             :       double wtot=0.0;
+     252       37107 :       for(unsigned i=0; i<weights.size(); i++) wtot+=weights[i];
+     253       37107 :       for(unsigned i=0; i<weights.size(); i++) weights[i]=weights[i]/wtot;
+     254        7349 :       first=false;
+     255             :     }
+     256             :   }
+     257             : 
+     258       32946 :   deriv.resize(getNumberOfAtoms());
+     259             : 
+     260       32946 :   if(dophases) {
+     261         241 :     dcenter_sin.resize(getNumberOfAtoms());
+     262         241 :     dcenter_cos.resize(getNumberOfAtoms());
+     263         241 :     Vector center_sin;
+     264         241 :     Vector center_cos;
+     265         241 :     Tensor invbox2pi=2*pi*getPbc().getInvBox();
+     266         241 :     Tensor box2pi=getPbc().getBox() / (2*pi);
+     267         964 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     268         723 :       double w=weights[i];
+     269             : 
+     270             :       // real to scaled
+     271         723 :       const Vector scaled=matmul(getPosition(i),invbox2pi);
+     272             :       const Vector ccos(
+     273         723 :         w*std::cos(scaled[0]),
+     274         723 :         w*std::cos(scaled[1]),
+     275         723 :         w*std::cos(scaled[2])
+     276         723 :       );
+     277             :       const Vector csin(
+     278         723 :         w*std::sin(scaled[0]),
+     279         723 :         w*std::sin(scaled[1]),
+     280         723 :         w*std::sin(scaled[2])
+     281         723 :       );
+     282         723 :       center_cos+=ccos;
+     283         723 :       center_sin+=csin;
+     284        9399 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     285             :           // k over real coordinates
+     286             :           // l over scaled coordinates
+     287        6507 :           dcenter_sin[i][l][k]=ccos[l]*invbox2pi[k][l];
+     288        6507 :           dcenter_cos[i][l][k]=-csin[l]*invbox2pi[k][l];
+     289             :         }
+     290             :     }
+     291             :     const Vector c(
+     292         241 :       std::atan2(center_sin[0],center_cos[0]),
+     293         241 :       std::atan2(center_sin[1],center_cos[1]),
+     294         241 :       std::atan2(center_sin[2],center_cos[2])
+     295         241 :     );
+     296             : 
+     297             :     // normalization is convenient for doing derivatives later
+     298         964 :     for(unsigned l=0; l<3; l++) {
+     299         723 :       double norm=1.0/(center_sin[l]*center_sin[l]+center_cos[l]*center_cos[l]);
+     300         723 :       center_sin[l]*=norm;
+     301         723 :       center_cos[l]*=norm;
+     302             :     }
+     303             : 
+     304         964 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     305         723 :       Tensor dd;
+     306        9399 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     307             :           // k over real coordinates
+     308             :           // l over scaled coordinates
+     309        6507 :           dd[l][k]= (center_cos[l]*dcenter_sin[i][l][k] - center_sin[l]*dcenter_cos[i][l][k]);
+     310             :         }
+     311             :       // scaled to real
+     312         723 :       deriv[i]=matmul(dd,box2pi);
+     313             :     }
+     314         241 :     setAtomsDerivatives(deriv);
+     315             :     // scaled to real
+     316         241 :     setPosition(matmul(c,box2pi));
+     317             :   } else {
+     318      412212 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     319      379507 :       double w=weights[i];
+     320      379507 :       pos+=w*getPosition(i);
+     321      379507 :       deriv[i]=w*Tensor::identity();
+     322             :     }
+     323       32705 :     setPosition(pos);
+     324       32705 :     setAtomsDerivatives(deriv);
+     325             :   }
+     326       32946 : }
+     327             : 
+     328             : }
+     329             : }
+
+
+
+ + + + +
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 000000000..c73b83365 --- /dev/null +++ b/coverage/vatom/CenterShortcut.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:707988.6 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom14CenterShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom14CenterShortcutC1ERKNS_13ActionOptionsE7748
_ZN4PLMD5vatom14CenterShortcut16registerKeywordsERNS_8KeywordsE8049
+
+
+ + + +
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 000000000..cef43568d --- /dev/null +++ b/coverage/vatom/CenterShortcut.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:707988.6 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom14CenterShortcut16registerKeywordsERNS_8KeywordsE8049
_ZN4PLMD5vatom14CenterShortcutC1ERKNS_13ActionOptionsE7748
_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 000000000..d03f400a5 --- /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:707988.6 %
Date:2024-10-17 16:45:00Functions: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        8049 : void CenterShortcut::registerKeywords( Keywords& keys ) {
+      36        8049 :   ActionShortcut::registerKeywords( keys );
+      37       16098 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the Gyration Tensor for");
+      38       16098 :   keys.add("compulsory","TYPE","RADIUS","The type of calculation relative to the Gyration Tensor you want to perform");
+      39       16098 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      40       16098 :   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       16098 :   keys.addFlag("PHASES",false,"use trigonometric phases when computing position of center");
+      45       16098 :   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       16098 :   keys.addFlag("MASS",false,"calculate the center of mass"); keys.addActionNameSuffix("_FAST");
+      48        8049 :   keys.setValueDescription("the position of the center of mass");
+      49       32196 :   keys.needsAction("MASS"); keys.needsAction("SUM"); keys.needsAction("CHARGE"); keys.needsAction("CONSTANT");
+      50       24147 :   keys.needsAction("CUSTOM"); keys.needsAction("POSITION"); keys.needsAction("ARGS2VATOM");
+      51        8049 : }
+      52             : 
+      53        7748 : CenterShortcut::CenterShortcut(const ActionOptions& ao):
+      54             :   Action(ao),
+      55        7748 :   ActionShortcut(ao)
+      56             : {
+      57             :   // Read in what we are doing with the weights
+      58       15496 :   bool usemass; parseFlag("MASS",usemass);
+      59        7748 :   std::vector<std::string> str_weights; parseVector("WEIGHTS",str_weights);
+      60        7757 :   if( usemass || str_weights.size()==0 || str_weights.size()>1 || (str_weights.size()==1 && str_weights[0]=="@Masses") ) {
+      61        7739 :     if( usemass && str_weights.size()!=0 ) error("WEIGHTS and MASS keywords cannot not be used simultaneously");
+      62             :     std::string wt_str;
+      63        7738 :     if( str_weights.size()>0 ) {
+      64       35278 :       wt_str="WEIGHTS=" + str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) wt_str += "," + str_weights[i];
+      65             :     }
+      66        7738 :     if( usemass || (str_weights.size()==1 && str_weights[0]=="@Masses") ) wt_str = "MASS";
+      67       15480 :     readInputLine( getShortcutLabel() + ": CENTER_FAST " + wt_str + " " + convertInputLineToString() );
+      68             :     return;
+      69             :   }
+      70             :   // Read in the atoms
+      71           9 :   std::string atlist; parse("ATOMS",atlist);
+      72             :   // Calculate the mass of the vatom
+      73          18 :   readInputLine( getShortcutLabel() + "_m: MASS ATOMS=" + atlist );
+      74          18 :   readInputLine( getShortcutLabel() + "_mass: SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_m" );
+      75             :   // Calculate the charge of the vatom
+      76          18 :   readInputLine( getShortcutLabel() + "_q: CHARGE ATOMS=" + atlist );
+      77          18 :   readInputLine( getShortcutLabel() + "_charge: SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_q" );
+      78             :   // Retrieve the number of atoms
+      79           9 :   ActionWithValue* am = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_m" );
+      80           9 :   unsigned nat=am->copyOutput(0)->getNumberOfValues();
+      81             :   // Get the weights to use for each atom
+      82           9 :   std::string wlab = getShortcutLabel() + "_w";
+      83           9 :   if( str_weights.size()>0 ) {
+      84           9 :     if( str_weights.size()==1 ) {
+      85           9 :       if( str_weights[0]=="@Charges" ) wlab = getShortcutLabel() + "_q";
+      86             :       else wlab=str_weights[0];
+      87           0 :     } else if( str_weights.size()==nat ) {
+      88           0 :       std::string vals=str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) vals += "," + str_weights[i];
+      89           0 :       readInputLine( getShortcutLabel() + "_w: CONSTANT VALUES=" + vals );
+      90           0 :     } else error("invalid input for WEIGHTS keyword " + str_weights[0] );
+      91             :   } else {
+      92           0 :     std::string ones="1"; for(unsigned i=1; i<nat; ++i) ones += ",1";
+      93           0 :     readInputLine( getShortcutLabel() + "_w: CONSTANT VALUES=" + ones );
+      94             :   }
+      95             :   // Read in the instructions on how to compute the center of mass
+      96          18 :   bool safe_phases, phases, nopbc; parseFlag("SAFE_PHASES",safe_phases); parseFlag("NOPBC",nopbc);
+      97          18 :   if( safe_phases ) phases=true; else parseFlag("PHASES",phases);
+      98             :   // This computes a center in the conventional way
+      99           9 :   if( !phases || safe_phases ) {
+     100             :     // Calculate the sum of the weights
+     101           4 :     readInputLine( getShortcutLabel() + "_wnorm: SUM PERIODIC=NO ARG=" + wlab );
+     102             :     // Compute the normalised weights
+     103           4 :     readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + getShortcutLabel() + "_wnorm," + wlab + " FUNC=y/x PERIODIC=NO");
+     104             :     // Get the positions into a multicolvar
+     105           3 :     if( phases || nopbc ) readInputLine( getShortcutLabel() + "_pos: POSITION NOPBC ATOMS=" + atlist );
+     106           2 :     else readInputLine( getShortcutLabel() + "_pos: POSITION WHOLEMOLECULES ATOMS=" + atlist );
+     107             :     // Multiply each vector of positions by the weight
+     108           4 :     readInputLine( getShortcutLabel() + "_xwvec: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_pos.x FUNC=x*y PERIODIC=NO");
+     109           4 :     readInputLine( getShortcutLabel() + "_ywvec: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_pos.y FUNC=x*y PERIODIC=NO");
+     110           4 :     readInputLine( getShortcutLabel() + "_zwvec: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_pos.z FUNC=x*y PERIODIC=NO");
+     111             :     // And sum the weighted vectors
+     112           4 :     readInputLine( getShortcutLabel() + "_x: SUM ARG=" + getShortcutLabel() + "_xwvec PERIODIC=NO");
+     113           4 :     readInputLine( getShortcutLabel() + "_y: SUM ARG=" + getShortcutLabel() + "_ywvec PERIODIC=NO");
+     114           4 :     readInputLine( getShortcutLabel() + "_z: SUM ARG=" + getShortcutLabel() + "_zwvec PERIODIC=NO");
+     115             :   }
+     116             :   // This computes a center using the trigonometric phases
+     117           9 :   if( phases ) {
+     118             :     // Get the positions into a multicolvar
+     119          14 :     readInputLine( getShortcutLabel() + "_fpos: POSITION SCALED_COMPONENTS ATOMS=" + atlist );
+     120             :     // Calculate the sines and cosines of the positions and multiply by the weights
+     121          14 :     readInputLine( getShortcutLabel() + "_sina: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.a FUNC=x*sin(2*pi*y) PERIODIC=NO");
+     122          14 :     readInputLine( getShortcutLabel() + "_cosa: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.a FUNC=x*cos(2*pi*y) PERIODIC=NO");
+     123          14 :     readInputLine( getShortcutLabel() + "_sinb: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.b FUNC=x*sin(2*pi*y) PERIODIC=NO");
+     124          14 :     readInputLine( getShortcutLabel() + "_cosb: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.b FUNC=x*cos(2*pi*y) PERIODIC=NO");
+     125          14 :     readInputLine( getShortcutLabel() + "_sinc: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.c FUNC=x*sin(2*pi*y) PERIODIC=NO");
+     126          14 :     readInputLine( getShortcutLabel() + "_cosc: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.c FUNC=x*cos(2*pi*y) PERIODIC=NO");
+     127             :     // Sum the sines and cosines
+     128          14 :     readInputLine( getShortcutLabel() + "_sinsuma: SUM ARG=" + getShortcutLabel() + "_sina PERIODIC=NO");
+     129          14 :     readInputLine( getShortcutLabel() + "_cossuma: SUM ARG=" + getShortcutLabel() + "_cosa PERIODIC=NO");
+     130          14 :     readInputLine( getShortcutLabel() + "_sinsumb: SUM ARG=" + getShortcutLabel() + "_sinb PERIODIC=NO");
+     131          14 :     readInputLine( getShortcutLabel() + "_cossumb: SUM ARG=" + getShortcutLabel() + "_cosb PERIODIC=NO");
+     132          14 :     readInputLine( getShortcutLabel() + "_sinsumc: SUM ARG=" + getShortcutLabel() + "_sinc PERIODIC=NO");
+     133          14 :     readInputLine( getShortcutLabel() + "_cossumc: SUM ARG=" + getShortcutLabel() + "_cosc PERIODIC=NO");
+     134             :     // And get the final position in fractional coordinates
+     135          14 :     readInputLine( getShortcutLabel() + "_a: CUSTOM ARG=" + getShortcutLabel() + "_sinsuma," + getShortcutLabel() + "_cossuma FUNC=atan2(x,y)/(2*pi) PERIODIC=NO");
+     136          14 :     readInputLine( getShortcutLabel() + "_b: CUSTOM ARG=" + getShortcutLabel() + "_sinsumb," + getShortcutLabel() + "_cossumb FUNC=atan2(x,y)/(2*pi) PERIODIC=NO");
+     137          14 :     readInputLine( getShortcutLabel() + "_c: CUSTOM ARG=" + getShortcutLabel() + "_sinsumc," + getShortcutLabel() + "_cossumc FUNC=atan2(x,y)/(2*pi) PERIODIC=NO");
+     138             :     // And create the virtual atom
+     139           7 :     if( safe_phases ) {
+     140           0 :       readInputLine( getShortcutLabel() + ": ARGS2VATOM XPOS=" + getShortcutLabel() + "_a YPOS=" + getShortcutLabel() + "_b ZPOS=" + getShortcutLabel() + "_c "
+     141           0 :                      + " XBKP=" + getShortcutLabel() + "_x YBKP=" + getShortcutLabel() + "_y ZBKP=" + getShortcutLabel() + "_z "
+     142           0 :                      + " MASS=" + getShortcutLabel() + "_mass CHARGE=" + getShortcutLabel() + "_charge FRACTIONAL");
+     143             :     } else {
+     144          21 :       readInputLine( getShortcutLabel() + ": ARGS2VATOM XPOS=" + getShortcutLabel() + "_a YPOS=" + getShortcutLabel() + "_b ZPOS=" + getShortcutLabel() + "_c "
+     145          21 :                      + " MASS=" + getShortcutLabel() + "_mass CHARGE=" + getShortcutLabel() + "_charge FRACTIONAL");
+     146             :     }
+     147             :   } else {
+     148             :     // And create the virtual atom
+     149           6 :     readInputLine( getShortcutLabel() + ": ARGS2VATOM XPOS=" + getShortcutLabel() + "_x YPOS=" + getShortcutLabel() + "_y ZPOS=" + getShortcutLabel() + "_z "
+     150           6 :                    + " MASS=" + getShortcutLabel() + "_mass CHARGE=" + getShortcutLabel() + "_charge ");
+     151             :   }
+     152        7752 : }
+     153             : 
+     154             : }
+     155             : }
+
+
+
+ + + + +
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 000000000..106fe3094 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE35
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE40
_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 000000000..c16892f66 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE40
_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 000000000..b83a99798 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + LCOV - plumed test coverage - vatom/FixedAtom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - FixedAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-10-17 16:45:00Functions: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          40 : void FixedAtom::registerKeywords(Keywords& keys) {
+     101          40 :   ActionWithVirtualAtom::registerKeywords(keys);
+     102          80 :   keys.add("compulsory","AT","coordinates of the virtual atom");
+     103          80 :   keys.add("compulsory","SET_MASS","1","mass of the virtual atom");
+     104          80 :   keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom");
+     105          80 :   keys.addFlag("SCALED_COMPONENTS",false,"use scaled components");
+     106          40 : }
+     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 000000000..5e3614c22 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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:7979100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE709
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE711
_ZN4PLMD5vatom5Ghost9calculateEv1413
+
+
+ + + +
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 000000000..8adf35278 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:7979100.0 %
Date:2024-10-17 16:45:00Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE711
_ZN4PLMD5vatom5Ghost9calculateEv1413
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE709
_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 000000000..7e7e61adb --- /dev/null +++ b/coverage/vatom/Ghost.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + 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:7979100.0 %
Date:2024-10-17 16:45:00Functions: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             : When running with periodic boundary conditions, the atoms should be
+      39             : in the proper periodic image. This is done automatically since PLUMED 2.10,
+      40             : by considering the ordered list of atoms and rebuilding the molecule using 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             : The following input instructs plumed to print the distance between the
+      52             : ghost atom and the center of mass for atoms 15,20:
+      53             : \plumedfile
+      54             : c1: GHOST ATOMS=1,5,10 COORDINATES=10.0,10.0,10.0
+      55             : c2: COM ATOMS=15,20
+      56             : d1: DISTANCE ATOMS=c1,c2
+      57             : PRINT ARG=d1
+      58             : \endplumedfile
+      59             : 
+      60             : */
+      61             : //+ENDPLUMEDOC
+      62             : 
+      63             : 
+      64             : class Ghost:
+      65             :   public ActionWithVirtualAtom
+      66             : {
+      67             :   std::vector<double> coord;
+      68             :   std::vector<Tensor> deriv;
+      69             :   bool nopbc=false;
+      70             : public:
+      71             :   explicit Ghost(const ActionOptions&ao);
+      72             :   void calculate() override;
+      73             :   static void registerKeywords( Keywords& keys );
+      74             : };
+      75             : 
+      76             : PLUMED_REGISTER_ACTION(Ghost,"GHOST")
+      77             : 
+      78         711 : void Ghost::registerKeywords(Keywords& keys) {
+      79         711 :   ActionWithVirtualAtom::registerKeywords(keys);
+      80        1422 :   keys.add("atoms","COORDINATES","coordinates of the ghost atom in the local reference frame");
+      81        1422 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      82         711 : }
+      83             : 
+      84         709 : Ghost::Ghost(const ActionOptions&ao):
+      85             :   Action(ao),
+      86         709 :   ActionWithVirtualAtom(ao)
+      87             : {
+      88             :   std::vector<AtomNumber> atoms;
+      89        1418 :   parseAtomList("ATOMS",atoms);
+      90         709 :   if(atoms.size()!=3) error("ATOMS should contain a list of three atoms");
+      91             : 
+      92        1418 :   parseVector("COORDINATES",coord);
+      93         709 :   if(coord.size()!=3) error("COORDINATES should be a list of three real numbers");
+      94             : 
+      95         709 :   parseFlag("NOPBC",nopbc);
+      96             : 
+      97         709 :   checkRead();
+      98         709 :   log.printf("  of atoms");
+      99        2836 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial());
+     100         709 :   log.printf("\n");
+     101             : 
+     102         709 :   if(nopbc) {
+     103           4 :     log<<"  PBC will be ignored\n";
+     104             :   } else {
+     105         705 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     106             :   }
+     107         709 :   requestAtoms(atoms);
+     108         709 : }
+     109             : 
+     110        1413 : void Ghost::calculate() {
+     111             : 
+     112        1413 :   if(!nopbc) makeWhole();
+     113             : 
+     114        1413 :   Vector pos;
+     115        1413 :   deriv.resize(getNumberOfAtoms());
+     116        1413 :   std::array<Vector,3> n;
+     117             : 
+     118             : // first versor
+     119        1413 :   Vector n01 = delta(getPosition(0), getPosition(1));
+     120        1413 :   n[0]=n01/n01.modulo();
+     121             : 
+     122             : // auxiliary vector
+     123        1413 :   Vector n02 = delta(getPosition(0), getPosition(2));
+     124             : 
+     125             : // second versor
+     126        1413 :   Vector n03 = crossProduct(n[0],n02);
+     127        1413 :   double n03_norm = n03.modulo();
+     128        1413 :   n[1]=n03/n03_norm;
+     129             : 
+     130             : // third versor
+     131        1413 :   n[2]=crossProduct(n[0],n[1]);
+     132             : 
+     133             : // origin of the reference system
+     134        1413 :   pos = getPosition(0);
+     135             : 
+     136        5652 :   for(unsigned i=0; i<3; ++i) {
+     137        4239 :     pos += coord[i] * n[i];
+     138             :   }
+     139             : 
+     140        1413 :   setPosition(pos);
+     141        1413 :   setMass(1.0);
+     142        1413 :   setCharge(0.0);
+     143             : 
+     144             : // some useful tensors for derivatives
+     145        1413 :   Tensor dn0d0  = (-Tensor::identity()+Tensor(n[0],n[0]))/n01.modulo();
+     146        1413 :   Tensor dn0d1  = (+Tensor::identity()-Tensor(n[0],n[0]))/n01.modulo();
+     147        1413 :   Tensor dn02d0 = -Tensor::identity();
+     148        1413 :   Tensor dn02d2 =  Tensor::identity();
+     149             : 
+     150             : // derivative of n1 = n0 x n02
+     151        1413 :   Tensor dn1d0, dn1d1, dn1d2;
+     152        1413 :   Vector aux0, aux1, aux2;
+     153             : 
+     154        5652 :   for(unsigned j=0; j<3; ++j) {
+     155             : // derivative of n0 x n02 with respect to point 0, coordinate j
+     156        4239 :     Vector tmp00  = Vector( dn0d0(j,0),  dn0d0(j,1),  dn0d0(j,2));
+     157        4239 :     Vector tmp020 = Vector(dn02d0(j,0), dn02d0(j,1), dn02d0(j,2));
+     158        4239 :     Vector tmp0   = crossProduct(tmp00,n02) + crossProduct(n[0],tmp020);
+     159        4239 :     aux0[j]       = dotProduct(tmp0,n[1]);
+     160             : // derivative of n0 x n02 with respect to point 1, coordinate j
+     161        4239 :     Vector tmp01  = Vector( dn0d1(j,0),  dn0d1(j,1),  dn0d1(j,2));
+     162        4239 :     Vector tmp1   = crossProduct(tmp01,n02);
+     163        4239 :     aux1[j]       = dotProduct(tmp1,n[1]);
+     164             : // derivative of n0 x n02 with respect to point 2, coordinate j
+     165        4239 :     Vector tmp022 = Vector(dn02d2(j,0), dn02d2(j,1), dn02d2(j,2));
+     166        4239 :     Vector tmp2   = crossProduct(n[0],tmp022);
+     167        4239 :     aux2[j]       = dotProduct(tmp2,n[1]);
+     168             : // derivative of n1 = (n0 x n02) / || (n0 x n02) ||
+     169       16956 :     for(unsigned i=0; i<3; ++i) {
+     170       12717 :       dn1d0(j,i) = ( tmp0[i] - aux0[j] * n[1][i] ) / n03_norm;
+     171       12717 :       dn1d1(j,i) = ( tmp1[i] - aux1[j] * n[1][i] ) / n03_norm;
+     172       12717 :       dn1d2(j,i) = ( tmp2[i] - aux2[j] * n[1][i] ) / n03_norm;
+     173             :     }
+     174             :   }
+     175             : 
+     176             : // Derivative of the last versor n2 = n0 x n1 =  ( n0( n0 n02 ) - n02 ) / || n0 x n02 ||
+     177             : // Scalar product and derivatives
+     178        1413 :   double n0_n02 = dotProduct(n[0],n02);
+     179        1413 :   Vector dn0_n02d0, dn0_n02d1, dn0_n02d2;
+     180             : 
+     181        5652 :   for(unsigned j=0; j<3; ++j) {
+     182       16956 :     for(unsigned i=0; i<3; ++i) {
+     183       12717 :       dn0_n02d0[j] += dn0d0(j,i)*n02[i] + n[0][i]*dn02d0(j,i);
+     184       12717 :       dn0_n02d1[j] += dn0d1(j,i)*n02[i];
+     185       12717 :       dn0_n02d2[j] +=                     n[0][i]*dn02d2(j,i);
+     186             :     }
+     187             :   }
+     188             : 
+     189        1413 :   Tensor dn2d0, dn2d1, dn2d2;
+     190        5652 :   for(unsigned j=0; j<3; ++j) {
+     191       16956 :     for(unsigned i=0; i<3; ++i) {
+     192       12717 :       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;
+     193       12717 :       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;
+     194       12717 :       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;
+     195             :     }
+     196             :   }
+     197             : 
+     198             : // Finally, the derivative tensor
+     199        1413 :   deriv[0] = Tensor::identity() + coord[0]*dn0d0 + coord[1]*dn1d0 + coord[2]*dn2d0;
+     200        1413 :   deriv[1] =                      coord[0]*dn0d1 + coord[1]*dn1d1 + coord[2]*dn2d1;
+     201        1413 :   deriv[2] =                                       coord[1]*dn1d2 + coord[2]*dn2d2;
+     202             : 
+     203        1413 :   setAtomsDerivatives(deriv);
+     204             : 
+     205             : // Virial contribution
+     206        1413 :   setBoxDerivativesNoPbc();
+     207        1413 : }
+     208             : 
+     209             : }
+     210             : }
+
+
+
+ + + + +
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 000000000..0d3a1e56d --- /dev/null +++ b/coverage/vatom/index-sort-f.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:36638694.8 %
Date:2024-10-17 16:45:00Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CenterShortcut.cpp +
88.6%88.6%
+
88.6 %70 / 7966.7 %2 / 3
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %79 / 7975.0 %3 / 4
Center.cpp +
99.2%99.2%
+
99.2 %122 / 12375.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 000000000..cd1580860 --- /dev/null +++ b/coverage/vatom/index-sort-l.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:36638694.8 %
Date:2024-10-17 16:45:00Functions: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.6%88.6%
+
88.6 %70 / 7966.7 %2 / 3
Center.cpp +
99.2%99.2%
+
99.2 %122 / 12375.0 %3 / 4
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %79 / 7975.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 000000000..53560bdc1 --- /dev/null +++ b/coverage/vatom/index.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:36638694.8 %
Date:2024-10-17 16:45:00Functions: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 %122 / 12375.0 %3 / 4
CenterShortcut.cpp +
88.6%88.6%
+
88.6 %70 / 7966.7 %2 / 3
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %79 / 7975.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 000000000..3afc52aa9 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..7aae6f5a2 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b05158576 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Chebyshev.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Chebyshev.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..a1aef04c2 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e1ba79c77 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0d0906312 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.gcov.html @@ -0,0 +1,278 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Combined.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Combined.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-10-17 16:45:00Functions: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 000000000..601f7c4be --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5de77009c --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..d641efeb8 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Cosine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Cosine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..752e0391d --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..82cd2e73a --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0f9f7e87a --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.gcov.html @@ -0,0 +1,277 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_CubicBsplines.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_CubicBsplines.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..0a5ae5e4f --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..47474d7cd --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4115e8ed6 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.gcov.html @@ -0,0 +1,445 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Custom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12515282.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..3cb931498 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c10456deb --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..42fd9adab --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Fourier.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Fourier.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..4dc72ec69 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f3b18a054 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..1a646e485 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.gcov.html @@ -0,0 +1,265 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Gaussians.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Gaussians.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..256d35447 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e26c39256 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c8c7720aa --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.gcov.html @@ -0,0 +1,248 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Legendre.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Legendre.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d96b1e0c2 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..978a4eb34 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f4a059fe4 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Powers.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Powers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..477c4ad99 --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f94342eaf --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a39ed27d0 --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Sine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Sine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..2a15907dd --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c4371df42 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..632135c25 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.gcov.html @@ -0,0 +1,494 @@ + + + + + + + LCOV - plumed test coverage - ves/BF_Wavelets.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Wavelets.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:118118100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..64f56a96d --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..3f5070630 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..b9662f332 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.gcov.html @@ -0,0 +1,481 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..e5009e106 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..65a694d58 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..670ce1864 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.gcov.html @@ -0,0 +1,393 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..f93262ccf --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func-sort-c.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..37de070ee --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..ce9b944a3 --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.gcov.html @@ -0,0 +1,593 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..63b20eee3 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..754a60163 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..7686d171f --- /dev/null +++ b/coverage/ves/CoeffsBase.h.gcov.html @@ -0,0 +1,335 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..db28c1f66 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html @@ -0,0 +1,388 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..17d679493 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func.html @@ -0,0 +1,388 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..253554693 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.gcov.html @@ -0,0 +1,791 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..55f38caad --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..e103b1277 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..c3597e79a --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.gcov.html @@ -0,0 +1,287 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..fad873b1f --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func-sort-c.html @@ -0,0 +1,468 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..5d121e695 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func.html @@ -0,0 +1,468 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..8f4d56694 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.gcov.html @@ -0,0 +1,971 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..cfed88d4c --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..c0b2ebc7e --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..0ea99b097 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.gcov.html @@ -0,0 +1,316 @@ + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..328eb2a44 --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..ac5b6473c --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..f90d3e7e1 --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html @@ -0,0 +1,218 @@ + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..63ef5a935 --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..5aedf2ba6 --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..4e00f329d --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..0176f4482 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..7a68096c0 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..161800a18 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.gcov.html @@ -0,0 +1,311 @@ + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..df579c5b9 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..b3e359ad9 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..380185bbd --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.gcov.html @@ -0,0 +1,158 @@ + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..ff4f1f9dd --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..46d7afdec --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..f7861b97c --- /dev/null +++ b/coverage/ves/GridProjWeights.h.gcov.html @@ -0,0 +1,126 @@ + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..d68a4aa7b --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..361743791 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..db20f35cf --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html @@ -0,0 +1,693 @@ + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..671b8b073 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..0958801a6 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..475a84bdb --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.gcov.html @@ -0,0 +1,326 @@ + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..6c4aadca2 --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-10-17 16:45:00Functions: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_LinearExpansionPESRegisterMeC2Ev5301
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev5301
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE5301
+
+
+ + + +
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 000000000..5e79b288e --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-10-17 16:45:00Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMe6createERKNS_13CLToolOptionsE44
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev5301
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev5301
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE5301
_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 000000000..2570208db --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html @@ -0,0 +1,757 @@ + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-10-17 16:45:00Functions: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       15947 : PLUMED_REGISTER_CLTOOL(MD_LinearExpansionPES,"ves_md_linearexpansion")
+     151             : 
+     152        5301 : void MD_LinearExpansionPES::registerKeywords( Keywords& keys ) {
+     153        5301 :   CLTool::registerKeywords( keys );
+     154       10602 :   keys.add("compulsory","nstep","10","The number of steps of dynamics you want to run.");
+     155       10602 :   keys.add("compulsory","tstep","0.005","The integration timestep.");
+     156       10602 :   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       10602 :   keys.add("compulsory","friction","10.","The friction of the Langevin thermostat. For multiple replica you can give a separate value for each replica.");
+     158       10602 :   keys.add("compulsory","random_seed","5293818","Value of random number seed.");
+     159       10602 :   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       10602 :   keys.add("compulsory","dimension","1","Number of dimensions, supports 1 to 3.");
+     161       10602 :   keys.add("compulsory","initial_position","Initial position of the particle. For multiple replica you can give a separate value for each replica.");
+     162       10602 :   keys.add("compulsory","replicas","1","Number of replicas.");
+     163       10602 :   keys.add("compulsory","basis_functions_1","Basis functions for dimension 1.");
+     164       10602 :   keys.add("optional","basis_functions_2","Basis functions for dimension 2 if needed.");
+     165       10602 :   keys.add("optional","basis_functions_3","Basis functions for dimension 3 if needed.");
+     166       10602 :   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       10602 :   keys.add("compulsory","output_coeffs","potential-coeffs.out.data","Filename of the output coefficient file for the potential.");
+     168       10602 :   keys.add("compulsory","output_coeffs_fmt","%30.16e","Format of the output coefficient file for the potential. Useful for regtests.");
+     169       10602 :   keys.add("optional","coeffs_prefactor","prefactor for multiplying the coefficients with. For multiple replica you can give a separate value for each replica.");
+     170       10602 :   keys.add("optional","template_coeffs_file","only generate a template coefficient file with the filename given and exit.");
+     171       10602 :   keys.add("compulsory","output_potential_grid","100","The number of grid points used for the potential and histogram output files.");
+     172       10602 :   keys.add("compulsory","output_potential","potential.data","Filename of the potential output file.");
+     173       10602 :   keys.add("compulsory","output_histogram","histogram.data","Filename of the histogram output file.");
+     174        5301 : }
+     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 000000000..aa99ada99 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b73292b01 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..65e00cac4 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.gcov.html @@ -0,0 +1,272 @@ + + + + + + + LCOV - plumed test coverage - ves/Opt_Adam.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Adam.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677293.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..601a0a1d2 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..9dcede307 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0233f8925 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html @@ -0,0 +1,378 @@ + + + + + + + LCOV - plumed test coverage - ves/Opt_BachAveragedSGD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_BachAveragedSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..d0699a3fa --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f4a7d2850 --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a760e8856 --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.gcov.html @@ -0,0 +1,197 @@ + + + + + + + LCOV - plumed test coverage - ves/Opt_Dummy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Dummy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..d66516717 --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..38fd170ef --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..cc2481c7c --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - ves/Opt_RobbinsMonroSGD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_RobbinsMonroSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..e0732865f --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func-sort-c.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68376389.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..a9439ec4b --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68376389.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..0a25550f9 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.gcov.html @@ -0,0 +1,1337 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68376389.5 %
Date:2024-10-17 16:45:00Functions: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          87 :   keys.setValueDescription("a scalar");
+     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 000000000..b6bdf68e9 --- /dev/null +++ b/coverage/ves/Optimizer.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..2e9a30d6c --- /dev/null +++ b/coverage/ves/Optimizer.h.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..04d178478 --- /dev/null +++ b/coverage/ves/Optimizer.h.gcov.html @@ -0,0 +1,430 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..9ef75840e --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..874029bf7 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..189f4da4a --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.gcov.html @@ -0,0 +1,312 @@ + + + + + + + LCOV - plumed test coverage - ves/OutputBasisFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputBasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10811098.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..7fe789ea3 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..e562d0a66 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..447fec07d --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + LCOV - plumed test coverage - ves/OutputFesBias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputFesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606888.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..e2ca99679 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b9aa9c7f2 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..af450dec4 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.gcov.html @@ -0,0 +1,302 @@ + + + + + + + LCOV - plumed test coverage - ves/OutputTargetDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputTargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838993.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..32ef72b2c --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..a72688b40 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4c4252935 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_Chi.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Chi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..cf6cd379e --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2668ed884 --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..bf0d68e25 --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_ChiSquared.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ChiSquared.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..6409b7e3c --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..169cab841 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2a053c03e --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_Custom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778986.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..ebd3545af --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..32abd9875 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5e8d6e0dc --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.gcov.html @@ -0,0 +1,205 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_Exponential.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Exponential.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..ff4a918c9 --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..30484961c --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..f2d5fbb69 --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html @@ -0,0 +1,300 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_ExponentiallyModifiedGaussian.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ExponentiallyModifiedGaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:576390.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..abde22c33 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..af8577896 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..968f4374f --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.gcov.html @@ -0,0 +1,391 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_Gaussian.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Gaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768490.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..83bf8664f --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6e82f524b --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..c9284dddd --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedExtremeValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedExtremeValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..e23c14728 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8eeea1a68 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..45da3d608 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html @@ -0,0 +1,303 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedNormal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedNormal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..6a2b11992 --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5120dbaff --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..5ac90f23a --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.gcov.html @@ -0,0 +1,294 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_Grid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555894.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..b1958dc3f --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fecdcdaf0 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fe130785e --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.gcov.html @@ -0,0 +1,353 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_LinearCombination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_LinearCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:587775.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..240de57b2 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..560f70be5 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..aa2424222 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.gcov.html @@ -0,0 +1,550 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4fa7bf67d --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..12413fc6f --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..fc9c9b577 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html @@ -0,0 +1,533 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b81d7aff1 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..51c6821e9 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..3d777b0e4 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_ProductCombination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:557573.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..b2dd37e41 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..24ca1d266 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..49d2288b4 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_ProductDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:487663.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..612797668 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0355a576b --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..406c525d9 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.gcov.html @@ -0,0 +1,381 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_Uniform.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Uniform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..45a2f26fb --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..83efd7ef4 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..2e45326aa --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_VonMises.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_VonMises.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747598.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..81a052a1b --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..486201f85 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..6aad6d589 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.gcov.html @@ -0,0 +1,240 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_WellTempered.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_WellTempered.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-10-17 16:45:00Functions: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 000000000..eb37dbd62 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..1f46cf596 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..afd331fbb --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..3e2836163 --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,176 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..a938efe4c --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func.html @@ -0,0 +1,176 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..4cbcdc34f --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.gcov.html @@ -0,0 +1,464 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..53af2ca4d --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..340b9dedf --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..cb4a432af --- /dev/null +++ b/coverage/ves/TargetDistribution.h.gcov.html @@ -0,0 +1,285 @@ + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-10-17 16:45:00Functions: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 000000000..8f074fbf1 --- /dev/null +++ b/coverage/ves/VesBias.cpp.func-sort-c.html @@ -0,0 +1,252 @@ + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..e99fbf5bc --- /dev/null +++ b/coverage/ves/VesBias.cpp.func.html @@ -0,0 +1,252 @@ + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..41c051596 --- /dev/null +++ b/coverage/ves/VesBias.cpp.gcov.html @@ -0,0 +1,829 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..8b697d8a2 --- /dev/null +++ b/coverage/ves/VesBias.h.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - ves/VesBias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..3c6839aec --- /dev/null +++ b/coverage/ves/VesBias.h.func.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - ves/VesBias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..6753faa62 --- /dev/null +++ b/coverage/ves/VesBias.h.gcov.html @@ -0,0 +1,491 @@ + + + + + + + LCOV - plumed test coverage - ves/VesBias.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-10-17 16:45:00Functions: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 000000000..626b34c3c --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:34235097.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..0623096ce --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:34235097.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..d151b46ea --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.gcov.html @@ -0,0 +1,790 @@ + + + + + + + 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:34235097.7 %
Date:2024-10-17 16:45:00Functions: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          12 :   keys.addOutputComponent("rct","default","the reweighting factor c(t)");
+     214          12 :   keys.addOutputComponent("work","default","the work done by the bias in one AV_STRIDE");
+     215           6 : }
+     216             : 
+     217           4 : VesDeltaF::VesDeltaF(const ActionOptions&ao)
+     218             :   : PLUMED_BIAS_INIT(ao)
+     219           4 :   , isFirstStep_(true)
+     220           4 :   , afterCalculate_(false)
+     221           4 :   , mean_counter_(0)
+     222           4 :   , av_counter_(0)
+     223           4 :   , work_(0)
+     224             : {
+     225             : //set beta
+     226           4 :   const double Kb=getKBoltzmann();
+     227           4 :   double KbT=getkBT();
+     228           4 :   plumed_massert(KbT>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     229           4 :   beta_=1.0/KbT;
+     230             : 
+     231             : //initialize probability grids using local free energies
+     232             :   bool spline=true;
+     233             :   bool sparsegrid=false;
+     234           4 :   std::string funcl="file.free"; //typical name given by sum_hills
+     235             : 
+     236             :   std::vector<std::string> fes_names;
+     237           8 :   for(unsigned n=0;; n++)//NB: here we start from FILE_F0 not from FILE_F1
+     238             :   {
+     239             :     std::string filename;
+     240          24 :     if(!parseNumbered("FILE_F",n,filename))
+     241             :       break;
+     242           8 :     fes_names.push_back(filename);
+     243           8 :     IFile gridfile;
+     244           8 :     gridfile.open(filename);
+     245           8 :     auto g=GridBase::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     246             : // we assume this cannot be sparse. in case we want it to be sparse, some of the methods
+     247             : // that are available only in Grid should be ported to GridBase
+     248           8 :     auto gg=dynamic_cast<Grid*>(g.get());
+     249             : // if this throws, g is deleted
+     250           8 :     plumed_assert(gg);
+     251             : // release ownership in order to transfer it to emplaced pointer
+     252             : // cppcheck-suppress ignoredReturnValue
+     253             :     g.release();
+     254           8 :     grid_p_.emplace_back(gg);
+     255          16 :   }
+     256           4 :   plumed_massert(grid_p_.size()>1,"at least 2 basins must be defined, starting from FILE_F0");
+     257           4 :   alpha_size_=grid_p_.size()-1;
+     258           4 :   sym_alpha_size_=alpha_size_*(alpha_size_+1)/2; //useful for symmetric matrix [alpha_size_]x[alpha_size_]
+     259             :   //check for consistency with first local free energy
+     260           8 :   for(unsigned n=1; n<grid_p_.size(); n++)
+     261             :   {
+     262           8 :     std::string error_tag="FILE_F"+std::to_string(n)+" '"+fes_names[n]+"' not compatible with reference one, FILE_F0";
+     263           4 :     plumed_massert(grid_p_[n]->getSize()==grid_p_[0]->getSize(),error_tag);
+     264           4 :     plumed_massert(grid_p_[n]->getMin()==grid_p_[0]->getMin(),error_tag);
+     265           4 :     plumed_massert(grid_p_[n]->getMax()==grid_p_[0]->getMax(),error_tag);
+     266           4 :     plumed_massert(grid_p_[n]->getBinVolume()==grid_p_[0]->getBinVolume(),error_tag);
+     267             :   }
+     268             : 
+     269           4 :   bool no_mintozero=false;
+     270           4 :   parseFlag("NO_MINTOZERO",no_mintozero);
+     271           4 :   if(!no_mintozero)
+     272             :   {
+     273           6 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     274           4 :       grid_p_[n]->setMinToZero();
+     275             :   }
+     276           4 :   bool normalize=false;
+     277           4 :   parseFlag("NORMALIZE",normalize);
+     278           4 :   norm_.resize(grid_p_.size(),0);
+     279           4 :   std::vector<double> c_norm(grid_p_.size());
+     280             :   //convert the FESs to probability distributions
+     281             :   //NB: the spline interpolation will be done on the probability distributions, not on the given FESs
+     282             :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     283          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     284             :   {
+     285         808 :     for(Grid::index_t t=0; t<grid_p_[n]->getSize(); t++)
+     286             :     {
+     287         800 :       std::vector<double> der(ncv);
+     288         800 :       const double val=std::exp(-beta_*grid_p_[n]->getValueAndDerivatives(t,der));
+     289        1600 :       for(unsigned s=0; s<ncv; s++)
+     290         800 :         der[s]*=-beta_*val;
+     291         800 :       grid_p_[n]->setValueAndDerivatives(t,val,der);
+     292         800 :       norm_[n]+=val;
+     293             :     }
+     294           8 :     c_norm[n]=1./beta_*std::log(norm_[n]);
+     295           8 :     if(normalize)
+     296             :     {
+     297           4 :       grid_p_[n]->scaleAllValuesAndDerivatives(1./norm_[n]);
+     298           4 :       norm_[n]=1;
+     299             :     }
+     300             :   }
+     301             : 
+     302             : //get target
+     303           4 :   double biasfactor=0;
+     304           4 :   parse("BIASFACTOR",biasfactor);
+     305           4 :   plumed_massert(biasfactor==0 || biasfactor>1,"BIASFACTOR must be zero (for uniform target) or greater than one");
+     306           4 :   if(biasfactor==0)
+     307           2 :     inv_gamma_=0;
+     308             :   else
+     309           2 :     inv_gamma_=1./biasfactor;
+     310           4 :   tg_counter_=0;
+     311           4 :   tg_stride_=1;
+     312           4 :   parse("TG_STRIDE",tg_stride_);
+     313           4 :   tg_dV_dAlpha_.resize(alpha_size_,0);
+     314           4 :   tg_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     315             : 
+     316             : //setup optimization stuff
+     317           4 :   minimization_step_=1;
+     318           4 :   parse("M_STEP",minimization_step_);
+     319             : 
+     320           4 :   av_stride_=500;
+     321           4 :   parse("AV_STRIDE",av_stride_);
+     322           4 :   av_dV_dAlpha_.resize(alpha_size_,0);
+     323           4 :   av_dV_dAlpha_prod_.resize(sym_alpha_size_,0);
+     324           4 :   av_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     325             : 
+     326           4 :   mean_weight_tau_=0;
+     327           4 :   parse("TAU_MEAN",mean_weight_tau_);
+     328           4 :   if(mean_weight_tau_!=1) //set it to 1 for basic SGD
+     329             :   {
+     330           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");
+     331           4 :     mean_weight_tau_/=av_stride_; //this way you can look at the number of simulation steps to choose TAU_MEAN
+     332             :   }
+     333             : 
+     334           8 :   parseVector("INITIAL_ALPHA",mean_alpha_);
+     335           4 :   if(mean_alpha_.size()>0)
+     336             :   {
+     337           2 :     plumed_massert(mean_alpha_.size()==alpha_size_,"provide one INITIAL_ALPHA for each basin beyond the first one");
+     338             :   }
+     339             :   else
+     340           2 :     mean_alpha_.resize(alpha_size_,0);
+     341           4 :   inst_alpha_=mean_alpha_;
+     342           4 :   exp_alpha_.resize(alpha_size_);
+     343           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     344           4 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     345           4 :   prev_exp_alpha_=exp_alpha_;
+     346             : 
+     347           4 :   damping_off_=false;
+     348           4 :   parseFlag("DAMPING_OFF",damping_off_);
+     349           4 :   if(damping_off_)
+     350           2 :     past_increment2_.resize(alpha_size_,1);
+     351             :   else
+     352           2 :     past_increment2_.resize(alpha_size_,0);
+     353             : 
+     354             : //file printing options
+     355           4 :   std::string alphaFileName("ALPHA");
+     356           4 :   parse("ALPHA_FILE",alphaFileName);
+     357           4 :   print_stride_=10;
+     358           8 :   parse("PRINT_STRIDE",print_stride_);
+     359             :   std::string fmt;
+     360           4 :   parse("FMT",fmt);
+     361             : 
+     362             : //other flags, mainly for debugging
+     363           4 :   NumParallel_=comm.Get_size();
+     364           4 :   rank_=comm.Get_rank();
+     365           4 :   bool serial=false;
+     366           4 :   parseFlag("SERIAL",serial);
+     367           4 :   if(serial)
+     368             :   {
+     369           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     370           2 :     NumParallel_=1;
+     371           2 :     rank_=0;
+     372             :   }
+     373             : 
+     374           4 :   bool multiple_walkers=false;
+     375           4 :   parseFlag("MULTIPLE_WALKERS",multiple_walkers);
+     376           4 :   if(!multiple_walkers)
+     377           2 :     NumWalkers_=1;
+     378             :   else
+     379             :   {
+     380           2 :     if(comm.Get_rank()==0)//multi_sim_comm works well on first rank only
+     381           2 :       NumWalkers_=multi_sim_comm.Get_size();
+     382           2 :     if(comm.Get_size()>1) //if each walker has more than one processor update them all
+     383           0 :       comm.Bcast(NumWalkers_,0);
+     384             :   }
+     385             : 
+     386           4 :   checkRead();
+     387             : 
+     388             : //restart if needed
+     389           4 :   if(getRestart())
+     390             :   {
+     391           2 :     IFile ifile;
+     392           2 :     ifile.link(*this);
+     393           2 :     if(NumWalkers_>1)
+     394           4 :       ifile.enforceSuffix("");
+     395           2 :     if(ifile.FileExist(alphaFileName))
+     396             :     {
+     397           2 :       log.printf("  Restarting from: %s\n",alphaFileName.c_str());
+     398           2 :       log.printf("    all options (also PRINT_STRIDE) must be consistent!\n");
+     399           2 :       log.printf("    any INITIAL_ALPHA will be overwritten\n");
+     400           2 :       ifile.open(alphaFileName);
+     401             :       double time;
+     402           2 :       std::vector<double> damping(alpha_size_);
+     403          20 :       while(ifile.scanField("time",time)) //room for improvements: only last line is important
+     404             :       {
+     405          16 :         for(unsigned i=0; i<alpha_size_; i++)
+     406             :         {
+     407           8 :           const std::string index(std::to_string(i+1));
+     408           8 :           prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     409          16 :           ifile.scanField("alpha_"+index,mean_alpha_[i]);
+     410          16 :           ifile.scanField("auxiliary_"+index,inst_alpha_[i]);
+     411          16 :           ifile.scanField("damping_"+index,damping[i]);
+     412             :         }
+     413           8 :         ifile.scanField();
+     414           8 :         mean_counter_+=print_stride_;
+     415             :       }
+     416           4 :       for(unsigned i=0; i<alpha_size_; i++)
+     417             :       {
+     418           2 :         exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     419           2 :         past_increment2_[i]=damping[i]*damping[i];
+     420             :       }
+     421             :       //sync all walkers and treads. Not sure is mandatory but is no harm
+     422           2 :       comm.Barrier();
+     423           2 :       if(comm.Get_rank()==0)
+     424           2 :         multi_sim_comm.Barrier();
+     425             :     }
+     426             :     else
+     427           0 :       log.printf("  -- WARNING: restart requested, but no '%s' file found!\n",alphaFileName.c_str());
+     428           2 :   }
+     429             : 
+     430             : //setup output file with Alpha values
+     431           4 :   alphaOfile_.link(*this);
+     432           4 :   if(NumWalkers_>1)
+     433             :   {
+     434           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()>0)
+     435             :       alphaFileName="/dev/null"; //only first walker writes on file
+     436           4 :     alphaOfile_.enforceSuffix("");
+     437             :   }
+     438           4 :   alphaOfile_.open(alphaFileName);
+     439           4 :   if(fmt.length()>0)
+     440           8 :     alphaOfile_.fmtField(" "+fmt);
+     441             : 
+     442             : //add other output components
+     443          12 :   addComponent("rct"); componentIsNotPeriodic("rct");
+     444           8 :   addComponent("work"); componentIsNotPeriodic("work");
+     445             : 
+     446             : //print some info
+     447           4 :   log.printf("  Temperature T: %g\n",1./(Kb*beta_));
+     448           4 :   log.printf("  Beta (1/Kb*T): %g\n",beta_);
+     449           4 :   log.printf("  Local free energy basins files and normalization constants:\n");
+     450          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     451           8 :     log.printf("    F_%d filename: %s  c_%d=%g\n",n,fes_names[n].c_str(),n,c_norm[n]);
+     452           4 :   if(no_mintozero)
+     453           2 :     log.printf(" -- NO_MINTOZERO: local free energies are not shifted to be zero at minimum\n");
+     454           4 :   if(normalize)
+     455           2 :     log.printf(" -- NORMALIZE: F_n+=c_n, alpha=DeltaF\n");
+     456           4 :   log.printf("  Using target distribution with 1/gamma = %g\n",inv_gamma_);
+     457           4 :   log.printf("    and updated with stride %d\n",tg_stride_);
+     458           4 :   log.printf("  Step for the minimization algorithm: %g\n",minimization_step_);
+     459           4 :   log.printf("  Stride for the ensemble average: %d\n",av_stride_);
+     460           4 :   if(mean_weight_tau_>1)
+     461           2 :     log.printf("  Exponentially decaying average with weight=tau/av_stride=%d\n",mean_weight_tau_);
+     462           4 :   if(mean_weight_tau_==1)
+     463           0 :     log.printf(" +++ WARNING +++ setting TAU_MEAN=1 is equivalent to use simple SGD, without mean alpha nor hessian contribution\n");
+     464           4 :   log.printf("  Initial guess for alpha:\n");
+     465           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     466           4 :     log.printf("    alpha_%d = %g\n",i+1,mean_alpha_[i]);
+     467           4 :   if(damping_off_)
+     468           2 :     log.printf(" -- DAMPING_OFF: the minimization step will NOT become smaller as the simulation goes on\n");
+     469           4 :   log.printf("  Printing on file %s with stride %d\n",alphaFileName.c_str(),print_stride_);
+     470           4 :   if(serial)
+     471           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     472           4 :   if(NumParallel_>1)
+     473           2 :     log.printf("  Using multiple threads per simulation: %d\n",NumParallel_);
+     474           4 :   if(multiple_walkers)
+     475             :   {
+     476           2 :     log.printf(" -- MULTIPLE_WALKERS: multiple simulations will combine statistics for the optimization\n");
+     477           2 :     if(NumWalkers_>1)
+     478             :     {
+     479           2 :       log.printf("    number of walkers: %d\n",NumWalkers_);
+     480           2 :       log.printf("    walker rank: %d\n",multi_sim_comm.Get_rank()); //only comm.Get_rank()=0 prints, so this is fine
+     481             :     }
+     482             :     else
+     483           0 :       log.printf(" +++ WARNING +++ only one replica found: are you sure you are running MPI-connected simulations?\n");
+     484             :   }
+     485           4 :   log.printf(" Bibliography ");
+     486           8 :   log<<plumed.cite("Invernizzi and Parrinello, J. Chem. Theory Comput. 15, 2187-2194 (2019)");
+     487           8 :   log<<plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+     488           4 :   if(inv_gamma_>0)
+     489           4 :     log<<plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     490             : 
+     491             : //last initializations
+     492           4 :   prob_.resize(grid_p_.size());
+     493           4 :   der_prob_.resize(grid_p_.size(),std::vector<double>(getNumberOfArguments()));
+     494           4 :   update_tg_and_rct();
+     495           8 : }
+     496             : 
+     497         804 : void VesDeltaF::calculate()
+     498             : {
+     499             : //get CVs
+     500         804 :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     501         804 :   std::vector<double> cv(ncv);
+     502        1608 :   for(unsigned s=0; s<ncv; s++)
+     503         804 :     cv[s]=getArgument(s);
+     504             : //get probabilities for each basin, and total one
+     505        2412 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     506        1608 :     prob_[n]=grid_p_[n]->getValueAndDerivatives(cv,der_prob_[n]);
+     507         804 :   tot_prob_=prob_[0];
+     508        1608 :   for(unsigned i=0; i<alpha_size_; i++)
+     509         804 :     tot_prob_+=prob_[i+1]*exp_alpha_[i];
+     510             : 
+     511             : //update bias and forces: V=-(1-inv_gamma_)*fes
+     512         804 :   setBias((1-inv_gamma_)/beta_*std::log(tot_prob_));
+     513        1608 :   for(unsigned s=0; s<ncv; s++)
+     514             :   {
+     515         804 :     double dProb_dCV_s=der_prob_[0][s];
+     516        1608 :     for(unsigned i=0; i<alpha_size_; i++)
+     517         804 :       dProb_dCV_s+=der_prob_[i+1][s]*exp_alpha_[i];
+     518         804 :     setOutputForce(s,-(1-inv_gamma_)/beta_/tot_prob_*dProb_dCV_s);
+     519             :   }
+     520         804 :   afterCalculate_=true;
+     521         804 : }
+     522             : 
+     523         804 : void VesDeltaF::update()
+     524             : {
+     525             : //skip first step to sync getTime() and av_counter_, as in METAD
+     526         804 :   if(isFirstStep_)
+     527             :   {
+     528           4 :     isFirstStep_=false;
+     529           4 :     return;
+     530             :   }
+     531         800 :   plumed_massert(afterCalculate_,"VesDeltaF::update() must be called after VesDeltaF::calculate() to work properly");
+     532         800 :   afterCalculate_=false;
+     533             : 
+     534             : //calculate derivatives for ensemble averages
+     535         800 :   std::vector<double> dV_dAlpha(alpha_size_);
+     536         800 :   std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     537        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     538         800 :     dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob_*prob_[i+1]*exp_alpha_[i];
+     539        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     540             :   {
+     541         800 :     d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     542        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     543         800 :       d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     544             :   }
+     545             : //update ensemble averages
+     546         800 :   av_counter_++;
+     547        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     548             :   {
+     549         800 :     av_dV_dAlpha_[i]+=(dV_dAlpha[i]-av_dV_dAlpha_[i])/av_counter_;
+     550        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     551             :     {
+     552         800 :       const unsigned ij=get_index(i,j);
+     553         800 :       av_dV_dAlpha_prod_[ij]+=(dV_dAlpha[i]*dV_dAlpha[j]-av_dV_dAlpha_prod_[ij])/av_counter_;
+     554         800 :       av_d2V_dAlpha2_[ij]+=(d2V_dAlpha2[ij]-av_d2V_dAlpha2_[ij])/av_counter_;
+     555             :     }
+     556             :   }
+     557             : //update work
+     558         800 :   double prev_tot_prob=prob_[0];
+     559        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     560         800 :     prev_tot_prob+=prob_[i+1]*prev_exp_alpha_[i];
+     561         800 :   work_+=(1-inv_gamma_)/beta_*std::log(tot_prob_/prev_tot_prob);
+     562             : 
+     563             : //update coefficients
+     564         800 :   if(av_counter_==av_stride_)
+     565             :   {
+     566          16 :     update_alpha();
+     567          16 :     tg_counter_++;
+     568          16 :     if(tg_counter_==tg_stride_)
+     569             :     {
+     570          12 :       update_tg_and_rct();
+     571          12 :       tg_counter_=0;
+     572             :     }
+     573             :     //reset the ensemble averages
+     574          16 :     av_counter_=0;
+     575             :     std::fill(av_dV_dAlpha_.begin(),av_dV_dAlpha_.end(),0);
+     576             :     std::fill(av_dV_dAlpha_prod_.begin(),av_dV_dAlpha_prod_.end(),0);
+     577             :     std::fill(av_d2V_dAlpha2_.begin(),av_d2V_dAlpha2_.end(),0);
+     578             :   }
+     579             : }
+     580             : 
+     581          16 : void VesDeltaF::update_tg_and_rct()
+     582             : {
+     583             : //calculate target averages
+     584          16 :   double Z_0=norm_[0];
+     585          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     586          16 :     Z_0+=norm_[i+1]*exp_alpha_[i];
+     587          16 :   double Z_tg=0;
+     588             :   std::fill(tg_dV_dAlpha_.begin(),tg_dV_dAlpha_.end(),0);
+     589             :   std::fill(tg_d2V_dAlpha2_.begin(),tg_d2V_dAlpha2_.end(),0);
+     590        1116 :   for(Grid::index_t t=rank_; t<grid_p_[0]->getSize(); t+=NumParallel_)
+     591             :   { //TODO can we recycle some code?
+     592        1100 :     std::vector<double> prob(grid_p_.size());
+     593        3300 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     594        2200 :       prob[n]=grid_p_[n]->getValue(t);
+     595        1100 :     double tot_prob=prob[0];
+     596        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     597        1100 :       tot_prob+=prob[i+1]*exp_alpha_[i];
+     598        1100 :     std::vector<double> dV_dAlpha(alpha_size_);
+     599        1100 :     std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     600        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     601        1100 :       dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob*prob[i+1]*exp_alpha_[i];
+     602        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     603             :     {
+     604        1100 :       d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     605        2200 :       for(unsigned j=i; j<alpha_size_; j++)
+     606        1100 :         d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     607             :     }
+     608        1100 :     const double unnorm_tg_p=std::pow(tot_prob,inv_gamma_);
+     609        1100 :     Z_tg+=unnorm_tg_p;
+     610        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     611        1100 :       tg_dV_dAlpha_[i]+=unnorm_tg_p*dV_dAlpha[i];
+     612        2200 :     for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     613        1100 :       tg_d2V_dAlpha2_[ij]+=unnorm_tg_p*d2V_dAlpha2[ij];
+     614             :   }
+     615          16 :   if(NumParallel_>1)
+     616             :   {
+     617          10 :     comm.Sum(Z_tg);
+     618          10 :     comm.Sum(tg_dV_dAlpha_);
+     619          10 :     comm.Sum(tg_d2V_dAlpha2_);
+     620             :   }
+     621          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     622          16 :     tg_dV_dAlpha_[i]/=Z_tg;
+     623          32 :   for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     624          16 :     tg_d2V_dAlpha2_[ij]/=Z_tg;
+     625          16 :   getPntrToComponent("rct")->set(-1./beta_*std::log(Z_tg/Z_0)); //Z_tg is the best available estimate of Z_V
+     626          16 : }
+     627             : 
+     628          16 : void VesDeltaF::update_alpha()
+     629             : {
+     630             : //combining the averages of multiple walkers
+     631          16 :   if(NumWalkers_>1)
+     632             :   {
+     633           8 :     if(comm.Get_rank()==0) //sum only once: in the first rank of each walker
+     634             :     {
+     635           8 :       multi_sim_comm.Sum(av_dV_dAlpha_);
+     636           8 :       multi_sim_comm.Sum(av_dV_dAlpha_prod_);
+     637           8 :       multi_sim_comm.Sum(av_d2V_dAlpha2_);
+     638          16 :       for(unsigned i=0; i<alpha_size_; i++)
+     639           8 :         av_dV_dAlpha_[i]/=NumWalkers_;
+     640          16 :       for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     641             :       {
+     642           8 :         av_dV_dAlpha_prod_[ij]/=NumWalkers_;
+     643           8 :         av_d2V_dAlpha2_[ij]/=NumWalkers_;
+     644             :       }
+     645             :     }
+     646           8 :     if(comm.Get_size()>1)//if there are more ranks for each walker, everybody has to know
+     647             :     {
+     648           0 :       comm.Bcast(av_dV_dAlpha_,0);
+     649           0 :       comm.Bcast(av_dV_dAlpha_prod_,0);
+     650           0 :       comm.Bcast(av_d2V_dAlpha2_,0);
+     651             :     }
+     652             :   }
+     653             :   //set work and reset it
+     654          16 :   getPntrToComponent("work")->set(work_);
+     655          16 :   work_=0;
+     656             : 
+     657             : //build the gradient and the Hessian of the functional
+     658          16 :   std::vector<double> grad_omega(alpha_size_);
+     659          16 :   std::vector<double> hess_omega(sym_alpha_size_);
+     660          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     661             :   {
+     662          16 :     grad_omega[i]=tg_dV_dAlpha_[i]-av_dV_dAlpha_[i];
+     663          32 :     for(unsigned j=i; j<alpha_size_; j++)
+     664             :     {
+     665          16 :       const unsigned ij=get_index(i,j);
+     666          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];
+     667             :     }
+     668             :   }
+     669             : //calculate the increment and update alpha
+     670          16 :   mean_counter_++;
+     671             :   long long unsigned mean_weight=mean_counter_;
+     672          16 :   if(mean_weight_tau_>0 && mean_weight_tau_<mean_counter_)
+     673             :     mean_weight=mean_weight_tau_;
+     674          16 :   std::vector<double> damping(alpha_size_);
+     675          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     676             :   {
+     677          16 :     double increment_i=grad_omega[i];
+     678          32 :     for(unsigned j=0; j<alpha_size_; j++)
+     679          16 :       increment_i+=hess_omega[get_index(i,j)]*(inst_alpha_[j]-mean_alpha_[j]);
+     680          16 :     if(!damping_off_)
+     681           8 :       past_increment2_[i]+=increment_i*increment_i;
+     682          16 :     damping[i]=std::sqrt(past_increment2_[i]);
+     683          16 :     prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     684          16 :     inst_alpha_[i]-=minimization_step_/damping[i]*increment_i;
+     685          16 :     mean_alpha_[i]+=(inst_alpha_[i]-mean_alpha_[i])/mean_weight;
+     686          16 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     687             :   }
+     688             : 
+     689             : //update the Alpha file
+     690          16 :   if(mean_counter_%print_stride_==0)
+     691             :   {
+     692          16 :     alphaOfile_.printField("time",getTime());
+     693          32 :     for(unsigned i=0; i<alpha_size_; i++)
+     694             :     {
+     695          16 :       const std::string index(std::to_string(i+1));
+     696          32 :       alphaOfile_.printField("alpha_"+index,mean_alpha_[i]);
+     697          32 :       alphaOfile_.printField("auxiliary_"+index,inst_alpha_[i]);
+     698          32 :       alphaOfile_.printField("damping_"+index,damping[i]);
+     699             :     }
+     700          16 :     alphaOfile_.printField();
+     701             :   }
+     702          16 : }
+     703             : 
+     704             : //mapping of a [alpha_size_]x[alpha_size_] symmetric matrix into a vector of size sym_alpha_size_, useful for the communicator
+     705        4632 : inline unsigned VesDeltaF::get_index(const unsigned i, const unsigned j) const
+     706             : {
+     707        4632 :   if(i<=j)
+     708        4632 :     return j+i*(alpha_size_-1)-i*(i-1)/2;
+     709             :   else
+     710           0 :     return get_index(j,i);
+     711             : }
+     712             : 
+     713             : }
+     714             : }
+
+
+
+ + + + +
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 000000000..7364dd818 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html @@ -0,0 +1,156 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..0c815ccdb --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func.html @@ -0,0 +1,156 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..4de8e8fb7 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.gcov.html @@ -0,0 +1,633 @@ + + + + + + + LCOV - plumed test coverage - ves/VesLinearExpansion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesLinearExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13914496.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..abd6c78d2 --- /dev/null +++ b/coverage/ves/VesTools.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..adfb1bb82 --- /dev/null +++ b/coverage/ves/VesTools.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..6d8802997 --- /dev/null +++ b/coverage/ves/VesTools.cpp.gcov.html @@ -0,0 +1,170 @@ + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-10-17 16:45:00Functions: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 000000000..a9db4f5b6 --- /dev/null +++ b/coverage/ves/VesTools.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - ves/VesTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..8bea7deeb --- /dev/null +++ b/coverage/ves/VesTools.h.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - plumed test coverage - ves/VesTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..77dd596d6 --- /dev/null +++ b/coverage/ves/VesTools.h.gcov.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - ves/VesTools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-10-17 16:45:00Functions: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 000000000..2eeb6b3ad --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..971718bd9 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..4a22b31c9 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.gcov.html @@ -0,0 +1,1058 @@ + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-10-17 16:45:00Functions: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 000000000..f95e6aa94 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..7d4b03e75 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..358283bd5 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.gcov.html @@ -0,0 +1,330 @@ + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-10-17 16:45:00Functions: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 000000000..0e591c7a9 --- /dev/null +++ b/coverage/ves/index-sort-f.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-10-17 16:45:00Functions:44467765.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
OutputFesBias.cpp +
88.2%88.2%
+
88.2 %60 / 6840.0 %2 / 5
TD_ProductDistribution.cpp +
63.2%63.2%
+
63.2 %48 / 7640.0 %4 / 10
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %83 / 8950.0 %2 / 4
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
TD_ProductCombination.cpp +
73.3%73.3%
+
73.3 %55 / 7560.0 %6 / 10
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7760.0 %6 / 10
VesBias.cpp +
76.2%76.2%
+
76.2 %324 / 42560.0 %27 / 45
TD_WellTempered.cpp +
90.3%90.3%
+
90.3 %28 / 3166.7 %4 / 6
Opt_Dummy.cpp +
95.2%95.2%
+
95.2 %20 / 2175.0 %3 / 4
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
Opt_RobbinsMonroSGD.cpp +
95.8%95.8%
+
95.8 %23 / 2475.0 %3 / 4
Opt_Adam.cpp +
93.1%93.1%
+
93.1 %67 / 7275.0 %3 / 4
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
BasisFunctions.cpp +
87.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %197 / 20483.3 %5 / 6
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %147 / 15183.3 %5 / 6
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.5%89.5%
+
89.5 %683 / 76384.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 %342 / 35087.5 %7 / 8
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.0 %1 / 1
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_Grid.cpp +
94.8%94.8%
+
94.8 %55 / 58100.0 %3 / 3
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
TD_GeneralizedNormal.cpp +
91.3%91.3%
+
91.3 %63 / 69100.0 %4 / 4
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_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
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
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
BF_Custom.cpp +
82.2%82.2%
+
82.2 %125 / 152100.0 %5 / 5
BF_Combined.cpp +
96.9%96.9%
+
96.9 %63 / 65100.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 000000000..d147e0f1a --- /dev/null +++ b/coverage/ves/index-sort-l.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-10-17 16:45:00Functions: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 %683 / 76384.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 %342 / 35087.5 %7 / 8
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Powers.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
BF_Legendre.cpp +
100.0%
+
100.0 %42 / 42100.0 %4 / 4
BF_Gaussians.cpp +
100.0%
+
100.0 %52 / 52100.0 %4 / 4
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index.html b/coverage/ves/index.html new file mode 100644 index 000000000..1a950b60e --- /dev/null +++ b/coverage/ves/index.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-10-17 16:45:00Functions: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 %683 / 76384.4 %27 / 32
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %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 %342 / 35087.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 000000000..e2645e003 --- /dev/null +++ b/coverage/volumes/ActionVolume.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:737597.3 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12ActionVolume12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE59
_ZN4PLMD7volumes12ActionVolumeC2ERKNS_13ActionOptionsE59
_ZN4PLMD7volumes12ActionVolume12isInSubChainERj104
_ZN4PLMD7volumes12ActionVolume16registerKeywordsERNS_8KeywordsE217
_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 000000000..acc3a913c --- /dev/null +++ b/coverage/volumes/ActionVolume.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:737597.3 %
Date:2024-10-17 16:45:00Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12ActionVolume12isInSubChainERj104
_ZN4PLMD7volumes12ActionVolume12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE59
_ZN4PLMD7volumes12ActionVolume16getNumberOfTasksERj533
_ZN4PLMD7volumes12ActionVolume16registerKeywordsERNS_8KeywordsE217
_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 000000000..3d84a44f6 --- /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:737597.3 %
Date:2024-10-17 16:45:00Functions: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         217 : void ActionVolume::registerKeywords( Keywords& keys ) {
+      30         217 :   ActionWithVector::registerKeywords( keys );
+      31         434 :   keys.add("atoms","ATOMS","the group of atoms that you would like to investigate");
+      32         434 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      33         434 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      34         434 :   keys.addFlag("OUTSIDE",false,"calculate quantities for colvars that are on atoms outside the region of interest");
+      35         217 :   keys.setValueDescription("vector of numbers between 0 and 1 that measure the degree to which each atom is within the volume of interest");
+      36         217 : }
+      37             : 
+      38          59 : ActionVolume::ActionVolume(const ActionOptions&ao):
+      39             :   Action(ao),
+      40          59 :   ActionWithVector(ao)
+      41             : {
+      42         118 :   std::vector<AtomNumber> atoms; parseAtomList("ATOMS",atoms);
+      43          59 :   if( atoms.size()==0 ) error("no atoms were specified");
+      44          59 :   log.printf("  examining positions of atoms ");
+      45       33354 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d", atoms[i].serial() );
+      46          59 :   log.printf("\n"); ActionAtomistic::requestAtoms( atoms );
+      47             : 
+      48          59 :   parseFlag("OUTSIDE",not_in); sigma=0.0;
+      49         166 :   if( keywords.exists("SIGMA") ) parse("SIGMA",sigma);
+      50         177 :   if( keywords.exists("KERNEL") ) parse("KERNEL",kerneltype);
+      51             : 
+      52          60 :   if( atoms.size()==1 ) ActionWithValue::addValueWithDerivatives();
+      53          58 :   else { std::vector<unsigned> shape(1); shape[0]=atoms.size(); ActionWithValue::addValue( shape ); }
+      54          59 :   setNotPeriodic(); getPntrToComponent(0)->setDerivativeIsZeroWhenValueIsZero();
+      55          59 : }
+      56             : 
+      57         104 : bool ActionVolume::isInSubChain( unsigned& nder ) {
+      58         104 :   nder = 0; getFirstActionInChain()->getNumberOfStreamedDerivatives( nder, getPntrToComponent(0) );
+      59         104 :   nder = nder - getNumberOfDerivatives();
+      60         104 :   return true;
+      61             : }
+      62             : 
+      63          59 : void ActionVolume::requestAtoms( const std::vector<AtomNumber> & a ) {
+      64          59 :   std::vector<AtomNumber> all_atoms( getAbsoluteIndexes() );
+      65         128 :   for(unsigned i=0; i<a.size(); ++i) all_atoms.push_back( a[i] );
+      66          59 :   ActionAtomistic::requestAtoms( all_atoms );
+      67          59 :   if( getPntrToComponent(0)->getRank()==0 ) getPntrToComponent(0)->resizeDerivatives( 3*getNumberOfAtoms()+9 );
+      68          59 : }
+      69             : 
+      70         863 : void ActionVolume::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+      71         863 :   task_reducing_actions.push_back(this);
+      72         863 : }
+      73             : 
+      74         533 : void ActionVolume::getNumberOfTasks( unsigned& ntasks ) {
+      75         533 :   setupRegions(); ActionWithVector::getNumberOfTasks( ntasks );
+      76         533 : }
+      77             : 
+      78      464761 : int ActionVolume::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+      79      464761 :   unsigned nref=getNumberOfAtoms()-getConstPntrToComponent(0)->getShape()[0];
+      80      464761 :   Vector wdf; Tensor vir; std::vector<Vector> refders( nref );
+      81      464761 :   double weight=calculateNumberInside( ActionAtomistic::getPosition(taskno), wdf, vir, refders );
+      82      464761 :   if( not_in ) weight = 1.0 - weight;
+      83      464761 :   if( weight>epsilon ) return 1;
+      84             :   return 0;
+      85             : }
+      86             : 
+      87        2081 : void ActionVolume::calculate() {
+      88        2081 :   if( actionInChain() ) return;
+      89        1750 :   if( getPntrToComponent(0)->getRank()==0 ) {
+      90        1560 :     setupRegions(); unsigned nref = getNumberOfAtoms() - 1;
+      91        1560 :     Vector wdf; Tensor vir; std::vector<Vector> refders( nref );
+      92        1560 :     double weight=calculateNumberInside( ActionAtomistic::getPosition(0), wdf, vir, refders );
+      93        1560 :     if( not_in ) {
+      94           0 :       weight = 1.0 - weight; wdf *= -1.; vir *=-1;
+      95           0 :       for(unsigned i=0; i<refders.size(); ++i) refders[i]*=-1;
+      96             :     }
+      97             :     // Atom position
+      98        1560 :     Value* v = getPntrToComponent(0); v->set( weight );
+      99        6240 :     for(unsigned i=0; i<3; ++i ) v->addDerivative( i, wdf[i] );
+     100             :     // Add derivatives with respect to reference positions
+     101        7800 :     for(unsigned i=0; i<refders.size(); ++i) {
+     102       24960 :       for(unsigned j=0; j<3; ++j ) v->addDerivative( 3 + 3*i + j, refders[i][j] );
+     103             :     }
+     104             :     // Add virial
+     105             :     unsigned vbase = 3*getNumberOfAtoms();
+     106       20280 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) v->addDerivative( vbase + 3*i + j, vir(i,j) );
+     107         190 :   } else runAllTasks();
+     108             : }
+     109             : 
+     110       62937 : void ActionVolume::performTask( const unsigned& curr, MultiValue& outvals ) const {
+     111       62937 :   unsigned nref=getNumberOfAtoms()-getConstPntrToComponent(0)->getShape()[0];
+     112       62937 :   Vector wdf; Tensor vir; std::vector<Vector> refders( nref );
+     113       62937 :   double weight=calculateNumberInside( ActionAtomistic::getPosition(curr), wdf, vir, refders );
+     114             : 
+     115       62937 :   if( not_in ) {
+     116        4000 :     weight = 1.0 - weight; wdf *= -1.; vir *=-1;
+     117        8000 :     for(unsigned i=0; i<refders.size(); ++i) refders[i]*=-1;
+     118             :   }
+     119       62937 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+     120       62937 :   outvals.setValue( ostrn, weight );
+     121             : 
+     122       62937 :   if( doNotCalculateDerivatives() ) return;
+     123             : 
+     124             :   // Atom position
+     125      146144 :   for(unsigned i=0; i<3; ++i ) { outvals.addDerivative( ostrn, 3*curr+i, wdf[i] ); outvals.updateIndex( ostrn, 3*curr+i ); }
+     126             :   // Add derivatives with respect to reference positions
+     127       36536 :   unsigned vbase = 3*(getNumberOfAtoms()-nref);
+     128       76572 :   for(unsigned i=0; i<refders.size(); ++i) {
+     129      160144 :     for(unsigned j=0; j<3; ++j ) { outvals.addDerivative( ostrn, vbase, refders[i][j] ); outvals.updateIndex( ostrn, vbase ); vbase++; }
+     130             :   }
+     131             :   // Add virial
+     132      146144 :   for(unsigned i=0; i<3; ++i) {
+     133      438432 :     for(unsigned j=0; j<3; ++j) { outvals.addDerivative( ostrn, vbase, vir(i,j) ); outvals.updateIndex( ostrn, vbase ); vbase++; }
+     134             :   }
+     135             : }
+     136             : 
+     137             : }
+     138             : }
+
+
+
+ + + + +
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 000000000..183fa6886 --- /dev/null +++ b/coverage/volumes/ActionVolume.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..9443de720 --- /dev/null +++ b/coverage/volumes/ActionVolume.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..edb352889 --- /dev/null +++ b/coverage/volumes/ActionVolume.h.gcov.html @@ -0,0 +1,164 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..abaa42199 --- /dev/null +++ b/coverage/volumes/Density.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:61154.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..c7c775721 --- /dev/null +++ b/coverage/volumes/Density.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:61154.5 %
Date:2024-10-17 16:45:00Functions: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 000000000..e906805a2 --- /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:61154.5 %
Date:2024-10-17 16:45:00Functions: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           2 :   keys.setValueDescription("indices for the specified group of atoms");
+      52           4 :   keys.needsAction("ONES"); keys.needsAction("GROUP");
+      53           2 : }
+      54             : 
+      55           0 : Density::Density(const ActionOptions& ao):
+      56             :   Action(ao),
+      57           0 :   ActionShortcut(ao)
+      58             : {
+      59           0 :   std::string atoms; parse("SPECIES",atoms);
+      60           0 :   readInputLine( getShortcutLabel() + ": GROUP ATOMS=" + atoms);
+      61           0 : }
+      62             : 
+      63             : }
+      64             : }
+
+
+
+ + + + +
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 000000000..53c1a4e5a --- /dev/null +++ b/coverage/volumes/VolumeAround.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12VolumeAroundC1ERKNS_13ActionOptionsE46
_ZN4PLMD7volumes12VolumeAround16registerKeywordsERNS_8KeywordsE156
_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 000000000..71f9fc373 --- /dev/null +++ b/coverage/volumes/VolumeAround.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeAround12setupRegionsEv388
_ZN4PLMD7volumes12VolumeAround16registerKeywordsERNS_8KeywordsE156
_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 000000000..09f37f100 --- /dev/null +++ b/coverage/volumes/VolumeAround.cpp.gcov.html @@ -0,0 +1,244 @@ + + + + + + + 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-10-17 16:45:00Functions: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         156 : void VolumeAround::registerKeywords( Keywords& keys ) {
+      99         156 :   ActionVolume::registerKeywords( keys ); keys.setDisplayName("AROUND");
+     100         312 :   keys.add("atoms","ORIGIN","the atom whose vicinity we are interested in examining");
+     101         312 :   keys.add("atoms-2","ATOM","an alternative to ORIGIN");
+     102         312 :   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         312 :   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         312 :   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         312 :   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         312 :   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         312 :   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         156 : }
+     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 000000000..6f4177672 --- /dev/null +++ b/coverage/volumes/VolumeBetweenContours.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes16VolumeInEnvelopeC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes16VolumeInEnvelope12setupRegionsEv5
_ZN4PLMD7volumes16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE7
_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 000000000..570b0ffde --- /dev/null +++ b/coverage/volumes/VolumeBetweenContours.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInEnvelope12setupRegionsEv5
_ZN4PLMD7volumes16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE7
_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 000000000..4d6fafe34 --- /dev/null +++ b/coverage/volumes/VolumeBetweenContours.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + 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-10-17 16:45:00Functions: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           7 : void VolumeInEnvelope::registerKeywords( Keywords& keys ) {
+      95          14 :   ActionVolume::registerKeywords( keys ); keys.remove("SIGMA"); keys.setDisplayName("INENVELOPE");
+      96          14 :   keys.add("atoms","FIELD_ATOMS","the atom whose positions we are constructing a field from");
+      97          14 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density esimtation");
+      98          14 :   keys.add("compulsory","CONTOUR","a switching funciton that tells PLUMED how large the density should be");
+      99          14 :   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           7 : }
+     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 000000000..869d166fe --- /dev/null +++ b/coverage/volumes/VolumeCavity.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12VolumeCavityD2Ev0
_ZN4PLMD7volumes12VolumeCavityC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes12VolumeCavityD0Ev1
_ZN4PLMD7volumes12VolumeCavityD1Ev1
_ZN4PLMD7volumes12VolumeCavity16registerKeywordsERNS_8KeywordsE7
_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 000000000..c3ebcf10b --- /dev/null +++ b/coverage/volumes/VolumeCavity.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeCavity12setupRegionsEv1560
_ZN4PLMD7volumes12VolumeCavity16registerKeywordsERNS_8KeywordsE7
_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 000000000..85b9b951a --- /dev/null +++ b/coverage/volumes/VolumeCavity.cpp.gcov.html @@ -0,0 +1,496 @@ + + + + + + + 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-10-17 16:45:00Functions: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           7 : void VolumeCavity::registerKeywords( Keywords& keys ) {
+     142           7 :   ActionVolume::registerKeywords( keys ); keys.setDisplayName("CAVITY");
+     143          14 :   keys.add("atoms","BOX","the positions of four atoms that define spatial extent of the cavity");
+     144          14 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     145          14 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     146          14 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     147           7 : }
+     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 000000000..2a1ef2e18 --- /dev/null +++ b/coverage/volumes/VolumeInCylinder.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes16VolumeInCylinder16registerKeywordsERNS_8KeywordsE7
_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 000000000..a37be0f7a --- /dev/null +++ b/coverage/volumes/VolumeInCylinder.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInCylinder12setupRegionsEv20
_ZN4PLMD7volumes16VolumeInCylinder16registerKeywordsERNS_8KeywordsE7
_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 000000000..6c0e118e5 --- /dev/null +++ b/coverage/volumes/VolumeInCylinder.cpp.gcov.html @@ -0,0 +1,249 @@ + + + + + + + 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-10-17 16:45:00Functions: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           7 : void VolumeInCylinder::registerKeywords( Keywords& keys ) {
+     103           7 :   ActionVolume::registerKeywords( keys ); keys.setDisplayName("INCYLINDER");
+     104          14 :   keys.add("atoms","CENTER","the atom whose vicinity we are interested in examining");
+     105          14 :   keys.add("compulsory","DIRECTION","the direction of the long axis of the cylinder. Must be x, y or z");
+     106          14 :   keys.add("compulsory","RADIUS","a switching function that gives the extent of the cylinder in the plane perpendicular to the direction");
+     107          14 :   keys.add("compulsory","LOWER","0.0","the lower boundary on the direction parallel to the long axis of the cylinder");
+     108          14 :   keys.add("compulsory","UPPER","0.0","the upper boundary on the direction parallel to the long axis of the cylinder");
+     109          14 :   keys.reset_style("SIGMA","optional");
+     110           7 : }
+     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 000000000..a75944b24 --- /dev/null +++ b/coverage/volumes/VolumeInSphere.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes14VolumeInSphereC1ERKNS_13ActionOptionsE10
_ZN4PLMD7volumes14VolumeInSphere16registerKeywordsERNS_8KeywordsE36
_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 000000000..60bdcd0ed --- /dev/null +++ b/coverage/volumes/VolumeInSphere.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-10-17 16:45:00Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes14VolumeInSphere12setupRegionsEv120
_ZN4PLMD7volumes14VolumeInSphere16registerKeywordsERNS_8KeywordsE36
_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 000000000..d6156a0bc --- /dev/null +++ b/coverage/volumes/VolumeInSphere.cpp.gcov.html @@ -0,0 +1,213 @@ + + + + + + + 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-10-17 16:45:00Functions: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          36 : void VolumeInSphere::registerKeywords( Keywords& keys ) {
+      99          36 :   ActionVolume::registerKeywords( keys ); keys.setDisplayName("INSPHERE");
+     100          72 :   keys.add("atoms","CENTER","the atom whose vicinity we are interested in examining");
+     101          72 :   keys.add("atoms-2","ATOM","the atom whose vicinity we are interested in examining");
+     102          72 :   keys.add("compulsory","RADIUS","the switching function that tells us the extent of the sphereical region of interest");
+     103          36 :   keys.remove("SIGMA");
+     104          36 : }
+     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 000000000..4ddade56d --- /dev/null +++ b/coverage/volumes/VolumeShortcut.h.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..9979e999a --- /dev/null +++ b/coverage/volumes/VolumeShortcut.h.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..b8946565c --- /dev/null +++ b/coverage/volumes/VolumeShortcut.h.gcov.html @@ -0,0 +1,198 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..147fa5ed9 --- /dev/null +++ b/coverage/volumes/VolumeTetrapore.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..67d2596a7 --- /dev/null +++ b/coverage/volumes/VolumeTetrapore.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-10-17 16:45:00Functions: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 000000000..86a82805e --- /dev/null +++ b/coverage/volumes/VolumeTetrapore.cpp.gcov.html @@ -0,0 +1,533 @@ + + + + + + + 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-10-17 16:45:00Functions: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 ); keys.setDisplayName("TETRAHEDRALPORE");
+     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 000000000..84ec7b658 --- /dev/null +++ b/coverage/volumes/index-sort-f.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - volumes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumesHitTotalCoverage
Test:plumed test coverageLines:48076362.9 %
Date:2024-10-17 16:45:00Functions: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 +
54.5%54.5%
+
54.5 %6 / 1133.3 %1 / 3
VolumeCavity.cpp +
79.1%79.1%
+
79.1 %167 / 21177.8 %7 / 9
VolumeAround.cpp +
100.0%
+
100.0 %49 / 4980.0 %4 / 5
VolumeInCylinder.cpp +
95.8%95.8%
+
95.8 %46 / 4880.0 %4 / 5
VolumeInSphere.cpp +
100.0%
+
100.0 %27 / 2780.0 %4 / 5
VolumeBetweenContours.cpp +
98.1%98.1%
+
98.1 %51 / 5280.0 %4 / 5
ActionVolume.cpp +
97.3%97.3%
+
97.3 %73 / 7590.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 000000000..e8c26820d --- /dev/null +++ b/coverage/volumes/index-sort-l.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - volumes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumesHitTotalCoverage
Test:plumed test coverageLines:48076362.9 %
Date:2024-10-17 16:45:00Functions: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 +
54.5%54.5%
+
54.5 %6 / 1133.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 %73 / 7590.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 000000000..349d9f969 --- /dev/null +++ b/coverage/volumes/index.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - volumes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumesHitTotalCoverage
Test:plumed test coverageLines:48076362.9 %
Date:2024-10-17 16:45:00Functions:476572.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionVolume.cpp +
97.3%97.3%
+
97.3 %73 / 7590.0 %9 / 10
ActionVolume.h +
100.0%
+
100.0 %7 / 7100.0 %2 / 2
Density.cpp +
54.5%54.5%
+
54.5 %6 / 1133.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/wham/Wham.cpp.func-sort-c.html b/coverage/wham/Wham.cpp.func-sort-c.html new file mode 100644 index 000000000..8cda2790d --- /dev/null +++ b/coverage/wham/Wham.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - wham/Wham.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - Wham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444793.6 %
Date:2024-10-17 16:45:00Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4wham4Wham22getNumberOfDerivativesEv0
_ZN4PLMD4wham4Wham5applyEv0
_ZN4PLMD4wham4WhamC2ERKNS_13ActionOptionsE0
_ZN4PLMD4wham4Wham9calculateEv12
_ZN4PLMD4wham4WhamC1ERKNS_13ActionOptionsE13
_ZN4PLMD4wham4Wham16registerKeywordsERNS_8KeywordsE29
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/Wham.cpp.func.html b/coverage/wham/Wham.cpp.func.html new file mode 100644 index 000000000..397675fed --- /dev/null +++ b/coverage/wham/Wham.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - wham/Wham.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - Wham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444793.6 %
Date:2024-10-17 16:45:00Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4wham4Wham16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD4wham4Wham22getNumberOfDerivativesEv0
_ZN4PLMD4wham4Wham5applyEv0
_ZN4PLMD4wham4Wham9calculateEv12
_ZN4PLMD4wham4WhamC1ERKNS_13ActionOptionsE13
_ZN4PLMD4wham4WhamC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/Wham.cpp.gcov.html b/coverage/wham/Wham.cpp.gcov.html new file mode 100644 index 000000000..882657cb5 --- /dev/null +++ b/coverage/wham/Wham.cpp.gcov.html @@ -0,0 +1,247 @@ + + + + + + + LCOV - plumed test coverage - wham/Wham.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - Wham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444793.6 %
Date:2024-10-17 16:45:00Functions: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 wham {
+      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          29 : void Wham::registerKeywords(Keywords& keys ) {
+      98          29 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      99          29 :   ActionWithArguments::registerKeywords( keys ); keys.remove("ARG");
+     100          58 :   keys.add("compulsory","ARG","the stored values for the bias");
+     101          58 :   keys.add("compulsory","MAXITER","1000","maximum number of iterations for WHAM algorithm");
+     102          58 :   keys.add("compulsory","WHAMTOL","1e-10","threshold for convergence of WHAM algorithm");
+     103          58 :   keys.add("optional","TEMP","the system temperature.  This is not required if your MD code passes this quantity to PLUMED");
+     104          29 :   keys.remove("NUMERICAL_DERIVATIVES");
+     105          29 :   keys.setValueDescription("the vector of WHAM weights to use for reweighting the elements in a time series");
+     106          29 : }
+     107             : 
+     108          13 : Wham::Wham(const ActionOptions&ao):
+     109             :   Action(ao),
+     110             :   ActionWithValue(ao),
+     111          13 :   ActionWithArguments(ao)
+     112             : {
+     113             :   // Read in the temperature
+     114          13 :   simtemp=getkBT();
+     115          13 :   if(simtemp==0) error("The MD engine does not pass the temperature to plumed so you have to specify it using TEMP");
+     116             :   // Now read in parameters of WHAM
+     117          26 :   parse("MAXITER",maxiter); parse("WHAMTOL",thresh);
+     118          13 :   if(comm.Get_rank()==0) nreplicas=multi_sim_comm.Get_size();
+     119          13 :   comm.Bcast(nreplicas,0); addValue( getPntrToArgument(0)->getShape() ); setNotPeriodic();
+     120          13 : }
+     121             : 
+     122          12 : void Wham::calculate() {
+     123             :   // Retrieve the values that were stored for the biase
+     124          12 :   std::vector<double> stored_biases( getPntrToArgument(0)->getNumberOfValues() );
+     125       25284 :   for(unsigned i=0; i<stored_biases.size(); ++i) stored_biases[i] = getPntrToArgument(0)->get(i);
+     126             :   // Get the minimum value of the bias
+     127          12 :   double minv = *min_element(std::begin(stored_biases), std::end(stored_biases));
+     128             :   // Resize final weights array
+     129          12 :   plumed_assert( stored_biases.size()%nreplicas==0 );
+     130          12 :   std::vector<double> final_weights( stored_biases.size() / nreplicas, 1.0 );
+     131          12 :   if( getPntrToComponent(0)->getNumberOfValues()!=final_weights.size() ) {
+     132          12 :     std::vector<unsigned> shape(1); shape[0]=final_weights.size(); getPntrToComponent(0)->setShape( shape );
+     133             :   }
+     134             :   // Offset and exponential of the bias
+     135          12 :   std::vector<double> expv( stored_biases.size() );
+     136       25284 :   for(unsigned i=0; i<expv.size(); ++i) expv[i] = exp( (-stored_biases[i]+minv) / simtemp );
+     137             :   // Initialize Z
+     138          12 :   std::vector<double> Z( nreplicas, 1.0 ), oldZ( nreplicas );
+     139             :   // Now the iterative loop to calculate the WHAM weights
+     140        4584 :   for(unsigned iter=0; iter<maxiter; ++iter) {
+     141             :     // Store Z
+     142       32088 :     for(unsigned j=0; j<Z.size(); ++j) oldZ[j]=Z[j];
+     143             :     // Recompute weights
+     144             :     double norm=0;
+     145     1613568 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     146             :       double ew=0;
+     147    11262888 :       for(unsigned k=0; k<Z.size(); ++k) ew += expv[j*Z.size()+k]  / Z[k];
+     148     1608984 :       final_weights[j] = 1.0 / ew; norm += final_weights[j];
+     149             :     }
+     150             :     // Normalize weights
+     151     1613568 :     for(unsigned j=0; j<final_weights.size(); ++j) final_weights[j] /= norm;
+     152             :     // Recompute Z
+     153       32088 :     for(unsigned j=0; j<Z.size(); ++j) Z[j] = 0.0;
+     154     1613568 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     155    11262888 :       for(unsigned k=0; k<Z.size(); ++k) Z[k] += final_weights[j]*expv[j*Z.size()+k];
+     156             :     }
+     157             :     // Normalize Z and compute change in Z
+     158       32088 :     double change=0; norm=0; for(unsigned k=0; k<Z.size(); ++k) norm+=Z[k];
+     159       32088 :     for(unsigned k=0; k<Z.size(); ++k) {
+     160       27504 :       Z[k] /= norm; double d = std::log( Z[k] / oldZ[k] ); change += d*d;
+     161             :     }
+     162        4584 :     if( change<thresh ) {
+     163        4224 :       for(unsigned j=0; j<final_weights.size(); ++j) getPntrToComponent(0)->set( j, final_weights[j] );
+     164          12 :       return;
+     165             :     }
+     166             :   }
+     167           0 :   error("Too many iterations in WHAM" );
+     168             : }
+     169             : 
+     170             : }
+     171             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/WhamHistogram.cpp.func-sort-c.html b/coverage/wham/WhamHistogram.cpp.func-sort-c.html new file mode 100644 index 000000000..8db9c7e9f --- /dev/null +++ b/coverage/wham/WhamHistogram.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - wham/WhamHistogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - WhamHistogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4wham13WhamHistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD4wham13WhamHistogramC1ERKNS_13ActionOptionsE7
_ZN4PLMD4wham13WhamHistogram16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/WhamHistogram.cpp.func.html b/coverage/wham/WhamHistogram.cpp.func.html new file mode 100644 index 000000000..1b435d076 --- /dev/null +++ b/coverage/wham/WhamHistogram.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - wham/WhamHistogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - WhamHistogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4wham13WhamHistogram16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4wham13WhamHistogramC1ERKNS_13ActionOptionsE7
_ZN4PLMD4wham13WhamHistogramC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/WhamHistogram.cpp.gcov.html b/coverage/wham/WhamHistogram.cpp.gcov.html new file mode 100644 index 000000000..0d45d471d --- /dev/null +++ b/coverage/wham/WhamHistogram.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + LCOV - plumed test coverage - wham/WhamHistogram.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - WhamHistogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-10-17 16:45:00Functions: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 wham {
+      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          10 : void WhamHistogram::registerKeywords( Keywords& keys ) {
+      86          10 :   ActionShortcut::registerKeywords( keys );
+      87          20 :   keys.add("compulsory","ARG","the arguments that you would like to make the histogram for");
+      88          20 :   keys.add("compulsory","BIAS","*.bias","the value of the biases to use when performing WHAM");
+      89          20 :   keys.add("compulsory","TEMP","the temperature at which the simulation was run");
+      90          20 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be stored to perform WHAM");
+      91          20 :   keys.add("compulsory","GRID_MIN","the minimum to use for the grid");
+      92          20 :   keys.add("compulsory","GRID_MAX","the maximum to use for the grid");
+      93          20 :   keys.add("compulsory","GRID_BIN","the number of bins to use for the grid");
+      94          20 :   keys.add("optional","BANDWIDTH","the bandwidth for kernel density estimation");
+      95          10 :   keys.setValueDescription("the histogram that was generated using the WHAM weights");
+      96          20 :   keys.needsAction("GATHER_REPLICAS"); keys.needsAction("CONCATENATE");
+      97          30 :   keys.needsAction("COLLECT"); keys.needsAction("WHAM"); keys.needsAction("KDE");
+      98          10 : }
+      99             : 
+     100             : 
+     101           7 : WhamHistogram::WhamHistogram( const ActionOptions& ao ) :
+     102             :   Action(ao),
+     103           7 :   ActionShortcut(ao)
+     104             : {
+     105             :   // Input for collection of weights for WHAM
+     106          14 :   std::string bias; parse("BIAS",bias);
+     107           7 :   std::string stride; parse("STRIDE",stride);
+     108             :   // Input for GATHER_REPLICAS
+     109          14 :   readInputLine( getShortcutLabel() + "_gather: GATHER_REPLICAS ARG=" + bias );
+     110             :   // Put all the replicas in a single vector
+     111          14 :   readInputLine( getShortcutLabel() + "_gatherv: CONCATENATE ARG=" + getShortcutLabel() + "_gather.*");
+     112             :   // Input for COLLECT_FRAMES
+     113          14 :   readInputLine( getShortcutLabel() + "_collect: COLLECT TYPE=vector ARG=" + getShortcutLabel() + "_gatherv STRIDE=" + stride);
+     114             :   // Input for WHAM
+     115          21 :   std::string temp, tempstr=""; parse("TEMP",temp); if( temp.length()>0 ) tempstr="TEMP=" + temp;
+     116          14 :   readInputLine( getShortcutLabel() + "_wham: WHAM ARG=" + getShortcutLabel() + "_collect " + tempstr );
+     117             :   // Input for COLLECT_FRAMES
+     118          14 :   std::vector<std::string> args; parseVector("ARG",args); std::string argstr;
+     119          14 :   for(unsigned i=0; i<args.size(); ++i) {
+     120          14 :     readInputLine( getShortcutLabel() + "_data_" + args[i] + ": COLLECT ARG=" + args[i] );
+     121           7 :     if( i==0 ) argstr = " ARG="; else argstr += ",";
+     122          14 :     argstr += getShortcutLabel() + "_data_" + args[i];
+     123             :   }
+     124             :   // Input for HISTOGRAM
+     125          14 :   std::string histo_line, bw=""; parse("BANDWIDTH",bw);
+     126           7 :   if( bw!="" ) histo_line += " BANDWIDTH=" + bw;
+     127             :   else histo_line += " KERNEL=DISCRETE";
+     128          21 :   std::string min; parse("GRID_MIN",min); histo_line += " GRID_MIN=" + min;
+     129          21 :   std::string max; parse("GRID_MAX",max); histo_line += " GRID_MAX=" + max;
+     130          14 :   std::string bin; parse("GRID_BIN",bin); histo_line += " GRID_BIN=" + bin;
+     131          14 :   readInputLine( getShortcutLabel() + ": KDE " + argstr + " HEIGHTS=" + getShortcutLabel() + "_wham" + histo_line );
+     132          14 : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/WhamWeights.cpp.func-sort-c.html b/coverage/wham/WhamWeights.cpp.func-sort-c.html new file mode 100644 index 000000000..9a2135f3a --- /dev/null +++ b/coverage/wham/WhamWeights.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - wham/WhamWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - WhamWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4wham11WhamWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4wham11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD4wham11WhamWeights16registerKeywordsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/WhamWeights.cpp.func.html b/coverage/wham/WhamWeights.cpp.func.html new file mode 100644 index 000000000..df53df272 --- /dev/null +++ b/coverage/wham/WhamWeights.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - plumed test coverage - wham/WhamWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - WhamWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-10-17 16:45:00Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4wham11WhamWeights16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4wham11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD4wham11WhamWeightsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/WhamWeights.cpp.gcov.html b/coverage/wham/WhamWeights.cpp.gcov.html new file mode 100644 index 000000000..c7b4e49b2 --- /dev/null +++ b/coverage/wham/WhamWeights.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + LCOV - plumed test coverage - wham/WhamWeights.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wham - WhamWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-10-17 16:45:00Functions: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 wham {
+      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           8 :   keys.setValueDescription("the weights that were calculated using WHAM");
+      85          16 :   keys.needsAction("GATHER_REPLICAS"); keys.needsAction("CONCATENATE");
+      86          24 :   keys.needsAction("COLLECT"); keys.needsAction("WHAM"); keys.needsAction("DUMPVECTOR");
+      87           8 : }
+      88             : 
+      89           6 : WhamWeights::WhamWeights( const ActionOptions& ao ) :
+      90             :   Action(ao),
+      91           6 :   ActionShortcut(ao)
+      92             : {
+      93             :   // Input for collection of weights for WHAM
+      94          12 :   std::string bias; parse("BIAS",bias);
+      95           6 :   std::string stride; parse("STRIDE",stride);
+      96             :   // Input for GATHER_REPLICAS
+      97          12 :   readInputLine( getShortcutLabel() + "_gather: GATHER_REPLICAS ARG=" + bias );
+      98             :   // Put all the replicas in a single vector
+      99          12 :   readInputLine( getShortcutLabel() + "_gatherv: CONCATENATE ARG=" + getShortcutLabel() + "_gather.*");
+     100             :   // Input for COLLECT_FRAMES
+     101          12 :   readInputLine( getShortcutLabel() + "_collect: COLLECT TYPE=vector ARG=" + getShortcutLabel() + "_gatherv STRIDE=" + stride);
+     102             :   // Input for WHAM
+     103          18 :   std::string temp, tempstr=""; parse("TEMP",temp); if( temp.length()>0 ) tempstr="TEMP=" + temp;
+     104          12 :   readInputLine( getShortcutLabel() + ": WHAM ARG=" + getShortcutLabel() + "_collect " + tempstr );
+     105             :   // Input for PRINT (will just output at end of calc
+     106          12 :   std::string filename, fmt; parse("FILE",filename); parse("FMT",fmt);
+     107          12 :   readInputLine( "DUMPVECTOR STRIDE=0 ARG=" + getShortcutLabel() + " FILE=" + filename + " FMT=" + fmt );
+     108           6 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/index-sort-f.html b/coverage/wham/index-sort-f.html new file mode 100644 index 000000000..cbf4740d0 --- /dev/null +++ b/coverage/wham/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - wham + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - whamHitTotalCoverage
Test:plumed test coverageLines:10210597.1 %
Date:2024-10-17 16:45:00Functions:71258.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Wham.cpp +
93.6%93.6%
+
93.6 %44 / 4750.0 %3 / 6
WhamWeights.cpp +
100.0%
+
100.0 %23 / 2366.7 %2 / 3
WhamHistogram.cpp +
100.0%
+
100.0 %35 / 3566.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/index-sort-l.html b/coverage/wham/index-sort-l.html new file mode 100644 index 000000000..3f586ddf3 --- /dev/null +++ b/coverage/wham/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - wham + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - whamHitTotalCoverage
Test:plumed test coverageLines:10210597.1 %
Date:2024-10-17 16:45:00Functions:71258.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Wham.cpp +
93.6%93.6%
+
93.6 %44 / 4750.0 %3 / 6
WhamWeights.cpp +
100.0%
+
100.0 %23 / 2366.7 %2 / 3
WhamHistogram.cpp +
100.0%
+
100.0 %35 / 3566.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wham/index.html b/coverage/wham/index.html new file mode 100644 index 000000000..491d288b4 --- /dev/null +++ b/coverage/wham/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - wham + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - whamHitTotalCoverage
Test:plumed test coverageLines:10210597.1 %
Date:2024-10-17 16:45:00Functions:71258.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Wham.cpp +
93.6%93.6%
+
93.6 %44 / 4750.0 %3 / 6
WhamHistogram.cpp +
100.0%
+
100.0 %35 / 3566.7 %2 / 3
WhamWeights.cpp +
100.0%
+
100.0 %23 / 2366.7 %2 / 3
+
+
+ + + + +
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 000000000..9a7c1712e --- /dev/null +++ b/coverage/wrapper/Plumed.h.func-sort-c.html @@ -0,0 +1,1224 @@ + + + + + + + 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:26755248.4 %
Date:2024-10-17 16:45:00Functions:14728851.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt11regex_errorE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt11regex_errorEC2ERKS3_PKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt11regex_errorEC2ERKS4_0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt12bad_weak_ptrE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt17bad_function_callE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt20bad_array_new_lengthE4initEPKc0
_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_toISt11regex_errorEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt12bad_weak_ptrEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt17bad_function_callEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt20bad_array_new_lengthEEEEvRKT_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_nestedclISt12system_errorEEvRKT_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_toISt11regex_errorE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt11regex_errorEC2ERKS2_PKc0
_ZN4PLMD6Plumed13add_buffer_toISt11regex_errorEC2ERKS3_0
_ZN4PLMD6Plumed13add_buffer_toISt12bad_weak_ptrE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt17bad_function_callE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt20bad_array_new_lengthE4initEPKc0
_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_toISt11regex_errorEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt12bad_weak_ptrEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt17bad_function_callEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt20bad_array_new_lengthEEEEvRKT_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_nestedclISt12system_errorEEvRKT_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
_ZN4PLMD6PlumedD0Ev0
_ZN4PLMD6PlumedD2Ev0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt11regex_errorE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt12bad_weak_ptrE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt17bad_function_callE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt20bad_array_new_lengthE4whatEv0
_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_toISt11regex_errorE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt12bad_weak_ptrE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt17bad_function_callE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt20bad_array_new_lengthE4whatEv0
_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_valid23
plumed_f_global_static24
plumed_f_safeptr_ptr24
plumed_ginitialized24
plumed_kernel_register26
plumed_f_gcmd_28
plumed_f_finalize_static30
PLUMED_F_CMD40
PLUMED_F_CMD_40
PLUMED_F_CMD__40
plumed_f_cmd__40
plumed_use_count42
plumed_c2f56
plumed_f_cmd_59
plumed_f_cmd60
plumed_gcreate61
plumed_gfinalize61
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_privE6plumedPKcRNS1_7SafePtrEP12plumed_error222
plumed_f_cmd_static279
_ZN4PLMD6Plumed10cmd_helperIRA18_KcPP19ompi_communicator_tLi0EEEvOT_OT0_352
plumed_cmd357
plumed_f2c373
plumed_global589
_ZN4PLMD6Plumed10cmd_helperIRA11_KcPiLi0EEEvOT_OT0_5248
_ZN4PLMD6Plumed10cmd_helperIRA15_KcPiLi0EEEvOT_OT0_5248
_ZN4PLMD6Plumed10make_shapeESt16initializer_listINS0_8SizeLikeEE5248
_ZN4PLMD6Plumed21cmd_helper_with_shapeIRA15_KcPcLi0EEEvOT_PT0_Pmb5248
_ZN4PLMD6Plumed3cmdIRA15_KcPcEEvOT_PT0_St16initializer_listINS0_8SizeLikeEE5248
_ZN4PLMD6Plumed8cmd_privE6plumedPKcRNS0_7SafePtrEP12plumed_error16096
plumed_cmd_safe_nothrow19162
plumed_symbol_table_reexport703210
plumed_retrieve_functions704190
plumed_malloc_pimpl722506
plumed_malloc725149
plumed_create735712
plumed_free747367
plumed_create_reference7652264
plumed_finalize8492747
+
+
+ + + +
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 000000000..34ed64458 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func.html @@ -0,0 +1,1224 @@ + + + + + + + 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:26755248.4 %
Date:2024-10-17 16:45:00Functions:14728851.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_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_toISt11regex_errorE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt11regex_errorEC2ERKS3_PKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt11regex_errorEC2ERKS4_0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt12bad_weak_ptrE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt17bad_function_callE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt20bad_array_new_lengthE4initEPKc0
_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_toISt11regex_errorEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt12bad_weak_ptrEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt17bad_function_callEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt20bad_array_new_lengthEEEEvRKT_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_nestedclISt12system_errorEEvRKT_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_privE6plumedPKcRNS1_7SafePtrEP12plumed_error222
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed10cmd_helperIRA11_KcPiLi0EEEvOT_OT0_5248
_ZN4PLMD6Plumed10cmd_helperIRA15_KcPiLi0EEEvOT_OT0_5248
_ZN4PLMD6Plumed10cmd_helperIRA18_KcPP19ompi_communicator_tLi0EEEvOT_OT0_352
_ZN4PLMD6Plumed10make_shapeESt16initializer_listINS0_8SizeLikeEE5248
_ZN4PLMD6Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt11regex_errorE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt11regex_errorEC2ERKS2_PKc0
_ZN4PLMD6Plumed13add_buffer_toISt11regex_errorEC2ERKS3_0
_ZN4PLMD6Plumed13add_buffer_toISt12bad_weak_ptrE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt17bad_function_callE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt20bad_array_new_lengthE4initEPKc0
_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_toISt11regex_errorEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt12bad_weak_ptrEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt17bad_function_callEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt20bad_array_new_lengthEEEEvRKT_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_nestedclISt12system_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD6Plumed21cmd_helper_with_shapeIRA15_KcPcLi0EEEvOT_PT0_Pmb5248
_ZN4PLMD6Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD6Plumed3cmdIRA15_KcPcEEvOT_PT0_St16initializer_listINS0_8SizeLikeEE5248
_ZN4PLMD6Plumed7rethrowER12plumed_error0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed8cmd_privE6plumedPKcRNS0_7SafePtrEP12plumed_error16096
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMD6PlumedD0Ev0
_ZN4PLMD6PlumedD2Ev0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt11regex_errorE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt12bad_weak_ptrE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt17bad_function_callE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt20bad_array_new_lengthE4whatEv0
_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_toISt11regex_errorE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt12bad_weak_ptrE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt17bad_function_callE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt20bad_array_new_lengthE4whatEv0
_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_nothrow19162
plumed_create735712
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_invalid2
plumed_create_reference7652264
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_finalize8492747
plumed_free747367
plumed_gcmd78
plumed_gcmd_safe0
plumed_gcreate61
plumed_gfinalize61
plumed_ginitialized24
plumed_global589
plumed_gvalid8
plumed_installed9
plumed_kernel_register26
plumed_malloc725149
plumed_malloc_pimpl722506
plumed_retrieve_functions704190
plumed_search_symbols8
plumed_symbol_table_reexport703210
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 000000000..e2f9ad367 --- /dev/null +++ b/coverage/wrapper/Plumed.h.gcov.html @@ -0,0 +1,4847 @@ + + + + + + + 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:26755248.4 %
Date:2024-10-17 16:45:00Functions:14728851.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_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 checks can be disabled by setting `export PLUMED_TYPESAFE_IGNORE=yes` at runtime.
+     341             : 
+     342             :   Typechecks are also enabled in the C interface (plumed_cmd). This function is replaced with a macro by default.
+     343             :   In particular:
+     344             :   - 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`.
+     345             :   - If the C interface is used in C code and compiled with a C11 compiler, it uses _Generic to pass type information.
+     346             :     Can be disabled using `-D__PLUMED_WRAPPER_C_TYPESAFE=0`.
+     347             : 
+     348             : \section ReferencePlumedH-2-5 New in PLUMED 2.5
+     349             : 
+     350             :   The wrappers in PLUMED 2.5 have been completely rewritten with several improvements.
+     351             :   The interface is almost perfectly backward compatible, although the behavior of C++ constructors
+     352             :   has been modified slightly.
+     353             :   In addition, a few new functions are introduced (explicitly marked in the documentation).
+     354             :   As a consequence, if your code uses some of the new functions, you will not be able
+     355             :   to link it directly with an older PLUMED library (though you will still be able to load
+     356             :   an older PLUMED library at runtime). In addition, the reference counter changes slightly
+     357             :   the behavior of the C++ methods used to interoperate with C and FORTRAN.
+     358             : 
+     359             :   An important novelty is in the way the runtime loader is implemented.
+     360             :   In particular, the loader works also if the symbols of the main executable are not exported.
+     361             :   The proper functions from the kernel are indeed searched explicitly now using `dlsym`.
+     362             : 
+     363             :   Some additional features can be enabled using suitable environment variables. In particular:
+     364             :   - `PLUMED_LOAD_DEBUG` can be set to report more information about the loading process.
+     365             :   - `PLUMED_LOAD_NAMESPACE` can be set to choose in which namespace PLUMED is loaded when using runtime
+     366             :     loading. As of version 2.10, PLUMED is loaded with RTLD_LOCAL by default. The behavior can be reverted
+     367             :     by exporting `PLUMED_LOAD_NAMESPACE=GLOBAL`. The default setting facilitates loading multiple
+     368             :     versions of PLUMED simultaneously.
+     369             :   - `PLUMED_LOAD_NODEEPBIND` can be set to load the PLUMED kernel in not-deepbind mode. Deepbind
+     370             :     mode implies that the symbols defined in the library are preferred to other symbols with the same name.
+     371             :     Only works on systems supporting `RTLD_DEEPBIND` and is mostly for debugging purposes.
+     372             : 
+     373             :   Another difference is that the implementation of the wrappers is now completely contained in the `Plumed.h`
+     374             :   file. You can see that the `Plumed.c` is much simpler now and just includes `Plumed.h`. With a similar
+     375             :   procedure you could compile the wrappers directly into your code making it unnecessary to link
+     376             :   the libplumedWrapper.a library. The corresponding macros are still subject to change and are not documented here.
+     377             : 
+     378             :   As written above, the plumed object now implements a reference counter.  Consider the following example
+     379             : \verbatim
+     380             :   plumed p=plumed_create();
+     381             :   plumed_cmd(p,"init",NULL);
+     382             :   plumed q=plumed_create_reference(p);
+     383             :   plumed_finalize(p);
+     384             : // at this stage, object q still exists
+     385             :   plumed_cmd(q,"whatever",NULL);
+     386             :   plumed_finalize(q);
+     387             : // now plumed has been really finalized
+     388             : \endverbatim
+     389             : 
+     390             :   In other words, every \ref plumed_create, \ref plumed_create_dlopen, \ref plumed_create_reference,
+     391             :   \ref plumed_create_reference_f, and \ref plumed_create_reference_v call must be matched by a \ref plumed_finalize.
+     392             :   Notice that in C++ whenever an object goes out of scope the reference counter
+     393             :   will be decreased. In addition, consider that conversion from C/FORTRAN/void* to C++ implies calling a C++ constructor, that
+     394             :   is increases the number of references by one. Converting from C++ to C/FORTRAN/void* instead does not call any constructor,
+     395             :   that is the number of references is unchanged.
+     396             : 
+     397             :   The change in the behavior of C++ constructors means that the following code will behave in a backward incompatible manner:
+     398             : \verbatim
+     399             :   plumed p=plumed_create();
+     400             :   plumed_cmd(p,"init",NULL);
+     401             :   Plumed q(p);
+     402             :   plumed_finalize(p);
+     403             : // at this stage, object q still exists with PLUMED 2.5
+     404             : // on the other hand, with PLUMED 2.4 object q refers to an
+     405             : // already finalized object
+     406             :   q.cmd("whatever",NULL);
+     407             : \endverbatim
+     408             : 
+     409             :   Another difference is that the value of the variable `PLUMED_KERNEL` is read every time a new
+     410             :   plumed object is instantiated. So, you might even use it to load different plumed versions
+     411             :   simultaneously, although the preferred way to do this is using the function \ref plumed_create_dlopen.
+     412             :   Notice that if you want to load multiple versions simultaneously you should load them in a local namespace.
+     413             :   \ref plumed_create_dlopen does it automatically, whereas loading through env var `PLUMED_KERNEL` only does it if
+     414             :   you also set env var `PLUMED_NAMESPACE=LOCAL`.
+     415             : 
+     416             :   Finally, a few functions have been added, namely:
+     417             :   - Functions to find if a plumed object is valid
+     418             :     (\ref plumed_valid(), \ref plumed_gvalid(), \ref PLMD::Plumed::valid(), and \ref PLMD::Plumed::gvalid()).
+     419             :   - Functions to create a plumed object based on the path of a specific kernel
+     420             :     (\ref plumed_create_dlopen() and \ref PLMD::Plumed::dlopen()).
+     421             :   - Functions to create a plumed object referencing to another one, implementing a reference counter
+     422             :     (\ref plumed_create_reference(), \ref plumed_create_reference_v(), \ref plumed_create_reference_f().
+     423             : 
+     424             : */
+     425             : 
+     426             : 
+     427             : /* BEGINNING OF DECLARATIONS */
+     428             : 
+     429             : /* SETTING DEFAULT VALUES FOR CONTROL MACROS */
+     430             : 
+     431             : /*
+     432             :   1: make the C wrapper functions extern (default)
+     433             :   0: make the C wrapper functions static (C) or inline (C++)
+     434             : 
+     435             :   If set to zero, it disables all functions that only make sense as extern, such as
+     436             :   Fortran wrappers, global objects, and plumed_kernel_register.
+     437             : 
+     438             :   It can be set to zero to include multiple copies of the wrapper implementation without worrying
+     439             :   about duplicated symbols.
+     440             : 
+     441             :   Notice that C++ wrappers are always inline. What this function controls is if the C wrappers
+     442             :   (called by the C++ wrappers) is inline or not. Also consider that if this header is compiled
+     443             :   with C++ and inline C wrappers, the C wrappers will be actually compiled with C++ linkage
+     444             :   in the root namespace.
+     445             : 
+     446             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     447             : */
+     448             : 
+     449             : #ifndef __PLUMED_WRAPPER_EXTERN
+     450             : #define __PLUMED_WRAPPER_EXTERN 1
+     451             : #endif
+     452             : 
+     453             : /*
+     454             :   1: emit global plumed object and related functions (default)
+     455             :   0: do not emit global plumed object and related functions
+     456             : 
+     457             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     458             : */
+     459             : 
+     460             : #ifndef __PLUMED_WRAPPER_GLOBAL
+     461             : #define __PLUMED_WRAPPER_GLOBAL 1
+     462             : #endif
+     463             : 
+     464             : /*
+     465             :   1: Enable typesafe C interface (default)
+     466             :   0: Disable typesafe C interface
+     467             : 
+     468             :   Only used in declarations. Requires C11 _Generic and variadic macros, and so it is
+     469             :   disabled by default with C++ and pre C11 compilers.
+     470             : 
+     471             :   https://mort.coffee/home/c-compiler-quirks/
+     472             : */
+     473             : 
+     474             : #ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     475             : #  if defined(__STDC_VERSION__)
+     476             : #    if ! defined(__cplusplus) && __STDC_VERSION__ >= 201112L
+     477             : #      if defined(__GNUC__) && !defined(__clang__)
+     478             : #        if (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
+     479             : #          define __PLUMED_WRAPPER_C_TYPESAFE 1
+     480             : #        endif
+     481             : #      else
+     482             : #        define __PLUMED_WRAPPER_C_TYPESAFE 1
+     483             : #      endif
+     484             : #    endif
+     485             : #  endif
+     486             : #  ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     487             : #    define __PLUMED_WRAPPER_C_TYPESAFE 0
+     488             : #  endif
+     489             : #endif
+     490             : 
+     491             : /*
+     492             :   1: Enable RTLD_DEEPBIND when possible (default)
+     493             :   0: Disable RTLD_DEEPBIND
+     494             : */
+     495             : 
+     496             : #ifndef __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+     497             : #define __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND 1
+     498             : #endif
+     499             : 
+     500             : /*
+     501             :   1: enable C++ wrapper (default)
+     502             :   0: disable C++ wrapper
+     503             : 
+     504             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     505             : */
+     506             : 
+     507             : #ifndef __PLUMED_WRAPPER_CXX
+     508             : #define __PLUMED_WRAPPER_CXX 1
+     509             : #endif
+     510             : 
+     511             : /*
+     512             :   1: new headers such as cstdlib are included in C++ (default)
+     513             :   0: old headers such as stdlib.h are included in C++
+     514             : 
+     515             :   Should only be set to zero when including the Plumed.h file in a file using the
+     516             :   old (stdlib.h) convention.
+     517             : 
+     518             :   Used both in declarations and definitions.
+     519             : */
+     520             : 
+     521             : #ifndef __PLUMED_WRAPPER_CXX_STD
+     522             : #define __PLUMED_WRAPPER_CXX_STD 1
+     523             : #endif
+     524             : 
+     525             : /*
+     526             :   1: place C++ wrappers in an anonymous namespace
+     527             :   0: place C++ wrappers in the PLMD namespace (default)
+     528             : 
+     529             :   It will make PLMD::Plumed a different class (though with the same name)
+     530             :   in each of the translation units in which `Plumed.h` is included.
+     531             : 
+     532             :   Can be used to completey separate C++ implementations. However, it will make
+     533             :   it impossible to transfer Plumed objects between different translation units
+     534             :   without converting to a void* or plumed object.
+     535             : 
+     536             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     537             : */
+     538             : 
+     539             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE
+     540             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 0
+     541             : #endif
+     542             : 
+     543             : 
+     544             : /*
+     545             :   1: throw exceptions such as PLMD::Exception
+     546             :   0: throw exceptions such as PLMD::Plumed::Exception (default)
+     547             : 
+     548             :   This is useful when including Plumed.h within the plumed library
+     549             :   in anonymous mode, to make sure that the exception types from the
+     550             :   library are used.
+     551             : */
+     552             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+     553             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 0
+     554             : #endif
+     555             : 
+     556             : /*
+     557             :   1: make PLMD::Plumed class polymorphic (default)
+     558             :   0: make PLMD::Plumed class non-polymorphic
+     559             : 
+     560             :   Only used in declarations.
+     561             : */
+     562             : 
+     563             : #ifndef __PLUMED_WRAPPER_CXX_POLYMORPHIC
+     564             : #define __PLUMED_WRAPPER_CXX_POLYMORPHIC 1
+     565             : #endif
+     566             : 
+     567             : /*
+     568             :   1: Forces strict mode for vector shapes
+     569             :   0: Enable backward compatible sloppy mode for vector shapes (default)
+     570             : 
+     571             :   Only used in declarations.
+     572             : 
+     573             : */
+     574             : #ifndef __PLUMED_WRAPPER_CXX_DETECT_SHAPES_STRICT
+     575             : #define __PLUMED_WRAPPER_CXX_DETECT_SHAPES_STRICT 0
+     576             : #endif
+     577             : 
+     578             : /*
+     579             :   1: Enable typesafe interface (default)
+     580             :   0: Disable typesafe interface
+     581             : 
+     582             :   Only used in declarations.
+     583             : */
+     584             : 
+     585             : #ifndef __PLUMED_WRAPPER_CXX_BIND_C
+     586             : #define __PLUMED_WRAPPER_CXX_BIND_C 1
+     587             : #endif
+     588             : 
+     589             : /*
+     590             :   1: Enable passing long long int
+     591             :   0: Disable passing long long int
+     592             : 
+     593             :   Only used in declarations. Default is 0 in C++<11 and 1 in C++>=11
+     594             : */
+     595             : 
+     596             : #ifndef __PLUMED_WRAPPER_CXX_LONGLONG
+     597             : #if __cplusplus > 199711L
+     598             : #define __PLUMED_WRAPPER_CXX_LONGLONG 1
+     599             : #else
+     600             : #define __PLUMED_WRAPPER_CXX_LONGLONG 0
+     601             : #endif
+     602             : #endif
+     603             : 
+     604             : /*
+     605             :   1: make the default constructor create an invalid object
+     606             :   0: make the default constructor create a valid object
+     607             : 
+     608             :   Only for internal usage.
+     609             : */
+     610             : #ifndef __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+     611             : #define __PLUMED_WRAPPER_CXX_DEFAULT_INVALID 0
+     612             : #endif
+     613             : 
+     614             : /*
+     615             :   Size of a buffer used to store message for exceptions with noexcept constructor.
+     616             :   Should typically hold short messages. Anyway, as long as the stack size stays within the correct
+     617             :   limits it does not seem to affect efficiency. Notice that there cannot be recursive calls of
+     618             :   PLMD::Plumed::cmd, so that it should be in practice irrelevant.
+     619             : */
+     620             : #ifndef __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER
+     621             : #define __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER 512
+     622             : #endif
+     623             : 
+     624             : /*
+     625             :   1: enable nested exceptions (only with C++11) (default)
+     626             :   0: disable nested exceptions
+     627             : 
+     628             :   For internal testing, used to mimic pre C++11 behavior on
+     629             :   nested exception.
+     630             : 
+     631             :   Only used in declarations.
+     632             : */
+     633             : 
+     634             : #ifndef __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+     635             : #define __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS 1
+     636             : #endif
+     637             : 
+     638             : /*
+     639             :  By default, assume C++11 compliant library is not available.
+     640             : */
+     641             : 
+     642             : #ifndef __PLUMED_WRAPPER_LIBCXX11
+     643             : #define __PLUMED_WRAPPER_LIBCXX11 0
+     644             : #endif
+     645             : 
+     646             : /*
+     647             :  By default, assume C++17 compliant library is not available.
+     648             : */
+     649             : 
+     650             : #ifndef __PLUMED_WRAPPER_LIBCXX17
+     651             : #define __PLUMED_WRAPPER_LIBCXX17 0
+     652             : #endif
+     653             : 
+     654             : /* The following macros are just to define shortcuts */
+     655             : 
+     656             : /* This is needed to use non c-style cast when working in c++ */
+     657             : #ifdef __cplusplus
+     658             : #define __PLUMED_WRAPPER_STATIC_CAST(to,what) static_cast<to>(what)
+     659             : #define __PLUMED_WRAPPER_REINTERPRET_CAST(to,what) reinterpret_cast<to>(what)
+     660             : #else
+     661             : #define __PLUMED_WRAPPER_STATIC_CAST(to,what) ((to) what)
+     662             : #define __PLUMED_WRAPPER_REINTERPRET_CAST(to,what) __PLUMED_WRAPPER_STATIC_CAST(to,what)
+     663             : #endif
+     664             : 
+     665             : /* Simplify addition of extern "C" blocks.  */
+     666             : #ifdef __cplusplus
+     667             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN extern "C" {
+     668             : #define __PLUMED_WRAPPER_EXTERN_C_END }
+     669             : #else
+     670             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN
+     671             : #define __PLUMED_WRAPPER_EXTERN_C_END
+     672             : #endif
+     673             : 
+     674             : /* Without C++, stdlib functions should not be prepended with ::std:: */
+     675             : #ifndef __cplusplus
+     676             : #undef __PLUMED_WRAPPER_CXX_STD
+     677             : #define __PLUMED_WRAPPER_CXX_STD 0
+     678             : #endif
+     679             : 
+     680             : /* Set prefix for stdlib functions */
+     681             : #if __PLUMED_WRAPPER_CXX_STD
+     682             : #define __PLUMED_WRAPPER_STD ::std::
+     683             : #else
+     684             : #define __PLUMED_WRAPPER_STD
+     685             : #endif
+     686             : 
+     687             : /* Allow using noexcept, explicit, and override with C++11 compilers */
+     688             : #ifdef __cplusplus /*{*/
+     689             : #if __cplusplus > 199711L
+     690             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT noexcept
+     691             : #define __PLUMED_WRAPPER_CXX_NORETURN [[ noreturn ]]
+     692             : #define __PLUMED_WRAPPER_CXX_EXPLICIT explicit
+     693             : #define __PLUMED_WRAPPER_CXX_OVERRIDE override
+     694             : #define __PLUMED_WRAPPER_CXX_NULLPTR  nullptr
+     695             : #else
+     696             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT throw()
+     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             : #else
+     703             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT
+     704             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     705             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     706             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     707             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     708             : #endif /*}*/
+     709             : 
+     710             : /* static inline, for to avoid compiler warnings */
+     711             : #if defined(__cplusplus) || __STDC_VERSION__>=199901L
+     712             : #define __PLUMED_WRAPPER_STATIC_INLINE static inline
+     713             : #else
+     714             : #define __PLUMED_WRAPPER_STATIC_INLINE static
+     715             : #endif
+     716             : 
+     717             : /* Macros for anonymous namespace */
+     718             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE && defined(__cplusplus) /*{*/
+     719             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN namespace {
+     720             : #define __PLUMED_WRAPPER_ANONYMOUS_END }
+     721             : #else
+     722             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN
+     723             : #define __PLUMED_WRAPPER_ANONYMOUS_END
+     724             : #endif /*}*/
+     725             : 
+     726             : #if __PLUMED_WRAPPER_EXTERN /*{*/
+     727             : 
+     728             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN extern
+     729             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_EXTERN_C_END
+     730             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN static
+     731             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_EXTERN_C_END
+     732             : 
+     733             : #else
+     734             : 
+     735             : #ifdef __cplusplus
+     736             : #define __PLUMED_WRAPPER_C_BEGIN  __PLUMED_WRAPPER_ANONYMOUS_BEGIN inline
+     737             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_ANONYMOUS_END
+     738             : #else
+     739             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_STATIC_INLINE
+     740             : #define __PLUMED_WRAPPER_C_END
+     741             : #endif
+     742             : 
+     743             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_C_BEGIN
+     744             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_C_END
+     745             : 
+     746             : /* with an not-external interface, it does not make sense to define global functions */
+     747             : #undef __PLUMED_WRAPPER_GLOBAL
+     748             : #define __PLUMED_WRAPPER_GLOBAL 0
+     749             : 
+     750             : #endif /*}*/
+     751             : 
+     752             : #if __PLUMED_WRAPPER_CXX_STD
+     753             : #include <cstddef> /* size_t */
+     754             : #include <cstring> /* memcpy */
+     755             : #include <cstdio> /* fprintf */
+     756             : #include <cstdlib> /* abort */
+     757             : #include <cassert> /* assert */
+     758             : #else
+     759             : #include <stddef.h>
+     760             : #include <string.h>
+     761             : #include <stdio.h> /* FILE and fprintf */
+     762             : #include <stdlib.h> /* abort */
+     763             : #include <limits.h> /* CHAR_MIN */
+     764             : #include <assert.h> /* assert */
+     765             : #endif
+     766             : 
+     767             : /**
+     768             :   This is an internal tool, to make sure that all malloc calls inside the
+     769             :   plumed library refer to the same implementation. When compiling with
+     770             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     771             :   allocations and deallocations, so as to debug the wrappers.
+     772             : */
+     773             : __PLUMED_WRAPPER_C_BEGIN
+     774             : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size);
+     775             : __PLUMED_WRAPPER_C_END
+     776             : 
+     777             : /**
+     778             :   This is an internal tool, to make sure that all free calls inside the
+     779             :   plumed library refer to the same implementation. When compiling with
+     780             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     781             :   allocations and deallocations, so as to debug the wrappers.
+     782             : */
+     783             : __PLUMED_WRAPPER_C_BEGIN
+     784             : void plumed_free(void* ptr);
+     785             : __PLUMED_WRAPPER_C_END
+     786             : 
+     787             : /**
+     788             :   \brief Main plumed object
+     789             : 
+     790             :   This is an object containing a Plumed instance, which should be used in
+     791             :   the MD engine. It should first be initialized with plumed_create(),
+     792             :   then it communicates with the MD engine using plumed_cmd(). Finally,
+     793             :   before the termination, it should be deallocated with plumed_finalize().
+     794             :   Its interface is very simple and general, and is expected
+     795             :   not to change across plumed versions. See \ref ReferencePlumedH.
+     796             : */
+     797             : typedef struct {
+     798             :   /**
+     799             :     \private
+     800             :     \brief Void pointer holding the real PlumedMain structure
+     801             : 
+     802             :     To maintain binary compatibility, we should not add members to this structure.
+     803             :     As of PLUMED 2.5, in order to add new components we do not store the pointer
+     804             :     to \ref PlumedMain here but rather a pointer to an intermediate private structure
+     805             :     that contains all the details.
+     806             :   */
+     807             :   void*p;
+     808             : } plumed;
+     809             : 
+     810             : typedef struct {
+     811             :   void* ptr;
+     812             :   void (*handler)(void*,int,const char*,const void*);
+     813             : } plumed_nothrow_handler;
+     814             : 
+     815             : /** \relates plumed
+     816             :     \brief Structure holding a typesafe pointer.
+     817             : */
+     818             : 
+     819             : typedef struct {
+     820             :   /** Pointer to data */
+     821             :   const void* ptr;
+     822             :   /** Number of elements (in case pointing to an array) */
+     823             :   __PLUMED_WRAPPER_STD size_t nelem;
+     824             :   /** Shape (scanned up to a zero value is found) */
+     825             :   const __PLUMED_WRAPPER_STD size_t* shape;
+     826             :   /**
+     827             :     sum of:
+     828             :     sizeof(pointed data), up to 0x10000 (65536). 0 means size not checked
+     829             :     0x10000    * data type, up to 0xff (255)
+     830             :                0 not typechecked
+     831             :                1 void
+     832             :                2 nullptr
+     833             :                3 integral
+     834             :                4 floating point
+     835             :                5 FILE (size will not be computed as it might be incomplete)
+     836             :                >5 not typechecked, reserved for future extensions
+     837             :     0x1000000  * 1 for unsigned (ignored)
+     838             :     0x2000000  * pointer/const type, up to 8
+     839             :                0 not typechecked
+     840             :                1 T (pass-by-value)
+     841             :                2 T       *
+     842             :                3 T const *
+     843             :                4 T       *       *
+     844             :                5 T       * const *
+     845             :                6 T const *       *
+     846             :                7 T const * const *
+     847             :     0x10000000 * 1 to forbid pointer copy (pointer copy is also forbidden for pass-by-value)
+     848             :     0x20000000 and higher bits are ignored, reserved for future extensions
+     849             :   */
+     850             :   __PLUMED_WRAPPER_STD size_t flags;
+     851             :   /** Optional information, not used yet  */
+     852             :   const void* opt;
+     853             : } plumed_safeptr;
+     854             : 
+     855             : /* local structure */
+     856             : typedef struct plumed_error_filesystem_path {
+     857             :   __PLUMED_WRAPPER_STD size_t numbytes;
+     858             :   void* ptr;
+     859             : } plumed_error_filesystem_path;
+     860             : 
+     861             : /**
+     862             :   Small structure that is only defined locally to retrieve errors.
+     863             : 
+     864             :   It is supposed to be used in the C11/C++ plumed_cmd interface as follows:
+     865             : \verbatim
+     866             :   plumed p;
+     867             :   plumed_error error;
+     868             : 
+     869             :   p=plumed_create();
+     870             : 
+     871             :   plumed_cmd(p,"setNatoms",10,&error);
+     872             :   if(error.code) {
+     873             :     fprintf(errors,"%d\n",error.code);
+     874             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     875             :   }
+     876             :   // if no error was raised (error.code==0), it is not necessary to call plumed_error_finalize.
+     877             :   // but doing it is harmless
+     878             : 
+     879             :   // no need to initialize error, it is written in the plumed_cmd function
+     880             :   plumed_cmd(p,"init",&error);
+     881             :   if(error.code) {
+     882             :     fprintf(errors,"%d\n",error.code);
+     883             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     884             :   }
+     885             : \endverbatim
+     886             : 
+     887             :   The layout of this structure is subject to change, thus all the functions manipulating it
+     888             :   are defined as inline/static functions. In the future, we might reach some form
+     889             :   of ABI stability, and these functions might be moved below to the implementation
+     890             :   file.
+     891             : 
+     892             :   Notice that there is a macro plumed_error() defined in the PLUMED source code
+     893             :   (at tools/Exception.h). There is no conflict with this type since C preprocessor
+     894             :   distinguishes macros and function-like macros.
+     895             : */
+     896             : typedef struct plumed_error {
+     897             :   /** code used for translating messages */
+     898             :   int code;
+     899             :   /** error code for system_error */
+     900             :   int error_code;
+     901             :   /** category - for errors */
+     902             :   int error_category;
+     903             :   /** path1 - for filesystem_error */
+     904             :   plumed_error_filesystem_path path1;
+     905             :   /** path2 - for filesystem_error */
+     906             :   plumed_error_filesystem_path path2;
+     907             :   /** message */
+     908             :   const char* what;
+     909             :   /** the buffer containing the message to be deallocated */
+     910             :   char* what_buffer;
+     911             :   /** pointer to nested exception */
+     912             :   struct plumed_error* nested;
+     913             : } plumed_error;
+     914             : 
+     915             : /** Initialize error (for internal usage) */
+     916             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_init(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     917             :   assert(error);
+     918       16318 :   error->code=0;
+     919       16318 :   error->error_code=0;
+     920       16318 :   error->error_category=0;
+     921       16318 :   error->path1.numbytes=0;
+     922       16318 :   error->path1.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+     923       16318 :   error->path2.numbytes=0;
+     924       16318 :   error->path2.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+     925       16318 :   error->what=__PLUMED_WRAPPER_CXX_NULLPTR;
+     926       16318 :   error->what_buffer=__PLUMED_WRAPPER_CXX_NULLPTR;
+     927       16318 :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+     928             : }
+     929             : 
+     930             : /** Finalize error - should be called when an error is raised to avoid leaks */
+     931             : /* cppcheck-suppress passedByValue */
+     932           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_finalize(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     933           0 :   if(!error.code) return;
+     934           0 :   if(error.nested) {
+     935           0 :     plumed_error_finalize(*error.nested);
+     936           0 :     plumed_free(error.nested);
+     937             :   }
+     938           0 :   if(error.path1.ptr) {
+     939           0 :     plumed_free(error.path1.ptr);
+     940             :   }
+     941           0 :   if(error.path2.ptr) {
+     942           0 :     plumed_free(error.path2.ptr);
+     943             :   }
+     944           0 :   if(error.what_buffer) {
+     945           0 :     plumed_free(error.what_buffer);
+     946             :   }
+     947             : }
+     948             : 
+     949             : /** Access message - more robust than directly accessing what ptr, for future extensibility */
+     950             : /* cppcheck-suppress passedByValue */
+     951             : __PLUMED_WRAPPER_STATIC_INLINE const char* plumed_error_what(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     952             :   return error.what;
+     953             : }
+     954             : 
+     955             : /** Set error to bad_alloc (for internal usage).
+     956             :     At variance with plumed_error_init, it also finalizes the error, possibly
+     957             :     deallocating any buffer.
+     958             : */
+     959           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set_bad_alloc(plumed_error*error) {
+     960             :   assert(error);
+     961           0 :   plumed_error_finalize(*error);
+     962             :   plumed_error_init(error);
+     963           0 :   error->what="[msg erased due to allocation failure]";
+     964           0 :   error->code=11400;
+     965           0 : }
+     966             : 
+     967             : /** Recursive merge (for internal usage) */
+     968             : __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 {
+     969             :   if(error->nested) plumed_error_recursive_merge(error->nested,buffer,join,len);
+     970             :   __PLUMED_WRAPPER_STD strncat(buffer,plumed_error_what(*error),*len);
+     971             :   *len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+     972             :   __PLUMED_WRAPPER_STD strncat(buffer,join,*len);
+     973             :   *len -= __PLUMED_WRAPPER_STD strlen(join);
+     974             : }
+     975             : 
+     976             : /** Merge with nested exceptions */
+     977             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_merge_with_nested(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     978             :   __PLUMED_WRAPPER_STD size_t len;
+     979             :   __PLUMED_WRAPPER_STD size_t len_join;
+     980             :   /* The is temporarily holding the new message */
+     981             :   char* new_buffer;
+     982             :   /* This is the string used to concatenate messages */
+     983             :   const char* join="\n\nThe above exception was the direct cause of the following exception:\n";
+     984             :   /* This is used to iterate over the linked list of nested exceptions */
+     985             :   plumed_error*e;
+     986             : 
+     987             :   /* If exception is not nested, nothing to do */
+     988             :   if(!error->nested) return;
+     989             : 
+     990             :   /* Accumulate the total length of the concatenated message */
+     991             :   len_join=__PLUMED_WRAPPER_STD strlen(join);
+     992             :   e=error;
+     993             :   len=__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     994             :   while(e->nested) {
+     995             :     e=e->nested;
+     996             :     len+=len_join+__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     997             :   }
+     998             : 
+     999             :   /* Allocate the new message */
+    1000             :   new_buffer=__PLUMED_WRAPPER_STATIC_CAST(char*, plumed_malloc(len+1));
+    1001             :   if(new_buffer) {
+    1002             :     /* If allocation was successful, merge the messages */
+    1003             :     new_buffer[0]='\0';
+    1004             :     /* Notice that we have a forward linked list but we need to go through that in backward order
+    1005             :        (inner to outer). To do that without allocating an additional array, we use a recursive
+    1006             :        function.
+    1007             :     */
+    1008             :     assert(error->nested);
+    1009             :     plumed_error_recursive_merge(error->nested,new_buffer,join,&len);
+    1010             :     __PLUMED_WRAPPER_STD strncat(new_buffer,plumed_error_what(*error),len);
+    1011             :     len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+    1012             :     /* we keep track of length of buffer for safety */
+    1013             :     assert(len==0);
+    1014             :   }
+    1015             :   error->what=new_buffer;
+    1016             : 
+    1017             :   /* Deallocate the previous message */
+    1018             :   if(error->what_buffer) plumed_free(error->what_buffer);
+    1019             :   error->what_buffer=new_buffer;
+    1020             : 
+    1021             :   /* Finalize the chain of nested exceptions */
+    1022             :   plumed_error_finalize(*error->nested);
+    1023             :   plumed_free(error->nested);
+    1024             :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+    1025             : 
+    1026             :   if(!error->what) {
+    1027             :     /* If allocation was not successful, reset to bad_alloc */
+    1028             :     plumed_error_set_bad_alloc(error);
+    1029             :   }
+    1030             : }
+    1031             : 
+    1032             : /** Rethrow error (calling abort) */
+    1033             : __PLUMED_WRAPPER_CXX_NORETURN __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_rethrow(plumed_error h) {
+    1034             :   if(h.nested) plumed_error_merge_with_nested(&h);
+    1035             :   __PLUMED_WRAPPER_STD fprintf(stderr,"Terminate due to exception. Code: %d\n%s\n",h.code,plumed_error_what(h));
+    1036             :   __PLUMED_WRAPPER_STD abort();
+    1037             : }
+    1038             : 
+    1039             : /** Callback (for internal usage) */
+    1040           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set(void*ptr,int code,const char*what,const void* opt) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1041             :   plumed_error* error;
+    1042             :   __PLUMED_WRAPPER_STD size_t len;
+    1043             :   void*const* options;
+    1044             :   plumed_error_filesystem_path path;
+    1045             : 
+    1046             :   error=__PLUMED_WRAPPER_STATIC_CAST(plumed_error*, ptr);
+    1047             : 
+    1048           0 :   error->code=code;
+    1049           0 :   error->error_code=0;
+    1050           0 :   len=__PLUMED_WRAPPER_STD strlen(what);
+    1051           0 :   error->what_buffer=__PLUMED_WRAPPER_STATIC_CAST(char*, plumed_malloc(len+1));
+    1052           0 :   if(!error->what_buffer) {
+    1053           0 :     plumed_error_set_bad_alloc(error);
+    1054           0 :     return;
+    1055             :   }
+    1056             : 
+    1057             :   __PLUMED_WRAPPER_STD strncpy(error->what_buffer,what,len+1);
+    1058           0 :   error->what=error->what_buffer;
+    1059             : 
+    1060             :   /* interpret optional arguments */
+    1061           0 :   if(opt) {
+    1062             :     options=__PLUMED_WRAPPER_STATIC_CAST(void*const*, opt);
+    1063           0 :     while(*options) {
+    1064             :       /* c: error code */
+    1065           0 :       if(*(__PLUMED_WRAPPER_STATIC_CAST(const char*,*options))=='c' && *(options+1)) {
+    1066           0 :         error->error_code=*(__PLUMED_WRAPPER_STATIC_CAST(const int*,*(options+1)));
+    1067           0 :         break;
+    1068             :       }
+    1069           0 :       options+=2;
+    1070             :     }
+    1071             : 
+    1072             :     options=__PLUMED_WRAPPER_STATIC_CAST(void*const*,opt);
+    1073           0 :     while(*options) {
+    1074             :       /* C: error_category */
+    1075           0 :       if(*(__PLUMED_WRAPPER_STATIC_CAST(char*, *options))=='C' && *(options+1)) {
+    1076           0 :         error->error_category=*(__PLUMED_WRAPPER_STATIC_CAST(const int*,*(options+1)));
+    1077           0 :         break;
+    1078             :       }
+    1079           0 :       options+=2;
+    1080             :     }
+    1081             : 
+    1082             :     options=__PLUMED_WRAPPER_STATIC_CAST(void*const*, opt);
+    1083           0 :     while(*options) {
+    1084             :       /* path 1 */
+    1085           0 :       if(*(__PLUMED_WRAPPER_STATIC_CAST(char*, *options))=='p' && *(options+1)) {
+    1086           0 :         path=*__PLUMED_WRAPPER_STATIC_CAST(plumed_error_filesystem_path*,*(options+1));
+    1087           0 :         error->path1.ptr=plumed_malloc(path.numbytes);
+    1088           0 :         if(!error->path1.ptr) {
+    1089           0 :           plumed_error_set_bad_alloc(error);
+    1090           0 :           return;
+    1091             :         }
+    1092           0 :         error->path1.numbytes=path.numbytes;
+    1093             :         __PLUMED_WRAPPER_STD memcpy(error->path1.ptr,path.ptr,path.numbytes);
+    1094             :         break;
+    1095             :       }
+    1096           0 :       options+=2;
+    1097             :     }
+    1098             : 
+    1099             :     options=__PLUMED_WRAPPER_STATIC_CAST(void*const*, opt);
+    1100           0 :     while(*options) {
+    1101             :       /* path 2 */
+    1102           0 :       if(*(__PLUMED_WRAPPER_STATIC_CAST(char*, *options))=='q' && *(options+1)) {
+    1103           0 :         path=*__PLUMED_WRAPPER_STATIC_CAST(plumed_error_filesystem_path*,*(options+1));
+    1104           0 :         error->path2.ptr=plumed_malloc(path.numbytes);
+    1105           0 :         if(!error->path2.ptr) {
+    1106           0 :           plumed_error_set_bad_alloc(error);
+    1107           0 :           return;
+    1108             :         }
+    1109           0 :         error->path2.numbytes=path.numbytes;
+    1110             :         __PLUMED_WRAPPER_STD memcpy(error->path2.ptr,path.ptr,path.numbytes);
+    1111             :         break;
+    1112             :       }
+    1113           0 :       options+=2;
+    1114             :     }
+    1115             : 
+    1116             :     options=__PLUMED_WRAPPER_STATIC_CAST(void*const*, opt);
+    1117           0 :     while(*options) {
+    1118             :       /* n: nested exception */
+    1119           0 :       if(*(__PLUMED_WRAPPER_STATIC_CAST(char*, *options))=='n' && *(options+1)) {
+    1120             :         /* notice that once this is allocated it is guaranteed to be deallocated by the recursive destructor */
+    1121           0 :         error->nested=__PLUMED_WRAPPER_STATIC_CAST(plumed_error*, plumed_malloc(sizeof(plumed_error)));
+    1122             :         /* this is if malloc fails */
+    1123           0 :         if(!error->nested) {
+    1124           0 :           plumed_error_set_bad_alloc(error);
+    1125           0 :           break;
+    1126             :         }
+    1127             :         plumed_error_init(__PLUMED_WRAPPER_STATIC_CAST(plumed_error*,error->nested));
+    1128             :         /* plumed will make sure to only use this if it is not null */
+    1129           0 :         *__PLUMED_WRAPPER_STATIC_CAST(void**,*(options+1))=error->nested;
+    1130           0 :         break;
+    1131             :       }
+    1132           0 :       options+=2;
+    1133             :     }
+    1134             :   }
+    1135             : }
+    1136             : 
+    1137             : /** \relates plumed
+    1138             :     \brief Constructor
+    1139             : 
+    1140             :     Constructs a plumed object.
+    1141             : 
+    1142             :     Notice that if you are linking against libplumedWrapper.a, if you are
+    1143             :     using a code patched in runtime mode, or if you are including the `Plumed.c`
+    1144             :     file directly in your code, this constructor might return an invalid plumed
+    1145             :     object. In particular, this could happen if the `PLUMED_KERNEL` environment
+    1146             :     variable is not set or set incorrectly. In order to detect an incorrect
+    1147             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1148             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1149             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1150             :     to finalize a plumed object even if it is invalid:
+    1151             : \verbatim
+    1152             :   plumed p=plumed_create();
+    1153             :   if(!plumed_valid(p)) {
+    1154             : // this will happen if the PLUMED_KERNEL variable is not set correctly
+    1155             :     plumed_finalize(p);
+    1156             :     return whatever;
+    1157             :   }
+    1158             : \endverbatim
+    1159             : 
+    1160             :     \return The constructed plumed object
+    1161             : */
+    1162             : __PLUMED_WRAPPER_C_BEGIN
+    1163             : plumed plumed_create(void);
+    1164             : __PLUMED_WRAPPER_C_END
+    1165             : 
+    1166             : /** \relates plumed
+    1167             :     \brief Constructor from path. Available as of PLUMED 2.5
+    1168             : 
+    1169             :     It tries to construct a plumed object loading the kernel located at path.
+    1170             :     Notice that it could leave the resulting object in an invalid state.
+    1171             :     In order to detect an invalid
+    1172             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1173             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1174             : 
+    1175             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1176             :     to finalize a plumed object even if it is invalid.
+    1177             : \verbatim
+    1178             :   plumed p=plumed_create(path);
+    1179             :   if(!plumed_valid(p)) {
+    1180             : // this will happen if the path argument is not set correctly
+    1181             :     plumed_finalize(p);
+    1182             :     return whatever;
+    1183             :   }
+    1184             : \endverbatim
+    1185             : 
+    1186             :     \return The constructed plumed object
+    1187             : */
+    1188             : __PLUMED_WRAPPER_C_BEGIN
+    1189             : plumed plumed_create_dlopen(const char*path);
+    1190             : __PLUMED_WRAPPER_C_END
+    1191             : 
+    1192             : 
+    1193             : /**
+    1194             :   \brief Constructor from path. Available as of PLUMED 2.5
+    1195             : 
+    1196             :   Same as \ref plumed_create_dlopen, but also allows to specify the mode for dlopen.
+    1197             : 
+    1198             :   \warning
+    1199             :   Use with care, since not all the possible modes work correctly with PLUMED.
+    1200             : */
+    1201             : __PLUMED_WRAPPER_C_BEGIN
+    1202             : plumed plumed_create_dlopen2(const char*path,int mode);
+    1203             : __PLUMED_WRAPPER_C_END
+    1204             : 
+    1205             : /**
+    1206             :   \brief Constructor from dlopen handle. Available as of PLUMED 2.8
+    1207             : 
+    1208             :   Same as  \ref plumed_create_dlopen, but it acts on an already loaded library.
+    1209             :   This allows to separate the library loading from the construction of the
+    1210             :   plumed object. By using this function, the caller takes the responsibility
+    1211             :   to later use dlclose on this handle.
+    1212             : */
+    1213             : __PLUMED_WRAPPER_C_BEGIN
+    1214             : plumed plumed_create_dlsym(void* dlhandle);
+    1215             : __PLUMED_WRAPPER_C_END
+    1216             : 
+    1217             : /** \relates plumed
+    1218             :     Create a new reference to an existing object, increasing its reference count. Available as of PLUMED 2.5
+    1219             : 
+    1220             :     Use it to increase by one the reference count of a plumed object.
+    1221             :     The resulting pointer might be identical to the one passed as an
+    1222             :     argument, but the reference count will be incremented by one.
+    1223             :     Notice that you should finalize the resulting object.
+    1224             : \verbatim
+    1225             :   plumed p1;
+    1226             :   plumed p2;
+    1227             :   p1=plumed_create();
+    1228             :   p2=plumed_create_reference(p1);
+    1229             :   plumed_finalize(p1);
+    1230             : // now you can still use p2
+    1231             :   plumed_cmd(p2,"init",NULL);
+    1232             :   plumed_finalize(p2);
+    1233             : // now the underlying object is destroyed.
+    1234             : \endverbatim
+    1235             : 
+    1236             :     If the `p` object is invalid, also the returned object will be invalid.
+    1237             : 
+    1238             :     \param p The plumed object that will be referenced to.
+    1239             :     \return The constructed plumed object
+    1240             : */
+    1241             : 
+    1242             : __PLUMED_WRAPPER_C_BEGIN
+    1243             : plumed plumed_create_reference(plumed p);
+    1244             : __PLUMED_WRAPPER_C_END
+    1245             : 
+    1246             : /** \relates plumed
+    1247             :     \brief Create a new reference to an existing object passed as a void pointer, increasing its reference count. Available as of PLUMED 2.5
+    1248             : 
+    1249             :   \return The constructed plumed object
+    1250             : */
+    1251             : 
+    1252             : __PLUMED_WRAPPER_C_BEGIN
+    1253             : plumed plumed_create_reference_v(void*v);
+    1254             : __PLUMED_WRAPPER_C_END
+    1255             : 
+    1256             : /** \relates plumed
+    1257             :     \brief Create a new reference to an existing object passed as a fortran string, increasing its reference count. Available as of PLUMED 2.5
+    1258             : 
+    1259             :   \return The constructed plumed object
+    1260             : */
+    1261             : 
+    1262             : __PLUMED_WRAPPER_C_BEGIN
+    1263             : plumed plumed_create_reference_f(const char*f);
+    1264             : __PLUMED_WRAPPER_C_END
+    1265             : 
+    1266             : /** \relates plumed
+    1267             :     \brief Constructor as invalid. Available as of PLUMED 2.5
+    1268             : 
+    1269             :    Can be used to create an object in the same state as if it was returned by
+    1270             :    plumed_create_dlopen with an incorrect path (or plumed_create using runtime binding
+    1271             :    and an incorrect PLUMED_KERNEL).
+    1272             : 
+    1273             :    Can be used to initialize a plumed object to a well-defined state without explicitly
+    1274             :    creating it. The resulting object can be checked later with \ref plumed_valid.
+    1275             :    Consider the following example
+    1276             : \verbatim
+    1277             :     plumed p;
+    1278             :     p=plumed_create_invalid();
+    1279             : // at this point p is initialized to a well-defined (invalid) state.
+    1280             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    1281             :     plumed_finalize(p);
+    1282             :     p=plumed_create();
+    1283             : \endverbatim
+    1284             : 
+    1285             :     \return The constructed plumed object
+    1286             : */
+    1287             : 
+    1288             : __PLUMED_WRAPPER_C_BEGIN
+    1289             : plumed plumed_create_invalid();
+    1290             : __PLUMED_WRAPPER_C_END
+    1291             : 
+    1292             : /** \relates plumed
+    1293             :     \brief Tells p to execute a command.
+    1294             : 
+    1295             :     If the object is not valid (see \ref plumed_valid), this command will exit.
+    1296             : 
+    1297             :     \param p The plumed object on which command is acting
+    1298             :     \param key The name of the command to be executed
+    1299             :     \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
+    1300             :                but for some choice of key it can change the content.
+    1301             : 
+    1302             :     Notice that within PLUMED we use a const_cast to remove any const qualifier from the second
+    1303             :     argument of \ref plumed_cmd.
+    1304             : 
+    1305             :     In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted,
+    1306             :     or you can equivalently pass NULL or nullptr).
+    1307             :     The set of possible keys is the real API of the plumed library, and will be expanded with time.
+    1308             :     New commands will be added, but backward compatibility will be retained as long as possible.
+    1309             : */
+    1310             : 
+    1311             : __PLUMED_WRAPPER_C_BEGIN
+    1312             : void plumed_cmd(plumed p,const char*key,const void*val);
+    1313             : __PLUMED_WRAPPER_C_END
+    1314             : 
+    1315             : /**
+    1316             :   \relates plumed
+    1317             :   \brief Same as \ref plumed_cmd, but does not throw exceptions.
+    1318             : 
+    1319             :   This function is meant to be used when errors should be handled explicitly.
+    1320             :   if an exception is raised within PLUMED, the function nothrow.handler() will
+    1321             :   be called with arguments (nothrow.ptr,code,message,opt). This allows the C++ interface
+    1322             :   to correctly rethrow exceptions, but might be used from C as well. opt can be used
+    1323             :   to pass further information (not used yet).
+    1324             : */
+    1325             : 
+    1326             : __PLUMED_WRAPPER_C_BEGIN
+    1327             : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow);
+    1328             : __PLUMED_WRAPPER_C_END
+    1329             : 
+    1330             : __PLUMED_WRAPPER_C_BEGIN
+    1331             : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr,plumed_nothrow_handler nothrow);
+    1332             : __PLUMED_WRAPPER_C_END
+    1333             : 
+    1334             : __PLUMED_WRAPPER_C_BEGIN
+    1335             : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr);
+    1336             : __PLUMED_WRAPPER_C_END
+    1337             : 
+    1338             : /** \relates plumed
+    1339             :     \brief Destructor.
+    1340             : 
+    1341             :     It must be used for any object created using \ref plumed_create(),
+    1342             :     even if the created object is not valid.
+    1343             : 
+    1344             :     \param p The plumed object to be deallocated
+    1345             : */
+    1346             : 
+    1347             : __PLUMED_WRAPPER_C_BEGIN
+    1348             : void plumed_finalize(plumed p);
+    1349             : __PLUMED_WRAPPER_C_END
+    1350             : 
+    1351             : /** \relates plumed
+    1352             :     \brief Check if plumed is installed (for runtime binding).
+    1353             : 
+    1354             :     Notice that this is equivalent to creating a dummy object and checking if it is valid.
+    1355             : 
+    1356             : \verbatim
+    1357             :   // this:
+    1358             :   //int a=plumed_installed();
+    1359             :   // is equivalent to this:
+    1360             : 
+    1361             :   plumed p=plumed_create();
+    1362             :   int a=plumed_valid(p);
+    1363             :   plumed_finalize(p);
+    1364             : 
+    1365             : \endverbatim
+    1366             : 
+    1367             :     This function is mostly provided for compatibility with PLUMED 2.4, where \ref plumed_valid()
+    1368             :     was not available. Using \ref plumed_valid() is now preferred since it creates a single object
+    1369             :     instead of creating a dummy object that is then discarded.
+    1370             : 
+    1371             :     \return 1 if plumed is installed, 0 otherwise
+    1372             : */
+    1373             : 
+    1374             : __PLUMED_WRAPPER_C_BEGIN
+    1375             : int plumed_installed(void);
+    1376             : __PLUMED_WRAPPER_C_END
+    1377             : 
+    1378             : /** \relates plumed
+    1379             :     \brief Check if plumed object is valid. Available as of PLUMED 2.5
+    1380             : 
+    1381             :     It might return false if plumed is not available at runtime.
+    1382             : 
+    1383             :     \return 1 if plumed is valid, 0 otherwise
+    1384             : */
+    1385             : 
+    1386             : __PLUMED_WRAPPER_C_BEGIN
+    1387             : int plumed_valid(plumed p);
+    1388             : __PLUMED_WRAPPER_C_END
+    1389             : 
+    1390             : /** \relates plumed
+    1391             :     \brief Returns the number of references to the underlying object. Available as of PLUMED 2.5.
+    1392             : */
+    1393             : 
+    1394             : __PLUMED_WRAPPER_C_BEGIN
+    1395             : int plumed_use_count(plumed p);
+    1396             : __PLUMED_WRAPPER_C_END
+    1397             : 
+    1398             : 
+    1399             : /* routines to convert char handler from/to plumed objects */
+    1400             : 
+    1401             : /** \related plumed
+    1402             :     \brief Converts a C handler to a FORTRAN handler
+    1403             : 
+    1404             :     \param p The C handler
+    1405             :     \param c The FORTRAN handler (a char[32])
+    1406             : 
+    1407             :     This function can be used to convert a plumed object created in C to
+    1408             :     a plumed handler that can be used in FORTRAN. Notice that the reference counter
+    1409             :     is not incremented. In other words, the FORTRAN object will be a weak reference.
+    1410             :     If you later finalize the C handler, the FORTRAN handler will be invalid.
+    1411             : \verbatim
+    1412             : #include <plumed/wrapper/Plumed.h>
+    1413             : int main(int argc,char*argv[]){
+    1414             :   plumed p;
+    1415             :   p=plumed_create();
+    1416             :   char fortran_handler[32];
+    1417             :   plumed_c2f(p,fortran_handler);
+    1418             :   printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
+    1419             :   fortran_routine(fortran_handler);
+    1420             :   plumed_finalize(p);
+    1421             :   return 0;
+    1422             : }
+    1423             : \endverbatim
+    1424             :   Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
+    1425             :   fortran_handler.
+    1426             : */
+    1427             : 
+    1428             : __PLUMED_WRAPPER_C_BEGIN
+    1429             : void   plumed_c2f(plumed p,char* c);
+    1430             : __PLUMED_WRAPPER_C_END
+    1431             : 
+    1432             : /** \related plumed
+    1433             :     \brief Converts a FORTRAN handler to a C handler
+    1434             :     \param c The FORTRAN handler (a char[32])
+    1435             :     \return The C handler
+    1436             : 
+    1437             :     This function can be used to convert a plumed object created in FORTRAN
+    1438             :     to a plumed handler that can be used in C.  Notice that the reference counter
+    1439             :     is not incremented. In other words, the C object will be a weak reference.
+    1440             :     If you later finalize the FORTRAN handler, the C handler will be invalid.
+    1441             : \verbatim
+    1442             : void c_routine(char handler[32]){
+    1443             :   plumed p;
+    1444             :   p=plumed_f2c(handler);
+    1445             :   plumed_cmd(p,"init",NULL);
+    1446             : }
+    1447             : \endverbatim
+    1448             :   Here `c_routine` is a C function that can be called from FORTRAN
+    1449             :   and interact with the provided plumed handler.
+    1450             : */
+    1451             : 
+    1452             : __PLUMED_WRAPPER_C_BEGIN
+    1453             : plumed plumed_f2c(const char* c);
+    1454             : __PLUMED_WRAPPER_C_END
+    1455             : 
+    1456             : /** \related plumed
+    1457             :     \brief Converts a plumed object to a void pointer. Available as of PLUMED 2.5.
+    1458             : 
+    1459             :     It returns a void pointer that can be converted back to a plumed object using \ref plumed_v2c.
+    1460             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1461             :     Notice that an invalid object (see \ref plumed_valid) can be converted to void* and back.
+    1462             : 
+    1463             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1464             : */
+    1465             : 
+    1466             : __PLUMED_WRAPPER_C_BEGIN
+    1467             : void* plumed_c2v(plumed p);
+    1468             : __PLUMED_WRAPPER_C_END
+    1469             : 
+    1470             : 
+    1471             : /** \related plumed
+    1472             :     \brief Converts a void pointer to a plumed object. Available as of PLUMED 2.5.
+    1473             : 
+    1474             :     It returns a plumed object from a void pointer obtained with \ref plumed_c2v.
+    1475             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1476             : 
+    1477             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1478             : */
+    1479             : 
+    1480             : __PLUMED_WRAPPER_C_BEGIN
+    1481             : plumed plumed_v2c(void*);
+    1482             : __PLUMED_WRAPPER_C_END
+    1483             : 
+    1484             : #if ! defined( __cplusplus) /*{*/
+    1485             : 
+    1486             : #if __PLUMED_WRAPPER_C_TYPESAFE /*{*/
+    1487             : 
+    1488             : #define __PLUMED_WRAPPER_C_TYPESAFE_INNER(type_,typen_,flags_) \
+    1489             :   static inline void plumed_cmdnse_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, const size_t* shape,plumed_error* error) { \
+    1490             :     plumed_safeptr safe; \
+    1491             :     plumed_nothrow_handler nothrow; \
+    1492             :     safe.ptr=ptr; \
+    1493             :     safe.nelem=nelem; \
+    1494             :     safe.shape=__PLUMED_WRAPPER_STATIC_CAST(const size_t*, shape); \
+    1495             :     safe.flags=flags_; \
+    1496             :     safe.opt=NULL; \
+    1497             :     if(error) { \
+    1498             :       plumed_error_init(error); \
+    1499             :       nothrow.ptr=error; \
+    1500             :       nothrow.handler=plumed_error_set; \
+    1501             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1502             :     } else { \
+    1503             :       plumed_cmd_safe(p,key,safe); \
+    1504             :     } \
+    1505             :   } \
+    1506             :   static inline void plumed_cmdne_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, plumed_error* error) { \
+    1507             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,error); \
+    1508             :   } \
+    1509             :   static inline void plumed_cmdse_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape, plumed_error* error) { \
+    1510             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,error); \
+    1511             :   } \
+    1512             :   static inline void plumed_cmdn_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem) { \
+    1513             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,NULL); \
+    1514             :   } \
+    1515             :   static inline void plumed_cmds_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape) { \
+    1516             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,NULL); \
+    1517             :   } \
+    1518             :   static inline void plumed_cmde_ ## typen_(plumed p,const char*key,type_*ptr, plumed_error* error) { \
+    1519             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,NULL,error); \
+    1520             :   }
+    1521             : 
+    1522             : #define __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,size) \
+    1523             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type,             type_ ## _p,  size | (0x10000*(code)) | (0x2000000*2)) \
+    1524             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const,       type_ ## _c,  size | (0x10000*(code)) | (0x2000000*3)) \
+    1525             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*,            type_ ## _pp, size | (0x10000*(code)) | (0x2000000*4)) \
+    1526             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*const,       type_ ## _pc, size | (0x10000*(code)) | (0x2000000*5)) \
+    1527             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*,      type_ ## _cp, size | (0x10000*(code)) | (0x2000000*6)) \
+    1528             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*const, type_ ## _cc, size | (0x10000*(code)) | (0x2000000*7))
+    1529             : 
+    1530             : #define __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(type,type_,code) __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,0)
+    1531             : 
+    1532             : #define __PLUMED_WRAPPER_C_TYPESAFE_SIZED(type,type_,code) \
+    1533             :   __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,sizeof(type)) \
+    1534             :   static inline void plumed_cmdnse_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, const size_t* shape, plumed_error* error) { \
+    1535             :     plumed_safeptr safe; \
+    1536             :     plumed_nothrow_handler nothrow; \
+    1537             :     (void) nelem; \
+    1538             :     (void) shape; \
+    1539             :     safe.ptr=&val; \
+    1540             :     safe.nelem=1; \
+    1541             :     safe.shape=NULL; \
+    1542             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    1543             :     safe.opt=NULL; \
+    1544             :     if(error) { \
+    1545             :       plumed_error_init(error); \
+    1546             :       nothrow.ptr=error; \
+    1547             :       nothrow.handler=plumed_error_set; \
+    1548             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1549             :     } else { \
+    1550             :       plumed_cmd_safe(p,key,safe); \
+    1551             :     } \
+    1552             :   } \
+    1553             :   static inline void plumed_cmdne_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, plumed_error* error) {  \
+    1554             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,error); \
+    1555             :   } \
+    1556             :   static inline void plumed_cmdse_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape, plumed_error* error) {  \
+    1557             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,error); \
+    1558             :   } \
+    1559             :   static inline void plumed_cmdn_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem) {  \
+    1560             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,NULL); \
+    1561             :   } \
+    1562             :   static inline void plumed_cmds_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape) {  \
+    1563             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,NULL); \
+    1564             :   } \
+    1565             :   static inline void plumed_cmde_ ## type_ ## _v(plumed p,const char*key,type val, plumed_error* error) {  \
+    1566             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,NULL,error); \
+    1567             :   }
+    1568             : 
+    1569             : #define __PLUMED_WRAPPER_C_GENERIC1(flavor,type,typen_) \
+    1570             :     type: plumed_ ## flavor ## _ ## typen_,
+    1571             : 
+    1572             : #define __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1573             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*,             type_ ## _p) \
+    1574             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*,       type_ ## _c) \
+    1575             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type**,            type_ ## _pp) \
+    1576             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*const*,       type_ ## _pc) \
+    1577             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const**,      type_ ## _cp) \
+    1578             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*const*, type_ ## _cc)
+    1579             : 
+    1580             : #define __PLUMED_WRAPPER_C_GENERIC2(flavor,type,type_) \
+    1581             :   __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1582             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type,             type_ ## _v)
+    1583             : 
+    1584             : /// Here we create all the required instances
+    1585             : /// 1: void
+    1586             : /// 3: integral
+    1587             : /// 4: floating
+    1588             : /// 5: FILE
+    1589             : /// 0x100: unsigned
+    1590             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(void,void,1)
+    1591             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(char,char,(CHAR_MIN==0)*0x100+3)
+    1592             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned char,unsigned_char,0x100+3)
+    1593             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(signed char,signed_char,0x100+3)
+    1594             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(short,short,3)
+    1595             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned short,unsigned_short,0x100+3)
+    1596             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(int,int,3)
+    1597             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned int,unsigned_int,0x100+3)
+    1598             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long,long,3)
+    1599             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long,unsigned_long,0x100+3)
+    1600             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long long,long_long,3)
+    1601             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long long,unsigned_long_long,0x100+3)
+    1602             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(float,float,4)
+    1603             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(double,double,4)
+    1604             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long double,long_double,4)
+    1605             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(FILE,FILE,5)
+    1606             : 
+    1607             : static inline void plumed_cmd_null_e(plumed p,const char*key,plumed_error* error,int ignore) {
+    1608             :   (void) ignore;
+    1609             :   plumed_cmde_void_p(p,key,NULL,error);
+    1610             : }
+    1611             : 
+    1612             : #define plumed_cmdnse_inner(flavor,val) _Generic((val), \
+    1613             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,void,void) \
+    1614             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,char,char) \
+    1615             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned char,unsigned_char) \
+    1616             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,signed char,signed_char) \
+    1617             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,short,short) \
+    1618             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned short,unsigned_short) \
+    1619             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,int,int) \
+    1620             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned int,unsigned_int) \
+    1621             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long,long) \
+    1622             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long,unsigned_long) \
+    1623             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long long,long_long) \
+    1624             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long long,unsigned_long_long) \
+    1625             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,float,float) \
+    1626             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,double,double) \
+    1627             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long double,long_double) \
+    1628             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,FILE,FILE) \
+    1629             :     default: plumed_ ## flavor ## _void_c)
+    1630             : 
+    1631             : #define plumed_cmd_2args(p,key) plumed_cmdnse_inner(cmdn,NULL) (p,key,NULL,0)
+    1632             : 
+    1633             : #define plumed_cmd_3args(p,key,X) _Generic((X), \
+    1634             :     plumed_error*: plumed_cmd_null_e, \
+    1635             :     default:       plumed_cmdnse_inner(cmdn,X)) (p,key,X,0)
+    1636             : 
+    1637             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1638             : #define plumed_cmd_4args(p,key,val,X) _Generic(((X)+(size_t)0), \
+    1639             :     const size_t *: plumed_cmdnse_inner(cmds,val), \
+    1640             :     size_t *: plumed_cmdnse_inner(cmds,val), \
+    1641             :     size_t: plumed_cmdnse_inner(cmdn,val), \
+    1642             :     plumed_error*: plumed_cmdnse_inner(cmde,val) \
+    1643             :     ) (p,key,val,X)
+    1644             : 
+    1645             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1646             : #define plumed_cmd_5args(p,key,val,X,error) _Generic(((X)+(size_t)0), \
+    1647             :     const size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1648             :     size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1649             :     size_t: plumed_cmdnse_inner(cmdne,val) \
+    1650             :     ) (p,key,val,X,error)
+    1651             : 
+    1652             : #define __PLUMED_WRAPPER_C_GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
+    1653             : #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__)
+    1654             : 
+    1655             : #define plumed_gcmd_c11(...) plumed_cmd(plumed_global(),__VA_ARGS__)
+    1656             : 
+    1657             : #define __PLUMED_WRAPPER_REDEFINE_CMD plumed_cmd_c11
+    1658             : #define __PLUMED_WRAPPER_REDEFINE_GCMD plumed_gcmd_c11
+    1659             : 
+    1660             : #endif /*}*/
+    1661             : 
+    1662             : #endif /*}*/
+    1663             : 
+    1664             : 
+    1665             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    1666             : 
+    1667             : /* Global C functions are always extern */
+    1668             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    1669             : 
+    1670             : /** \relates plumed
+    1671             :     \brief Retrieves an handler to the global structure.
+    1672             : 
+    1673             :   You can use this if you work on a code that uses the global structure and you want to
+    1674             :   pass to a generic routine an handler to the same structure. E.g.
+    1675             : 
+    1676             : \verbatim
+    1677             :   plumed p=plumed_global();
+    1678             :   some_routine(p);
+    1679             : \endverbatim
+    1680             : */
+    1681             : extern
+    1682             : plumed plumed_global(void);
+    1683             : 
+    1684             : /** \relates plumed
+    1685             :     \brief Check if the global interface has been initialized.
+    1686             : 
+    1687             :     \return 1 if plumed has been initialized, 0 otherwise
+    1688             : */
+    1689             : extern
+    1690             : int plumed_ginitialized(void);
+    1691             : 
+    1692             : /** \relates plumed
+    1693             :     \brief Constructor for the global interface.
+    1694             : 
+    1695             :     \note Equivalent to plumed_create(), but initialize the static global plumed object
+    1696             : */
+    1697             : extern
+    1698             : void plumed_gcreate(void);
+    1699             : 
+    1700             : /** \relates plumed
+    1701             :     \brief Tells to the global interface to execute a command.
+    1702             : 
+    1703             :     \param key The name of the command to be executed
+    1704             :     \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
+    1705             :                but for some choice of key it can change the content
+    1706             : 
+    1707             :     `plumed_gcmd(a,b);` is equivalent to `plumed_cmd(plumed_global(),a,b);`.
+    1708             : */
+    1709             : extern
+    1710             : void plumed_gcmd(const char* key,const void* val);
+    1711             : 
+    1712             : /** \relates plumed
+    1713             :     \brief Tells to the global interface to execute a command.
+    1714             : 
+    1715             :     \param key The name of the command to be executed
+    1716             :     \param safe A safe pointer
+    1717             : 
+    1718             :     `plumed_gcmd_safe(a,b);` is equivalent to `plumed_cmd_safe(plumed_global(),a,b);`.
+    1719             : */
+    1720             : extern
+    1721             : void plumed_gcmd_safe(const char* key,plumed_safeptr);
+    1722             : 
+    1723             : /** \relates plumed
+    1724             :     \brief Destructor for the global interface.
+    1725             : 
+    1726             :     `plumed_gfinalize(a,b);` is similar to `plumed_finalize(plumed_global(),a,b);`, but not completely
+    1727             :     equivalent. In particular, plumed_gfinalize() also makes sure that the global object
+    1728             :     is reset to its initial status. After calling it, \ref plumed_ginitialized() will thus return 0.
+    1729             : */
+    1730             : extern
+    1731             : void plumed_gfinalize(void);
+    1732             : 
+    1733             : /** \relates plumed
+    1734             :     \brief Check if global plumed object is valid. Available as of PLUMED 2.5
+    1735             : 
+    1736             :     It might return zero if plumed is not available at runtime.
+    1737             : 
+    1738             :     \return 1 if plumed is valid, 0 otherwise.
+    1739             : */
+    1740             : extern
+    1741             : int plumed_gvalid();
+    1742             : 
+    1743             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    1744             : 
+    1745             : #endif /*}*/
+    1746             : 
+    1747             : #if defined( __cplusplus) && __PLUMED_WRAPPER_CXX /*{*/
+    1748             : 
+    1749             : #if __PLUMED_WRAPPER_CXX_STD
+    1750             : #include <cstdlib> /* NULL getenv */
+    1751             : #include <cstddef> /* nullptr_t */
+    1752             : #include <cstring> /* strncat strlen */
+    1753             : #include <cassert> /* assert */
+    1754             : #include <climits> /* CHAR_MIN */
+    1755             : #else
+    1756             : #include <stddef.h>
+    1757             : #include <stdlib.h>
+    1758             : #include <string.h>
+    1759             : #include <assert.h>
+    1760             : #include <limits.h>
+    1761             : #endif
+    1762             : 
+    1763             : #include <exception> /* exception bad_exception */
+    1764             : #include <stdexcept> /* runtime_error logic_error invalid_argument domain_error length_error out_of_range range_error overflow_error underflow_error */
+    1765             : #include <string> /* string */
+    1766             : #include <ios> /* iostream_category (C++11) ios_base::failure (C++11 and C++<11) */
+    1767             : #include <new> /* bad_alloc bad_array_new_length (C++11) */
+    1768             : #include <typeinfo> /* bad_typeid bad_cast */
+    1769             : #include <limits> /* numeric_limits */
+    1770             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1771             : #include <system_error> /* system_error generic_category system_category */
+    1772             : #include <future> /* future_category */
+    1773             : #include <memory> /* bad_weak_ptr */
+    1774             : #include <functional> /* bad_function_call */
+    1775             : #include <regex> /* regex_error */
+    1776             : #endif
+    1777             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1778             : #include <any> /* bad_any_cast */
+    1779             : #include <variant> /* bad_variant_access */
+    1780             : #include <optional> /* bad_optional_access */
+    1781             : #include <filesystem> /* filesystem_error */
+    1782             : #endif
+    1783             : 
+    1784             : #if __cplusplus >= 201703L
+    1785             : #include <memory> /* unique_ptr */
+    1786             : #include <string_view> /* string_view */
+    1787             : #endif
+    1788             : 
+    1789             : #if __cplusplus > 199711L
+    1790             : #include <array> /* array */
+    1791             : #include <initializer_list> /* initializer_list */
+    1792             : #include <type_traits> /* std::enable_if */
+    1793             : #endif
+    1794             : 
+    1795             : /* C++ interface is hidden in PLMD namespace (same as plumed library) */
+    1796             : namespace PLMD {
+    1797             : 
+    1798             : /* Optionally, it is further hidden in an anonymous namespace */
+    1799             : 
+    1800             : __PLUMED_WRAPPER_ANONYMOUS_BEGIN /*{*/
+    1801             : 
+    1802             : /**
+    1803             :   Retrieve PLUMED_EXCEPTIONS_DEBUG (internal utility).
+    1804             : 
+    1805             :   This function should not be used by external programs. It is defined
+    1806             :   as inline static so that it can store a static variable (for quicker access)
+    1807             :   without adding a unique global symbol to a library including this header file.
+    1808             : */
+    1809           0 : inline static bool PlumedGetenvExceptionsDebug() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1810           0 :   static const char* res=__PLUMED_WRAPPER_STD getenv("PLUMED_EXCEPTIONS_DEBUG");
+    1811           0 :   return res;
+    1812             : }
+    1813             : 
+    1814             : #if __cplusplus > 199711L
+    1815             : 
+    1816             : /**
+    1817             : 
+    1818             : We use a separate namespace here instead of hiding these classes in the Plumed
+    1819             : class, because some of these structs might be specialized by the user.
+    1820             : 
+    1821             : */
+    1822             : namespace wrapper {
+    1823             : 
+    1824             : /// This is to replace c++17 std::void_t
+    1825             : template<typename... Ts>
+    1826             : struct make_void { using type = void; };
+    1827             : template<typename... Ts>
+    1828             : using void_t = typename make_void<Ts...>::type;
+    1829             : 
+    1830             : /// Primary template, assumes T does not have both size() and data() methods
+    1831             : template<typename T, typename = void>
+    1832             : struct has_size_and_data : std::false_type {};
+    1833             : 
+    1834             : /// Specialization for types T that do have both size() and data() methods
+    1835             : template<typename T>
+    1836             : struct has_size_and_data<T, void_t<decltype(std::declval<T>().size()), decltype(std::declval<T>().data())>> : std::true_type {};
+    1837             : 
+    1838             : /// Primary template, assumes T is not a custom structure.
+    1839             : /// Can be specialized to inform about custom structures
+    1840             : template<typename T>
+    1841             : struct is_custom_array : std::false_type {
+    1842             :   typedef void value_type;
+    1843             : };
+    1844             : 
+    1845             : /// Template specialization for std::array
+    1846             : template<typename T, std::size_t N>
+    1847             : struct is_custom_array<std::array<T,N>> : std::true_type {
+    1848             :   using value_type = typename std::array<T,N>::value_type;
+    1849             : };
+    1850             : 
+    1851             : /// Template specialization for C arrays.
+    1852             : /// Note: we have to use it as wrapper::is_custom_array<typename std::remove_reference<T>::type>::value
+    1853             : /// because C arrays are only passed by reference!
+    1854             : template<typename T, std::size_t N>
+    1855             : struct is_custom_array<T[N]> : std::true_type {
+    1856             :   using value_type = typename std::remove_reference<decltype(std::declval<T[N]>()[0])>::type;
+    1857             : };
+    1858             : 
+    1859             : /// Generic utility to retrieve the size of a container
+    1860             : template<typename T>
+    1861             : inline std::size_t size(const T&obj) {
+    1862             :   return obj.size();
+    1863             : }
+    1864             : 
+    1865             : /// Specialization for std::string, which returns size()+1, which includes the terminating null character
+    1866             : template<>
+    1867             : inline std::size_t size(const std::string &obj) {
+    1868             :   return obj.size()+1;
+    1869             : }
+    1870             : 
+    1871             : /// Report the size of a custom_array.
+    1872             : /// typename std::remove_reference<T>::type is needed because C arrays are passed by reference
+    1873             : template<typename T, typename std::enable_if<wrapper::is_custom_array<typename std::remove_reference<T>::type>::value, int>::type = 0>
+    1874             : inline std::size_t custom_array_size() {
+    1875             :   using value_type = typename wrapper::is_custom_array<typename std::remove_reference<T>::type>::value_type;
+    1876             :   constexpr std::size_t value_size=sizeof(value_type);
+    1877             :   static_assert(value_size>0,"cannot use custom arrays of void types");
+    1878             :   static_assert(sizeof(T)%value_size==0,"custom array has incorrect size");
+    1879             :   return sizeof(T)/sizeof(value_type);
+    1880             : }
+    1881             : 
+    1882             : /// Cast a pointer to a custom_array to a pointer of its value_type.
+    1883             : /// typename std::remove_reference<T>::type is needed because C arrays are passed by reference
+    1884             : template<typename T, typename std::enable_if<wrapper::is_custom_array<typename std::remove_reference<T>::type>::value, int>::type = 0>
+    1885             : inline typename wrapper::is_custom_array<T>::value_type* custom_array_cast(T* val) {
+    1886             :   using value_type = typename wrapper::is_custom_array<typename std::remove_reference<T>::type>::value_type;
+    1887             :   return reinterpret_cast<value_type*>(val);
+    1888             : }
+    1889             : 
+    1890             : }
+    1891             : 
+    1892             : #endif
+    1893             : 
+    1894             : 
+    1895             : /**
+    1896             :   C++ wrapper for \ref plumed.
+    1897             : 
+    1898             :   This class provides a C++ interface to PLUMED.
+    1899             :   It only containts a \ref plumed object, but wraps it with a number of useful methods.
+    1900             :   All methods are inlined so as to avoid the compilation of an extra c++ file.
+    1901             : 
+    1902             : */
+    1903             : 
+    1904             : class Plumed {
+    1905             :   /**
+    1906             :     C structure.
+    1907             :   */
+    1908             :   plumed main;
+    1909             : 
+    1910             : private:
+    1911             : 
+    1912             :   /**
+    1913             :     This is an internal utility to dispatch exceptions based on the plumed_error object.
+    1914             : 
+    1915             :     It takes information about the exception to be thrown by the passed h object
+    1916             :     and use it to call function f() on the resulting exception. Notice that:
+    1917             :     - this function does not consider if the error is nested.
+    1918             :     - f should be a callable object, so that it can store information
+    1919             :     - f operator() should be a template function so as to act based on the
+    1920             :       type of its argument
+    1921             : 
+    1922             :     New exceptions added here should be kept in sync with core/PlumedMainInitializer.cpp
+    1923             : 
+    1924             :     Notice that this function also finalizes in place plumed_error h, so as to avoid
+    1925             :     memory leaks.
+    1926             :   */
+    1927             :   template<typename F>
+    1928           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void exception_dispatch(plumed_error&h,F f) {
+    1929             :     /* this is required to make sure h is finalized when leaving this function */
+    1930             :     finalize_plumed_error finalize(h);
+    1931             :     /* grab the message */
+    1932             :     const char* msg=plumed_error_what(h);
+    1933           0 :     if(h.code==1) f(Plumed::Invalid(msg));
+    1934             :     /* logic errors */
+    1935           0 :     if(h.code>=10100 && h.code<10200) {
+    1936           0 :       if(h.code>=10105 && h.code<10110) f(::std::invalid_argument(msg));
+    1937           0 :       if(h.code>=10110 && h.code<10115) f(::std::domain_error(msg));
+    1938           0 :       if(h.code>=10115 && h.code<10120) f(::std::length_error(msg));
+    1939           0 :       if(h.code>=10120 && h.code<10125) f(::std::out_of_range(msg));
+    1940             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1941             :       if(h.code==10125) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::broken_promise),msg));
+    1942             :       if(h.code==10126) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::future_already_retrieved),msg));
+    1943             :       if(h.code==10127) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::promise_already_satisfied),msg));
+    1944             :       if(h.code==10128) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::no_state),msg));
+    1945             : #endif
+    1946           0 :       f(::std::logic_error(msg));
+    1947             :     }
+    1948             :     /* runtime errors */
+    1949           0 :     if(h.code>=10200 && h.code<10300) {
+    1950           0 :       if(h.code>=10205 && h.code<10210) f(::std::range_error(msg));
+    1951           0 :       if(h.code>=10210 && h.code<10215) f(::std::overflow_error(msg));
+    1952           0 :       if(h.code>=10215 && h.code<10220) f(::std::underflow_error(msg));
+    1953             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1954           0 :       if(h.code==10220) f(::std::system_error(h.error_code,::std::generic_category(),msg));
+    1955           0 :       if(h.code==10221) f(::std::system_error(h.error_code,::std::system_category(),msg));
+    1956           0 :       if(h.code==10222) f(::std::system_error(h.error_code,::std::iostream_category(),msg));
+    1957           0 :       if(h.code==10223) f(::std::system_error(h.error_code,::std::future_category(),msg));
+    1958             : #endif
+    1959             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1960             :       if(h.code==10229) {
+    1961             :         ::std::error_code error_code;
+    1962             :         if(h.error_category==1) error_code=::std::error_code(h.error_code,::std::generic_category());
+    1963             :         if(h.error_category==2) error_code=::std::error_code(h.error_code,::std::system_category());
+    1964             :         if(h.error_category==3) error_code=::std::error_code(h.error_code,::std::iostream_category());
+    1965             :         if(h.error_category==4) error_code=::std::error_code(h.error_code,::std::future_category());
+    1966             : 
+    1967             :         if(!h.path1.ptr) {
+    1968             :           f(::std::filesystem::filesystem_error(msg,error_code));
+    1969             :         } else if(!h.path2.ptr) {
+    1970             :           /*
+    1971             :              In principle native_format is a possible value of an enum,
+    1972             :              so should be accessible as ::std::filesystem::path::native_format
+    1973             :              However, some clang versions declare it as enum class. Thus,
+    1974             :              ::std::filesystem::path::format::native_format is more portable.
+    1975             :           */
+    1976             :           f(::std::filesystem::filesystem_error(msg,
+    1977             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1978             :                                                     reinterpret_cast<::std::filesystem::path::value_type*>(h.path1.ptr),
+    1979             :                                                     h.path1.numbytes/sizeof(::std::filesystem::path::value_type)
+    1980             :                                                     ),
+    1981             :                                                     ::std::filesystem::path::format::native_format),
+    1982             :                                                 error_code));
+    1983             :         } else {
+    1984             :           f(::std::filesystem::filesystem_error(msg,
+    1985             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1986             :                                                     reinterpret_cast<::std::filesystem::path::value_type*>(h.path1.ptr),
+    1987             :                                                     h.path1.numbytes/sizeof(::std::filesystem::path::value_type)
+    1988             :                                                     ),
+    1989             :                                                     ::std::filesystem::path::format::native_format),
+    1990             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1991             :                                                     reinterpret_cast<::std::filesystem::path::value_type*>(h.path2.ptr),
+    1992             :                                                     h.path2.numbytes/sizeof(::std::filesystem::path::value_type)
+    1993             :                                                     ),
+    1994             :                                                     ::std::filesystem::path::format::native_format),
+    1995             :                                                 error_code));
+    1996             :         }
+    1997             :       }
+    1998             : #endif
+    1999             :       if(h.code>=10230 && h.code<10240) {
+    2000             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2001             : // These cases are probably useless as it looks like this should always be std::iostream_category
+    2002           0 :         if(h.code==10230) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::generic_category())));
+    2003           0 :         if(h.code==10231) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::system_category())));
+    2004           0 :         if(h.code==10232) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::iostream_category())));
+    2005           0 :         if(h.code==10233) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::future_category())));
+    2006             : #endif
+    2007           0 :         f(::std::ios_base::failure(msg));
+    2008             :       }
+    2009             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2010           0 :       if(h.code==10240) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_collate),msg));
+    2011           0 :       if(h.code==10241) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_ctype),msg));
+    2012           0 :       if(h.code==10242) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_escape),msg));
+    2013           0 :       if(h.code==10243) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_backref),msg));
+    2014           0 :       if(h.code==10244) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_brack),msg));
+    2015           0 :       if(h.code==10245) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_paren),msg));
+    2016           0 :       if(h.code==10246) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_brace),msg));
+    2017           0 :       if(h.code==10247) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_badbrace),msg));
+    2018           0 :       if(h.code==10248) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_range),msg));
+    2019           0 :       if(h.code==10249) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_space),msg));
+    2020           0 :       if(h.code==10250) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_badrepeat),msg));
+    2021           0 :       if(h.code==10251) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_complexity),msg));
+    2022           0 :       if(h.code==10252) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_stack),msg));
+    2023             : #endif
+    2024           0 :       f(::std::runtime_error(msg));
+    2025             :     }
+    2026             :     /* "bad" errors */
+    2027             :     /* "< ::" space required in C++ < 11 */
+    2028           0 :     if(h.code>=11000 && h.code<11100) f(add_buffer_to< ::std::bad_typeid>(msg));
+    2029           0 :     if(h.code>=11100 && h.code<11200) {
+    2030             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    2031             :       if(h.code>=11150) f(add_buffer_to< ::std::bad_any_cast>(msg));
+    2032             : #endif
+    2033           0 :       f(add_buffer_to< ::std::bad_cast>(msg));
+    2034             :     }
+    2035             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2036           0 :     if(h.code>=11200 && h.code<11300) f(add_buffer_to< ::std::bad_weak_ptr>(msg));
+    2037           0 :     if(h.code>=11300 && h.code<11400) f(add_buffer_to< ::std::bad_function_call>(msg));
+    2038             : #endif
+    2039           0 :     if(h.code>=11400 && h.code<11500) {
+    2040             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2041           0 :       if(h.code>=11410 && h.code<11420) f(add_buffer_to< ::std::bad_array_new_length>(msg));
+    2042             : #endif
+    2043           0 :       f(add_buffer_to< ::std::bad_alloc>(msg));
+    2044             :     }
+    2045           0 :     if(h.code>=11500 && h.code<11600) f(add_buffer_to< ::std::bad_exception>(msg));
+    2046             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    2047             :     if(h.code>=11600 && h.code<11700) f(add_buffer_to< ::std::bad_optional_access>(msg));
+    2048             :     if(h.code>=11700 && h.code<11800) f(add_buffer_to< ::std::bad_variant_access>(msg));
+    2049             : #endif
+    2050             :     /* lepton error */
+    2051           0 :     if(h.code>=19900 && h.code<20000) f(Plumed::LeptonException(msg));
+    2052             :     /* plumed exceptions */
+    2053           0 :     if(h.code>=20000 && h.code<30000) {
+    2054             :       /* debug - only raised with debug options */
+    2055           0 :       if(h.code>=20100 && h.code<20200) f(Plumed::ExceptionDebug(msg));
+    2056             :       /* error - runtime check */
+    2057           0 :       if(h.code>=20200 && h.code<20300) f(Plumed::ExceptionError(msg));
+    2058             :       /* error - type error */
+    2059           0 :       if(h.code>=20300 && h.code<20400) f(Plumed::ExceptionTypeError(msg));
+    2060           0 :       f(Plumed::Exception(msg));
+    2061             :     }
+    2062             :     /* fallback for any other exception */
+    2063           0 :     f(add_buffer_to< ::std::exception>(msg));
+    2064           0 :   }
+    2065             : 
+    2066             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    2067             :   /** Internal class used by exception_dispatch. */
+    2068             :   class rethrow_nested {
+    2069             :   public:
+    2070             :     template<typename E>
+    2071             :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    2072           0 :       std::throw_with_nested(e);
+    2073             :     }
+    2074             :   };
+    2075             : #endif
+    2076             : 
+    2077             :   /** Internal class used by exception_dispatch. */
+    2078             :   class rethrow_not_nested {
+    2079             :   public:
+    2080             :     template<typename E>
+    2081           0 :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    2082           0 :       throw e;
+    2083             :     }
+    2084             :   };
+    2085             : 
+    2086             :   /** Internal class to simplify plumed_error finalization */
+    2087             :   class finalize_plumed_error {
+    2088             :     plumed_error&e;
+    2089             :     finalize_plumed_error(const finalize_plumed_error&); //not implemented
+    2090             :   public:
+    2091           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT finalize_plumed_error(plumed_error&e):
+    2092           0 :       e(e)
+    2093             :     {}
+    2094           0 :     ~finalize_plumed_error() {
+    2095           0 :       plumed_error_finalize(e);
+    2096           0 :       e.code=0; // make sure it's not finalized again
+    2097           0 :     }
+    2098             :   };
+    2099             : 
+    2100             :   /**
+    2101             :     Recursive function that rethrows an exception with all the nested ones.
+    2102             : 
+    2103             :     In order to do so, we start throwing from the first exception that was originally thrown
+    2104             :     and recursively throw the others using throw_with_nested.
+    2105             : 
+    2106             :     plumed_error h is finalized at exit by the exception_dispatch function, to avoid memory leaks
+    2107             :   */
+    2108           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow(plumed_error&h) {
+    2109             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    2110             :     /*
+    2111             :       When using C++11 nested exceptions, we need to rethrow recursively
+    2112             :     */
+    2113             :     try {
+    2114           0 :       if(h.nested) rethrow(*h.nested); /* recursive throw */
+    2115           0 :     } catch(...) {
+    2116           0 :       exception_dispatch(h,rethrow_nested());
+    2117           0 :     }
+    2118           0 :     exception_dispatch(h,rethrow_not_nested());
+    2119             : #else
+    2120             :     /*
+    2121             :       When using C++<11 exceptions, we merge the message and then throw the resulting exception
+    2122             :     */
+    2123             :     if(h.nested) plumed_error_merge_with_nested(&h);
+    2124             :     exception_dispatch(h,rethrow_not_nested());
+    2125             : #endif
+    2126             :   }
+    2127             : 
+    2128             : public:
+    2129             :   /**
+    2130             :     This is a tool to rethrow an error as an exception and finalize the error.
+    2131             : 
+    2132             :     In practice, this makes it possible to write a code like this:
+    2133             :     ```
+    2134             :     Plumed p;
+    2135             :     plumed_error e;
+    2136             :     // store error in e if something wrong happes
+    2137             :     // notice that Plumed (C++) is implicitly converted to plumed (C) when calling plumed_cmd
+    2138             :     plumed_cmd(p,"init",&e);
+    2139             :     // do other things here
+    2140             :     // then throw the exception
+    2141             :     if(e.code) plumed_error_rethrow(e);
+    2142             : 
+    2143             :     It should be used through the macro plumed_error_rethrow.
+    2144             :     ```
+    2145             :   */
+    2146             :   __PLUMED_WRAPPER_CXX_NORETURN static void plumed_error_rethrow_cxx(plumed_error h) {
+    2147           0 :     rethrow(h);
+    2148             :   }
+    2149             : 
+    2150             : private:
+    2151             :   /**
+    2152             :     Rethrow the current exception.
+    2153             : 
+    2154             :     This is useful in order to handle an exception thrown by a kernel <=2.4.
+    2155             :     Only std exceptions are handled, though some of them are thrown as special
+    2156             :     Plumed exceptions in order to be attached a message.
+    2157             :   */
+    2158           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow() {
+    2159             :     try {
+    2160           0 :       throw;
+    2161           0 :     } catch(const ::std::bad_exception & e) {
+    2162           0 :       throw add_buffer_to< ::std::bad_exception>(e.what());
+    2163             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2164           0 :     } catch(const ::std::bad_array_new_length & e) {
+    2165           0 :       throw add_buffer_to< ::std::bad_array_new_length>(e.what());
+    2166             : #endif
+    2167           0 :     } catch(const ::std::bad_alloc & e) {
+    2168           0 :       throw add_buffer_to< ::std::bad_alloc>(e.what());
+    2169             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2170           0 :     } catch(const ::std::bad_function_call & e) {
+    2171           0 :       throw add_buffer_to< ::std::bad_function_call>(e.what());
+    2172           0 :     } catch(const ::std::bad_weak_ptr & e) {
+    2173           0 :       throw add_buffer_to< ::std::bad_weak_ptr>(e.what());
+    2174             : #endif
+    2175           0 :     } catch(const ::std::bad_cast & e) {
+    2176           0 :       throw add_buffer_to< ::std::bad_cast>(e.what());
+    2177           0 :     } catch(const ::std::bad_typeid & e) {
+    2178           0 :       throw add_buffer_to< ::std::bad_typeid>(e.what());
+    2179             :       // not implemented yet: std::regex_error
+    2180             :       // we do not allow regex yet due to portability problems with gcc 4.8
+    2181             :       // as soon as we transition to using <regex> it should be straightforward to add
+    2182           0 :     } catch(const ::std::ios_base::failure & e) {
+    2183             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2184           0 :       throw ::std::ios_base::failure(e.what(),e.code());
+    2185             : #else
+    2186             :       throw ::std::ios_base::failure(e.what());
+    2187             : #endif
+    2188             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2189           0 :     } catch(const ::std::system_error & e) {
+    2190           0 :       throw ::std::system_error(e.code(),e.what());
+    2191             : #endif
+    2192           0 :     } catch(const ::std::underflow_error &e) {
+    2193           0 :       throw ::std::underflow_error(e.what());
+    2194           0 :     } catch(const ::std::overflow_error &e) {
+    2195           0 :       throw ::std::overflow_error(e.what());
+    2196           0 :     } catch(const ::std::range_error &e) {
+    2197           0 :       throw ::std::range_error(e.what());
+    2198           0 :     } catch(const ::std::runtime_error & e) {
+    2199           0 :       throw ::std::runtime_error(e.what());
+    2200             :       // not implemented yet: std::future_error
+    2201             :       // not clear how useful it would be.
+    2202           0 :     } catch(const ::std::out_of_range & e) {
+    2203           0 :       throw ::std::out_of_range(e.what());
+    2204           0 :     } catch(const ::std::length_error & e) {
+    2205           0 :       throw ::std::length_error(e.what());
+    2206           0 :     } catch(const ::std::domain_error & e) {
+    2207           0 :       throw ::std::domain_error(e.what());
+    2208           0 :     } catch(const ::std::invalid_argument & e) {
+    2209           0 :       throw ::std::invalid_argument(e.what());
+    2210           0 :     } catch(const ::std::logic_error & e) {
+    2211           0 :       throw ::std::logic_error(e.what());
+    2212           0 :     } catch(const ::std::exception & e) {
+    2213           0 :       throw add_buffer_to< ::std::exception>(e.what());
+    2214           0 :     } catch(...) {
+    2215           0 :       throw add_buffer_to< ::std::bad_exception>("plumed could not translate exception");
+    2216           0 :     }
+    2217             :   }
+    2218             : 
+    2219             : public:
+    2220             : 
+    2221             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2222             :   using Exception = PLMD::Exception;
+    2223             : #else
+    2224             :   /**
+    2225             :     Base class used to rethrow PLUMED exceptions.
+    2226             :   */
+    2227             :   class Exception :
+    2228             :     public ::std::exception
+    2229             :   {
+    2230             :     ::std::string msg;
+    2231             :   public:
+    2232           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Exception(const char* msg): msg(msg) {}
+    2233           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    2234             : #if ! (__cplusplus > 199711L)
+    2235             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2236             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2237             :     ~Exception() throw() {}
+    2238             : #endif
+    2239             :   };
+    2240             : #endif
+    2241             : 
+    2242             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2243             :   using ExceptionError = PLMD::ExceptionError;
+    2244             : #else
+    2245             :   /**
+    2246             :     Used to rethrow a PLMD::ExceptionError
+    2247             :   */
+    2248           0 :   class ExceptionError :
+    2249             :     public Exception {
+    2250             :   public:
+    2251           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionError(const char* msg): Exception(msg) {}
+    2252             : #if ! (__cplusplus > 199711L)
+    2253             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2254             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2255             :     ~ExceptionError() throw() {}
+    2256             : #endif
+    2257             :   };
+    2258             : #endif
+    2259             : 
+    2260             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2261             :   using ExceptionDebug = PLMD::ExceptionDebug;
+    2262             : #else
+    2263             :   /**
+    2264             :     Used to rethrow a PLMD::ExceptionDebug
+    2265             :   */
+    2266           0 :   class ExceptionDebug :
+    2267             :     public Exception {
+    2268             :   public:
+    2269           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionDebug(const char* msg): Exception(msg) {}
+    2270             : #if ! (__cplusplus > 199711L)
+    2271             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2272             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2273             :     ~ExceptionDebug() throw() {}
+    2274             : #endif
+    2275             :   };
+    2276             : #endif
+    2277             : 
+    2278             :   /**
+    2279             :     Thrown when trying to access an invalid plumed object
+    2280             :   */
+    2281             : 
+    2282           0 :   class Invalid :
+    2283             :     public Exception {
+    2284             :   public:
+    2285           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Invalid(const char* msg): Exception(msg) {}
+    2286             : #if ! (__cplusplus > 199711L)
+    2287             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2288             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2289             :     ~Invalid() throw() {}
+    2290             : #endif
+    2291             :   };
+    2292             : 
+    2293             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2294             :   using ExceptionTypeError = PLMD::ExceptionTypeError;
+    2295             : #else
+    2296             :   /**
+    2297             :     Thrown when a wrong pointer is passed to the PLUMED interface.
+    2298             :   */
+    2299           0 :   class ExceptionTypeError:
+    2300             :     public Exception {
+    2301             :   public:
+    2302           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionTypeError(const char* msg): Exception(msg) {}
+    2303             : #if ! (__cplusplus > 199711L)
+    2304             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2305             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2306             :     ~ExceptionTypeError() throw() {}
+    2307             : #endif
+    2308             :   };
+    2309             : #endif
+    2310             : 
+    2311             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2312             :   using LeptonException = PLMD::lepton::Exception;
+    2313             : #else
+    2314             :   /**
+    2315             :     Class used to rethrow Lepton exceptions.
+    2316             :   */
+    2317             : 
+    2318             :   class LeptonException :
+    2319             :     public ::std::exception
+    2320             :   {
+    2321             :     ::std::string msg;
+    2322             :   public:
+    2323           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT LeptonException(const char* msg): msg(msg) {}
+    2324           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    2325             : #if ! (__cplusplus > 199711L)
+    2326             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2327             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2328             :     ~LeptonException() throw() {}
+    2329             : #endif
+    2330             :   };
+    2331             : #endif
+    2332             : 
+    2333             : private:
+    2334             :   /*
+    2335             :     These exceptions are declared as private as they are not supposed to be
+    2336             :     catched by value. they only exist to allow a buffer to be attached to
+    2337             :     the std::exceptions that do not contain it already.
+    2338             :     Notice that these exceptions are those whose constructor should never throw, and as
+    2339             :     such they use a fixed size buffer.
+    2340             :   */
+    2341             : 
+    2342             :   template<typename T>
+    2343           0 :   class add_buffer_to:
+    2344             :     public T
+    2345             :   {
+    2346             :     char msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER];
+    2347           0 :     void init(const char* msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2348           0 :       this->msg[0]='\0';
+    2349           0 :       __PLUMED_WRAPPER_STD strncpy(this->msg,msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER);
+    2350           0 :       this->msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1]='\0';
+    2351           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");
+    2352           0 :     }
+    2353             :   public:
+    2354           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT add_buffer_to(const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2355           0 :       init(msg);
+    2356             :     }
+    2357           0 :   add_buffer_to(const T& base,const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT:
+    2358           0 :     T(base)
+    2359             :     {
+    2360           0 :       init(msg);
+    2361           0 :     }
+    2362           0 :   add_buffer_to(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT:
+    2363           0 :     T(other)
+    2364             :     {
+    2365           0 :       init(other.msg);
+    2366           0 :     }
+    2367             :     add_buffer_to & operator=(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2368             :       if(this==&other) return *this;
+    2369             :       init(other.msg);
+    2370             :       return *this;
+    2371             :     }
+    2372           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {
+    2373           0 :       return msg;
+    2374             :     }
+    2375             : #if ! (__cplusplus > 199711L)
+    2376             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2377             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2378             :     ~add_buffer_to() throw() {}
+    2379             : #endif
+    2380             :   };
+    2381             : 
+    2382             : private:
+    2383             :   /// Small class that wraps plumed_safeptr in order to make its initialization easier
+    2384             :   class SafePtr {
+    2385             :     /// non copyable (copy would require managing buffer, could be added in the future if needed)
+    2386             :     SafePtr(const SafePtr&);
+    2387             :     /// non assignable (assignment would require managing buffer, could be added in the future if needed)
+    2388             :     SafePtr& operator=(SafePtr const&);
+    2389             :   public:
+    2390             :     plumed_safeptr safe;
+    2391             :     /// This buffer holds a copy of the data when they are passed by value.
+    2392             :     /// The size is sufficient to hold any primitive type.
+    2393             :     /// Notice that the buffer is required to enable conversions (e.g., passing a class that can be converted to int)
+    2394             :     /// and, at the same time, allow the object to exist after SafePtr constructor has completed.
+    2395             :     /// A perhaps cleaner implementation would require a base class containing
+    2396             :     /// the plumed_safeptr object, derived classes depending on the
+    2397             :     /// argument type as a template parameter, and overloaded functions
+    2398             :     /// returning this derived class.
+    2399             :     char buffer[32];
+    2400             :     /// Default constructor, nullptr
+    2401             :     SafePtr() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2402             :       safe.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2403             :       safe.nelem=0;
+    2404             :       safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2405             :       safe.flags=0x10000*2;
+    2406             :       safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2407             :       buffer[0]='\0';
+    2408             :     }
+    2409             : 
+    2410         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 {
+    2411         222 :       this->safe=safe;
+    2412         222 :       buffer[0]='\0';
+    2413             :       if(nelem>0) this->safe.nelem=nelem;
+    2414             :       if(shape) this->safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape);
+    2415             :     }
+    2416             : 
+    2417             : #if __cplusplus > 199711L
+    2418             :     /// Construct from null
+    2419             :     SafePtr(__PLUMED_WRAPPER_STD nullptr_t,__PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) noexcept {
+    2420             :       safe.ptr=nullptr;
+    2421             :       safe.nelem=0;
+    2422             :       safe.shape=nullptr;
+    2423             :       safe.flags=0x10000*2;
+    2424             :       safe.opt=nullptr;
+    2425             :       buffer[0]='\0';
+    2426             :       (void) nelem;
+    2427             :       (void) shape;
+    2428             :     }
+    2429             : #endif
+    2430             : 
+    2431             : /// Macro that generate a constructor with given type and flags
+    2432             : #define __PLUMED_WRAPPER_SAFEPTR_INNER(type_,flags_) \
+    2433             :   SafePtr(type_*ptr, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2434             :     safe.ptr=ptr; \
+    2435             :     safe.nelem=nelem; \
+    2436             :     safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape); \
+    2437             :     safe.flags=flags_; \
+    2438             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2439             :     buffer[0]='\0'; \
+    2440             :   }
+    2441             : 
+    2442             : /// Macro that uses __PLUMED_WRAPPER_SAFEPTR_INNER to generate constructors with
+    2443             : /// all possible pointer-const combinations
+    2444             : #define __PLUMED_WRAPPER_SAFEPTR(type,code,size) \
+    2445             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type,             size | (0x10000*(code)) | (0x2000000*2)) \
+    2446             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const,       size | (0x10000*(code)) | (0x2000000*3)) \
+    2447             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*,            size | (0x10000*(code)) | (0x2000000*4)) \
+    2448             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*const,       size | (0x10000*(code)) | (0x2000000*5)) \
+    2449             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*,      size | (0x10000*(code)) | (0x2000000*6)) \
+    2450             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*const, size | (0x10000*(code)) | (0x2000000*7))
+    2451             : 
+    2452             : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
+    2453             : #define __PLUMED_WRAPPER_SAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_SAFEPTR(type,code,0)
+    2454             : 
+    2455             : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
+    2456             : /// In addition to generating constructors with all pointer types, it generates a constructor to
+    2457             : /// allow pass-by-value
+    2458             : #define __PLUMED_WRAPPER_SAFEPTR_SIZED(type,code) \
+    2459             :   __PLUMED_WRAPPER_SAFEPTR(type,code,sizeof(type)) \
+    2460             :   SafePtr(type val, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2461             :     assert(sizeof(type)<=32); \
+    2462             :     (void) nelem; \
+    2463             :     (void) shape; \
+    2464             :     safe.ptr=buffer; \
+    2465             :     safe.nelem=1; \
+    2466             :     safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2467             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    2468             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2469             :     __PLUMED_WRAPPER_STD memcpy(buffer,&val,sizeof(type)); \
+    2470             :   }
+    2471             : 
+    2472             : /// Here we create all the required instances
+    2473             : /// 1: void
+    2474             : /// 3: integral
+    2475             : /// 4: floating
+    2476             : /// 5: FILE
+    2477             : /// 0x100: unsigned
+    2478         352 :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(void,1)
+    2479        5248 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
+    2480             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned char,3)
+    2481             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(signed char,0x100+3)
+    2482             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(short,3)
+    2483             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned short,0x100+3)
+    2484       10496 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(int,3)
+    2485             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned int,0x100+3)
+    2486             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long,3)
+    2487             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long,0x100+3)
+    2488             : #if __PLUMED_WRAPPER_CXX_LONGLONG
+    2489             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long long,3)
+    2490             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long long,0x100+3)
+    2491             : #endif
+    2492             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(float,4)
+    2493             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(double,4)
+    2494             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long double,4)
+    2495             :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(FILE,5)
+    2496             : 
+    2497             :     /// Return the contained plumed_safeptr
+    2498             :     plumed_safeptr get_safeptr() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2499       16318 :       return safe;
+    2500             :     }
+    2501             : 
+    2502             :   };
+    2503             : 
+    2504             : #if __cplusplus > 199711L
+    2505             :   /// Small structure used to pass elements of a shape initializer_list.
+    2506             :   /// We use simple conversions, without sign checks, which implicitly means that size=-1 is a very large size
+    2507             :   struct SizeLike {
+    2508             :     std::size_t size;
+    2509             :     SizeLike(short unsigned size): size(size) {}
+    2510             :     SizeLike(unsigned size): size(size) {}
+    2511             :     SizeLike(long unsigned size): size(size) {}
+    2512             :     SizeLike(long long unsigned size): size(size) {}
+    2513             :     SizeLike(short size): size(std::size_t(size)) {}
+    2514        5248 :     SizeLike(int size): size(std::size_t(size)) {}
+    2515             :     SizeLike(long int size): size(std::size_t(size)) {}
+    2516             :     SizeLike(long long int size): size(std::size_t(size)) {}
+    2517             :   };
+    2518             : #endif
+    2519             : 
+    2520             : public:
+    2521             : 
+    2522             :   /**
+    2523             :      Check if plumed is installed (for runtime binding)
+    2524             :      \return true if plumed is installed, false otherwise
+    2525             :      \note Equivalent to plumed_installed() but returns a bool
+    2526             :   */
+    2527             :   static bool installed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2528             :     return plumed_installed();
+    2529             :   }
+    2530             :   /**
+    2531             :      Check if Plumed object is valid. Available as of PLUMED 2.5
+    2532             :      \return true if plumed is valid, false otherwise
+    2533             :      \note Equivalent to plumed_valid() but returns a bool
+    2534             :   */
+    2535             :   bool valid() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2536             :     return plumed_valid(main);
+    2537             :   }
+    2538             : #if __cplusplus > 199711L
+    2539             :   /**
+    2540             :      Same as \ref valid(). Available as of PLUMED 2.5.
+    2541             : 
+    2542             :   Allow code such as
+    2543             :   \verbatim
+    2544             :   Plumed p;
+    2545             :   if(!p) raise_error();
+    2546             :   p.cmd("init");
+    2547             :   \endverbatim
+    2548             : 
+    2549             :   In order to avoid ambiguous conversions, this is only allowed when compiling with C++11
+    2550             :   where it is marked as explicit.
+    2551             :   */
+    2552             :   explicit
+    2553             :   operator bool() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2554             :     return plumed_valid(main);
+    2555             :   }
+    2556             : #endif
+    2557             : 
+    2558             :   /**
+    2559             :      Returns the number of references to this object. Available as of PLUMED 2.5.
+    2560             :     \note Equivalent to plumed_use_count()
+    2561             :   */
+    2562             :   int useCount() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2563             :     return plumed_use_count(main);
+    2564             :   }
+    2565             : 
+    2566             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2567             :   /**
+    2568             :      Check if global-plumed has been initialized
+    2569             :      \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
+    2570             :              called), false otherwise.
+    2571             :      \note Equivalent to plumed_ginitialized() but returns a bool
+    2572             :   */
+    2573             :   static bool ginitialized() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2574             :     return plumed_ginitialized();
+    2575             :   }
+    2576             :   /**
+    2577             :      Check if global-plumed is valid
+    2578             :      \return true if global plumed object (see global()) is valid.
+    2579             :      \note Equivalent to plumed_gvalid() but returns a bool
+    2580             :   */
+    2581             :   static bool gvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2582             :     return plumed_gvalid();
+    2583             :   }
+    2584             :   /**
+    2585             :      Initialize global-plumed.
+    2586             :      \warning Using the global objects in C++ is not recommended since they are difficult to use in
+    2587             :               an exception safe manner. In particular, one should explicitly catch exceptions to
+    2588             :               properly call gfinalize()
+    2589             :      \note Equivalent to plumed_gcreate()
+    2590             :   */
+    2591             :   static void gcreate() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2592             :     plumed_gcreate();
+    2593             :   }
+    2594             :   /**
+    2595             :      Send a command to global-plumed
+    2596             :       \param key The name of the command to be executed
+    2597             :      \note Equivalent to plumed_gcmd()
+    2598             :   */
+    2599             :   static void gcmd(const char*key) {
+    2600             :     global().cmd(key);
+    2601             :   }
+    2602             : 
+    2603             : #if __cplusplus > 199711L
+    2604             : 
+    2605             :   /**
+    2606             :      Send a command to global-plumed.
+    2607             :   */
+    2608             :   template<typename T>
+    2609             :   static void gcmd(const char*key,T&& val) {
+    2610             :     global().cmd(key,std::forward<T>(val));
+    2611             :   }
+    2612             : 
+    2613             :   /**
+    2614             :      Send a command to global-plumed.
+    2615             :      This version detects passing size or shape as a pointer.
+    2616             :   */
+    2617             :   template<typename T,typename M>
+    2618             :   static void gcmd(const char*key,T* val, M&& more) {
+    2619             :     global().cmd(key,val,std::forward<M>(more));
+    2620             :   }
+    2621             : 
+    2622             :   /**
+    2623             :      Send a command to global-plumed.
+    2624             :      This version detects passing shape as an initializer_list.
+    2625             :   */
+    2626             :   template<typename T>
+    2627             :   static void gcmd(const char*key,T* val, std::initializer_list<SizeLike> shape) {
+    2628             :     global().cmd(key,val,shape);
+    2629             :   }
+    2630             : 
+    2631             : #else
+    2632             : 
+    2633             :   /**
+    2634             :      Send a command to global-plumed
+    2635             :       \param key The name of the command to be executed
+    2636             :       \param val The argument.
+    2637             :      \note Equivalent to plumed_gcmd()
+    2638             :   */
+    2639             :   template<typename T>
+    2640             :   static void gcmd(const char*key,T val) {
+    2641             :     global().cmd(key,val);
+    2642             :   }
+    2643             :   /**
+    2644             :      Send a command to global-plumed
+    2645             :       \param key The name of the command to be executed
+    2646             :       \param val The argument.
+    2647             :       \param nelem Number of elements in the passed array, for typechecking.
+    2648             :      \note Equivalent to plumed_gcmd()
+    2649             :   */
+    2650             :   template<typename T>
+    2651             :   static void gcmd(const char*key,T* val,__PLUMED_WRAPPER_STD size_t nelem) {
+    2652             :     global().cmd(key,val,nelem);
+    2653             :   }
+    2654             : 
+    2655             :   /**
+    2656             :      Send a command to global-plumed
+    2657             :       \param key The name of the command to be executed
+    2658             :       \param val The argument.
+    2659             :       \param shape The shape of the argument.
+    2660             :      \note Equivalent to plumed_gcmd()
+    2661             :   */
+    2662             :   template<typename T>
+    2663             :   static void gcmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2664             :     global().cmd(key,val,shape);
+    2665             :   }
+    2666             : 
+    2667             : #endif
+    2668             : 
+    2669             :   /**
+    2670             :      Finalize global-plumed
+    2671             :   */
+    2672             :   static void gfinalize() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2673             :     plumed_gfinalize();
+    2674             :   }
+    2675             :   /**
+    2676             :      Returns the Plumed global object
+    2677             : 
+    2678             :      Notice that the object is copied, thus increasing the reference counter of the
+    2679             :      global object. In this manner, the global object will survive after a call to
+    2680             :      \ref gfinalize() if the resulting object is still in scope.
+    2681             : 
+    2682             :      \return The Plumed global object
+    2683             :   */
+    2684             :   static Plumed global() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2685             :     return Plumed(plumed_global());
+    2686             :   }
+    2687             : #endif /*}*/
+    2688             :   /**
+    2689             :      Constructor.
+    2690             : 
+    2691             :     Notice that when using runtime binding the constructed object might be
+    2692             :     invalid. One might check it using the \ref valid() method.
+    2693             : 
+    2694             :     \note Performs the same task a plumed_create()
+    2695             :   */
+    2696        5248 : Plumed()__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2697             : #if __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+    2698             :   main(plumed_create_invalid())
+    2699             : #else
+    2700        5248 :   main(plumed_create())
+    2701             : #endif
+    2702             :   {
+    2703             :   }
+    2704             : 
+    2705             :   /**
+    2706             :      Clone a Plumed object from a FORTRAN char* handler.
+    2707             : 
+    2708             :      \param c The FORTRAN handler (a char[32]).
+    2709             : 
+    2710             :      The reference counter for the corresponding object will be increased
+    2711             :      to make sure that the object will be available after plumed_f_finalize is called
+    2712             :      if the created object is still in scope.
+    2713             :   */
+    2714             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(const char*c)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2715             :   main(plumed_create_reference_f(c))
+    2716             :   {
+    2717             :   }
+    2718             : 
+    2719             :   /**
+    2720             :     Create a reference from a void* pointer. Available as of PLUMED 2.5.
+    2721             :   */
+    2722             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(void*v)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2723             :   main(plumed_create_reference_v(v))
+    2724             :   {
+    2725             :   }
+    2726             : 
+    2727             :   /**
+    2728             :      Clone a Plumed object from a C plumed structure
+    2729             : 
+    2730             :      \param p The C plumed structure.
+    2731             : 
+    2732             :      The reference counter for the corresponding object will be increased
+    2733             :      to make sure that the object will be available after plumed_finalize is called
+    2734             :      if the created object is still in scope.
+    2735             :   */
+    2736             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(plumed p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2737             :   main(plumed_create_reference(p))
+    2738             :   {
+    2739             :   }
+    2740             : 
+    2741             :   /** Copy constructor.
+    2742             : 
+    2743             :     Takes a reference, incrementing the reference counter of the corresponding object.
+    2744             :   */
+    2745             : Plumed(const Plumed& p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2746             :   main(plumed_create_reference(p.main))
+    2747             :   {
+    2748             :   }
+    2749             : 
+    2750             :   /** Assignment operator. Available as of PLUMED 2.5.
+    2751             : 
+    2752             :     Takes a reference,incrementing the reference counter of the corresponding object.
+    2753             :   */
+    2754             :   Plumed&operator=(const Plumed&p) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2755             :     if(this != &p) {
+    2756             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2757             :       if(main.p) plumed_finalize(main);
+    2758             :       main=plumed_create_reference(p.main);
+    2759             :     }
+    2760             :     return *this;
+    2761             :   }
+    2762             : 
+    2763             :   /*
+    2764             :     PLUMED >= 2.4 requires a C++11 compiler.
+    2765             :     Anyway, since Plumed.h file might be redistributed with other codes
+    2766             :     and it should be possible to combine it with earlier PLUMED versions,
+    2767             :     we here explicitly check if C+11 is available before enabling move semantics.
+    2768             :   */
+    2769             : #if __cplusplus > 199711L
+    2770             :   /** Move constructor. Available as of PLUMED 2.5.
+    2771             :     Only if move semantics is enabled.
+    2772             :   */
+    2773             : Plumed(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2774             :   main(p.main)
+    2775             :   {
+    2776             :     p.main.p=nullptr;
+    2777             :   }
+    2778             :   /** Move assignment. Available as of PLUMED 2.5.
+    2779             :     Only if move semantics is enabled.
+    2780             :   */
+    2781             :   Plumed& operator=(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2782             :     if(this != &p) {
+    2783             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2784             :       if(main.p) plumed_finalize(main);
+    2785             :       main=p.main;
+    2786             :       p.main.p=nullptr;
+    2787             :     }
+    2788             :     return *this;
+    2789             :   }
+    2790             : #endif
+    2791             :   /**
+    2792             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2793             : 
+    2794             :     It returns an object created with \ref plumed_create_dlopen. The object is owned and
+    2795             :     is then finalized in the destructor. It can be used as follows:
+    2796             :   \verbatim
+    2797             :     PLMD::Plumed p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2798             :   // or, equivalenty:
+    2799             :   //    PLMD::Plumed p(PLMD::Plumed::dlopen("/path/to/libplumedKernel.so"));
+    2800             :     p.cmd("init");
+    2801             :   \endverbatim
+    2802             :     or, equivalently, as
+    2803             :   \verbatim
+    2804             :     auto p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2805             :     p.cmd("init");
+    2806             :   \endverbatim
+    2807             :   */
+    2808             :   static Plumed dlopen(const char* path)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2809             :     plumed p=plumed_create_dlopen(path);
+    2810             :     Plumed pp(p);
+    2811             :     plumed_finalize(p);
+    2812             :     return pp;
+    2813             :   }
+    2814             : 
+    2815             :   /**
+    2816             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2817             : 
+    2818             :     Same as \ref dlopen(const char* path), but allows a dlopen mode to be chosen explicitly.
+    2819             :   */
+    2820             :   static Plumed dlopen(const char* path,int mode)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2821             :     plumed p=plumed_create_dlopen2(path,mode);
+    2822             :     Plumed pp(p);
+    2823             :     plumed_finalize(p);
+    2824             :     return pp;
+    2825             :   }
+    2826             :   /**
+    2827             :     Create a PLUMED object loading from an already opened shared library. Available as of PLUMED 2.8.
+    2828             : 
+    2829             :     Same as \ref dlopen(const char* path), but searches functions in an already loaded library.
+    2830             :     See \ref plumed_create_dlsym.
+    2831             :   */
+    2832             :   static Plumed dlsym(void* dlhandle)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2833             :     plumed p=plumed_create_dlsym(dlhandle);
+    2834             :     Plumed pp(p);
+    2835             :     plumed_finalize(p);
+    2836             :     return pp;
+    2837             :   }
+    2838             : 
+    2839             :   /** Invalid constructor. Available as of PLUMED 2.5.
+    2840             : 
+    2841             :     Can be used to initialize an invalid object. It might be useful to postpone
+    2842             :     the initialization of a Plumed object. Consider the following case
+    2843             :   \verbatim
+    2844             :     Plumed p;
+    2845             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2846             :     p.cmd("init")
+    2847             :   \endverbatim
+    2848             :     Here the `p` object will be initialized *before* the `PLUMED_KERNEL` env var has been set.
+    2849             :     This can be particularly problematic if `p` is stored in some high level class.
+    2850             :     The following case would do the job
+    2851             :   \verbatim
+    2852             :     Plumed p;
+    2853             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2854             :     p=Plumed();
+    2855             :     p.cmd("init")
+    2856             :   \endverbatim
+    2857             :     However, there will be some error reported related to the attempt to load the kernel
+    2858             :     when `p` is initialized. The following solution is the optimal one:
+    2859             :   \verbatim
+    2860             :     Plumed p(Plumed::makeInvalid());
+    2861             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2862             :     p=Plumed();
+    2863             :     p.cmd("init")
+    2864             :   \endverbatim
+    2865             :   */
+    2866             :   static Plumed makeInvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2867             :     plumed p=plumed_create_invalid();
+    2868             :     Plumed pp(p);
+    2869             :     plumed_finalize(p);
+    2870             :     return pp;
+    2871             :   }
+    2872             : 
+    2873             :   /**
+    2874             :     Create a valid PLMD::Plumed object.
+    2875             : 
+    2876             :     Can be used to create a valid object e.g. when Plumed.h was compiled with
+    2877             :     `-D__PLUMED_WRAPPER_CXX_DEFAULT_INVALID`. For internal usage.
+    2878             :   */
+    2879             : 
+    2880             :   static Plumed makeValid()__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2881             :     plumed p=plumed_create();
+    2882             :     Plumed pp(p);
+    2883             :     plumed_finalize(p);
+    2884             :     return pp;
+    2885             :   }
+    2886             : 
+    2887             : 
+    2888             :   /**
+    2889             :      Retrieve the C plumed structure for this object.
+    2890             : 
+    2891             :      Notice that the resulting plumed structure is a weak reference and
+    2892             :      should NOT be finalized, unless a new reference is explicitly added
+    2893             :   \verbatim
+    2894             :   Plumed p;
+    2895             :   plumed c=p;
+    2896             :   plumed_finalize(c); // <- this is wrong
+    2897             :   \endverbatim
+    2898             :   \verbatim
+    2899             :   Plumed p;
+    2900             :   plumed c=plumed_create_reference(p);
+    2901             :   plumed_finalize(c); // <- this is right
+    2902             :   \endverbatim
+    2903             :   */
+    2904             :   operator plumed()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2905             :     return main;
+    2906             :   }
+    2907             : 
+    2908             :   /**
+    2909             :      Retrieve a FORTRAN handler for this object
+    2910             :       \param c The FORTRAN handler (a char[32]).
+    2911             :     Notice that the resulting plumed structure is a weak reference and
+    2912             :     should NOT be finalized, unless a new reference is explicitly added.
+    2913             :   */
+    2914             :   void toFortran(char*c)const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2915             :     plumed_c2f(main,c);
+    2916             :   }
+    2917             : 
+    2918             :   /**
+    2919             :      Retrieve a void* handler for this object. Available as of PLUMED 2.5.
+    2920             :     Notice that the resulting plumed structure is a weak reference and
+    2921             :     should NOT be finalized, unless a new reference is explicitly added.
+    2922             :   */
+    2923             :   void* toVoid()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2924             :     return plumed_c2v(main);
+    2925             :   }
+    2926             : 
+    2927             :   /**
+    2928             :     Increase reference counter. Available as of PLUMED 2.5.
+    2929             : 
+    2930             :     Using this method improperly might interfere with correct object construction
+    2931             :     and destruction.
+    2932             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2933             : 
+    2934             :     A possible usage is to transfer the ownership of a temporary
+    2935             :     object when it is converted
+    2936             :   \verbatim
+    2937             :   plumed p=Plumed::dlopen(path).incref()
+    2938             :   // without incref(), the just constructed object will be destroyed
+    2939             :   // when the temporary object is deleted.
+    2940             :   ... do stuff ...
+    2941             :   plumed_finalize(p);
+    2942             :   \endverbatim
+    2943             : 
+    2944             :   */
+    2945             :   Plumed& incref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2946             :     plumed_create_reference(main);
+    2947             :     return *this;
+    2948             :   }
+    2949             : 
+    2950             :   /**
+    2951             :     Decrease reference counter. Available as of PLUMED 2.5.
+    2952             : 
+    2953             :     Using this method improperly might interfere with correct object construction
+    2954             :     and destruction.
+    2955             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2956             :   */
+    2957             :   Plumed& decref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2958             : // calling decref on a moved plumed object should give an error, so we do not check if main.p!=NULL here:
+    2959             :     plumed_finalize(main);
+    2960             :     return *this;
+    2961             :   }
+    2962             : 
+    2963             : private:
+    2964             : 
+    2965             :   /**
+    2966             :     Private version of cmd. It is used here to avoid duplication of code between typesafe and not-typesafe versions
+    2967             :   */
+    2968       16318 :   static void cmd_priv(plumed main,const char*key, SafePtr& safe, plumed_error*error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2969             : 
+    2970             :     plumed_error error_cxx;
+    2971             :     plumed_error_init(&error_cxx);
+    2972             : 
+    2973             :     plumed_nothrow_handler nothrow;
+    2974       16318 :     if(error) {
+    2975             :       plumed_error_init(error);
+    2976           0 :       nothrow.ptr=error;
+    2977             :     } else {
+    2978       16318 :       nothrow.ptr=&error_cxx;
+    2979             :     }
+    2980       16318 :     nothrow.handler=plumed_error_set;
+    2981             : 
+    2982             :     try {
+    2983       16318 :       plumed_cmd_safe_nothrow(main,key,safe.get_safeptr(),nothrow);
+    2984           0 :     } catch (...) {
+    2985             :       assert(error_cxx.code==0); /* no need to plumed_error_finalize here */
+    2986             :       /*
+    2987             :         When loading a kernel <=2.4, plumed_cmd_nothrow could throw an exception.
+    2988             :         If the exception is transmitted through the C interface and arrives here,
+    2989             :         we translate it so as to free the virtual tables of the loaded kernel.
+    2990             :       */
+    2991           0 :       rethrow();
+    2992           0 :     }
+    2993             :     /* plumed_error_rethrow is finalizing */
+    2994       16318 :     if(!error && error_cxx.code!=0) plumed_error_rethrow_cxx(error_cxx);
+    2995       16318 :   }
+    2996             : 
+    2997             : public:
+    2998             : 
+    2999             : #if __cplusplus > 199711L
+    3000             : 
+    3001             : private:
+    3002             : 
+    3003             :   // Small class to manage termination of string_view.
+    3004             :   // The class has a SSO with size 128, so that most messages should fit without
+    3005             :   // any allocation
+    3006             :   class CString {
+    3007             :     /// local buffer (fast)
+    3008             :     char static_buffer[128];
+    3009             :     /// dynamic buffer (requires allocation)
+    3010             :     std::unique_ptr<char[]> dynamic_buffer;
+    3011             :     /// actual pointer
+    3012             :     const char * str;
+    3013             :     /// Move constructor is deleted
+    3014             :     CString(CString&&) = delete;
+    3015             :     /// Move assignment operator is deleted
+    3016             :     CString& operator=(CString&&) = delete;
+    3017             :   public:
+    3018             :     /// Initialize from a const char*, copying the address
+    3019             :     CString(const char* str) noexcept
+    3020             :     {
+    3021             :       this->str=str;
+    3022             :       this->static_buffer[0]='\0';
+    3023             :     }
+    3024             :     /// Initialize from a std:string, taking the address of the corresponding c_str
+    3025             :     CString(const std::string & str) noexcept
+    3026             :     {
+    3027             :       this->str=str.c_str();
+    3028             :       this->static_buffer[0]='\0';
+    3029             :     }
+    3030             : #if __cplusplus >= 201703L
+    3031             :     /// Initialize from a std::string_view, only C++17
+    3032             :     /// Add a null terminator. If possible, use a local buffer, other wise allocate one.
+    3033             :     CString(std::string_view str) {
+    3034             :       std::size_t len=str.length();
+    3035             :       char* buffer;
+    3036             :       if(sizeof(static_buffer)>=len+1) {
+    3037             :         // in this case, the string_view fits in the local buffer
+    3038             :         buffer=static_buffer;
+    3039             :       } else {
+    3040             :         // in this case, the string_view does not fit in the local buffer
+    3041             :         // hence we allocate a unique_ptr
+    3042             :         dynamic_buffer=std::make_unique<char[]>(len+1);
+    3043             :         buffer=dynamic_buffer.get();
+    3044             :       }
+    3045             :       // at this point, buffer is guaranteed to have size >= len+1
+    3046             :       str.copy(buffer,len);
+    3047             :       buffer[len]='\0'; // ensure null termination
+    3048             :       this->str=buffer;
+    3049             :       this->static_buffer[0]='\0';
+    3050             :     }
+    3051             : #endif
+    3052             :     operator const char* () const noexcept {
+    3053             :       return str;
+    3054             :     }
+    3055             :   };
+    3056             : 
+    3057             :   /// Internal tool to convert initializer_list to shape
+    3058             :   /// This is just taking an initializer list and making a std::array
+    3059        5248 :   std::array<std::size_t,5>  make_shape(std::initializer_list<SizeLike> shape) {
+    3060        5248 :     if(shape.size()>4) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    3061             :     std::array<std::size_t,5> shape_;
+    3062             :     unsigned j=0;
+    3063       10496 :     for(auto i : shape) {
+    3064        5248 :       shape_[j]=i.size;
+    3065        5248 :       j++;
+    3066             :     }
+    3067        5248 :     shape_[j]=0;
+    3068        5248 :     return shape_;
+    3069             :   }
+    3070             : 
+    3071             :   /// Internal utility to append a shape.
+    3072             :   /// Create a new shape where newindex has been appended to the last non zero element.
+    3073             :   std::array<std::size_t,5> append_size(std::size_t* shape,std::size_t newindex) {
+    3074             :     std::array<std::size_t,5> shape_;
+    3075             :     unsigned i;
+    3076             :     for(i=0; i<4; i++) {
+    3077             :       shape_[i]=shape[i];
+    3078             :       if(shape[i]==0) break;
+    3079             :     } // one less because we need to append another number!
+    3080             :     if(i==4) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    3081             :     shape_[i]=newindex;
+    3082             :     shape_[i+1]=0;
+    3083             :     return shape_;
+    3084             :   }
+    3085             : 
+    3086             : /// Helper functions for interpreting commands. **They are all internals**.
+    3087             : /// cmd_helper is called when we have no shape information associated.
+    3088             : /// cmd_helper_with_shape is called when we have shape information associated.
+    3089             : /// cmd_helper_with_nelem is called when we have size information associated.
+    3090             : /// The nocopy bool tells us if this pointer is pointing to a temporary variable, it is propagated by the cmd_helper_with_shape version
+    3091             : /// It makes sure PLUMED will not keep a copy.
+    3092             : /// The variants below change for the type of the val argument
+    3093             : /// There is a chain of SFINAE conditions. This would be better implement with if constexpr, but we avoid doing so
+    3094             : /// to keep this compatible with C++11.
+    3095             : 
+    3096             : /// cmd_helper with custom array val (includes std::array)
+    3097             : /// temporaries are detected and the information is propragated
+    3098             :   template<typename Key,typename T, typename std::enable_if<wrapper::is_custom_array<typename std::remove_reference<T>::type>::value, int>::type = 0>
+    3099             :   void cmd_helper(Key && key,T&& val) {
+    3100             :     std::size_t shape[] { wrapper::custom_array_size<T>(), 0 };
+    3101             :     cmd_helper_with_shape(std::forward<Key>(key),wrapper::custom_array_cast(&val),shape, std::is_rvalue_reference<T&&>::value);
+    3102             :   }
+    3103             : 
+    3104             : /// cmd_helper with size/data val (typically, std::vector, std::string, small_vector, etc)
+    3105             : /// temporaries are detected and the information is propragated
+    3106             :   template<typename Key,typename T, typename std::enable_if<!wrapper::is_custom_array<typename std::remove_reference<T>::type>::value && wrapper::has_size_and_data<T>::value, int>::type = 0>
+    3107             :   void cmd_helper(Key && key,T&& val) {
+    3108             :     std::size_t shape[] { wrapper::size(val), 0 };
+    3109             :     cmd_helper_with_shape(std::forward<Key>(key),val.data(),shape, std::is_rvalue_reference<T&&>::value);
+    3110             :   }
+    3111             : 
+    3112             : /// cmd_helper with raw pointer val
+    3113             : /// temporaries are not detected. We can indeed save the pointer, even if it's a temporary as it is in the case cmd("a",&a)
+    3114             : /// here we use std::remove_reference to detect properly pointers to arrays
+    3115             :   template<typename Key,typename T, typename std::enable_if<!wrapper::is_custom_array<typename std::remove_reference<T>::type>::value && !wrapper::has_size_and_data<T>::value && std::is_pointer<typename std::remove_reference<T>::type>::value, int>::type = 0>
+    3116       10848 :   void cmd_helper(Key && key,T&& val) {
+    3117             : #if __PLUMED_WRAPPER_CXX_DETECT_SHAPES_STRICT
+    3118             :     // this would be strict checking
+    3119             :     // "a pointer without a specified size is meant to be pointing to a size 1 object"
+    3120             :     std::size_t shape[] {  0, 0 };
+    3121             :     if(val) shape[0]=1;
+    3122             :     cmd_helper_with_shape(std::forward<Key>(key),val,shape);
+    3123             : #else
+    3124             :     if(wrapper::is_custom_array<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value) {
+    3125             :       // if we are passing a pointer to a fixed sized array, we make sure to retain the information related to
+    3126             :       // the rank of the array and the following (fixed) dimensions
+    3127             :       std::size_t shape[] {  0, 0 };
+    3128             :       if(val) shape[0]=std::numeric_limits<std::size_t>::max();
+    3129             :       cmd_helper_with_shape(std::forward<Key>(key),val,shape);
+    3130             :     } else {
+    3131             :       // otherwise, for backward compatibility, the pointer is assumed with no shape information
+    3132       10848 :       SafePtr s(val,0,nullptr);
+    3133       10848 :       cmd_priv(main,CString(key),s);
+    3134             :     }
+    3135             : #endif
+    3136       10848 :   }
+    3137             : 
+    3138             : /// cmd_helper in remaining cases, that is when val is passed by value
+    3139             : /// temporaries are not detected. However, the argument is passed by value and its address is not copyable anyway
+    3140             :   template<typename Key,typename T, typename std::enable_if<!wrapper::is_custom_array<typename std::remove_reference<T>::type>::value && !wrapper::has_size_and_data<T>::value && !std::is_pointer<typename std::remove_reference<T>::type>::value, int>::type = 0>
+    3141             :   void cmd_helper(Key && key,T&& val) {
+    3142             :     SafePtr s(val,0,nullptr);
+    3143             :     cmd_priv(main,CString(key),s);
+    3144             :   }
+    3145             : 
+    3146             : /// cmd_helper_with_shape with custom array val (includes std::array and C arrays)
+    3147             : /// nocopy information is propagated
+    3148             :   template<typename Key,typename T, typename std::enable_if<wrapper::is_custom_array<T>::value, int>::type = 0>
+    3149             :   void cmd_helper_with_shape(Key && key,T* val, __PLUMED_WRAPPER_STD size_t* shape,bool nocopy=false) {
+    3150             :     auto newptr=wrapper::custom_array_cast(val);
+    3151             :     auto newshape=append_size(shape,wrapper::custom_array_size<T>());
+    3152             :     cmd_helper_with_shape(std::forward<Key>(key),newptr,newshape.data(),nocopy);
+    3153             :   }
+    3154             : 
+    3155             : /// cmd_helper_with_shape with pointer to simple type val.
+    3156             : /// nocopy information is used to pass the proper flags to plumed
+    3157             :   template<typename Key,typename T, typename std::enable_if<!wrapper::is_custom_array<T>::value, int>::type = 0>
+    3158        5248 :   void cmd_helper_with_shape(Key && key,T* val, __PLUMED_WRAPPER_STD size_t* shape,bool nocopy=false) {
+    3159             :     SafePtr s(val,0,shape);
+    3160        5248 :     if(nocopy) s.safe.flags |= 0x10000000;
+    3161        5248 :     cmd_priv(main,CString(key),s);
+    3162        5248 :   }
+    3163             : 
+    3164             : #if ! __PLUMED_WRAPPER_CXX_DETECT_SHAPES_STRICT
+    3165             : /// cmd_helper_with_nelem with custom array val (includes std::array)
+    3166             : /// this helper is only used for backward compatibility, so it does not need to take into account
+    3167             : /// the copyability of the pointer
+    3168             :   template<typename Key,typename T, typename std::enable_if<wrapper::is_custom_array<T>::value, int>::type = 0>
+    3169             :   void cmd_with_nelem(Key && key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
+    3170             :     std::size_t shape[] {  0, 0 };
+    3171             :     if(val) shape[0]=nelem;
+    3172             :     cmd_helper_with_shape(std::forward<Key>(key),val,shape);
+    3173             :   }
+    3174             : 
+    3175             : /// cmd_helper_with_nelem with pointer to simple type val.
+    3176             : /// this helper is only used for backward compatibility, so it does not need to take into account
+    3177             : /// the copyability of the pointer
+    3178             :   template<typename Key,typename T, typename std::enable_if<!wrapper::is_custom_array<T>::value, int>::type = 0>
+    3179             :   void cmd_with_nelem(Key && key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
+    3180             :     // pointer, directly managed by SafePtr
+    3181             :     SafePtr s(val,nelem,nullptr);
+    3182             :     cmd_priv(main,CString(key),s);
+    3183             :   }
+    3184             : #endif
+    3185             : 
+    3186             : public:
+    3187             : 
+    3188             :   /**
+    3189             :      Send a command to this plumed object
+    3190             :       \param key The name of the command to be executed
+    3191             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    3192             :             rethrow any exception raised within PLUMED.
+    3193             :   */
+    3194             :   template<typename Key>
+    3195             :   void cmd(Key && key) {
+    3196             :     SafePtr s;
+    3197             :     cmd_priv(main,CString(key),s);
+    3198             :   }
+    3199             : 
+    3200             :   /**
+    3201             :      Send a command to this plumed object
+    3202             :       \param key The name of the command to be executed
+    3203             :       \param val The argument.
+    3204             :   */
+    3205             :   template<typename Key,typename T>
+    3206             :   void cmd(Key && key,T&& val) {
+    3207       10848 :     cmd_helper(std::forward<Key>(key),std::forward<T>(val));
+    3208       10848 :   }
+    3209             : 
+    3210             :   /**
+    3211             :      Send a command to this plumed object
+    3212             :       \param key The name of the command to be executed
+    3213             :       \param val The argument.
+    3214             :       \note This overload accepts a pointer and corresponding size
+    3215             :             information. It's usage is discouraged:
+    3216             :             the overload accepting shape information should be preferred.
+    3217             :   */
+    3218             : 
+    3219             :   template<typename Key,typename T, typename I, typename std::enable_if<std::is_integral<I>::value, int>::type = 0>
+    3220             :   void cmd(Key && key,T* val, I nelem) {
+    3221             : #if __PLUMED_WRAPPER_CXX_DETECT_SHAPES_STRICT
+    3222             :     static_assert("in strict mode you cannot pass nelem, please pass full shape instead");
+    3223             : #else
+    3224             :     cmd_with_nelem(std::forward<Key>(key),val,__PLUMED_WRAPPER_STD size_t(nelem));
+    3225             : #endif
+    3226             :   }
+    3227             : 
+    3228             :   /**
+    3229             :      Send a command to this plumed object
+    3230             :       \param key The name of the command to be executed
+    3231             :       \param val The argument.
+    3232             :       \note This overload accepts a pointer and corresponding shape
+    3233             :             information. Shape is passed a size_t pointer,
+    3234             :             but the overload accepting an initializer_list
+    3235             :             has a more friendly syntax.
+    3236             :   */
+    3237             :   template<typename Key,typename T>
+    3238             :   void cmd(Key && key,T* val, __PLUMED_WRAPPER_STD size_t* shape) {
+    3239             :     unsigned i;
+    3240             :     for(i=0; i<5; i++) if(shape[i]==0) break;
+    3241             :     if(i==5) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    3242             :     cmd_helper_with_shape(std::forward<Key>(key),val,shape);
+    3243             :   }
+    3244             : 
+    3245             :   /**
+    3246             :      Send a command to this plumed object
+    3247             :       \param key The name of the command to be executed
+    3248             :       \param val The argument.
+    3249             :       \note This overload accepts a pointer and corresponding shape
+    3250             :             information. Shape is passed a size_t pointer,
+    3251             :             but the overload accepting an initializer_list
+    3252             :             has a more friendly syntax.
+    3253             :   */
+    3254             :   template<typename Key,typename T>
+    3255        5248 :   void cmd(Key && key,T* val, std::initializer_list<SizeLike> shape) {
+    3256        5248 :     auto shape_=make_shape(shape);
+    3257        5248 :     cmd_helper_with_shape(std::forward<Key>(key),val,shape_.data());
+    3258        5248 :   }
+    3259             : 
+    3260             : public:
+    3261             : 
+    3262             : #else
+    3263             : 
+    3264             :   /**
+    3265             :      Send a command to this plumed object
+    3266             :       \param key The name of the command to be executed
+    3267             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    3268             :             rethrow any exception raised within PLUMED.
+    3269             :   */
+    3270             :   void cmd(const char*key) {
+    3271             :     plumed_cmd_cxx(main,key);
+    3272             :   }
+    3273             : 
+    3274             : 
+    3275             :   /**
+    3276             :      Send a command to this plumed object
+    3277             :       \param key The name of the command to be executed
+    3278             :       \param val The argument, passed by value.
+    3279             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    3280             :             rethrow any exception raised within PLUMED.
+    3281             :       \note Unless PLUMED library is <=2.7,
+    3282             :              the type of the argument is checked.
+    3283             :   */
+    3284             :   template<typename T>
+    3285             :   void cmd(const char*key,T val) {
+    3286             :     plumed_cmd_cxx(main,key,val);
+    3287             :   }
+    3288             : 
+    3289             :   /**
+    3290             :      Send a command to this plumed object
+    3291             :       \param key The name of the command to be executed
+    3292             :       \param val The argument, passed by pointer.
+    3293             :       \param shape A zero-terminated array containing the shape of the data.
+    3294             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    3295             :             rethrow any exception raised within PLUMED.
+    3296             :       \note Unless PLUMED library is <=2.7,
+    3297             :              the type of the argument is checked. If shape is passed, it is also
+    3298             :              checked that PLUMED access only compatible indexes.
+    3299             :   */
+    3300             :   template<typename T>
+    3301             :   void cmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    3302             :     unsigned i;
+    3303             :     for(i=0; i<5; i++) if(shape[i]==0) break;
+    3304             :     if(i==5) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    3305             :     plumed_cmd_cxx(main,key,val,shape);
+    3306             :   }
+    3307             : 
+    3308             :   /**
+    3309             :      Send a command to this plumed object
+    3310             :       \param key The name of the command to be executed
+    3311             :       \param val The argument, passed by pointer.
+    3312             :       \param nelem The number of elements passed.
+    3313             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    3314             :             rethrow any exception raised within PLUMED.
+    3315             :       \note Unless PLUMED library is <=2.7,
+    3316             :              the type of the argument is checked.  nelem is used to check
+    3317             :              the maximum index interpreting the array as flattened.
+    3318             :   */
+    3319             :   template<typename T>
+    3320             :   void cmd(const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
+    3321             :     plumed_cmd_cxx(main,key,val,nelem);
+    3322             :   }
+    3323             : 
+    3324             : #endif
+    3325             : 
+    3326             : 
+    3327             :   /**
+    3328             :      Destructor
+    3329             : 
+    3330             :      It calls \ref plumed_finalize(). Notice that this is done also if the
+    3331             :      constructor failed (that is, if it returned an invalid object). This allows
+    3332             :      declaring Plumed objects also if PLUMED is actually not available, provided
+    3333             :      one does not use the \ref cmd method.
+    3334             : 
+    3335             :      Destructor is virtual so as to allow correct inheritance from Plumed object.
+    3336             :   */
+    3337             : #if __PLUMED_WRAPPER_CXX_POLYMORPHIC
+    3338             :   virtual
+    3339             : #endif
+    3340        5248 :   ~Plumed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3341             : // the check is needed to avoid calling plumed_finalize on moved objects
+    3342        5248 :     if(main.p) plumed_finalize(main);
+    3343        5248 :   }
+    3344             : 
+    3345             :   /**
+    3346             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3347             :     namely implement typechecks and rethrowing exception.
+    3348             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3349             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3350             :     Available as of PLUMED 2.8.
+    3351             :   */
+    3352             :   static void plumed_cmd_cxx(plumed p,const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3353             :     SafePtr s;
+    3354             :     cmd_priv(p,key,s,error);
+    3355             :   }
+    3356             : 
+    3357             :   /**
+    3358             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3359             :     namely implement typechecks and rethrowing exception.
+    3360             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3361             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3362             :     Available as of PLUMED 2.8.
+    3363             :   */
+    3364             :   template<typename T>
+    3365         222 :   static void plumed_cmd_cxx(plumed p,const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3366             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    3367         222 :     cmd_priv(p,key,s,error);
+    3368         222 :   }
+    3369             : 
+    3370             :   /**
+    3371             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3372             :     namely implement typechecks and rethrowing exception.
+    3373             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3374             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3375             :     Available as of PLUMED 2.8.
+    3376             :   */
+    3377             :   template<typename T>
+    3378             :   static void plumed_cmd_cxx(plumed p,const char*key,T* val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3379             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    3380             :     cmd_priv(p,key,s,error);
+    3381             :   }
+    3382             : 
+    3383             :   /**
+    3384             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3385             :     namely implement typechecks and rethrowing exception.
+    3386             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3387             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3388             :     Available as of PLUMED 2.8.
+    3389             :   */
+    3390             :   template<typename T>
+    3391             :   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) {
+    3392             :     SafePtr s(val,nelem,__PLUMED_WRAPPER_CXX_NULLPTR);
+    3393             :     cmd_priv(p,key,s,error);
+    3394             :   }
+    3395             : 
+    3396             :   /**
+    3397             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3398             :     namely implement typechecks and rethrowing exception.
+    3399             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3400             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3401             :     Available as of PLUMED 2.8.
+    3402             :   */
+    3403             :   template<typename T>
+    3404             :   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) {
+    3405             :     unsigned i;
+    3406             :     for(i=0; i<5; i++) if(shape[i]==0) break;
+    3407             :     if(i==5) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    3408             :     SafePtr s(val,0,shape);
+    3409             :     cmd_priv(p,key,s,error);
+    3410             :   }
+    3411             : 
+    3412             : 
+    3413             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3414             :   /**
+    3415             :     \related Plumed
+    3416             :     This function can be used to make plumed_gcmd behave as the C++ wrapper PLMD::Plumed::gcmd,
+    3417             :     namely implement typechecks and rethrowing exception.
+    3418             :     To be used through the macro plumed_gcmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3419             :     Available as of PLUMED 2.8.
+    3420             :   */
+    3421             : 
+    3422             :   /**
+    3423             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3424             :     namely implement typechecks and rethrowing exception.
+    3425             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3426             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3427             :     Available as of PLUMED 2.8.
+    3428             :   */
+    3429             :   static void plumed_gcmd_cxx(const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3430             :     plumed_cmd_cxx(plumed_global(),key,error);
+    3431             :   }
+    3432             : 
+    3433             :   /**
+    3434             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3435             :     namely implement typechecks and rethrowing exception.
+    3436             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3437             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3438             :     Available as of PLUMED 2.8.
+    3439             :   */
+    3440             :   template<typename T>
+    3441             :   static void plumed_gcmd_cxx(const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3442             :     plumed_cmd_cxx(plumed_global(),key,val,error);
+    3443             :   }
+    3444             : 
+    3445             :   /**
+    3446             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3447             :     namely implement typechecks and rethrowing exception.
+    3448             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3449             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3450             :     Available as of PLUMED 2.8.
+    3451             :   */
+    3452             :   template<typename T>
+    3453             :   static void plumed_gcmd_cxx(const char*key,T val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3454             :     plumed_cmd_cxx(plumed_global(),key,val,nelem,error);
+    3455             :   }
+    3456             : 
+    3457             :   /**
+    3458             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3459             :     namely implement typechecks and rethrowing exception.
+    3460             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3461             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3462             :     Available as of PLUMED 2.8.
+    3463             :   */
+    3464             :   template<typename T>
+    3465             :   static void plumed_gcmd_cxx(const char*key,T val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3466             :     unsigned i;
+    3467             :     for(i=0; i<5; i++) if(shape[i]==0) break;
+    3468             :     if(i==5) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    3469             :     plumed_cmd_cxx(plumed_global(),key,val,shape,error);
+    3470             :   }
+    3471             : 
+    3472             : #endif /*}*/
+    3473             : 
+    3474             : #if __PLUMED_WRAPPER_CXX_BIND_C /*{*/
+    3475             : 
+    3476             : #define __PLUMED_WRAPPER_REDEFINE_CMD ::PLMD::Plumed::plumed_cmd_cxx
+    3477             : 
+    3478             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3479             : #define __PLUMED_WRAPPER_REDEFINE_GCMD ::PLMD::Plumed::plumed_gcmd_cxx
+    3480             : #endif /*}*/
+    3481             : 
+    3482             : #define __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW ::PLMD::Plumed::plumed_error_rethrow_cxx
+    3483             : 
+    3484             : #endif /*}*/
+    3485             : 
+    3486             : };
+    3487             : 
+    3488             : /**
+    3489             :   \related Plumed
+    3490             :   Comparison operator. Available as of PLUMED 2.5.
+    3491             : */
+    3492             : inline
+    3493             : bool operator==(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3494             :   return a.toVoid()==b.toVoid();
+    3495             : }
+    3496             : 
+    3497             : /**
+    3498             :   \related Plumed
+    3499             :   Comparison operator. Available as of PLUMED 2.5.
+    3500             : */
+    3501             : inline
+    3502             : bool operator!=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3503             :   return a.toVoid()!=b.toVoid();
+    3504             : }
+    3505             : 
+    3506             : /**
+    3507             :   \related Plumed
+    3508             :   Comparison operator. Available as of PLUMED 2.5.
+    3509             : */
+    3510             : inline
+    3511             : bool operator<=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3512             :   return a.toVoid()<=b.toVoid();
+    3513             : }
+    3514             : 
+    3515             : /**
+    3516             :   \related Plumed
+    3517             :   Comparison operator. Available as of PLUMED 2.5.
+    3518             : */
+    3519             : inline
+    3520             : bool operator<(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3521             :   return a.toVoid()<b.toVoid();
+    3522             : }
+    3523             : 
+    3524             : /**
+    3525             :   \related Plumed
+    3526             :   Comparison operator. Available as of PLUMED 2.5.
+    3527             : */
+    3528             : inline
+    3529             : bool operator>=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3530             :   return a.toVoid()>=b.toVoid();
+    3531             : }
+    3532             : 
+    3533             : /**
+    3534             :   \related Plumed
+    3535             :   Comparison operator. Available as of PLUMED 2.5.
+    3536             : */
+    3537             : inline
+    3538             : bool operator>(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3539             :   return a.toVoid()>b.toVoid();
+    3540             : }
+    3541             : 
+    3542             : __PLUMED_WRAPPER_ANONYMOUS_END /*}*/
+    3543             : 
+    3544             : }
+    3545             : 
+    3546             : #endif /*}*/
+    3547             : 
+    3548             : #endif /*}*/
+    3549             : 
+    3550             : /* END OF DECLARATIONS */
+    3551             : 
+    3552             : /*
+    3553             : 
+    3554             :   1: emit implementation
+    3555             :   0: do not emit implementation
+    3556             : 
+    3557             :   Allows an implementation to be emitted together with the declarations.
+    3558             : 
+    3559             :   Used to decide if definitions should be emitted. This macro could have a different
+    3560             :   value when Plumed.h is reincluded. As a consequence, we map it to a local
+    3561             :   macro (__PLUMED_WRAPPER_IMPLEMENTATION_) that is reset at the end of this file.
+    3562             : */
+    3563             : 
+    3564             : #ifdef __PLUMED_WRAPPER_IMPLEMENTATION
+    3565             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ __PLUMED_WRAPPER_IMPLEMENTATION
+    3566             : #else
+    3567             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ 0
+    3568             : #endif
+    3569             : 
+    3570             : /* BEGINNING OF DEFINITIONS */
+    3571             : 
+    3572             : #if __PLUMED_WRAPPER_IMPLEMENTATION_  /*{*/
+    3573             : #ifndef __PLUMED_wrapper_Plumed_implementation /*{*/
+    3574             : #define __PLUMED_wrapper_Plumed_implementation
+    3575             : 
+    3576             : /*
+    3577             :   the following macros only control the implementation
+    3578             : */
+    3579             : 
+    3580             : /*
+    3581             :   1: enable the definition of plumed_symbol_table_reexport
+    3582             :   0: does not enable the definition of plumed_symbol_table_reexport
+    3583             : 
+    3584             :   This is only needed in the official plumed library to make
+    3585             :   the symbol table available. This is a hack to reexport the function table
+    3586             :   and is only needed when creating the library libplumed.so.
+    3587             : */
+    3588             : 
+    3589             : #ifndef __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3590             : #define __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE 0
+    3591             : #endif
+    3592             : 
+    3593             : /*
+    3594             :   1: write on stderr changes in reference counters
+    3595             :   0: do not write changes in reference counters
+    3596             : 
+    3597             :   Used for debugging.
+    3598             : 
+    3599             :   Only used in definitions.
+    3600             : */
+    3601             : 
+    3602             : #ifndef __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3603             : #define __PLUMED_WRAPPER_DEBUG_REFCOUNT 0
+    3604             : #endif
+    3605             : 
+    3606             : /*
+    3607             :   1: emit plumed_kernel_register function (default)
+    3608             :   0: do not emit plumed_kernel_register function
+    3609             : 
+    3610             :   This function is only needed to avoid an extra warning when loading old (<=2.4) kernels.
+    3611             :   We might change its default in the future.
+    3612             : 
+    3613             :   Used only in definitions.
+    3614             : */
+    3615             : 
+    3616             : #ifndef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3617             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 1
+    3618             : #endif
+    3619             : 
+    3620             : /*
+    3621             :   1: emit Fortran wrappers
+    3622             :   0: do not emit Fortran wrappers (default)
+    3623             : 
+    3624             :   Used only in definitions.
+    3625             : */
+    3626             : 
+    3627             : #ifndef __PLUMED_WRAPPER_FORTRAN
+    3628             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3629             : #endif
+    3630             : 
+    3631             : /*
+    3632             :   With internal interface, it does not make sense to emit kernel register or fortran interfaces
+    3633             : */
+    3634             : 
+    3635             : #if ! __PLUMED_WRAPPER_EXTERN /*{*/
+    3636             : #undef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3637             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 0
+    3638             : #undef __PLUMED_WRAPPER_FORTRAN
+    3639             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3640             : #endif /*}*/
+    3641             : 
+    3642             : #ifdef __PLUMED_HAS_DLOPEN
+    3643             : #include <dlfcn.h> /* dlopen dlerror dlsym */
+    3644             : #endif
+    3645             : 
+    3646             : #if __PLUMED_WRAPPER_CXX_STD
+    3647             : #include <cstdio>  /* fprintf */
+    3648             : #include <cstring> /* memcpy strlen strncpy memcmp memmove strcmp memcpy */
+    3649             : #include <cassert> /* assert */
+    3650             : #include <cstdlib> /* getenv malloc free abort */
+    3651             : #include <climits> /* CHAR_BIT */
+    3652             : #else
+    3653             : #include <stdio.h>
+    3654             : #include <string.h>
+    3655             : #include <assert.h>
+    3656             : #include <stdlib.h>
+    3657             : #include <limits.h>
+    3658             : #endif
+    3659             : 
+    3660             : /**
+    3661             :   Function pointer to plumed_create
+    3662             : */
+    3663             : 
+    3664             : typedef void*(*plumed_create_pointer)(void);
+    3665             : /**
+    3666             :   Function pointer to plumed_cmd
+    3667             : */
+    3668             : typedef void(*plumed_cmd_pointer)(void*,const char*,const void*);
+    3669             : 
+    3670             : /**
+    3671             :   Function pointer to plumed_finalize
+    3672             : */
+    3673             : typedef void(*plumed_finalize_pointer)(void*);
+    3674             : 
+    3675             : /**
+    3676             :    Holder for plumedmain function pointers.
+    3677             : */
+    3678             : typedef struct {
+    3679             :   plumed_create_pointer create;
+    3680             :   plumed_cmd_pointer cmd;
+    3681             :   plumed_finalize_pointer finalize;
+    3682             : } plumed_plumedmain_function_holder;
+    3683             : 
+    3684             : /**
+    3685             :   Holder for plumed symbol table.
+    3686             : 
+    3687             :   The table contains pointers to function exported from plumed. Functions can be added increasing the version number.
+    3688             :   Notice that the default way to extend functionalities is by adding cmd strings. This is a last resort, and all new
+    3689             :   functions should be explicitly motivated. Here's the addition:
+    3690             : 
+    3691             :   version=2, cmd_nothrow.
+    3692             : 
+    3693             :   This function accepts an extra argument `plumed_nothrow_handler*handler`.
+    3694             :   In case an exception is thrown within plumed, it just calls `handler->handler(handler->ptr,code,message,opt)` and return.
+    3695             :   An alternative would have been to install an error handler (with a call to cmd("setErrorHandler")). However, the cost
+    3696             :   of doing it everytime Plumed::cmd is called is too high. On the other hand, installing it only at object construction
+    3697             :   is very risky since and object created in that way would not report any error if manipulated from the C interface.
+    3698             :   So, it looks like this is the only possibility.
+    3699             : 
+    3700             :   version=3, cmd_safe and cmd_safe_nothrow
+    3701             : 
+    3702             :   These are functions that accept a plumed_safeptr object, which can carry information about the passed type and size.
+    3703             :   Since new information should be passed at every cmd call, this can only be obtained by adding new cmd calls.
+    3704             : 
+    3705             :   version=4, thread-safe reference counter
+    3706             : 
+    3707             :   These functions allow to access a thread-safe reference counter that is stored within the PlumedMain object.
+    3708             :   This allows avoiding to enable atomic access also the C compiler used build Plumed.c. It's added here and not as a new
+    3709             :   cmd since this is a very low-level functionality.
+    3710             : */
+    3711             : typedef struct {
+    3712             :   /**
+    3713             :     Version number.
+    3714             : 
+    3715             :     Minimum value is 1.
+    3716             :   */
+    3717             :   int version;
+    3718             :   /**
+    3719             :     Pointers to standard plumed functions (create/cmd/finalize).
+    3720             : 
+    3721             :     Always available.
+    3722             :   */
+    3723             :   plumed_plumedmain_function_holder functions;
+    3724             :   /**
+    3725             :     Pointer to a cmd function guaranteed not to throw exceptions.
+    3726             : 
+    3727             :     Available with version>=2.
+    3728             :   */
+    3729             :   void (*cmd_nothrow)(void*plumed,const char*key,const void*val,plumed_nothrow_handler);
+    3730             :   /**
+    3731             :     Pointer to a cmd function that accepts typeinfos.
+    3732             : 
+    3733             :     Available with version>=3.
+    3734             :   */
+    3735             :   void (*cmd_safe)(void*plumed,const char*key,plumed_safeptr);
+    3736             : 
+    3737             :   /**
+    3738             :     Pointer to a cmd function guaranteed not to throw exceptions and that accepts typeinfos.
+    3739             : 
+    3740             :     Available with version>=3.
+    3741             :   */
+    3742             :   void (*cmd_safe_nothrow)(void*plumed,const char*key,plumed_safeptr,plumed_nothrow_handler);
+    3743             : 
+    3744             :   /**
+    3745             :     Pointer to a function that increments the internal reference counter.
+    3746             : 
+    3747             :     Available with version>=4.
+    3748             :   */
+    3749             :   unsigned (*create_reference)(void*);
+    3750             :   /**
+    3751             :     Pointer to a function that decrements the internal reference counter.
+    3752             : 
+    3753             :     Available with version>=4.
+    3754             :   */
+    3755             :   unsigned (*delete_reference)(void*);
+    3756             :   /**
+    3757             :     Pointer to a function that returns the internal reference counter.
+    3758             : 
+    3759             :     Available with version>=4.
+    3760             :   */
+    3761             :   unsigned (*use_count)(void*);
+    3762             : } plumed_symbol_table_type;
+    3763             : 
+    3764             : /* Utility to convert function pointers to pointers, just for the sake of printing them */
+    3765             : #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))); }
+    3766             : 
+    3767             : #define __PLUMED_GETENV __PLUMED_WRAPPER_STD getenv
+    3768             : #define __PLUMED_FPRINTF __PLUMED_WRAPPER_STD fprintf
+    3769             : 
+    3770             : /**
+    3771             :   Historically (PLUMED<=2.4) register for plumedmain function pointers.
+    3772             :   As of PLUMED>=2.5, this function does not do anything except for reporting the attempt to register
+    3773             :   something. It always returns NULL. The function should be here anyway to allow an incomplete
+    3774             :   libplumedKernel (<=2.4), expecting this function to be present, to be loaded correctly.
+    3775             : */
+    3776             : #if __PLUMED_WRAPPER_KERNEL_REGISTER
+    3777             : /* Since it is only called from outside, it must be hardcoded to be extern */
+    3778             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    3779             : extern plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder*);
+    3780          26 : plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder* f) {
+    3781             :   void* tmpptr;
+    3782          26 :   if(f) {
+    3783          26 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
+    3784           0 :       __PLUMED_FPRINTF(stderr,"+++ Ignoring registration at %p (",__PLUMED_WRAPPER_STATIC_CAST(const void*,f));
+    3785             :       __PLUMED_CONVERT_FPTR(tmpptr,f->create);
+    3786           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3787             :       __PLUMED_CONVERT_FPTR(tmpptr,f->cmd);
+    3788           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3789             :       __PLUMED_CONVERT_FPTR(tmpptr,f->finalize);
+    3790           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3791             :     }
+    3792             :   }
+    3793          26 :   return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3794             : }
+    3795             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    3796             : #endif
+    3797             : 
+    3798             : #if defined( __PLUMED_HAS_DLOPEN) /*{*/
+    3799             : /**
+    3800             : Try to dlopen a path with a given mode.
+    3801             : If the dlopen command fails, it tries to strip the `Kernel` part of the name.
+    3802             : 
+    3803             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3804             : It is first declared then defined to make sure it is a regular C static function.
+    3805             : */
+    3806             : 
+    3807             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3808           9 : void* plumed_attempt_dlopen(const char*path,int mode) {
+    3809             :   char* pathcopy;
+    3810             :   void* p;
+    3811             :   char* pc;
+    3812             :   __PLUMED_WRAPPER_STD size_t strlenpath;
+    3813             :   pathcopy=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3814             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3815             :   pc=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3816             :   strlenpath=0;
+    3817           9 :   dlerror();
+    3818           9 :   p=dlopen(path,mode);
+    3819           9 :   if(!p) {
+    3820             :     /*
+    3821             :       Something went wrong. We try to remove "Kernel" string from the PLUMED_KERNEL variable
+    3822             :       and load directly the shared library. Notice that this particular path is only expected
+    3823             :       to be necessary when using PLUMED<=2.4 and the symbols in the main executable are
+    3824             :       not visible. All the other cases (either PLUMED>=2.5 or symbols in the main executable visible)
+    3825             :       should work correctly without entering here.
+    3826             :     */
+    3827           0 :     __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3828           0 :     strlenpath=__PLUMED_WRAPPER_STD strlen(path);
+    3829           0 :     pathcopy=__PLUMED_WRAPPER_STATIC_CAST(char*, plumed_malloc(strlenpath+1));
+    3830           0 :     if(!pathcopy) {
+    3831           0 :       __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3832           0 :       __PLUMED_WRAPPER_STD abort();
+    3833             :     }
+    3834             :     __PLUMED_WRAPPER_STD memcpy(pathcopy,path,strlenpath+1);
+    3835           0 :     pc=pathcopy+strlenpath-6;
+    3836           0 :     while(pc>=pathcopy && __PLUMED_WRAPPER_STD memcmp(pc,"Kernel",6)) pc--;
+    3837           0 :     if(pc>=pathcopy) {
+    3838           0 :       __PLUMED_WRAPPER_STD memmove(pc, pc+6, __PLUMED_WRAPPER_STD strlen(pc)-5);
+    3839           0 :       __PLUMED_FPRINTF(stderr,"+++ This error is expected if you are trying to load a kernel <=2.4\n");
+    3840           0 :       __PLUMED_FPRINTF(stderr,"+++ Trying %s +++\n",pathcopy);
+    3841           0 :       dlerror();
+    3842           0 :       p=dlopen(pathcopy,mode);
+    3843           0 :       if(!p) __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3844             :     }
+    3845           0 :     plumed_free(pathcopy);
+    3846             :   }
+    3847           9 :   return p;
+    3848             : }
+    3849             : __PLUMED_WRAPPER_INTERNALS_END
+    3850             : 
+    3851             : /**
+    3852             :   Utility to search for a function.
+    3853             : */
+    3854             : #ifdef __cplusplus
+    3855             : #define __PLUMED_WRAPPER_SEARCHF_CAST(functype,func,tmpptr) func=reinterpret_cast<functype>(tmpptr)
+    3856             : #else
+    3857             : #define __PLUMED_WRAPPER_SEARCHF_CAST(functype,func,tmpptr)  *(void **)&func=tmpptr
+    3858             : #endif
+    3859             : #define __PLUMED_SEARCH_FUNCTION(functype,tmpptr,handle,func,name,debug) \
+    3860             :   if(!func) { \
+    3861             :     tmpptr=dlsym(handle,name); \
+    3862             :     if(tmpptr) { \
+    3863             :       __PLUMED_WRAPPER_SEARCHF_CAST(functype,func,tmpptr); \
+    3864             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ %s found at %p +++\n",name,tmpptr); \
+    3865             :     } else { \
+    3866             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ Function %s not found\n",name); \
+    3867             :     } \
+    3868             :   }
+    3869             : 
+    3870             : /**
+    3871             : Search symbols in a dlopened library.
+    3872             : 
+    3873             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3874             : */
+    3875             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3876           9 : void plumed_search_symbols(void* handle, plumed_plumedmain_function_holder* f,plumed_symbol_table_type** table) {
+    3877             :   plumed_plumedmain_function_holder functions;
+    3878             :   plumed_symbol_table_type* table_ptr;
+    3879             :   void* tmpptr;
+    3880             :   char* debug;
+    3881             :   functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3882             :   functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3883             :   functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3884             :   table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3885           9 :   tmpptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3886             :   /*
+    3887             :     Notice that as of PLUMED 2.5 we ignore self registrations.
+    3888             :     Pointers are searched in the form of a single pointer to a structure, which
+    3889             :     is the standard way in PLUMED 2.5, as well as using alternative names used in
+    3890             :     PLUMED 2.0 to 2.4 (e.g. plumedmain_create) and in some intermediate versions between
+    3891             :     PLUMED 2.4 and 2.5 (e.g. plumed_plumedmain_create). The last chance is probably
+    3892             :     unnecessary and might be removed at some point.
+    3893             :   */
+    3894           9 :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3895           9 :   table_ptr=__PLUMED_WRAPPER_STATIC_CAST(plumed_symbol_table_type*, dlsym(handle,"plumed_symbol_table"));
+    3896           9 :   if(table_ptr) functions=table_ptr->functions;
+    3897           9 :   if(debug) {
+    3898           0 :     if(table_ptr) {
+    3899           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table version %i found at %p +++\n",table_ptr->version,__PLUMED_WRAPPER_STATIC_CAST(void*,table_ptr));
+    3900           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_function_pointers found at %p (",__PLUMED_WRAPPER_STATIC_CAST(void*,&table_ptr->functions));
+    3901             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.create);
+    3902           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3903             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.cmd);
+    3904           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3905             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.finalize);
+    3906           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3907             :     } else {
+    3908           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table (available in PLUMED>=2.5) not found, perhaps kernel is older +++\n");
+    3909             :     }
+    3910             :   }
+    3911             :   /* only searches if they were not found already */
+    3912           9 :   __PLUMED_SEARCH_FUNCTION(plumed_create_pointer,tmpptr,handle,functions.create,"plumedmain_create",debug);
+    3913           9 :   __PLUMED_SEARCH_FUNCTION(plumed_create_pointer,tmpptr,handle,functions.create,"plumed_plumedmain_create",debug);
+    3914           9 :   __PLUMED_SEARCH_FUNCTION(plumed_cmd_pointer,tmpptr,handle,functions.cmd,"plumedmain_cmd",debug);
+    3915           9 :   __PLUMED_SEARCH_FUNCTION(plumed_cmd_pointer,tmpptr,handle,functions.cmd,"plumed_plumedmain_cmd",debug);
+    3916           9 :   __PLUMED_SEARCH_FUNCTION(plumed_finalize_pointer,tmpptr,handle,functions.finalize,"plumedmain_finalize",debug);
+    3917           9 :   __PLUMED_SEARCH_FUNCTION(plumed_finalize_pointer,tmpptr,handle,functions.finalize,"plumed_plumedmain_finalize",debug);
+    3918           9 :   if(functions.create && functions.cmd && functions.finalize) {
+    3919           9 :     if(debug) __PLUMED_FPRINTF(stderr,"+++ PLUMED was loaded correctly +++\n");
+    3920           9 :     *f=functions;
+    3921           9 :     if(table) *table=table_ptr;
+    3922             :   } else {
+    3923           0 :     if(!functions.create) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_create not found +++\n");
+    3924           0 :     if(!functions.cmd) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_cmd not found +++\n");
+    3925           0 :     if(!functions.finalize) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_finalize not found +++\n");
+    3926           0 :     f->create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3927           0 :     f->cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3928           0 :     f->finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3929           0 :     if(table) *table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3930             :   }
+    3931           9 : }
+    3932             : __PLUMED_WRAPPER_INTERNALS_END
+    3933             : 
+    3934             : #endif /*}*/
+    3935             : 
+    3936             : 
+    3937             : #if __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3938             : 
+    3939             : /*
+    3940             :   Here is the case where plumed_symbol_table is
+    3941             :   visible as extern. We first declare it (together with plumed_symbol_table_init) ...
+    3942             : */
+    3943             : 
+    3944             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3945             : extern
+    3946             : plumed_symbol_table_type plumed_symbol_table;
+    3947             : __PLUMED_WRAPPER_EXTERN_C_END
+    3948             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3949             : extern
+    3950             : void plumed_symbol_table_init(void);
+    3951             : __PLUMED_WRAPPER_EXTERN_C_END
+    3952             : 
+    3953             : /*
+    3954             :   ... and then make available a function that returns the address
+    3955             :   of the symbol table.
+    3956             : */
+    3957             : __PLUMED_WRAPPER_C_BEGIN
+    3958      703210 : plumed_symbol_table_type* plumed_symbol_table_reexport() {
+    3959             :   /* make sure the table is initialized */
+    3960      703210 :   plumed_symbol_table_init();
+    3961      728269 :   return &plumed_symbol_table;
+    3962             : }
+    3963             : __PLUMED_WRAPPER_C_END
+    3964             : 
+    3965             : #else
+    3966             : 
+    3967             : /*
+    3968             :   Here is the case where plumed_symbol_table is not
+    3969             :   visible as extern. We thus assume that plumed_symbol_table_reexport is
+    3970             :   available.
+    3971             : */
+    3972             : 
+    3973             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3974             : extern plumed_symbol_table_type* plumed_symbol_table_reexport();
+    3975             : __PLUMED_WRAPPER_EXTERN_C_END
+    3976             : #endif
+    3977             : 
+    3978             : 
+    3979             : /*
+    3980             :   Returns the global pointers, either those available at link time or those
+    3981             :   found in the library loaded at PLUMED_KERNEL env var.
+    3982             :   If plumed_symbol_table_ptr is not NULL, it is used to return a pointer to the symbol table
+    3983             :   (if available).
+    3984             :   Notice that problems can be detected checking if the functions have a NULL ptr.
+    3985             :   On the other hand, the symbol table pointer might be NULL just because the plumed version is <=2.4.
+    3986             :   If handle is not NULL, it is used to return a dlopen handle that could be subsequently dlclosed.
+    3987             : */
+    3988             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3989      704190 : void plumed_retrieve_functions(plumed_plumedmain_function_holder* functions, plumed_symbol_table_type** plumed_symbol_table_ptr,void** handle) {
+    3990             : #if ! __PLUMED_WRAPPER_LINK_RUNTIME
+    3991             :   /*
+    3992             :     Real interface, constructed using the symbol table obtained with plumed_symbol_table_reexport.
+    3993             :     This makes the symbols hardcoded and independent of a mis-set PLUMED_KERNEL variable.
+    3994             :   */
+    3995      704190 :   plumed_symbol_table_type* ptr=plumed_symbol_table_reexport();
+    3996      730276 :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=ptr;
+    3997      730276 :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3998      730276 :   if(functions) *functions=ptr->functions;
+    3999             : #elif ! defined(__PLUMED_HAS_DLOPEN)
+    4000             :   /*
+    4001             :     When dlopen is not available, we hard code them to NULL
+    4002             :   */
+    4003             :   __PLUMED_FPRINTF(stderr,"+++ PLUMED has been compiled without dlopen and without a static kernel +++\n");
+    4004             :   plumed_plumedmain_function_holder g= {__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR};
+    4005             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4006             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4007             :   if(functions) *functions=g;
+    4008             : #else
+    4009             :   /*
+    4010             :     On the other hand, for runtime binding, we use dlsym to find the relevant functions.
+    4011             :   */
+    4012             :   plumed_plumedmain_function_holder g;
+    4013             :   /* search is done once and only once */
+    4014             :   const char* path;
+    4015             :   void* p;
+    4016             :   char* debug;
+    4017             :   int dlopenmode;
+    4018             :   g.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4019             :   g.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4020             :   g.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4021             :   path=__PLUMED_GETENV("PLUMED_KERNEL");
+    4022             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4023             :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    4024             :   dlopenmode=0;
+    4025             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4026             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4027             : #ifdef __PLUMED_DEFAULT_KERNEL
+    4028             :   /*
+    4029             :     This variable allows a default path for the kernel to be hardcoded.
+    4030             :     Can be useful for hardcoding the predefined plumed location
+    4031             :     still allowing the user to override this choice setting PLUMED_KERNEL.
+    4032             :     The path should be chosen at compile time adding e.g.
+    4033             :     -D__PLUMED_DEFAULT_KERNEL=/opt/local/lib/libplumed.dylib
+    4034             :   */
+    4035             :   /* This is required to add quotes */
+    4036             : #define PLUMED_QUOTE_DIRECT(name) #name
+    4037             : #define PLUMED_QUOTE(macro) PLUMED_QUOTE_DIRECT(macro)
+    4038             :   if(! (path && (*path) )) path=PLUMED_QUOTE(__PLUMED_DEFAULT_KERNEL);
+    4039             : #endif
+    4040             : #if defined(__PLUMED_PROGRAM_NAME) && defined(__PLUMED_SOEXT)
+    4041             :   if(! (path && (*path) )) path="lib" __PLUMED_PROGRAM_NAME "Kernel." __PLUMED_SOEXT;
+    4042             : #endif
+    4043             :   if(path && (*path)) {
+    4044             :     __PLUMED_FPRINTF(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
+    4045             :     __PLUMED_FPRINTF(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
+    4046             :     if(debug) __PLUMED_FPRINTF(stderr,"+++ Loading with mode RTLD_NOW");
+    4047             :     dlopenmode=RTLD_NOW;
+    4048             :     if(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE"),"GLOBAL")) {
+    4049             :       dlopenmode=dlopenmode|RTLD_GLOBAL;
+    4050             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_GLOBAL");
+    4051             :     } else {
+    4052             :       dlopenmode=dlopenmode|RTLD_LOCAL;
+    4053             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_LOCAL");
+    4054             :     }
+    4055             : #ifdef RTLD_DEEPBIND
+    4056             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    4057             :     if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
+    4058             :       dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    4059             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_DEEPBIND");
+    4060             :     }
+    4061             : #endif
+    4062             : #endif
+    4063             :     if(debug) __PLUMED_FPRINTF(stderr," +++\n");
+    4064             :     p=plumed_attempt_dlopen(path,dlopenmode);
+    4065             :     if(p) plumed_search_symbols(p,&g,plumed_symbol_table_ptr);
+    4066             :   }
+    4067             :   if(handle) *handle=p;
+    4068             :   if(functions) *functions=g;
+    4069             : #endif
+    4070      730276 : }
+    4071             : __PLUMED_WRAPPER_INTERNALS_END
+    4072             : 
+    4073             : /**
+    4074             :   Implementation.
+    4075             :   Small object used to store pointers directly into the plumed object defined in Plumed.h.
+    4076             :   This allows avoiding the extra function call to plumed_retrieve_functions at every cmd,
+    4077             :   at the cost of an extra indirection.
+    4078             : */
+    4079             : typedef struct {
+    4080             :   /* allows errors with pointers to be found when debugging */
+    4081             :   char magic[6];
+    4082             :   /* reference count. this is only used with PLUMED<=2.8. Later versions have an internal thread-safe reference counter. */
+    4083             :   int refcount;
+    4084             :   /* handler to dlopened library. NULL if there was no library opened */
+    4085             :   void* dlhandle;
+    4086             :   /* non zero if, upon destruction, the library should be dlclosed */
+    4087             :   int dlclose;
+    4088             :   /* 1 if path to kernel was taken from PLUMED_KERNEL var, 0 otherwise */
+    4089             :   int used_plumed_kernel;
+    4090             :   /* function pointers */
+    4091             :   plumed_plumedmain_function_holder functions;
+    4092             :   /* pointer to the symbol table. NULL if kernel <=2.4 */
+    4093             :   plumed_symbol_table_type* table;
+    4094             :   /* pointer to plumed object */
+    4095             :   void* p;
+    4096             : } plumed_implementation;
+    4097             : 
+    4098             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    4099      722507 : plumed_implementation* plumed_malloc_pimpl() {
+    4100             :   plumed_implementation* pimpl;
+    4101             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    4102      722506 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, plumed_malloc(sizeof(plumed_implementation)));
+    4103      735970 :   if(!pimpl) {
+    4104           0 :     __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    4105           0 :     __PLUMED_WRAPPER_STD abort();
+    4106             :   }
+    4107             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4108      735970 :   __PLUMED_WRAPPER_STD memcpy(pimpl->magic,"pLuMEd",6);
+    4109             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4110      735970 :   pimpl->refcount=1;
+    4111             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4112             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4113             :   __PLUMED_FPRINTF(stderr,"refcount: new at %p\n",__PLUMED_WRAPPER_STATIC_CAST(void*,pimpl));
+    4114             : #endif
+    4115             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4116      735970 :   pimpl->dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4117             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4118      735970 :   pimpl->dlclose=0;
+    4119             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4120      735970 :   pimpl->used_plumed_kernel=0;
+    4121             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4122      735970 :   pimpl->functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4123             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4124      735970 :   pimpl->functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4125             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4126      735970 :   pimpl->functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4127             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4128      735970 :   pimpl->table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4129             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    4130      735970 :   pimpl->p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4131      735970 :   return pimpl;
+    4132             : }
+    4133             : __PLUMED_WRAPPER_INTERNALS_END
+    4134             : 
+    4135             : #ifndef NDEBUG
+    4136             : 
+    4137             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    4138             : int plumed_check_pimpl(plumed_implementation*pimpl) {
+    4139             :   if(!pimpl) return 0;
+    4140             :   if(__PLUMED_WRAPPER_STD memcmp(pimpl->magic,"pLuMEd",6)) return 0;
+    4141             :   return 1;
+    4142             : }
+    4143             : __PLUMED_WRAPPER_INTERNALS_END
+    4144             : #endif
+    4145             : 
+    4146             : /* C wrappers: */
+    4147             : 
+    4148             : __PLUMED_WRAPPER_C_BEGIN
+    4149      735712 : plumed plumed_create(void) {
+    4150             :   /* returned object */
+    4151             :   plumed p;
+    4152             :   /* pointer to implementation */
+    4153             :   plumed_implementation* pimpl;
+    4154             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    4155      735712 :   pimpl=plumed_malloc_pimpl();
+    4156             :   /* store pointers in pimpl */
+    4157      732233 :   plumed_retrieve_functions(&pimpl->functions,&pimpl->table,&pimpl->dlhandle);
+    4158             : #if __PLUMED_WRAPPER_LINK_RUNTIME
+    4159             :   /* note if PLUMED_KERNEL variable was used */
+    4160             :   pimpl->used_plumed_kernel=1;
+    4161             : #endif
+    4162             :   /* note if handle should not be dlclosed */
+    4163      754264 :   pimpl->dlclose=1;
+    4164      754264 :   if(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE"),"no")) pimpl->dlclose=0;
+    4165             :   /* in case of failure, return */
+    4166             :   /* the resulting object should be plumed_finalized, though you cannot use plumed_cmd */
+    4167      792837 :   if(!pimpl->functions.create) {
+    4168             :     /* store pimpl in returned object */
+    4169             :     p.p=pimpl;
+    4170           0 :     return p;
+    4171             :   }
+    4172             :   assert(pimpl->functions.cmd);
+    4173             :   assert(pimpl->functions.finalize);
+    4174             :   /* obtain object */
+    4175      792837 :   pimpl->p=(*(pimpl->functions.create))();
+    4176             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    4177             :   /* user might identify this using plumed_valid() */
+    4178             :   /* store pimpl in returned object */
+    4179             :   p.p=pimpl;
+    4180      789225 :   return p;
+    4181             : }
+    4182             : __PLUMED_WRAPPER_C_END
+    4183             : 
+    4184             : __PLUMED_WRAPPER_C_BEGIN
+    4185           9 : plumed plumed_create_dlopen(const char*path) {
+    4186             :   int dlopenmode;
+    4187             :   /* plumed_create_dlopen always uses RTLD_LOCAL and, when possible, RTLD_DEEPBIND to allow multiple versions */
+    4188             : #ifdef __PLUMED_HAS_DLOPEN
+    4189             :   dlopenmode=RTLD_NOW|RTLD_LOCAL;
+    4190             : #ifdef RTLD_DEEPBIND
+    4191             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    4192           9 :   if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    4193             : #endif
+    4194             : #endif
+    4195             : #else
+    4196             :   dlopenmode=0;
+    4197             : #endif
+    4198           9 :   return plumed_create_dlopen2(path,dlopenmode);
+    4199             : }
+    4200             : __PLUMED_WRAPPER_C_END
+    4201             : 
+    4202             : __PLUMED_WRAPPER_C_BEGIN
+    4203           9 : plumed plumed_create_dlsym(void* dlhandle) {
+    4204             :   /* returned object */
+    4205             :   plumed p;
+    4206             :   /* pointer to implementation */
+    4207             :   plumed_implementation* pimpl;
+    4208             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    4209           9 :   pimpl=plumed_malloc_pimpl();
+    4210             : #ifdef __PLUMED_HAS_DLOPEN
+    4211           9 :   pimpl->dlhandle=dlhandle;
+    4212           9 :   plumed_search_symbols(pimpl->dlhandle,&pimpl->functions,&pimpl->table);
+    4213             : #endif
+    4214           9 :   if(!pimpl->functions.create) {
+    4215             :     p.p=pimpl;
+    4216           0 :     return p;
+    4217             :   }
+    4218             :   assert(pimpl->functions.cmd);
+    4219             :   assert(pimpl->functions.finalize);
+    4220             :   /* obtain object */
+    4221           9 :   pimpl->p=(*(pimpl->functions.create))();
+    4222             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    4223             :   /* user might identify this using plumed_valid() */
+    4224             :   /* store pimpl in returned object */
+    4225             :   p.p=pimpl;
+    4226           9 :   return p;
+    4227             : }
+    4228             : __PLUMED_WRAPPER_C_END
+    4229             : 
+    4230             : __PLUMED_WRAPPER_C_BEGIN
+    4231           9 : plumed plumed_create_dlopen2(const char*path,int mode) {
+    4232             : #ifdef __PLUMED_HAS_DLOPEN
+    4233             :   /* returned object */
+    4234             :   plumed p;
+    4235             :   /* pointer to implementation */
+    4236             :   plumed_implementation* pimpl;
+    4237             :   /* handler */
+    4238             :   void* dlhandle;
+    4239             :   dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4240           9 :   if(path) dlhandle=plumed_attempt_dlopen(path,mode);
+    4241             :   /* a NULL handle implies the file could not be loaded */
+    4242           9 :   if(dlhandle) {
+    4243           9 :     p=plumed_create_dlsym(dlhandle);
+    4244             :     /* obtain pimpl */
+    4245           9 :     pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4246             :     /* make sure the handler is closed when plumed is finalized */
+    4247           9 :     pimpl->dlclose=1;
+    4248           9 :     return p;
+    4249             :   }
+    4250             : #else
+    4251             :   (void) path;
+    4252             :   (void) mode;
+    4253             : #endif
+    4254           0 :   return plumed_create_invalid();
+    4255             : }
+    4256             : __PLUMED_WRAPPER_C_END
+    4257             : 
+    4258             : __PLUMED_WRAPPER_C_BEGIN
+    4259     7652264 : plumed plumed_create_reference(plumed p) {
+    4260             :   plumed_implementation* pimpl;
+    4261             :   /* obtain pimpl */
+    4262     7652264 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4263             :   assert(plumed_check_pimpl(pimpl));
+    4264             :   /* increase reference count */
+    4265             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    4266     7652264 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    4267     7607931 :     pimpl->table->create_reference(pimpl->p);
+    4268             :   } else {
+    4269       44333 :     pimpl->refcount++;
+    4270             :   }
+    4271             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4272             :   __PLUMED_FPRINTF(stderr,"refcount: increase at %p\n",__PLUMED_WRAPPER_STATIC_CAST(void*,pimpl));
+    4273             : #endif
+    4274     7611344 :   return p;
+    4275             : }
+    4276             : __PLUMED_WRAPPER_C_END
+    4277             : 
+    4278             : __PLUMED_WRAPPER_C_BEGIN
+    4279           2 : plumed plumed_create_reference_v(void*v) {
+    4280           2 :   return plumed_create_reference(plumed_v2c(v));
+    4281             : }
+    4282             : __PLUMED_WRAPPER_C_END
+    4283             : 
+    4284             : __PLUMED_WRAPPER_C_BEGIN
+    4285           8 : plumed plumed_create_reference_f(const char*f) {
+    4286           8 :   return plumed_create_reference(plumed_f2c(f));
+    4287             : }
+    4288             : __PLUMED_WRAPPER_C_END
+    4289             : 
+    4290             : __PLUMED_WRAPPER_C_BEGIN
+    4291           2 : plumed plumed_create_invalid() {
+    4292             :   plumed p;
+    4293             :   plumed_implementation* pimpl;
+    4294           2 :   pimpl=plumed_malloc_pimpl();
+    4295             :   p.p=pimpl;
+    4296           2 :   return p;
+    4297             : }
+    4298             : __PLUMED_WRAPPER_C_END
+    4299             : 
+    4300             : __PLUMED_WRAPPER_C_BEGIN
+    4301         357 : void plumed_cmd(plumed p,const char*key,const void*val) {
+    4302             :   plumed_implementation* pimpl;
+    4303             :   /* obtain pimpl */
+    4304         357 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4305             :   assert(plumed_check_pimpl(pimpl));
+    4306         357 :   if(!pimpl->p) {
+    4307           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    4308           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    4309           0 :     __PLUMED_WRAPPER_STD abort();
+    4310             :   }
+    4311             :   assert(pimpl->functions.create);
+    4312             :   assert(pimpl->functions.cmd);
+    4313             :   assert(pimpl->functions.finalize);
+    4314             :   /* execute */
+    4315         357 :   (*(pimpl->functions.cmd))(pimpl->p,key,val);
+    4316         357 : }
+    4317             : __PLUMED_WRAPPER_C_END
+    4318             : 
+    4319             : __PLUMED_WRAPPER_C_BEGIN
+    4320       19384 : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr safe,plumed_nothrow_handler nothrow) {
+    4321             :   plumed_implementation* pimpl;
+    4322             :   /* This is to allow caller to use a null handler to imply that handling is not done */
+    4323       19384 :   if(!nothrow.handler) {
+    4324          37 :     plumed_cmd_safe(p,key,safe);
+    4325          37 :     return;
+    4326             :   }
+    4327             :   /* obtain pimpl */
+    4328       19347 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4329             :   assert(plumed_check_pimpl(pimpl));
+    4330       19347 :   if(!pimpl->p) {
+    4331           0 :     if(pimpl->used_plumed_kernel) {
+    4332           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);
+    4333             :     } else {
+    4334           0 :       nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.",__PLUMED_WRAPPER_CXX_NULLPTR);
+    4335             :     }
+    4336           0 :     return;
+    4337             :   }
+    4338             :   assert(pimpl->functions.create);
+    4339             :   assert(pimpl->functions.cmd);
+    4340             :   assert(pimpl->functions.finalize);
+    4341             :   /* execute */
+    4342       19347 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe_nothrow))(pimpl->p,key,safe,nothrow);
+    4343           0 :   else if(pimpl->table && pimpl->table->version>1) (*(pimpl->table->cmd_nothrow))(pimpl->p,key,safe.ptr,nothrow);
+    4344           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    4345             : }
+    4346             : __PLUMED_WRAPPER_C_END
+    4347             : 
+    4348             : __PLUMED_WRAPPER_C_BEGIN
+    4349           0 : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow) {
+    4350             :   plumed_safeptr safe;
+    4351           0 :   safe.ptr=val;
+    4352           0 :   safe.flags=0;
+    4353           0 :   safe.nelem=0;
+    4354           0 :   safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4355           0 :   safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4356           0 :   plumed_cmd_safe_nothrow(p,key,safe,nothrow);
+    4357           0 : }
+    4358             : __PLUMED_WRAPPER_C_END
+    4359             : 
+    4360             : __PLUMED_WRAPPER_C_BEGIN
+    4361          95 : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr safe) {
+    4362             :   plumed_implementation* pimpl;
+    4363             :   /* obtain pimpl */
+    4364          95 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4365             :   assert(plumed_check_pimpl(pimpl));
+    4366          95 :   if(!pimpl->p) {
+    4367           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    4368           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    4369           0 :     __PLUMED_WRAPPER_STD abort();
+    4370             :   }
+    4371             :   assert(pimpl->functions.create);
+    4372             :   assert(pimpl->functions.cmd);
+    4373             :   assert(pimpl->functions.finalize);
+    4374             :   /* execute */
+    4375          95 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe))(pimpl->p,key,safe);
+    4376           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    4377          95 : }
+    4378             : __PLUMED_WRAPPER_C_END
+    4379             : 
+    4380             : 
+    4381             : __PLUMED_WRAPPER_C_BEGIN
+    4382     8492748 : void plumed_finalize(plumed p) {
+    4383             :   plumed_implementation* pimpl;
+    4384             :   /* obtain pimpl */
+    4385     8492748 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4386             :   assert(plumed_check_pimpl(pimpl));
+    4387             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4388             :   __PLUMED_FPRINTF(stderr,"refcount: decrease at %p\n",__PLUMED_WRAPPER_STATIC_CAST(void*,pimpl));
+    4389             : #endif
+    4390             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    4391     8492748 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    4392     8433442 :     if(pimpl->table->delete_reference(pimpl->p)>0) return;
+    4393             :   } else {
+    4394       59306 :     if(--pimpl->refcount>0) return;
+    4395             :   }
+    4396             :   /* to allow finalizing an invalid plumed object, we only call
+    4397             :      finalize if the object is valid */
+    4398      782666 :   if(pimpl->p) {
+    4399             :     assert(pimpl->functions.create);
+    4400             :     assert(pimpl->functions.cmd);
+    4401             :     assert(pimpl->functions.finalize);
+    4402             :     /* finalize */
+    4403      782664 :     (*(pimpl->functions.finalize))(pimpl->p);
+    4404             :   }
+    4405             : #ifdef __PLUMED_HAS_DLOPEN
+    4406             :   /* dlclose library */
+    4407      756640 :   if(pimpl->dlhandle && pimpl->dlclose) {
+    4408           9 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) __PLUMED_FPRINTF(stderr,"+++ Unloading library\n");
+    4409           9 :     dlclose(pimpl->dlhandle);
+    4410             :   }
+    4411             : #endif
+    4412             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4413             :   __PLUMED_FPRINTF(stderr,"refcount: delete at %p\n",__PLUMED_WRAPPER_STATIC_CAST(void*,pimpl));
+    4414             : #endif
+    4415             :   /* free pimpl space */
+    4416      756639 :   plumed_free(pimpl);
+    4417             : }
+    4418             : __PLUMED_WRAPPER_C_END
+    4419             : 
+    4420             : __PLUMED_WRAPPER_C_BEGIN
+    4421          23 : int plumed_valid(plumed p) {
+    4422             :   plumed_implementation* pimpl;
+    4423             :   /* obtain pimpl */
+    4424          23 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4425             :   assert(plumed_check_pimpl(pimpl));
+    4426          24 :   if(pimpl->p) return 1;
+    4427           2 :   else return 0;
+    4428             : }
+    4429             : __PLUMED_WRAPPER_C_END
+    4430             : 
+    4431             : __PLUMED_WRAPPER_C_BEGIN
+    4432          42 : int plumed_use_count(plumed p) {
+    4433             :   plumed_implementation* pimpl;
+    4434             :   /* obtain pimpl */
+    4435          42 :   pimpl=__PLUMED_WRAPPER_STATIC_CAST(plumed_implementation*, p.p);
+    4436             :   assert(plumed_check_pimpl(pimpl));
+    4437             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    4438          42 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    4439          42 :     return pimpl->table->use_count(pimpl->p);
+    4440             :   } else {
+    4441           0 :     return pimpl->refcount;
+    4442             :   }
+    4443             : }
+    4444             : __PLUMED_WRAPPER_C_END
+    4445             : 
+    4446             : __PLUMED_WRAPPER_C_BEGIN
+    4447           9 : int plumed_installed(void) {
+    4448             :   plumed p;
+    4449             :   int result;
+    4450           9 :   p=plumed_create();
+    4451           9 :   result=plumed_valid(p);
+    4452           9 :   plumed_finalize(p);
+    4453           9 :   return result;
+    4454             : }
+    4455             : __PLUMED_WRAPPER_C_END
+    4456             : 
+    4457             : __PLUMED_WRAPPER_C_BEGIN
+    4458      725149 : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size) {
+    4459             :   void* ptr;
+    4460      725150 :   ptr=__PLUMED_WRAPPER_STD malloc(size);
+    4461             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4462             :   if(ptr) fprintf(stderr,"plumed_malloc: %p\n",ptr);
+    4463             : #endif
+    4464      725149 :   return ptr;
+    4465             : }
+    4466             : __PLUMED_WRAPPER_C_END
+    4467             : 
+    4468             : __PLUMED_WRAPPER_C_BEGIN
+    4469      747367 : void plumed_free(void* ptr) {
+    4470      747368 :   __PLUMED_WRAPPER_STD free(ptr);
+    4471             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4472             :   fprintf(stderr,"plumed_free: %p\n",ptr);
+    4473             : #endif
+    4474      747368 : }
+    4475             : __PLUMED_WRAPPER_C_END
+    4476             : 
+    4477             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    4478             : 
+    4479             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    4480             : 
+    4481             : /* we declare a Plumed_g_main object here, in such a way that it is always available */
+    4482             : 
+    4483             : static plumed plumed_gmain= {__PLUMED_WRAPPER_CXX_NULLPTR};
+    4484             : 
+    4485         589 : plumed plumed_global(void) {
+    4486         589 :   return plumed_gmain;
+    4487             : }
+    4488             : 
+    4489          61 : void plumed_gcreate(void) {
+    4490             :   /* should be created once */
+    4491             :   assert(plumed_gmain.p==__PLUMED_WRAPPER_CXX_NULLPTR);
+    4492          61 :   plumed_gmain=plumed_create();
+    4493          61 : }
+    4494             : 
+    4495          78 : void plumed_gcmd(const char*key,const void*val) {
+    4496          78 :   plumed_cmd(plumed_gmain,key,val);
+    4497          78 : }
+    4498             : 
+    4499             : /* cppcheck-suppress passedByValue */
+    4500           0 : void plumed_gcmd_safe(const char*key,plumed_safeptr safe) {
+    4501           0 :   plumed_cmd_safe(plumed_gmain,key,safe);
+    4502           0 : }
+    4503             : 
+    4504          61 : void plumed_gfinalize(void) {
+    4505          61 :   plumed_finalize(plumed_gmain);
+    4506          61 :   plumed_gmain.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4507          61 : }
+    4508             : 
+    4509          24 : int plumed_ginitialized(void) {
+    4510          24 :   if(plumed_gmain.p) return 1;
+    4511          16 :   else        return 0;
+    4512             : }
+    4513             : 
+    4514           8 : int plumed_gvalid() {
+    4515             :   assert(plumed_gmain.p);
+    4516           8 :   return plumed_valid(plumed_gmain);
+    4517             : }
+    4518             : 
+    4519             : __PLUMED_WRAPPER_EXTERN_C_END
+    4520             : 
+    4521             : #endif /*}*/
+    4522             : 
+    4523             : __PLUMED_WRAPPER_C_BEGIN
+    4524          56 : void plumed_c2f(plumed p,char*c) {
+    4525             :   unsigned i;
+    4526             :   unsigned char* cc;
+    4527             :   /*
+    4528             :     Convert the address stored in p.p into a proper FORTRAN string
+    4529             :     made of only ASCII characters. For this to work, the two following
+    4530             :     assertions should be satisfied:
+    4531             :   */
+    4532             :   assert(CHAR_BIT<=12);
+    4533             :   assert(sizeof(p.p)<=16);
+    4534             : 
+    4535             :   assert(c);
+    4536             :   cc=__PLUMED_WRAPPER_REINTERPRET_CAST(unsigned char*,&p.p);
+    4537         504 :   for(i=0; i<sizeof(p.p); i++) {
+    4538             :     /*
+    4539             :       characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
+    4540             :     */
+    4541         448 :     c[2*i]=cc[i]/64+48;
+    4542         448 :     c[2*i+1]=cc[i]%64+48;
+    4543             :   }
+    4544         504 :   for(; i<16; i++) {
+    4545         448 :     c[2*i]=' ';
+    4546         448 :     c[2*i+1]=' ';
+    4547             :   }
+    4548          56 : }
+    4549             : __PLUMED_WRAPPER_C_END
+    4550             : 
+    4551             : __PLUMED_WRAPPER_C_BEGIN
+    4552         373 : plumed plumed_f2c(const char*c) {
+    4553             :   plumed p;
+    4554             :   unsigned i;
+    4555             :   unsigned char* cc;
+    4556             : 
+    4557             :   assert(CHAR_BIT<=12);
+    4558             :   assert(sizeof(p.p)<=16);
+    4559             : 
+    4560             :   assert(c);
+    4561             : 
+    4562             :   /*
+    4563             :      needed to avoid cppcheck warning on uninitialized p
+    4564             :   */
+    4565         373 :   p.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4566             :   cc=__PLUMED_WRAPPER_REINTERPRET_CAST(unsigned char*,&p.p);
+    4567        3357 :   for(i=0; i<sizeof(p.p); i++) {
+    4568             :     assert(c[2*i]>=48 && c[2*i]<48+64);
+    4569             :     assert(c[2*i+1]>=48 && c[2*i+1]<48+64);
+    4570             :     /*
+    4571             :       perform the reversed transform
+    4572             :     */
+    4573        2984 :     cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
+    4574             :   }
+    4575        3357 :   for(; i<16; i++) {
+    4576             :     assert(c[2*i]==' ');
+    4577             :     assert(c[2*i+1]==' ');
+    4578             :   }
+    4579         373 :   return p;
+    4580             : }
+    4581             : __PLUMED_WRAPPER_C_END
+    4582             : 
+    4583             : __PLUMED_WRAPPER_C_BEGIN
+    4584           2 : void* plumed_c2v(plumed p) {
+    4585             :   assert(plumed_check_pimpl(__PLUMED_WRAPPER_REINTERPRET_CAST(plumed_implementation*,p.p)));
+    4586           2 :   return p.p;
+    4587             : }
+    4588             : __PLUMED_WRAPPER_C_END
+    4589             : 
+    4590             : __PLUMED_WRAPPER_C_BEGIN
+    4591           2 : plumed plumed_v2c(void* v) {
+    4592             :   assert(plumed_check_pimpl(__PLUMED_WRAPPER_REINTERPRET_CAST(plumed_implementation*,v)));
+    4593             :   plumed p;
+    4594             :   p.p=v;
+    4595           2 :   return p;
+    4596             : }
+    4597             : __PLUMED_WRAPPER_C_END
+    4598             : 
+    4599             : #if __PLUMED_WRAPPER_FORTRAN /*{*/
+    4600             : 
+    4601             : /*
+    4602             :   Fortran wrappers
+    4603             :   These are just like the global C wrappers. They are
+    4604             :   just defined here and not declared since they
+    4605             :   should not be used from c/c++ anyway.
+    4606             : 
+    4607             :   We use a macro that does the following:
+    4608             :   - declare a static function named NAME_static
+    4609             :   - declare a number of functions named NAME_ etc, with all possible
+    4610             :     fortran mangling schemes (zero, one, or two underscores, lower and upper case)
+    4611             :   - define the NAME_static function.
+    4612             : 
+    4613             :   The static function is used basically as an inline function in a C-compatible manner.
+    4614             : */
+    4615             : 
+    4616             : #define __PLUMED_IMPLEMENT_FORTRAN(lower,upper,arg1,arg2) \
+    4617             :   static void lower ## _static arg1; \
+    4618             :   extern void lower      arg1 {lower ## _static arg2;} \
+    4619             :   extern void lower ##_  arg1 {lower ## _static arg2;} \
+    4620             :   extern void lower ##__ arg1 {lower ## _static arg2;} \
+    4621             :   extern void upper      arg1 {lower ## _static arg2;} \
+    4622             :   extern void upper ##_  arg1 {lower ## _static arg2;} \
+    4623             :   extern void upper ##__ arg1 {lower ## _static arg2;} \
+    4624             :   static void lower ## _static arg1
+    4625             : 
+    4626             : /* FORTRAN wrappers would only make sense as extern "C" */
+    4627             : 
+    4628             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    4629             : 
+    4630          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create,PLUMED_F_CREATE,(char*c),(c)) {
+    4631          18 :   plumed_c2f(plumed_create(),c);
+    4632          18 : }
+    4633             : 
+    4634          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_dlopen,PLUMED_F_CREATE_DLOPEN,(char*path,char*c),(path,c)) {
+    4635           6 :   plumed_c2f(plumed_create_dlopen(path),c);
+    4636           6 : }
+    4637             : 
+    4638          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_reference,PLUMED_F_CREATE_REFERENCE,(char* r,char*c),(r,c)) {
+    4639           6 :   plumed_c2f(plumed_create_reference_f(r),c);
+    4640           6 : }
+    4641             : 
+    4642           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_invalid,PLUMED_F_CREATE_INVALID,(char* c),(c)) {
+    4643           0 :   plumed_c2f(plumed_create_invalid(),c);
+    4644           0 : }
+    4645             : 
+    4646         558 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_cmd,PLUMED_F_CMD,(char*c,char*key,void*val),(c,key,val)) {
+    4647         279 :   plumed_cmd(plumed_f2c(c),key,val);
+    4648         279 : }
+    4649             : 
+    4650          60 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_finalize,PLUMED_F_FINALIZE,(char*c),(c)) {
+    4651          30 :   plumed_finalize(plumed_f2c(c));
+    4652          30 : }
+    4653             : 
+    4654          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_installed,PLUMED_F_INSTALLED,(int*i),(i)) {
+    4655             :   assert(i);
+    4656           6 :   *i=plumed_installed();
+    4657           6 : }
+    4658             : 
+    4659             : /* New in PLUMED 2.5 */
+    4660           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_valid,PLUMED_F_VALID,(char*c,int*i),(c,i)) {
+    4661             :   assert(i);
+    4662           0 :   *i=plumed_valid(plumed_f2c(c));
+    4663           0 : }
+    4664             : 
+    4665          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_use_count,PLUMED_F_USE_COUNT,(char*c,int*i),(c,i)) {
+    4666             :   assert(i);
+    4667          18 :   *i=plumed_use_count(plumed_f2c(c));
+    4668          18 : }
+    4669             : 
+    4670             : /* New in PLUMED 2.8 */
+    4671             : 
+    4672             : /* note: flags & (~0x1ffffff) removes bits that are set here (code and size) */
+    4673             : 
+    4674             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,suffix) \
+    4675             : 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) {\
+    4676             :   plumed_safeptr safe; \
+    4677             :   safe.ptr=val; \
+    4678             :   safe.nelem=nelem; \
+    4679             :   safe.shape=shape; \
+    4680             :   safe.flags= (flags & (~0x1ffffffu)) + 0x10000*code + size; \
+    4681             :   safe.opt=opt; \
+    4682             :   return safe; \
+    4683             : }
+    4684             : 
+    4685             : #define __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,size,code) \
+    4686             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,) \
+    4687             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,_scalar)
+    4688             : 
+    4689             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(type,type_,code) \
+    4690             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,0,code)
+    4691             : 
+    4692             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(type,type_,code) \
+    4693             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,sizeof(type),code)
+    4694             : 
+    4695          24 : __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(void,ptr,0)
+    4696           1 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(float,float,4)
+    4697          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(double,double,4)
+    4698           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long double,long_double,4)
+    4699          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(int,int,3)
+    4700           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(short,short,3)
+    4701           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long,long,3)
+    4702          20 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(char,char,3)
+    4703             : 
+    4704             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    4705             : 
+    4706          48 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_global,PLUMED_F_GLOBAL,(char*c),(c)) {
+    4707          24 :   plumed_c2f(plumed_gmain,c);
+    4708          24 : }
+    4709             : 
+    4710          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i),(i)) {
+    4711             :   assert(i);
+    4712          18 :   *i=plumed_ginitialized();
+    4713          18 : }
+    4714             : 
+    4715          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcreate,PLUMED_F_GCREATE,(void),()) {
+    4716          14 :   plumed_gcreate();
+    4717          14 : }
+    4718             : 
+    4719         156 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcmd,PLUMED_F_GCMD,(char*key,void*val),(key,val)) {
+    4720          78 :   plumed_gcmd(key,val);
+    4721          78 : }
+    4722             : 
+    4723          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gfinalize,PLUMED_F_GFINALIZE,(void),()) {
+    4724          14 :   plumed_gfinalize();
+    4725          14 : }
+    4726             : 
+    4727             : /* New in PLUMED 2.5 */
+    4728          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gvalid,PLUMED_F_GVALID,(int*i),(i)) {
+    4729             :   assert(i);
+    4730           6 :   *i=plumed_gvalid();
+    4731           6 : }
+    4732             : 
+    4733             : #endif /*}*/
+    4734             : 
+    4735             : __PLUMED_WRAPPER_EXTERN_C_END
+    4736             : 
+    4737             : #endif /*}*/
+    4738             : 
+    4739             : #endif /*}*/
+    4740             : 
+    4741             : #endif /*}*/
+    4742             : 
+    4743             : /* END OF DEFINITIONS */
+    4744             : 
+    4745             : /* reset variable to allow it to be redefined upon re-inclusion */
+    4746             : 
+    4747             : #undef __PLUMED_WRAPPER_IMPLEMENTATION_
+    4748             : 
+    4749             : /* this macro is set in declarations */
+    4750             : #ifdef __PLUMED_WRAPPER_REDEFINE_CMD
+    4751             : #if defined(plumed_cmd)
+    4752             : #undef plumed_cmd
+    4753             : #endif
+    4754             : #define plumed_cmd __PLUMED_WRAPPER_REDEFINE_CMD
+    4755             : #endif
+    4756             : 
+    4757             : /* this macro is set in declarations */
+    4758             : #ifdef __PLUMED_WRAPPER_REDEFINE_GCMD
+    4759             : #if defined(plumed_gcmd)
+    4760             : #undef plumed_gcmd
+    4761             : #endif
+    4762             : #define plumed_gcmd __PLUMED_WRAPPER_REDEFINE_GCMD
+    4763             : #endif
+    4764             : 
+    4765             : /* this macro is set in declarations */
+    4766             : #ifdef __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4767             : #if defined(plumed_error_rethrow)
+    4768             : #undef plumed_error_rethrow
+    4769             : #endif
+    4770             : #define plumed_error_rethrow __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4771             : #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 000000000..81b4e73df --- /dev/null +++ b/coverage/wrapper/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:26755248.4 %
Date:2024-10-17 16:45:00Functions:14728851.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
48.4%48.4%
+
48.4 %267 / 55251.0 %147 / 288
+
+
+ + + + +
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 000000000..d6a84a201 --- /dev/null +++ b/coverage/wrapper/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:26755248.4 %
Date:2024-10-17 16:45:00Functions:14728851.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
48.4%48.4%
+
48.4 %267 / 55251.0 %147 / 288
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index.html b/coverage/wrapper/index.html new file mode 100644 index 000000000..abcb5e118 --- /dev/null +++ b/coverage/wrapper/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:26755248.4 %
Date:2024-10-17 16:45:00Functions:14728851.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
48.4%48.4%
+
48.4 %267 / 55251.0 %147 / 288
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/index.html b/index.html new file mode 100644 index 000000000..cc4afdd80 --- /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. + +