OpenMD
3.2
Molecular Dynamics in the Open
Toggle main menu visibility
Loading...
Searching...
No Matches
LU.hpp
1
/*
2
* Copyright (c) 2004-present, The University of Notre Dame. All rights
3
* reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
7
*
8
* 1. Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
*
11
* 2. Redistributions in binary form must reproduce the above copyright notice,
12
* this list of conditions and the following disclaimer in the documentation
13
* and/or other materials provided with the distribution.
14
*
15
* 3. Neither the name of the copyright holder nor the names of its
16
* contributors may be used to endorse or promote products derived from
17
* this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
* POSSIBILITY OF SUCH DAMAGE.
30
*
31
* SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32
* research, please cite the following paper when you publish your work:
33
*
34
* [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35
*
36
* Good starting points for code and simulation methodology are:
37
*
38
* [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39
* [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40
* [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41
* [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42
* [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43
* [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44
* [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45
* [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46
*/
47
48
/*=========================================================================
49
50
Program: Visualization Toolkit
51
Module: Excerpted from vtkMath.cxx
52
53
Copyright (c) 1993-2015 Ken Martin, Will Schroeder, Bill Lorensen
54
All rights reserved.
55
56
Redistribution and use in source and binary forms, with or without
57
modification, are permitted provided that the following conditions are met:
58
59
* Redistributions of source code must retain the above copyright notice,
60
this list of conditions and the following disclaimer.
61
62
* Redistributions in binary form must reproduce the above copyright notice,
63
this list of conditions and the following disclaimer in the documentation
64
and/or other materials provided with the distribution.
65
66
* Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
67
of any contributors may be used to endorse or promote products derived
68
from this software without specific prior written permission.
69
70
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
71
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
74
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
76
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
77
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
78
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
79
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80
81
=========================================================================*/
82
#ifndef MATH_LU_HPP
83
#define MATH_LU_HPP
84
85
#include <iostream>
86
#include <limits>
87
88
namespace
OpenMD
{
89
90
constexpr
double
SMALL_NUMBER = 1.0e-12;
91
constexpr
int
MAX_SCRATCH_ARRAY_SIZE = 10;
92
93
/**
94
* Invert input square matrix A into matrix AI.
95
* @param A input square matrix
96
* @param AI output square matrix
97
* @return true if inverse is computed, otherwise return false
98
* @note A is modified during the inversion
99
*/
100
template
<
class
MatrixType>
101
bool
invertMatrix
(MatrixType& A, MatrixType& AI) {
102
using
Real =
typename
MatrixType::ElemType;
103
104
if
(A.getNRow() != A.getNCol() || A.getNRow() != AI.getNRow() ||
105
A.getNCol() != AI.getNCol()) {
106
return
false
;
107
}
108
109
int
size = A.getNRow();
110
111
// Check on allocation of working vectors
112
//
113
int
iScratch[MAX_SCRATCH_ARRAY_SIZE];
114
int
* index = (size <= MAX_SCRATCH_ARRAY_SIZE ? iScratch :
new
int
[size]);
115
Real dScratch[MAX_SCRATCH_ARRAY_SIZE];
116
Real* column = (size <= MAX_SCRATCH_ARRAY_SIZE ? dScratch :
new
Real[size]);
117
118
bool
retVal =
invertMatrix
(A, AI, size, index, column);
119
120
if
(size > MAX_SCRATCH_ARRAY_SIZE) {
121
delete
[] index;
122
delete
[] column;
123
}
124
return
retVal;
125
}
126
127
/**
128
* Invert input square matrix A into matrix AI (Thread safe versions).
129
* @param A input square matrix
130
* @param AI output square matrix
131
* @param size size of the matrix and temporary arrays
132
* @param tmp1Size temporary array
133
* @param tmp2Size temporary array
134
* @return true if inverse is computed, otherwise return false
135
* @note A is modified during the inversion.
136
*/
137
template
<
class
MatrixType>
138
bool
invertMatrix
(MatrixType& A, MatrixType& AI,
unsigned
int
size,
139
int
* tmp1Size,
140
typename
MatrixType::ElemPoinerType tmp2Size) {
141
if
(A.getNRow() != A.getNCol() || A.getNRow() != AI.getNRow() ||
142
A.getNCol() != AI.getNCol() || A.getNRow() != size) {
143
return
false
;
144
}
145
146
unsigned
int
i, j;
147
148
//
149
// Factor matrix; then begin solving for inverse one column at a time.
150
// Note: tmp1Size returned value is used later, tmp2Size is just working
151
// memory whose values are not used in LUSolveLinearSystem
152
//
153
if
(
LUFactorLinearSystem
(A, tmp1Size, size, tmp2Size) == 0) {
154
return
false
;
155
}
156
157
for
(j = 0; j < size; ++j) {
158
for
(i = 0; i < size; ++i) {
159
tmp2Size[i] = 0.0;
160
}
161
tmp2Size[j] = 1.0;
162
163
LUSolveLinearSystem
(A, tmp1Size, tmp2Size, size);
164
165
for
(i = 0; i < size; i++) {
166
AI(i, j) = tmp2Size[i];
167
}
168
}
169
170
return
true
;
171
}
172
173
/**
174
* Factor linear equations Ax = b using LU decompostion A = LU where L is
175
* lower triangular matrix and U is upper triangular matrix.
176
* @param A input square matrix
177
* @param index pivot indices
178
* @param size size of the matrix and temporary arrays
179
* @param tmpSize temporary array
180
* @return true if inverse is computed, otherwise return false
181
* @note A is modified during the inversion.
182
*/
183
template
<
class
MatrixType>
184
int
LUFactorLinearSystem
(MatrixType& A,
int
* index,
int
size,
185
typename
MatrixType::ElemPoinerType tmpSize) {
186
using
Real =
typename
MatrixType::ElemType;
187
188
int
i, j, k;
189
int
maxI = 0;
190
Real largest, temp1, temp2, sum;
191
192
//
193
// Loop over rows to get implicit scaling information
194
//
195
for
(i = 0; i < size; ++i) {
196
for
(largest = 0.0, j = 0; j < size; ++j) {
197
if
((temp2 = std::abs(A(i, j))) > largest) { largest = temp2; }
198
}
199
200
if
(largest == 0.0) {
201
std::cerr <<
"Unable to factor linear system"
;
202
return
0;
203
}
204
tmpSize[i] = 1.0 / largest;
205
}
206
//
207
// Loop over all columns using Crout's method
208
//
209
for
(j = 0; j < size; ++j) {
210
for
(i = 0; i < j; ++i) {
211
sum = A(i, j);
212
for
(k = 0; k < i; ++k) {
213
sum -= A(i, k) * A(k, j);
214
}
215
A(i, j) = sum;
216
}
217
//
218
// Begin search for largest pivot element
219
//
220
for
(largest = 0.0, i = j; i < size; ++i) {
221
sum = A(i, j);
222
for
(k = 0; k < j; ++k) {
223
sum -= A(i, k) * A(k, j);
224
}
225
A(i, j) = sum;
226
227
if
((temp1 = tmpSize[i] * std::abs(sum)) >= largest) {
228
largest = temp1;
229
maxI = i;
230
}
231
}
232
//
233
// Check for row interchange
234
//
235
if
(j != maxI) {
236
for
(k = 0; k < size; ++k) {
237
std::swap(A(maxI, k), A(j, k));
238
}
239
tmpSize[maxI] = tmpSize[j];
240
}
241
//
242
// Divide by pivot element and perform elimination
243
//
244
index[j] = maxI;
245
246
if
(std::abs(A(j, j)) <= SMALL_NUMBER) {
247
std::cerr <<
"Unable to factor linear system"
;
248
return
false
;
249
}
250
251
if
(j != (size - 1)) {
252
temp1 = 1.0 / A(j, j);
253
for
(i = j + 1; i < size; ++i) {
254
A(i, j) *= temp1;
255
}
256
}
257
}
258
259
return
1;
260
}
261
262
/**
263
* Solve linear equations Ax = b using LU decompostion A = LU where L is
264
* lower triangular matrix and U is upper triangular matrix.
265
* @param A input square matrix
266
* @param index pivot indices
267
* @param x vector
268
* @param size size of the matrix and temporary arrays
269
* @return true if inverse is computed, otherwise return false
270
* @note A=LU and index[] are generated from method LUFactorLinearSystem).
271
* Also, solution vector is written directly over input load vector.
272
*/
273
template
<
class
MatrixType>
274
void
LUSolveLinearSystem
(MatrixType& A,
int
* index,
275
typename
MatrixType::ElemPoinerType x,
int
size) {
276
using
Real =
typename
MatrixType::ElemType;
277
278
int
i, j, ii, idx;
279
Real sum;
280
//
281
// Proceed with forward and backsubstitution for L and U
282
// matrices. First, forward substitution.
283
//
284
for
(ii = -1, i = 0; i < size; ++i) {
285
idx = index[i];
286
sum = x[idx];
287
x[idx] = x[i];
288
289
if
(ii >= 0) {
290
for
(j = ii; j <= (i - 1); ++j) {
291
sum -= A(i, j) * x[j];
292
}
293
}
else
if
(sum != 0.0) {
294
ii = i;
295
}
296
297
x[i] = sum;
298
}
299
//
300
// Now, back substitution
301
//
302
for
(i = size - 1; i >= 0; i--) {
303
sum = x[i];
304
for
(j = i + 1; j < size; ++j) {
305
sum -= A(i, j) * x[j];
306
}
307
x[i] = sum / A(i, i);
308
}
309
}
310
}
// namespace OpenMD
311
312
#endif
OpenMD
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Definition
ActionCorrFunc.cpp:63
OpenMD::LUSolveLinearSystem
void LUSolveLinearSystem(MatrixType &A, int *index, typename MatrixType::ElemPoinerType x, int size)
Solve linear equations Ax = b using LU decompostion A = LU where L is lower triangular matrix and U i...
Definition
LU.hpp:274
OpenMD::LUFactorLinearSystem
int LUFactorLinearSystem(MatrixType &A, int *index, int size, typename MatrixType::ElemPoinerType tmpSize)
Factor linear equations Ax = b using LU decompostion A = LU where L is lower triangular matrix and U ...
Definition
LU.hpp:184
OpenMD::invertMatrix
bool invertMatrix(MatrixType &A, MatrixType &AI)
Invert input square matrix A into matrix AI.
Definition
LU.hpp:101
math
LU.hpp
Generated on
for OpenMD by
1.17.0