source: src/solver/dsysv.hpp@ 64ba929

Last change on this file since 64ba929 was dfed1c, checked in by Julian Iseringhausen <isering@…>, 14 years ago

Major vmg update.

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@1136 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 4.5 KB
RevLine 
[48b662]1/**
2 * @file dsysv.hpp
3 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
4 * @date Mon Apr 18 13:09:54 2011
5 *
6 * @brief Lapack solver for symmetric matrices
7 *
8 */
9
10#ifndef DSYSV_HPP_
11#define DSYSV_HPP_
12
13#ifndef HAVE_LAPACK
14#error You need LAPACK in order to use MGDSYSV
15#endif
16
17#include <cassert>
18#include <cstddef>
19
20#include "base/defs.hpp"
21
22namespace VMG
23{
24
25extern "C"
26{
27
28void FC_FUNC(dsysv, DSYSV) (const char* UPLO, const int* N, const int* NRHS,
29 double* A, const int* LDA, int* IPIV, double* B,
30 const int* LDB, double* WORK, const int* LWORK,
31 int* INFO);
32
33void FC_FUNC(dsyrfs, DSYRFS) (const char* UPLO, const int* N, const int* NRHS,
34 const vmg_float* A, const int* LDA, double* AF,
35 const int* LDAF, const int* IPIV, const vmg_float* B,
36 const int* LDB, double* X, const int* LDX,
37 double* FERR, double* BERR, double* WORK, int* IWORK,
38 int* INFO);
39
40void FC_FUNC(ssysv, SSYSV) (const char* UPLO, const int* N, const int* NRHS, float* A,
41 const int* LDA, int* IPIV, float* B, const int* LDB,
42 float* WORK, const int* LWORK, int* INFO);
43
44void FC_FUNC(ssyrfs, SSYRFS) (const char* UPLO, const int* N, const int* NRHS,
45 const vmg_float* A, const int* LDA, float* AF,
46 const int* LDAF, const int* IPIV, const vmg_float* B,
47 const int* LDB, float* X, const int* LDX, float* FERR,
48 float* BERR, double* WORK, int* IWORK, int* INFO);
49
50} /* extern "C" */
51
52/* By default, assume fcs_float is double. */
53#if defined(FCS_FLOAT_IS_FLOAT)
54#define dsysv FC_FUNC(ssysv, SSYSV)
55#define dsyrfs FC_FUNC(ssyrfs, SSYRFS)
56#else
57#define dsysv FC_FUNC(dsysv, DSYSV)
58#define dsyrfs FC_FUNC(dsyrfs, DSYRFS)
59#endif
60
61template<class T>
62class DSYSV : public T
63{
64public:
65 DSYSV() :
66 T()
67 {Init();}
68
69 virtual ~DSYSV();
70
71private:
72 void Init();
73 void Realloc();
74 void Compute();
75
76 char la_uplo;
77 int la_n, la_nrhs, *la_ipiv, la_lwork, la_info, *la_iwork;
78 vmg_float *la_A, *la_A_orig, *la_B, *la_B_orig, *la_work, *la_work2;
79
[dfed1c]80 int cur_lapack_size, max_lapack_size;
[48b662]81};
82
83template<class T>
84void DSYSV<T>::Compute()
85{
86 vmg_float ferr, berr;
87 vmg_float opt_work;
88
89 this->Realloc();
90
91 for (int i=0; i<this->cur_lapack_size; i++) {
92 la_B[i] = la_B_orig[i] = this->Rhs(i);
93 for (int j=i; j<this->cur_lapack_size; j++)
94 la_A[j + i*this->cur_lapack_size] = la_A_orig[j + i*this->cur_lapack_size] = this->Mat(i,j);
95 }
96
97 // Determine optimal size of working space
98 this->la_lwork = -1;
99 dsysv (&la_uplo, &la_n, &la_nrhs, la_A, &la_n, la_ipiv, la_B, &la_n, &opt_work, &la_lwork, &la_info);
100
101 // Resize working space
102 this->la_lwork = static_cast<int>(opt_work);
103 delete [] this->la_work;
104 this->la_work = new vmg_float[this->la_lwork];
105
106 // Solve system
107 dsysv (&la_uplo, &la_n, &la_nrhs, la_A, &la_n, la_ipiv, la_B, &la_n, la_work, &la_lwork, &la_info);
108
109 // Improve computed solution
110 dsyrfs (&la_uplo, &la_n, &la_nrhs, la_A_orig, &la_n, la_A, &la_n, la_ipiv, la_B_orig, &la_n, la_B, &la_n, &ferr, &berr, la_work2, la_iwork, &la_info);
111
112 // Write solution back
113 for (int i=0; i<this->cur_lapack_size; i++)
114 this->Sol(i) = this->la_B[i];
115}
116
117template<class T>
118void DSYSV<T>::Realloc()
119{
120 this->cur_lapack_size = this->Size();
121
122 if (this->cur_lapack_size > this->max_lapack_size) {
123
124 delete [] la_A;
125 delete [] la_A_orig;
126 delete [] la_B;
127 delete [] la_B_orig;
128 delete [] la_ipiv;
129 delete [] la_work2;
130 delete [] la_iwork;
131
132 this->la_A = new vmg_float[this->cur_lapack_size * this->cur_lapack_size];
133 this->la_A_orig = new vmg_float[this->cur_lapack_size * this->cur_lapack_size];
134 this->la_B = new vmg_float[this->cur_lapack_size];
135 this->la_B_orig = new vmg_float[this->cur_lapack_size];
136 this->la_ipiv = new int[this->cur_lapack_size];
137 this->la_work2 = new vmg_float[3 * this->cur_lapack_size];
138 this->la_iwork = new int[this->cur_lapack_size];
139
140 this->la_n = this->cur_lapack_size;
141
142 this->max_lapack_size = this->cur_lapack_size;
143
144 }
145}
146
147template<class T>
148void DSYSV<T>::Init()
149{
150 this->cur_lapack_size = 0;
151 this->max_lapack_size = 0;
152
153 this->la_A = NULL;
154 this->la_A_orig = NULL;
155 this->la_B = NULL;
156 this->la_B_orig = NULL;
157 this->la_work = NULL;
158 this->la_ipiv = NULL;
159 this->la_work2 = NULL;
160 this->la_iwork = NULL;
161
162 this->la_nrhs = 1;
163 this->la_uplo = 'L';
164}
165
166template<class T>
167DSYSV<T>::~DSYSV()
168{
169 delete [] this->la_A;
170 delete [] this->la_A_orig;
171 delete [] this->la_B;
172 delete [] this->la_B_orig;
173 delete [] this->la_work;
174 delete [] this->la_ipiv;
175 delete [] this->la_work2;
176 delete [] this->la_iwork;
177}
178
179}
180
181#endif /* DSYSV_HPP_ */
Note: See TracBrowser for help on using the repository browser.