1
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
3
// See the LICENSE.txt file for license information. Please report all
4
// bugs and problems to <gmsh@geuz.org>.
9
#include "GmshConfig.h"
10
#include "GmshMessage.h"
11
#include "linearSystemCSR.h"
13
#define SWAP(a,b) temp=(a);(a)=(b);(b)=temp;
14
#define SWAPI(a,b) tempi=(a);(a)=(b);(b)=tempi;
16
static void *CSRMalloc(size_t size)
19
if (!size) return(NULL);
24
static void *CSRRealloc(void *ptr, size_t size)
26
if (!size) return(NULL);
27
ptr = realloc(ptr,size);
31
static void CSRList_Realloc(CSRList_T *liste,int n)
35
if (liste->array == NULL) {
36
liste->nmax = ((n - 1) / liste->incr + 1) * liste->incr;
37
liste->array = (char *)CSRMalloc(liste->nmax * liste->size);
40
if (n > liste->nmax) {
41
liste->nmax = ((n - 1) / liste->incr + 1) * liste->incr;
42
temp = (char *)CSRRealloc(liste->array, liste->nmax * liste->size);
49
static CSRList_T *CSRList_Create(int n, int incr, int size)
54
if (incr <= 0) incr = 1;
56
liste = (CSRList_T *)CSRMalloc(sizeof(CSRList_T));
65
CSRList_Realloc(liste,n);
69
static void CSRList_Delete(CSRList_T *liste)
77
void CSRList_Add(CSRList_T *liste, void *data)
81
CSRList_Realloc(liste,liste->n);
83
memcpy(&liste->array[(liste->n - 1) * liste->size],data,liste->size);
86
int CSRList_Nbr(CSRList_T *liste)
92
void linearSystemCSR<double>::allocate(int _nbRows)
98
CSRList_Delete(jptr_);
115
a_ = CSRList_Create (_nbRows, _nbRows, sizeof(double));
116
ai_ = CSRList_Create (_nbRows, _nbRows, sizeof(INDEX_TYPE));
117
ptr_ = CSRList_Create (_nbRows, _nbRows, sizeof(INDEX_TYPE));
118
jptr_ = CSRList_Create (_nbRows+1, _nbRows, sizeof(INDEX_TYPE));
120
something = new char[_nbRows];
122
for (int i=0;i<_nbRows;i++)something[i] = 0;
124
_b = new std::vector<double>(_nbRows);
125
_x = new std::vector<double>(_nbRows);
128
const int NSTACK = 50;
129
const unsigned int M_sort2 = 7;
131
static void free_ivector(int *v, long nl, long nh)
133
// free an int vector allocated with ivector()
134
free((char*)(v+nl-1));
137
static int *ivector(long nl, long nh)
139
// allocate an int vector with subscript range v[nl..nh]
141
v=(int *)malloc((size_t) ((nh-nl+2)*sizeof(int)));
142
if (!v) fprintf(stderr, "allocation failure in ivector()\n");
146
static int cmpij(INDEX_TYPE ai,INDEX_TYPE aj,INDEX_TYPE bi,INDEX_TYPE bj)
155
template <class scalar>
156
static void _sort2_xkws(unsigned long n, double arr[], INDEX_TYPE ai[], INDEX_TYPE aj[])
158
unsigned long i,ir=n,j,k,l=1;
159
int *istack,jstack=0;
164
istack=ivector(1,NSTACK);
166
if (ir-l < M_sort2) {
167
for (j=l+1;j<=ir;j++) {
171
for (i=j-1;i>=1;i--) {
172
if (cmpij(ai[i -1],aj[i -1],b,c) <= 0) break;
173
arr[i+1 -1]=arr[i -1];
182
free_ivector(istack,1,NSTACK);
191
SWAP(arr[k -1],arr[l+1 -1])
192
SWAPI(ai[k -1],ai[l+1 -1])
193
SWAPI(aj[k -1],aj[l+1 -1])
194
if (cmpij(ai[l+1 -1],aj[l+1 -1],ai[ir -1],aj[ir -1])>0){
195
SWAP(arr[l+1 -1],arr[ir -1])
196
SWAPI(ai[l+1 -1],ai[ir -1])
197
SWAPI(aj[l+1 -1],aj[ir -1])
199
if (cmpij(ai[l -1],aj[l -1],ai[ir -1],aj[ir -1])>0){
200
SWAP(arr[l -1],arr[ir -1])
201
SWAPI(ai[l -1],ai[ir -1])
202
SWAPI(aj[l -1],aj[ir -1])
204
if (cmpij(ai[l+1 -1],aj[l+1 -1],ai[l -1],aj[l -1])>0){
205
SWAP(arr[l+1 -1],arr[l -1])
206
SWAPI(ai[l+1 -1],ai[l -1])
207
SWAPI(aj[l+1 -1],aj[l -1])
215
do i++; while (cmpij(ai[i -1],aj[i -1],b,c) < 0);
216
do j--; while (cmpij(ai[j -1],aj[j -1],b,c) > 0);
218
SWAP(arr[i -1],arr[j -1])
219
SWAPI(ai[i -1],ai[j -1])
220
SWAPI(aj[i -1],aj[j -1])
229
if (jstack > NSTACK) {
230
Msg::Fatal("NSTACK too small while sorting the columns of the matrix");
247
template <class scalar>
248
static void sortColumns(int NbLines,
255
// replace pointers by lines
256
int *count = new int [NbLines];
258
for(int i=0;i<NbLines;i++){
260
INDEX_TYPE _position = jptr[i];
263
INDEX_TYPE _position_temp = _position;
264
_position = ptr[_position];
265
ptr[_position_temp] = i;
266
if (_position == 0) break;
269
_sort2_xkws<double>(nnz,a,ptr,ai);
271
for(int i=1;i<=NbLines;i++){
272
jptr[i] = jptr[i-1] + count[i-1];
275
for(int i=0;i<NbLines;i++){
276
for (int j= jptr[i] ; j<jptr[i+1]-1 ; j++){
285
#if defined(HAVE_GMM)
290
int linearSystemCSRGmm<double>::systemSolve()
293
sortColumns(_b->size(),
295
(INDEX_TYPE *) ptr_->array,
296
(INDEX_TYPE *) jptr_->array,
297
(INDEX_TYPE *) ai_->array,
298
(double*) a_->array);
301
gmm::csr_matrix_ref<double*,INDEX_TYPE *,INDEX_TYPE *, 0>
302
ref((double*)a_->array, (INDEX_TYPE *) ai_->array,
303
(INDEX_TYPE *)jptr_->array, _b->size(), _b->size());
304
gmm::csr_matrix<double,0> M;
307
gmm::ildltt_precond<gmm::csr_matrix<double, 0> > P(M, 10, 1.e-10);
308
gmm::iteration iter(_prec);
309
iter.set_noisy(_noisy);
310
if(_gmres) gmm::gmres(M, *_x, *_b, P, 100, iter);
311
else gmm::cg(M, *_x, *_b, P, iter);