Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RFLU_InvertMatrixSVD.F90
Go to the documentation of this file.
1 ! *********************************************************************
2 ! * Rocstar Simulation Suite *
3 ! * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4 ! * *
5 ! * Illinois Rocstar LLC *
6 ! * Champaign, IL *
7 ! * www.illinoisrocstar.com *
8 ! * sales@illinoisrocstar.com *
9 ! * *
10 ! * License: See LICENSE file in top level of distribution package or *
11 ! * http://opensource.org/licenses/NCSA *
12 ! *********************************************************************
13 ! *********************************************************************
14 ! * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15 ! * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16 ! * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17 ! * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18 ! * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19 ! * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20 ! * Arising FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21 ! * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22 ! *********************************************************************
23 ! ******************************************************************************
24 !
25 ! Purpose: Invert general m-by-n matrix A using SVD
26 !
27 ! Description: None.
28 !
29 ! Input:
30 ! global Pointer to global data
31 ! nRows Number of rows of A
32 ! nCols Number of columns of A
33 ! a Matrix A, to be inverted
34 !
35 ! Output:
36 ! aInv Inverse of A
37 ! sCount Number of singular values below threshold
38 !
39 ! Notes:
40 ! 1. Uses LAPACK routines to carry out SVD.
41 !
42 ! ******************************************************************************
43 !
44 ! $Id: RFLU_InvertMatrixSVD.F90,v 1.9 2008/12/06 08:44:12 mtcampbe Exp $
45 !
46 ! Copyright: (c) 2002-2005 by the University of Illinois
47 !
48 ! ******************************************************************************
49 
50 SUBROUTINE rflu_invertmatrixsvd(global,nRows,nCols,a,aInv,sCount)
51 
52  USE moddatatypes
53  USE moderror
54  USE modglobal, ONLY: t_global
55 
56  USE modsortsearch
57 
58  IMPLICIT NONE
59 
60 ! ******************************************************************************
61 ! Definitions and declarations
62 ! ******************************************************************************
63 
64 ! ==============================================================================
65 ! Arguments
66 ! ==============================================================================
67 
68  INTEGER, INTENT(IN) :: nrows,ncols
69  INTEGER, INTENT(OUT), OPTIONAL :: scount
70  REAL(RFREAL) :: a(nrows,ncols),ainv(ncols,nrows)
71  TYPE(t_global), POINTER :: global
72 
73 ! ==============================================================================
74 ! Locals
75 ! ==============================================================================
76 
77  CHARACTER(CHRLEN) :: rcsidentstring
78  INTEGER :: errorflag,i,info,j,workarrayrealsize
79  INTEGER :: workarrayint(8*ncols)
80  REAL(RFREAL) :: s(ncols)
81  REAL(RFREAL), DIMENSION(:), ALLOCATABLE :: workarrayreal
82  REAL(RFREAL) :: sinv(ncols,nrows),u(nrows,nrows),vt(ncols,ncols), &
83  v(ncols,ncols)
84 
85 ! ******************************************************************************
86 ! Start
87 ! ******************************************************************************
88 
89  rcsidentstring = '$RCSfile: RFLU_InvertMatrixSVD.F90,v $ $Revision: 1.9 $'
90 
91  CALL registerfunction(global,'RFLU_InvertMatrixSVD',&
92  'RFLU_InvertMatrixSVD.F90')
93 
94 ! ******************************************************************************
95 ! Set work array size and allocate memory
96 ! ******************************************************************************
97 
98  workarrayrealsize = 2*(4*ncols*ncols + nrows + 9*ncols)
99 
100  ALLOCATE(workarrayreal(workarrayrealsize),stat=errorflag)
101  global%error = errorflag
102  IF ( global%error /= err_none ) THEN
103  CALL errorstop(global,err_allocate,__line__,'workArrayReal')
104  END IF ! global%error
105 
106 ! ******************************************************************************
107 ! Perform SVD
108 ! ******************************************************************************
109 
110  CALL dgesdd('A',nrows,ncols,a,nrows,s,u,nrows,vt,ncols,workarrayreal, &
111  workarrayrealsize,workarrayint,info)
112  global%error = info
113  IF ( global%error /= err_none ) THEN
114  CALL errorstop(global,err_lapack_output,__line__)
115  END IF ! global%error
116 
117 ! ******************************************************************************
118 ! Construct actual singular-value matrix
119 ! ******************************************************************************
120 
121  scount = 0
122 
123  DO i = 1,ncols ! Explicit loop to avoid Frost problem
124  DO j = 1,nrows
125  sinv(i,j) = 0.0_rfreal
126  END DO ! j
127  END DO ! i
128 
129 ! Based on absolute size
130 ! DO i = 1,nCols
131 ! IF ( s(i) > 100.0_RFREAL*EPSILON(1.0_RFREAL) ) THEN
132 ! sInv(i,i) = 1.0_RFREAL/s(i)
133 ! ELSE
134 ! sInv(i,i) = 0.0_RFREAL
135 ! sCount = sCount + 1
136 ! END IF ! s
137 ! END DO ! i
138 
139 ! Based on ratio of successive singular values
140  IF ( s(1) > 100.0_rfreal*epsilon(1.0_rfreal) ) THEN
141  sinv(1,1) = 1.0_rfreal/s(1)
142  ELSE
143  sinv(1,1) = 0.0_rfreal
144  scount = 1
145  END IF ! s
146 
147  outerloop: DO i = 2,ncols
148  IF ( s(i) > 0.01_rfreal*s(i-1) ) THEN
149  sinv(i,i) = 1.0_rfreal/s(i)
150  ELSE
151  sinv(i,i) = 0.0_rfreal
152  scount = scount + 1
153 
154  DO j = i+1,ncols
155  sinv(j,j) = 0.0_rfreal
156  scount = scount + 1
157  END DO ! j
158 
159  EXIT outerloop
160  END IF ! s
161  END DO outerloop
162 
163 ! ******************************************************************************
164 ! Compute inverse
165 ! ******************************************************************************
166 
167  ainv = matmul(transpose(vt),matmul(sinv,transpose(u))) ! Lapack
168 
169 ! ******************************************************************************
170 ! End
171 ! ******************************************************************************
172 
173  DEALLOCATE(workarrayreal,stat=errorflag)
174  global%error = errorflag
175  IF ( global%error /= err_none ) THEN
176  CALL errorstop(global,err_deallocate,__line__,'workArrayReal')
177  END IF ! global%error
178 
179  CALL deregisterfunction(global)
180 
181 END SUBROUTINE rflu_invertmatrixsvd
182 
183 ! ******************************************************************************
184 !
185 ! RCS Revision history:
186 !
187 ! $Log: RFLU_InvertMatrixSVD.F90,v $
188 ! Revision 1.9 2008/12/06 08:44:12 mtcampbe
189 ! Updated license.
190 !
191 ! Revision 1.8 2008/11/19 22:17:25 mtcampbe
192 ! Added Illinois Open Source License/Copyright
193 !
194 ! Revision 1.7 2006/04/07 15:19:16 haselbac
195 ! Removed tabs
196 !
197 ! Revision 1.6 2005/10/05 13:51:42 haselbac
198 ! Cosmetics
199 !
200 ! Revision 1.5 2003/12/04 03:23:56 haselbac
201 ! Fixed bug, changed init, added new method of detecting singularity
202 !
203 ! Revision 1.4 2003/07/22 01:56:50 haselbac
204 ! Change to init of sInv and cosmetics
205 !
206 ! Revision 1.3 2002/10/08 15:48:56 haselbac
207 ! {IO}STAT=global%error replaced by {IO}STAT=errorFlag - SGI problem
208 !
209 ! Revision 1.2 2002/09/09 14:15:01 haselbac
210 ! global now under regions, bug fix: workArrayReal not deallocated
211 !
212 ! Revision 1.1 2002/07/25 14:34:59 haselbac
213 ! Initial revision
214 !
215 ! ******************************************************************************
216 
217 
218 
219 
220 
221 
222 
double s
Definition: blastest.C:80
subroutine ainv(ajac, ajacin, det, ndim)
Definition: ainv.f90:53
subroutine rflu_invertmatrixsvd(global, nRows, nCols, a, aInv, sCount)
subroutine registerfunction(global, funName, fileName)
Definition: ModError.F90:449
subroutine dgesdd(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
blockLoc i
Definition: read.cpp:79
j indices j
Definition: Indexing.h:6
subroutine errorstop(global, errorCode, errorLine, addMessage)
Definition: ModError.F90:483
subroutine deregisterfunction(global)
Definition: ModError.F90:469
RT a() const
Definition: Line_2.h:140