2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
39 * Implements helper functions for checkpointing the AWH state and observables history.
41 * \author Viveca Lindahl
42 * \author Berk Hess <hess@kth.se>
48 #include "correlationhistory.h"
52 #include "gromacs/gmxlib/network.h"
53 #include "gromacs/mdtypes/awh_correlation_history.h"
54 #include "gromacs/mdtypes/commrec.h"
55 #include "gromacs/utility/arrayref.h"
56 #include "gromacs/utility/exceptions.h"
57 #include "gromacs/utility/gmxassert.h"
59 #include "correlationgrid.h"
64 void initCorrelationGridHistory(CorrelationGridHistory
*correlationGridHistory
,
65 int numCorrelationTensors
,
67 int blockDataListSize
)
69 correlationGridHistory
->numCorrelationTensors
= numCorrelationTensors
;
70 correlationGridHistory
->tensorSize
= tensorSize
;
71 correlationGridHistory
->blockDataListSize
= blockDataListSize
;
73 correlationGridHistory
->blockDataBuffer
.resize(numCorrelationTensors
*tensorSize
*blockDataListSize
);
76 CorrelationGridHistory
initCorrelationGridHistoryFromState(const CorrelationGrid
&correlationGrid
)
78 CorrelationGridHistory correlationGridHistory
;
80 initCorrelationGridHistory(&correlationGridHistory
, correlationGrid
.tensors().size(), correlationGrid
.tensorSize(), correlationGrid
.blockDataListSize());
82 return correlationGridHistory
;
85 /* Update the correlation grid history for checkpointing. */
86 void updateCorrelationGridHistory(CorrelationGridHistory
*correlationGridHistory
,
87 const CorrelationGrid
&correlationGrid
)
89 GMX_RELEASE_ASSERT(correlationGridHistory
!= nullptr, "We need a valid history object");
91 gmx::ArrayRef
<CorrelationBlockDataHistory
> blockDataBuffer
= correlationGridHistory
->blockDataBuffer
;
93 /* Store the grid in a linear array */
94 gmx::index bufferIndex
= 0;
95 for (const CorrelationTensor
&tensor
: correlationGrid
.tensors())
97 const int numDims
= tensor
.blockDataList()[0].coordData().size();
98 const int tensorSize
= tensor
.blockDataList()[0].correlationIntegral().size();
100 /* Loop of the tensor elements, ignore the symmetric data */
103 for (int k
= 0; k
< tensorSize
; k
++)
105 /* BlockData for each correlation element */
106 for (const CorrelationBlockData
&blockData
: tensor
.blockDataList())
108 const CorrelationBlockData::CoordData
&cx
= blockData
.coordData()[d1
];
109 const CorrelationBlockData::CoordData
&cy
= blockData
.coordData()[d2
];
111 CorrelationBlockDataHistory
&bdh
= blockDataBuffer
[bufferIndex
];
113 bdh
.blockSumWeight
= blockData
.blockSumWeight();
114 bdh
.blockSumSquareWeight
= blockData
.blockSumSquareWeight();
115 bdh
.blockSumWeightX
= cx
.blockSumWeightX
;
116 bdh
.blockSumWeightY
= cy
.blockSumWeightX
;
117 bdh
.sumOverBlocksSquareBlockWeight
= blockData
.sumOverBlocksSquareBlockWeight();
118 bdh
.sumOverBlocksBlockSquareWeight
= blockData
.sumOverBlocksBlockSquareWeight();
119 bdh
.sumOverBlocksBlockWeightBlockWeightX
= cx
.sumOverBlocksBlockWeightBlockWeightX
;
120 bdh
.sumOverBlocksBlockWeightBlockWeightY
= cy
.sumOverBlocksBlockWeightBlockWeightX
;
121 bdh
.previousBlockIndex
= blockData
.previousBlockIndex();
122 bdh
.blockLength
= blockData
.blockLength();
123 bdh
.correlationIntegral
= blockData
.correlationIntegral()[k
];
137 GMX_RELEASE_ASSERT(bufferIndex
== blockDataBuffer
.ssize(), "We should store exactly as many elements as the buffer size");
140 void CorrelationBlockData::restoreFromHistory(const CorrelationBlockDataHistory
&blockHistory
,
141 const std::vector
<CorrelationBlockData::CoordData
> &coordData
,
142 const std::vector
<double> &correlationIntegral
)
144 blockSumWeight_
= blockHistory
.blockSumWeight
;
145 blockSumSquareWeight_
= blockHistory
.blockSumSquareWeight
;
146 sumOverBlocksSquareBlockWeight_
= blockHistory
.sumOverBlocksSquareBlockWeight
;
147 sumOverBlocksBlockSquareWeight_
= blockHistory
.sumOverBlocksBlockSquareWeight
;
148 previousBlockIndex_
= blockHistory
.previousBlockIndex
;
149 blockLength_
= blockHistory
.blockLength
;
150 coordData_
= coordData
;
151 correlationIntegral_
= correlationIntegral
;
154 /* Restore a correlation element from history. */
155 void CorrelationTensor::restoreFromHistory(const std::vector
<CorrelationBlockDataHistory
> &blockDataBuffer
,
158 /* Blockdata for each correlation element */
159 for (CorrelationBlockData
&blockData
: blockDataList_
)
161 /* Correlation elements for each tensor */
162 const int numDims
= blockDataList_
[0].coordData().size();
163 const int tensorSize
= blockDataList_
[0].correlationIntegral().size();
167 /* Temporary containers to collect data */
168 std::vector
<CorrelationBlockData::CoordData
> coordData(numDims
);
169 std::vector
<double> correlationIntegral(tensorSize
);
170 for (int k
= 0; k
< tensorSize
; k
++)
172 if (*bufferIndex
>= blockDataBuffer
.size())
174 GMX_THROW(InvalidInputError("Mismatch of the correlation tensor size for the force correlation between checkpoint and simulation. Likely you have provided a checkpoint from a different simulation."));
176 const CorrelationBlockDataHistory
&blockHistory
= blockDataBuffer
[*bufferIndex
];
178 /* To simplify the checkpointing, CorrelationBlockDataHistory
179 * duplicates some weight data for all tensor elements.
180 * Here we collect the coordinate and tensor data
181 * in temporary buffers.
183 coordData
[d1
].blockSumWeightX
= blockHistory
.blockSumWeightX
;
184 coordData
[d2
].blockSumWeightX
= blockHistory
.blockSumWeightY
;
185 coordData
[d1
].sumOverBlocksBlockWeightBlockWeightX
= blockHistory
.sumOverBlocksBlockWeightBlockWeightX
;
186 coordData
[d2
].sumOverBlocksBlockWeightBlockWeightX
= blockHistory
.sumOverBlocksBlockWeightBlockWeightY
;
188 correlationIntegral
[k
] = blockHistory
.correlationIntegral
;
190 /* Check if we collected all data needed for blockData */
191 if (k
== tensorSize
- 1)
193 blockData
.restoreFromHistory(blockHistory
, coordData
, correlationIntegral
);
208 /* Restores the correlation grid state from the correlation grid history. */
209 void CorrelationGrid::restoreStateFromHistory(const CorrelationGridHistory
&correlationGridHistory
)
211 if (tensors_
.size() != static_cast<size_t>(correlationGridHistory
.numCorrelationTensors
))
213 GMX_THROW(InvalidInputError("Mismatch of the grid size for the force correlation between checkpoint and simulation. Likely you have provided a checkpoint from a different simulation."));
216 /* Extract the state from the linear history array */
217 size_t bufferIndex
= 0;
218 for (CorrelationTensor
&tensor
: tensors_
)
220 tensor
.restoreFromHistory(correlationGridHistory
.blockDataBuffer
,
224 if (bufferIndex
!= correlationGridHistory
.blockDataBuffer
.size())
226 GMX_THROW(InvalidInputError("Mismatch of the correlation tensor size for the force correlation between checkpoint and simulation. Likely you have provided a checkpoint from a different simulation."));