Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2015-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 "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 24 : void ActionWithInputMatrix::registerKeywords( Keywords& keys ) {
33 24 : MultiColvarFunction::registerKeywords( keys ); keys.remove("DATA");
34 24 : keys.add("compulsory","MATRIX","the action that calcualtes the adjacency matrix vessel we would like to analyse");
35 24 : }
36 :
37 :
38 19 : ActionWithInputMatrix::ActionWithInputMatrix(const ActionOptions& ao):
39 : Action(ao),
40 : MultiColvarFunction(ao),
41 19 : mymatrix(NULL)
42 : {
43 19 : matsums=true;
44 19 : if( keywords.exists("MATRIX") ) {
45 17 : std::vector<AtomNumber> fake_atoms;
46 17 : if( !parseMultiColvarAtomList("MATRIX",-1,fake_atoms ) ) error("unable to interpret input matrix");
47 17 : if( mybasemulticolvars.size()!=1 ) error("should be exactly one matrix input");
48 :
49 : // Retrieve the adjacency matrix of interest
50 17 : for(unsigned i=0; i<mybasemulticolvars[0]->getNumberOfVessels(); ++i) {
51 17 : mymatrix = dynamic_cast<AdjacencyMatrixVessel*>( mybasemulticolvars[0]->getPntrToVessel(i) );
52 17 : if( mymatrix ) break ;
53 : }
54 17 : if( !mymatrix ) error( mybasemulticolvars[0]->getLabel() + " does not calculate an adjacency matrix");
55 :
56 17 : atom_lab.resize(0); unsigned nnodes; // Delete all the atom labels that have been created
57 17 : if( mymatrix->undirectedGraph() ) nnodes = (mymatrix->function)->ablocks[0].size();
58 2 : else nnodes = (mymatrix->function)->ablocks[0].size() + (mymatrix->function)->ablocks[1].size();
59 17 : for(unsigned i=0; i<nnodes; ++i) atom_lab.push_back( std::pair<unsigned,unsigned>( 1, i ) );
60 : }
61 19 : }
62 :
63 13207 : unsigned ActionWithInputMatrix::getNumberOfDerivatives() {
64 13207 : return (mymatrix->function)->getNumberOfDerivatives();
65 : }
66 :
67 16234670 : unsigned ActionWithInputMatrix::getNumberOfNodes() const {
68 16234670 : return (mymatrix->function)->ablocks[0].size();
69 : }
70 :
71 52243 : AdjacencyMatrixVessel* ActionWithInputMatrix::getAdjacencyVessel() const {
72 52243 : return mymatrix;
73 : }
74 :
75 156 : AtomNumber ActionWithInputMatrix::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
76 156 : return (mymatrix->function)->getAbsoluteIndexOfCentralAtom(i);
77 : }
78 :
79 9464 : double ActionWithInputMatrix::retrieveConnectionValue( const unsigned& i, const unsigned& j, std::vector<double>& vals ) const {
80 9464 : if( !mymatrix->matrixElementIsActive( i, j ) ) return 0;
81 9464 : unsigned vi, myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
82 :
83 9464 : mymatrix->retrieveValueWithIndex( myelem, false, vals ); double df;
84 9464 : return (mymatrix->function)->transformStoredValues( vals, vi, df );
85 : }
86 :
87 1838 : void ActionWithInputMatrix::getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const {
88 1838 : if( (mymatrix->function)->mybasemulticolvars.size()==0 ) {
89 139 : std::vector<double> tvals( mymatrix->getNumberOfComponents() ); orient0.assign(orient0.size(),0);
90 4985 : for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
91 4846 : if( mymatrix->undirectedGraph() && ind==i ) continue;
92 4732 : orient0[1]+=retrieveConnectionValue( ind, i, tvals );
93 : }
94 1977 : orient0[0]=1.0; return;
95 : }
96 1699 : (mymatrix->function)->getInputData( ind, normed, myatoms, orient0 );
97 : }
98 :
99 1400 : void ActionWithInputMatrix::addConnectionDerivatives( const unsigned& i, const unsigned& j, std::vector<double>& vals, MultiValue& myvals, MultiValue& myvout ) const {
100 2800 : if( !mymatrix->matrixElementIsActive( i, j ) ) return;
101 1400 : unsigned vi, myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
102 :
103 1400 : mymatrix->retrieveValueWithIndex( myelem, false, vals );
104 1400 : double df, val = (mymatrix->function)->transformStoredValues( vals, vi, df );
105 1400 : mymatrix->retrieveDerivatives( myelem, false, myvals );
106 22400 : for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
107 21000 : unsigned ider=myvals.getActiveIndex(jd);
108 21000 : myvout.addDerivative( 1, ider, df*myvals.getDerivative( vi, ider ) );
109 : }
110 : }
111 :
112 1664 : MultiValue& ActionWithInputMatrix::getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const {
113 1664 : if( (mymatrix->function)->mybasemulticolvars.size()==0 ) {
114 75 : MultiValue& myder=mymatrix->getTemporyMultiValue(0);
115 75 : if( myder.getNumberOfValues()!=2 || myder.getNumberOfDerivatives()!=(mymatrix->function)->getNumberOfDerivatives() ) {
116 2 : myder.resize( 2, (mymatrix->function)->getNumberOfDerivatives() );
117 : }
118 75 : myder.clearAll();
119 75 : std::vector<double> tvals( mymatrix->getNumberOfComponents() );
120 150 : MultiValue myvals( 2, (mymatrix->function)->getNumberOfDerivatives() );
121 825 : for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
122 750 : if( mymatrix->undirectedGraph() && ind==i ) continue;
123 700 : addConnectionDerivatives( ind, i, tvals, myvals, myder );
124 : }
125 150 : myder.updateDynamicList(); return myder;
126 : }
127 1589 : return (mymatrix->function)->getInputDerivatives( ind, normed, myatoms );
128 : }
129 :
130 61 : unsigned ActionWithInputMatrix::getNumberOfNodeTypes() const {
131 61 : unsigned size = (mymatrix->function)->mybasemulticolvars.size();
132 61 : if( size==0 ) return 1;
133 61 : return size;
134 : }
135 :
136 2135 : unsigned ActionWithInputMatrix::getNumberOfQuantities() const {
137 2135 : if( (mymatrix->function)->mybasemulticolvars.size()==0 ) return 2;
138 2081 : return (mymatrix->function)->mybasemulticolvars[0]->getNumberOfQuantities();
139 : }
140 :
141 34 : unsigned ActionWithInputMatrix::getNumberOfAtomsInGroup( const unsigned& igrp ) const {
142 : plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
143 34 : return (mymatrix->function)->mybasemulticolvars[igrp]->getFullNumberOfTasks();
144 : }
145 :
146 7 : multicolvar::MultiColvarBase* ActionWithInputMatrix::getBaseMultiColvar( const unsigned& igrp ) const {
147 : plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
148 7 : return (mymatrix->function)->mybasemulticolvars[igrp];
149 : }
150 :
151 28979 : Vector ActionWithInputMatrix::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
152 28979 : return (getAdjacencyVessel()->function)->getPositionOfAtomForLinkCells( iatom );
153 : }
154 :
155 : }
156 2523 : }
|