All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BridgeVessel.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 The plumed team
3  (see the PEOPLE file at the root of the distribution for a list of names)
4 
5  See http://www.plumed-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
8 
9  plumed is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  plumed is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #include "BridgeVessel.h"
23 #include "tools/Matrix.h"
24 #include "core/ActionWithArguments.h"
25 
26 namespace PLMD {
27 namespace vesselbase {
28 
30 Vessel(da),
31 inum(0)
32 {
33  resizeBuffer(0);
34 }
35 
40  mynumerical_values.resize( getAction()->getNumberOfDerivatives()*myOutputValues->getNumberOfComponents() );
41  inum=0;
42  }
43 }
44 
46  myOutputAction=myact;
47  myOutputValues=dynamic_cast<ActionWithValue*>( myact );
48  plumed_assert( myOutputValues );
49 }
50 
52  plumed_merror("I shouldn't end up here");
53 }
54 
57 }
58 
60  myOutputAction->performTask( getAction()->current );
64  }
66  return ( !myOutputAction->contributorsAreUnlocked || keep );
67 }
68 
72  if ( inum<mynumerical_values.size() ){
73  for(unsigned i=0;i<myOutputValues->getNumberOfComponents();++i){
75  inum++;
76  }
77  plumed_dbg_assert( inum<=mynumerical_values.size() );
78  } else {
79  plumed_assert( inum==mynumerical_values.size() );
80  }
81  }
82 }
83 
87  ActionWithVessel* vval=dynamic_cast<ActionWithVessel*>( myOutputAction );
88  for(unsigned i=0;i<nextra;++i){
89  vval->bridgeVariable=i; getAction()->calculate();
90  for(unsigned j=0;j<myOutputValues->getNumberOfComponents();++j) tmpder(j,i) = myOutputValues->getOutputQuantity(j);
91  }
92  vval->bridgeVariable=nextra; getAction()->calculate();
93  inum=0; // Reset inum now that we have finished calling calculate
94  std::vector<double> base( myOutputValues->getNumberOfComponents() );
95  for(unsigned j=0;j<myOutputValues->getNumberOfComponents();++j) base[j] = myOutputValues->getOutputQuantity(j);
96 
97  const double delta=sqrt(epsilon);
98  ActionAtomistic* aa=dynamic_cast<ActionAtomistic*>( getAction() );
99  unsigned nvals=myOutputValues->getNumberOfComponents();
100  for(unsigned j=0;j<nvals;++j) ( myOutputValues->copyOutput(j) )->clearDerivatives();
101 
102  if( aa ){
103  ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( getAction() );
104  plumed_assert( !aarg ); Tensor box=aa->getBox();
105  unsigned natoms=aa->getNumberOfAtoms();
106  for(unsigned j=0;j<nvals;++j){
107  double ref=( myOutputValues->copyOutput(j) )->get();
108  if( ( myOutputValues->copyOutput(j) )->hasDerivatives() ){
109  for(unsigned i=0;i<3*natoms;++i){
110  double d=( mynumerical_values[i*nvals+j] - ref)/delta;
111  ( myOutputValues->copyOutput(j) )->addDerivative(i,d);
112  }
113  Tensor virial;
114  for(int i=0;i<3;i++) for(int k=0;k<3;k++){
115  virial(i,k)=( mynumerical_values[ nvals*(3*natoms + 3*i + k) + j ]-ref)/delta;
116  }
117  virial=-matmul(box.transpose(),virial);
118  for(int i=0;i<3;i++) for(int k=0;k<3;k++) ( myOutputValues->copyOutput(j) )->addDerivative(3*natoms+3*k+i,virial(k,i));
119  }
120  }
121  } else {
122  plumed_merror("not implemented or tested yet");
123 // unsigned nder=myOutputAction->getNumberOfDerivatives();
124 // for(unsigned j=0;j<nvals;++j){
125 // double ref=( myOutputValues->copyOutput(j) )->get();
126 // if( ( myOutputValues->copyOutput(j) )->hasDerivatives() ){
127 // for(unsigned i=0;i<nder;++i){
128 // double d=( mynumerical_values[i*nvals+j] - ref)/delta;
129 // ( myOutputValues->copyOutput(j) )->addDerivative(i,d);
130 // }
131 // }
132 // }
133  }
134  // Add the derivatives wrt to the local quantities we are working with
135  for(unsigned j=0;j<nvals;++j){
136  unsigned k=0;
137  for(unsigned i=getAction()->getNumberOfDerivatives();i<myOutputAction->getNumberOfDerivatives();++i){
138  ( myOutputValues->copyOutput(j) )->addDerivative( i, (tmpder(j,k)-base[j])/sqrt(epsilon) ); k++;
139  }
140  }
141 }
142 
143 bool BridgeVessel::applyForce( std::vector<double>& outforces ){
144  bool hasforce=false; outforces.assign(outforces.size(),0.0);
146  std::vector<double> eforces( nextra, 0.0 );
147  for(unsigned i=0;i<myOutputAction->getNumberOfVessels();++i){
149  hasforce=true;
150  for(unsigned j=0;j<outforces.size();++j) outforces[j]+=forces[j];
151  for(unsigned j=0;j<nextra;++j) eforces[j]+=forces[ outforces.size()+j ];
152  }
153  }
154  if(hasforce) myOutputAction->applyBridgeForces( eforces );
155  return hasforce;
156 }
157 
158 }
159 }
160 
std::string description()
Should not be called.
const double epsilon
TensorGeneric< m, n > transpose() const
return the transpose matrix
Definition: Tensor.h:325
Class implementing fixed size matrices of doubles.
Definition: Tensor.h:70
TensorGeneric< n, l > matmul(const TensorGeneric< n, m > &a, const TensorGeneric< m, l > &b)
Definition: Tensor.h:343
double getNLTolerance() const
Return the value for the neighbor list tolerance.
virtual bool checkNumericalDerivatives() const
Check if numerical derivatives should be performed.
Definition: Action.h:227
virtual unsigned getNumberOfDerivatives()=0
Get the number of derivatives for final calculated quantity.
bool calculate()
Actually do the calculation.
virtual void calculate()=0
Calculate an Action.
This is used to create PLMD::Action objects that take the output from some other Action as input...
std::vector< double > thisval
The value of the current element in the sum.
void prepare()
Jobs to do before the task list starts.
Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some ...
void setOutputAction(ActionWithVessel *myOutputAction)
Setup the action we are outputting to.
void clearAfterTask()
Clear tempory data that is calculated for each task.
void resizeBuffer(const unsigned &n)
Set the size of the data buffer.
Definition: Vessel.h:221
Action used to create objects that access the positions of the atoms from the MD code.
void resize()
Resize the quantities in the vessel.
Value * copyOutput(const std::string &name) const
Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions) You ...
bool applyForce(std::vector< double > &forces)
Apply some force.
VectorGeneric< n > delta(const VectorGeneric< n > &v1, const VectorGeneric< n > &v2)
Definition: Vector.h:262
bool calculateAllVessels()
This loops over all the vessels calculating them and also sets all the element derivatives equal to z...
virtual void performTask(const unsigned &j)=0
Calculate one of the functions in the distribution.
This class is used to pass the input to Vessels.
Definition: Vessel.h:53
unsigned getNumberOfVessels() const
Get the number of vessels.
double getOutputQuantity(const unsigned j) const
Get the value of one of the components of the PLMD::Action.
double getTolerance() const
Return the value of the tolerance.
void int double * da
Definition: Matrix.h:47
void finish()
Finish the calculation.
virtual void doJobsRequiredBeforeTaskList()
Do any jobs that are required before the task list is undertaken.
int getNumberOfComponents() const
Returns the number of values defined.
ActionWithValue * myOutputValues
Definition: BridgeVessel.h:46
void completeNumericalDerivatives()
Calculate numerical derivatives.
const Tensor & getBox() const
Get position of i-th atom.
unsigned getNumberOfAtoms() const
Get number of available atoms.
ActionWithVessel * myOutputAction
Definition: BridgeVessel.h:45
virtual void applyBridgeForces(const std::vector< double > &bb)
Apply forces from bridge vessel - this is rarely used - currently only in ActionVolume.
bool contributorsAreUnlocked
The terms in the series are locked.
void resizeFunctions()
Resize all the functions when the number of derivatives change.
std::vector< double > mynumerical_values
Definition: BridgeVessel.h:44
std::vector< double > forces
Definition: BridgeVessel.h:42
void finishComputations()
Finish running all the calculations.
Vessel * getPntrToVessel(const unsigned &i)
Get a pointer to the ith vessel.
ActionWithVessel * getAction()
Return a pointer to the action we are working in.
Definition: Vessel.h:236
This is used to create PLMD::Action objects that are computed by calculating the same function multip...
BridgeVessel(const VesselOptions &)