Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2014-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 "MultiValue.h"
23 :
24 : namespace PLMD {
25 :
26 108454 : MultiValue::MultiValue( const unsigned& nvals, const unsigned& nder ):
27 : values(nvals),
28 : nderivatives(nder),
29 109595 : derivatives(nvals*nder),
30 : tmpval(0),
31 : tmpder(nder),
32 218049 : atLeastOneSet(false)
33 : {
34 109532 : std::vector<unsigned> myind( nder );
35 193902 : for(unsigned i=0; i<nder; ++i) myind[i]=i;
36 109542 : hasDerivatives.createIndexListFromVector( myind );
37 109606 : }
38 :
39 41761 : void MultiValue::resize( const unsigned& nvals, const unsigned& nder ) {
40 41761 : values.resize(nvals); nderivatives=nder; derivatives.resize( nvals*nder );
41 41822 : tmpder.resize( nder ); hasDerivatives.clear(); std::vector<unsigned> myind( nder );
42 45732 : for(unsigned i=0; i<nder; ++i) myind[i]=i;
43 41820 : hasDerivatives.createIndexListFromVector( myind );
44 41810 : atLeastOneSet=false;
45 41822 : }
46 :
47 2088940 : void MultiValue::clearAll() {
48 2088940 : if( atLeastOneSet && !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
49 2089227 : for(unsigned i=0; i<values.size(); ++i) clear(i);
50 2089900 : clearTemporyDerivatives(); hasDerivatives.deactivateAll(); atLeastOneSet=false;
51 2089227 : }
52 :
53 8293850 : void MultiValue::clear( const unsigned& ival ) {
54 8293850 : values[ival]=0;
55 8295833 : unsigned base=ival*nderivatives, ndert=hasDerivatives.getNumberActive();
56 8348060 : for(unsigned i=0; i<ndert; ++i) derivatives[ base+hasDerivatives[i] ]=0.;
57 8295507 : }
58 :
59 2089766 : void MultiValue::clearTemporyDerivatives() {
60 2089766 : unsigned ndert=hasDerivatives.getNumberActive(); tmpval=0.;
61 2101560 : for(unsigned i=0; i<ndert; ++i) tmpder[ hasDerivatives[i] ]=0.;
62 2089959 : }
63 :
64 523121 : void MultiValue::chainRule( const unsigned& ival, const unsigned& iout, const unsigned& stride, const unsigned& off,
65 : const double& df, const unsigned& bufstart, std::vector<double>& buffer ) {
66 523121 : if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
67 :
68 : plumed_dbg_assert( off<stride );
69 523451 : unsigned base=nderivatives*ival, ndert=hasDerivatives.getNumberActive();
70 518333 : unsigned start=bufstart+stride*(nderivatives+1)*iout + stride;
71 30312170 : for(unsigned i=0; i<ndert; ++i) {
72 29788664 : unsigned jder=hasDerivatives[i];
73 29839896 : buffer[start+jder*stride] += df*derivatives[base+jder];
74 : }
75 523506 : }
76 :
77 57550 : void MultiValue::copyValues( MultiValue& outvals ) const {
78 : plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() );
79 57550 : for(unsigned i=0; i<values.size(); ++i) outvals.setValue( i, values[i] );
80 :
81 57562 : }
82 :
83 50650 : void MultiValue::copyDerivatives( MultiValue& outvals ) {
84 : plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() && nderivatives<=outvals.getNumberOfDerivatives() );
85 50650 : if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
86 :
87 50652 : outvals.atLeastOneSet=true; unsigned ndert=hasDerivatives.getNumberActive();
88 3756575 : for(unsigned j=0; j<ndert; ++j) {
89 3705925 : unsigned jder=hasDerivatives[j]; outvals.hasDerivatives.activate(jder);
90 : }
91 :
92 50650 : unsigned base=0, obase=0;
93 162482 : for(unsigned i=0; i<values.size(); ++i) {
94 8317297 : for(unsigned j=0; j<ndert; ++j) {
95 8205465 : unsigned jder=hasDerivatives[j];
96 8216611 : outvals.derivatives[obase+jder] += derivatives[base+jder];
97 : }
98 111832 : obase+=outvals.nderivatives; base+=nderivatives;
99 : }
100 50655 : }
101 :
102 1869852 : void MultiValue::quotientRule( const unsigned& nder, const unsigned& oder ) {
103 : plumed_dbg_assert( nder<values.size() && oder<values.size() );
104 1869852 : if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
105 :
106 1869857 : unsigned ndert=hasDerivatives.getNumberActive(); double wpref;
107 1869653 : unsigned obase=oder*nderivatives, nbase=nder*nderivatives;
108 :
109 1869653 : if( fabs(tmpval)>epsilon ) { wpref=1.0/tmpval; }
110 0 : else { wpref=1.0; }
111 :
112 1869653 : double pref = values[nder]*wpref*wpref;
113 179888507 : for(unsigned j=0; j<ndert; ++j) {
114 178018690 : unsigned jder=hasDerivatives[j];
115 178027299 : derivatives[obase+jder] = wpref*derivatives[nbase+jder] - pref*tmpder[jder];
116 : }
117 1869817 : values[oder] = wpref*values[nder];
118 1869834 : }
119 :
120 4821 : }
|