Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2015-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 "ActionWithInputMatrix.h"
23 : #include "AdjacencyMatrixVessel.h"
24 : #include "AdjacencyMatrixBase.h"
25 : #include "vesselbase/ActionWithVessel.h"
26 : #include "core/PlumedMain.h"
27 : #include "core/ActionSet.h"
28 :
29 : namespace PLMD {
30 : namespace adjmat {
31 :
32 30 : void ActionWithInputMatrix::registerKeywords( Keywords& keys ) {
33 30 : MultiColvarBase::registerKeywords( keys );
34 120 : keys.add("compulsory","MATRIX","the action that calcualtes the adjacency matrix vessel we would like to analyse");
35 30 : }
36 :
37 :
38 25 : ActionWithInputMatrix::ActionWithInputMatrix(const ActionOptions& ao):
39 : Action(ao),
40 : MultiColvarBase(ao),
41 25 : mymatrix(NULL)
42 : {
43 25 : matsums=true;
44 50 : if( keywords.exists("MATRIX") ) {
45 : std::vector<AtomNumber> fake_atoms;
46 46 : if( !parseMultiColvarAtomList("MATRIX",-1,fake_atoms ) ) error("unable to interpret input matrix");
47 23 : if( mybasemulticolvars.size()!=1 ) error("should be exactly one matrix input");
48 :
49 : // Retrieve the adjacency matrix of interest
50 46 : for(unsigned i=0; i<mybasemulticolvars[0]->getNumberOfVessels(); ++i) {
51 23 : mymatrix = dynamic_cast<AdjacencyMatrixVessel*>( mybasemulticolvars[0]->getPntrToVessel(i) );
52 23 : if( mymatrix ) break ;
53 : }
54 23 : if( !mymatrix ) error( mybasemulticolvars[0]->getLabel() + " does not calculate an adjacency matrix");
55 :
56 23 : atom_lab.resize(0); unsigned nnodes; // Delete all the atom labels that have been created
57 44 : if( mymatrix->undirectedGraph() ) nnodes = (mymatrix->function)->ablocks[0].size();
58 6 : else nnodes = (mymatrix->function)->ablocks[0].size() + (mymatrix->function)->ablocks[1].size();
59 13349 : for(unsigned i=0; i<nnodes; ++i) atom_lab.push_back( std::pair<unsigned,unsigned>( 1, i ) );
60 : }
61 25 : }
62 :
63 13240 : unsigned ActionWithInputMatrix::getNumberOfDerivatives() {
64 13240 : return (mymatrix->function)->getNumberOfDerivatives();
65 : }
66 :
67 16261547 : unsigned ActionWithInputMatrix::getNumberOfNodes() const {
68 32523094 : return (mymatrix->function)->ablocks[0].size();
69 : }
70 :
71 53354 : AdjacencyMatrixVessel* ActionWithInputMatrix::getAdjacencyVessel() const {
72 53354 : return mymatrix;
73 : }
74 :
75 504 : AtomNumber ActionWithInputMatrix::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
76 504 : return (mymatrix->function)->getAbsoluteIndexOfCentralAtom(i);
77 : }
78 :
79 38388 : double ActionWithInputMatrix::retrieveConnectionValue( const unsigned& i, const unsigned& j, std::vector<double>& vals ) const {
80 38388 : if( !mymatrix->matrixElementIsActive( i, j ) ) return 0;
81 17296 : unsigned myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
82 :
83 : // unsigned vi; double df;
84 17296 : mymatrix->retrieveValueWithIndex( myelem, false, vals );
85 17296 : return vals[0]*vals[1]; // (mymatrix->function)->transformStoredValues( vals, vi, df );
86 : }
87 :
88 1940 : void ActionWithInputMatrix::getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const {
89 3880 : if( (mymatrix->function)->mybasemulticolvars.size()==0 ) {
90 482 : std::vector<double> tvals( mymatrix->getNumberOfComponents() ); orient0.assign(orient0.size(),0);
91 34103 : for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
92 33862 : if( mymatrix->undirectedGraph() && ind==i ) continue;
93 67292 : orient0[1]+=retrieveConnectionValue( ind, i, tvals );
94 : }
95 241 : orient0[0]=1.0; return;
96 : }
97 1699 : (mymatrix->function)->getInputData( ind, normed, myatoms, orient0 );
98 : }
99 :
100 1440 : void ActionWithInputMatrix::addConnectionDerivatives( const unsigned& i, const unsigned& j, MultiValue& myvals, MultiValue& myvout ) const {
101 1440 : if( !mymatrix->matrixElementIsActive( i, j ) ) return;
102 1440 : unsigned myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
103 : // Get derivatives and add
104 1440 : mymatrix->retrieveDerivatives( myelem, false, myvals );
105 60732 : for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
106 29646 : unsigned ider=myvals.getActiveIndex(jd);
107 29646 : myvout.addDerivative( 1, ider, myvals.getDerivative( 1, ider ) );
108 : }
109 : }
110 :
111 1679 : MultiValue& ActionWithInputMatrix::getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const {
112 3358 : if( (mymatrix->function)->mybasemulticolvars.size()==0 ) {
113 90 : MultiValue& myder=mymatrix->getTemporyMultiValue(0);
114 177 : if( myder.getNumberOfValues()!=2 || myder.getNumberOfDerivatives()!=(mymatrix->function)->getNumberOfDerivatives() ) {
115 3 : myder.resize( 2, (mymatrix->function)->getNumberOfDerivatives() );
116 : }
117 90 : myder.clearAll();
118 180 : MultiValue myvals( (mymatrix->function)->getNumberOfQuantities(), (mymatrix->function)->getNumberOfDerivatives() );
119 885 : for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
120 860 : if( mymatrix->undirectedGraph() && ind==i ) continue;
121 730 : addConnectionDerivatives( ind, i, myvals, myder );
122 : }
123 : myder.updateDynamicList(); return myder;
124 : }
125 1589 : return (mymatrix->function)->getInputDerivatives( ind, normed, myatoms );
126 : }
127 :
128 66 : unsigned ActionWithInputMatrix::getNumberOfNodeTypes() const {
129 132 : unsigned size = (mymatrix->function)->mybasemulticolvars.size();
130 66 : if( size==0 ) return 1;
131 61 : return size;
132 : }
133 :
134 2171 : unsigned ActionWithInputMatrix::getNumberOfQuantities() const {
135 4342 : if( (mymatrix->function)->mybasemulticolvars.size()==0 ) return 2;
136 2082 : return (mymatrix->function)->mybasemulticolvars[0]->getNumberOfQuantities();
137 : }
138 :
139 34 : unsigned ActionWithInputMatrix::getNumberOfAtomsInGroup( const unsigned& igrp ) const {
140 : plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
141 102 : return (mymatrix->function)->mybasemulticolvars[igrp]->getFullNumberOfTasks();
142 : }
143 :
144 7 : multicolvar::MultiColvarBase* ActionWithInputMatrix::getBaseMultiColvar( const unsigned& igrp ) const {
145 : plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
146 14 : return (mymatrix->function)->mybasemulticolvars[igrp];
147 : }
148 :
149 30059 : Vector ActionWithInputMatrix::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
150 30059 : return (getAdjacencyVessel()->function)->getPositionOfAtomForLinkCells( iatom );
151 : }
152 :
153 : }
154 4839 : }
|