ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/math/LU.hpp
Revision: 2596
Committed: Wed Feb 22 20:35:16 2006 UTC (18 years, 4 months ago) by tim
File size: 9893 byte(s)
Log Message:
Adding Hydrodynamics Module

File Contents

# Content
1 /*
2 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 *
4 * The University of Notre Dame grants you ("Licensee") a
5 * non-exclusive, royalty free, license to use, modify and
6 * redistribute this software in source and binary code form, provided
7 * that the following conditions are met:
8 *
9 * 1. Acknowledgement of the program authors must be made in any
10 * publication of scientific results based in part on use of the
11 * program. An acceptable form of acknowledgement is citation of
12 * the article in which the program was described (Matthew
13 * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 * Parallel Simulation Engine for Molecular Dynamics,"
16 * J. Comput. Chem. 26, pp. 252-271 (2005))
17 *
18 * 2. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 3. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * This software is provided "AS IS," without a warranty of any
27 * kind. All express or implied conditions, representations and
28 * warranties, including any implied warranty of merchantability,
29 * fitness for a particular purpose or non-infringement, are hereby
30 * excluded. The University of Notre Dame and its licensors shall not
31 * be liable for any damages suffered by licensee as a result of
32 * using, modifying or distributing the software or its
33 * derivatives. In no event will the University of Notre Dame or its
34 * licensors be liable for any lost revenue, profit or data, or for
35 * direct, indirect, special, consequential, incidental or punitive
36 * damages, however caused and regardless of the theory of liability,
37 * arising out of the use of or inability to use software, even if the
38 * University of Notre Dame has been advised of the possibility of
39 * such damages.
40 */
41
42 /*=========================================================================
43
44 Program: Visualization Toolkit
45 Module: $RCSfile: LU.hpp,v $
46
47 Copyright (c) 1993-2003 Ken Martin, Will Schroeder, Bill Lorensen
48 All rights reserved.
49
50 Redistribution and use in source and binary forms, with or without
51 modification, are permitted provided that the following conditions are met:
52
53 * Redistributions of source code must retain the above copyright notice,
54 this list of conditions and the following disclaimer.
55
56 * Redistributions in binary form must reproduce the above copyright notice,
57 this list of conditions and the following disclaimer in the documentation
58 and/or other materials provided with the distribution.
59
60 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
61 of any contributors may be used to endorse or promote products derived
62 from this software without specific prior written permission.
63
64 * Modified source versions must be plainly marked as such, and must not be
65 misrepresented as being the original software.
66
67 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
68 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
69 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
70 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
71 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
72 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
73 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
74 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
75 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
76 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77
78 =========================================================================*/
79 #ifndef MATH_LU_HPP
80 #define MATH_LU_HPP
81
82 #include "utils/NumericConstant.hpp"
83
84 namespace oopse {
85
86 /**
87 * Invert input square matrix A into matrix AI.
88 * @param A input square matrix
89 * @param AI output square matrix
90 * @return true if inverse is computed, otherwise return false
91 * @note A is modified during the inversion
92 */
93 template<class MatrixType>
94 bool invertMatrix(MatrixType& A, MatrixType& AI)
95 {
96 typedef typename MatrixType::ElemType Real;
97 if (A.getNRow() != A.getNCol() || A.getNRow() != AI.getNRow() || A.getNCol() != AI.getNCol()) {
98 return false;
99 }
100
101 int size = A.getNRow();
102 int *index=NULL, iScratch[10];
103 Real *column=NULL, dScratch[10];
104
105 // Check on allocation of working vectors
106 //
107 if ( size <= 10 ) {
108 index = iScratch;
109 column = dScratch;
110 } else {
111 index = new int[size];
112 column = new Real[size];
113 }
114
115 bool retVal = invertMatrix(A, AI, size, index, column);
116
117 if ( size > 10 ) {
118 delete [] index;
119 delete [] column;
120 }
121
122 return retVal;
123 }
124
125 /**
126 * Invert input square matrix A into matrix AI (Thread safe versions).
127 * @param A input square matrix
128 * @param AI output square matrix
129 * @param size size of the matrix and temporary arrays
130 * @param tmp1Size temporary array
131 * @param tmp2Size temporary array
132 * @return true if inverse is computed, otherwise return false
133 * @note A is modified during the inversion.
134 */
135
136 template<class MatrixType>
137 bool invertMatrix(MatrixType& A , MatrixType& AI, int size,
138 int *tmp1Size, typename MatrixType::ElemPoinerType tmp2Size)
139 {
140 if (A.getNRow() != A.getNCol() || A.getNRow() != AI.getNRow() || A.getNCol() != AI.getNCol() || A.getNRow() != size) {
141 return false;
142 }
143
144 int i, j;
145
146 //
147 // Factor matrix; then begin solving for inverse one column at a time.
148 // Note: tmp1Size returned value is used later, tmp2Size is just working
149 // memory whose values are not used in LUSolveLinearSystem
150 //
151 if ( LUFactorLinearSystem(A, tmp1Size, size, tmp2Size) == 0 ){
152 return false;
153 }
154
155 for ( j=0; j < size; j++ ) {
156 for ( i=0; i < size; i++ ) {
157 tmp2Size[i] = 0.0;
158 }
159 tmp2Size[j] = 1.0;
160
161 LUSolveLinearSystem(A,tmp1Size,tmp2Size,size);
162
163 for ( i=0; i < size; i++ ) {
164 AI(i, j) = tmp2Size[i];
165 }
166 }
167
168 return true;
169 }
170
171 /**
172 * Factor linear equations Ax = b using LU decompostion A = LU where L is
173 * lower triangular matrix and U is upper triangular matrix.
174 * @param A input square matrix
175 * @param index pivot indices
176 * @param size size of the matrix and temporary arrays
177 * @param tmpSize temporary array
178 * @return true if inverse is computed, otherwise return false
179 * @note A is modified during the inversion.
180 */
181 template<class MatrixType>
182 int LUFactorLinearSystem(MatrixType& A, int *index, int size,
183 typename MatrixType::ElemPoinerType tmpSize)
184 {
185 typedef typename MatrixType::ElemType Real;
186 int i, j, k;
187 int maxI = 0;
188 Real largest, temp1, temp2, sum;
189
190 //
191 // Loop over rows to get implicit scaling information
192 //
193 for ( i = 0; i < size; i++ ) {
194 for ( largest = 0.0, j = 0; j < size; j++ ) {
195 if ( (temp2 = fabs(A(i, j))) > largest ) {
196 largest = temp2;
197 }
198 }
199
200 if ( largest == 0.0 ) {
201 //vtkGenericWarningMacro(<<"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]*fabs(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 temp1 = A(maxI, k);
238 A(maxI, k) = A(j, k);
239 A(j, k) = temp1;
240 }
241 tmpSize[maxI] = tmpSize[j];
242 }
243 //
244 // Divide by pivot element and perform elimination
245 //
246 index[j] = maxI;
247
248 if ( fabs(A(j, j)) <= oopse::NumericConstant::epsilon ) {
249 //vtkGenericWarningMacro(<<"Unable to factor linear system");
250 return false;
251 }
252
253 if ( j != (size-1) ) {
254 temp1 = 1.0 / A(j, j);
255 for ( i = j + 1; i < size; i++ ) {
256 A(i, j) *= temp1;
257 }
258 }
259 }
260
261 return 1;
262 }
263
264 /**
265 * Solve linear equations Ax = b using LU decompostion A = LU where L is
266 * lower triangular matrix and U is upper triangular matrix.
267 * @param A input square matrix
268 * @param index pivot indices
269 * @param size size of the matrix and temporary arrays
270 * @param tmpSize temporary array
271 * @return true if inverse is computed, otherwise return false
272 * @note A=LU and index[] are generated from method LUFactorLinearSystem).
273 * Also, solution vector is written directly over input load vector.
274 */
275 template<class MatrixType>
276 void LUSolveLinearSystem(MatrixType& A, int *index,
277 typename MatrixType::ElemPoinerType x, int size)
278 {
279 typedef typename MatrixType::ElemType Real;
280 int i, j, ii, idx;
281 Real sum;
282 //
283 // Proceed with forward and backsubstitution for L and U
284 // matrices. First, forward substitution.
285 //
286 for ( ii = -1, i = 0; i < size; i++ ) {
287 idx = index[i];
288 sum = x[idx];
289 x[idx] = x[i];
290
291 if ( ii >= 0 ) {
292 for ( j = ii; j <= (i-1); j++ ) {
293 sum -= A(i, j)*x[j];
294 }
295 } else if (sum) {
296 ii = i;
297 }
298
299 x[i] = sum;
300 }
301 //
302 // Now, back substitution
303 //
304 for ( i = size-1; i >= 0; i-- ) {
305 sum = x[i];
306 for ( j = i + 1; j < size; j++ ) {
307 sum -= A(i, j)*x[j];
308 }
309 x[i] = sum / A(i, i);
310 }
311 }
312
313 }
314
315 #endif

Properties

Name Value
svn:executable *