num_matrix_diag.F90 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. !
  2. ! NAME
  3. ! num_matrix_diag - defines diag matrix
  4. !
  5. ! USAGE
  6. !
  7. ! use num_matrix_diag
  8. !
  9. ! type(TDiagMatrix) :: A
  10. !
  11. ! ! initialize matrix:
  12. ! ! o no memory allocated
  13. ! ! o zero flag
  14. ! call Init( A, 'matrix A' )
  15. !
  16. ! ! (re)allocate memory to store contents:
  17. ! call SetStorage( A, am )
  18. ! call ClearStorage( A )
  19. !
  20. ! ! zero flag ?
  21. ! if ( IsZero(A) ) ...
  22. !
  23. ! ! define diag matrix:
  24. ! call SetDiag( A, m, n )
  25. ! call SetDiag( A, arr(:) ) ! define as square matrix
  26. !
  27. ! ! done
  28. ! call Done( A )
  29. !
  30. module num_matrix_diag
  31. implicit none
  32. ! --- in/out ------------------------------------
  33. private
  34. public :: TDiagMatrix
  35. public :: Init, Done
  36. public :: SetStorage, ClearStorage
  37. public :: IsZero
  38. public :: SetDiag
  39. ! --- const ----------------------------------
  40. character(len=*), parameter :: mname = 'module num_matrix_diag'
  41. ! --- types ------------------------------------
  42. type TDiagMatrix
  43. ! key name for error mesages
  44. character(len=20) :: key
  45. ! logical matrix dimension:
  46. integer :: m, n
  47. ! contents flags
  48. logical :: zero
  49. ! physical storage:
  50. real, pointer :: a(:)
  51. integer :: am
  52. integer :: knd
  53. end type TDiagMatrix
  54. ! --- interfaces ------------------------------
  55. interface Init
  56. module procedure mat_Init
  57. end interface
  58. interface Done
  59. module procedure mat_Done
  60. end interface
  61. interface SetStorage
  62. module procedure mat_SetStorage
  63. end interface
  64. interface ClearStorage
  65. module procedure mat_ClearStorage
  66. end interface
  67. interface IsZero
  68. module procedure mat_IsZero
  69. end interface
  70. interface SetDiag
  71. module procedure mat_SetDiag_range
  72. module procedure mat_SetDiag_array
  73. end interface
  74. contains
  75. ! ==============================================================
  76. subroutine mat_Init( mat, key )
  77. ! --- in/out ------------------------------
  78. type(TDiagMatrix), intent(out) :: mat
  79. character(len=*), intent(in) :: key
  80. ! --- const ----------------------------------
  81. character(len=*), parameter :: name = mname//', mat_Init'
  82. ! --- begin -------------------------------
  83. ! store key
  84. mat%key = key
  85. ! dummy size:
  86. mat%m = 0
  87. mat%n = 0
  88. ! start with zero matrix:
  89. mat%zero = .true.
  90. ! initialize physical storage
  91. nullify( mat%a )
  92. mat%knd = kind(1.0)
  93. end subroutine mat_Init
  94. ! ***
  95. subroutine mat_Done( mat )
  96. ! --- in/out ------------------------------
  97. type(TDiagMatrix), intent(inout) :: mat
  98. ! --- const ----------------------------------
  99. character(len=*), parameter :: name = mname//', mat_Done'
  100. ! --- begin -------------------------------
  101. ! clear memory ...
  102. call ClearStorage( mat )
  103. end subroutine mat_Done
  104. ! =========================================================
  105. subroutine mat_SetStorage( mat, am )
  106. ! --- in/out ------------------------------
  107. type(TDiagMatrix), intent(inout) :: mat
  108. integer, intent(in) :: am
  109. ! --- const ----------------------------------
  110. character(len=*), parameter :: name = mname//', mat_SetStorage'
  111. ! --- local -------------------------------
  112. integer :: stat
  113. ! --- begin -------------------------------
  114. ! check ...
  115. if ( (am < 1) ) then
  116. write (*,'("ERROR - strange storage definition:")')
  117. write (*,'("ERROR - storage : ",i6)') am
  118. write (*,'("ERROR - matrix key : ",a)') mat%key
  119. write (*,'("ERROR in ",a)') name; stop
  120. end if
  121. ! set maximum shape:
  122. mat%am = am
  123. ! allocate memory:
  124. if ( associated(mat%a) ) then
  125. if ( size(mat%a) /= mat%am ) then
  126. deallocate( mat%a, stat=stat )
  127. if ( stat /= 0 ) then
  128. write (*,'("ERROR - error during deallocation of matrix;")')
  129. write (*,'("ERROR - status : ",i6)') stat
  130. write (*,'("ERROR - matrix key : ",a)') mat%key
  131. write (*,'("ERROR in ",a)') name; stop
  132. end if
  133. end if
  134. end if
  135. if ( .not. associated(mat%a) ) then
  136. allocate( mat%a(mat%am), stat=stat )
  137. if ( stat /= 0 ) then
  138. write (*,'("ERROR - error during allocation of matrix;")')
  139. write (*,'("ERROR - status : ",i6)') stat
  140. write (*,'("ERROR - matrix key : ",a)') mat%key
  141. write (*,'("ERROR in ",a)') name; stop
  142. end if
  143. end if
  144. ! not zero anymore
  145. mat%zero = .false.
  146. end subroutine mat_SetStorage
  147. ! ***
  148. subroutine mat_ClearStorage( mat )
  149. ! --- in/out ------------------------------
  150. type(TDiagMatrix), intent(inout) :: mat
  151. ! --- const ----------------------------------
  152. character(len=*), parameter :: name = mname//', mat_ClearStorage'
  153. ! --- local -------------------------------
  154. integer :: stat
  155. ! --- begin -------------------------------
  156. ! remove physical storage ...
  157. if ( associated(mat%a) ) then
  158. deallocate( mat%a, stat=stat )
  159. if ( stat /= 0 ) then
  160. write (*,'("ERROR - error during deallocation of matrix;")')
  161. write (*,'("ERROR - status : ",i6)') stat
  162. write (*,'("ERROR - matrix key : ",a)') mat%key
  163. write (*,'("ERROR in ",a)') name; stop
  164. end if
  165. nullify( mat%a )
  166. end if
  167. end subroutine mat_ClearStorage
  168. ! =========================================================
  169. logical function mat_IsZero( mat )
  170. ! --- in/out ------------------------------
  171. type(TDiagMatrix), intent(in) :: mat
  172. ! --- begin -------------------------------
  173. mat_IsZero = mat%zero
  174. end function mat_IsZero
  175. ! =========================================================
  176. subroutine mat_SetDiag_range( mat, m, n )
  177. ! --- in/out ------------------------------
  178. type(TDiagMatrix), intent(inout) :: mat
  179. integer, intent(in) :: m, n
  180. ! --- const ----------------------------------
  181. character(len=*), parameter :: name = mname//', mat_SetDiag_range'
  182. ! --- begin -------------------------------
  183. ! memory allocated ?
  184. if ( .not. associated(mat%a) ) then
  185. write (*,'("ERROR - no storage allocated")')
  186. write (*,'("ERROR - matrix key : ",a)') mat%key
  187. write (*,'("ERROR in ",a)') name; stop
  188. end if
  189. ! check ...
  190. if ( (m < 1) .or. (n < 1) .or. &
  191. (min(m,n) > mat%am) ) then
  192. write (*,'("ERROR - strange diag matrix definition:")')
  193. write (*,'("ERROR - matrix shape : ",2i6)') m, n
  194. write (*,'("ERROR - storage : ",2i6)') mat%am
  195. write (*,'("ERROR - matrix key : ",a)') mat%key
  196. write (*,'("ERROR in ",a)') name; stop
  197. end if
  198. ! logical shape of the matrix:
  199. mat%m = m
  200. mat%n = n
  201. end subroutine mat_SetDiag_range
  202. ! ***
  203. subroutine mat_SetDiag_array( mat, arr )
  204. ! --- in/out ------------------------------
  205. type(TDiagMatrix), intent(inout) :: mat
  206. real, intent(in) :: arr(:)
  207. ! --- const ----------------------------------
  208. character(len=*), parameter :: name = mname//', mat_SetDiag_array'
  209. ! --- local --------------------------------
  210. integer :: m, n
  211. ! --- begin -------------------------------
  212. ! extract shape; square matrix with arr(:) as diagonal
  213. m = size(arr)
  214. n = size(arr)
  215. ! set shape etc, checks included:
  216. call SetDiag( mat, m, n )
  217. ! fill contents
  218. mat%a(1:m) = arr
  219. end subroutine mat_SetDiag_array
  220. end module num_matrix_diag