35 static int find_position(
int *Ai,
int Alen,
int idx)
41 register int lo = 0, hi = Alen - 1, mid;
47 if(idx < Ai[mid]) hi = mid - 1;
48 else if(idx > Ai[mid]) lo = mid + 1;
62 template<
typename Scalar>
63 CSCMatrix<Scalar>::CSCMatrix()
65 this->size = 0; nnz = 0;
71 template<
typename Scalar>
72 CSCMatrix<Scalar>::CSCMatrix(
unsigned int size)
78 template<
typename Scalar>
79 CSCMatrix<Scalar>::~CSCMatrix()
84 template<
typename Scalar>
85 void CSCMatrix<Scalar>::multiply_with_vector(Scalar* vector_in, Scalar* vector_out)
88 for (
int j = 0; j<n; j++) vector_out[j] = 0;
89 for (
int j = 0; j<n; j++)
91 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
93 vector_out[Ai[i]] += vector_in[j]*Ax[i];
98 template<
typename Scalar>
99 void CSCMatrix<Scalar>::multiply_with_Scalar(Scalar value)
101 for (
unsigned int i = 0; i < this->nnz; i++) Ax[i] *= value;
104 template<
typename Scalar>
105 void CSCMatrix<Scalar>::alloc()
107 assert(this->pages != NULL);
110 Ap =
new int[this->size + 1];
111 int aisize = this->get_num_indices();
112 Ai =
new int[aisize];
117 for (i = 0; i < this->size; i++)
120 pos += this->sort_and_store_indices(this->pages[i], Ai + pos, Ai + aisize);
124 delete [] this->pages;
127 nnz = Ap[this->size];
129 Ax =
new Scalar[nnz];
130 memset(Ax, 0,
sizeof(Scalar) * nnz);
133 template<
typename Scalar>
134 void CSCMatrix<Scalar>::free()
154 template<
typename Scalar>
155 Scalar CSCMatrix<Scalar>::get(
unsigned int m,
unsigned int n)
158 int mid = find_position(Ai + Ap[n], Ap[n + 1] - Ap[n], m);
163 return Ax[Ap[n] + mid];
166 template<
typename Scalar>
167 void CSCMatrix<Scalar>::zero()
169 memset(Ax, 0,
sizeof(Scalar) * nnz);
173 void CSCMatrix<double>::add(
unsigned int m,
unsigned int n,
double v)
178 int pos = find_position(Ai + Ap[n], Ap[n + 1] - Ap[n], m);
182 this->info(
"CSCMatrix<Scalar>::add(): i = %d, j = %d.", m, n);
187 Ax[Ap[n] + pos] += v;
192 void CSCMatrix<std::complex<double> >::add(
unsigned int m,
unsigned int n, std::complex<double> v)
197 int pos = find_position(Ai + Ap[n], Ap[n + 1] - Ap[n], m);
201 this->info(
"CSCMatrix<Scalar>::add(): i = %d, j = %d.", m, n);
206 Ax[Ap[n] + pos] += v;
210 template<
typename Scalar>
211 void CSCMatrix<Scalar>::add_to_diagonal_blocks(
int num_stages, CSCMatrix<Scalar>* mat_block)
213 int ndof = mat_block->get_size();
214 if(this->get_size() != (
unsigned int) num_stages * ndof)
217 for (
int i = 0; i < num_stages; i++)
219 this->add_as_block(ndof*i, ndof*i, mat_block);
223 template<
typename Scalar>
224 void CSCMatrix<Scalar>::add_sparse_to_diagonal_blocks(
int num_stages, SparseMatrix<Scalar>* mat)
226 add_to_diagonal_blocks(num_stages,
static_cast<CSCMatrix<Scalar>*
>(mat));
229 template<
typename Scalar>
230 unsigned int CSCMatrix<Scalar>::get_nnz()
const
235 template<
typename Scalar>
236 void CSCMatrix<Scalar>::add_as_block(
unsigned int offset_i,
unsigned int offset_j, CSCMatrix<Scalar>* mat)
238 UMFPackIterator<Scalar> mat_it(mat);
239 UMFPackIterator<Scalar> this_it(
this);
242 bool this_not_empty = this_it.init();
247 bool mat_not_finished = mat_it.init();
252 while(mat_not_finished)
254 mat_it.get_current_position(mat_i, mat_j, mat_val);
255 bool found = this_it.move_to_position(mat_i + offset_i, mat_j + offset_j);
258 mat_i + offset_i, mat_j + offset_j);
259 this_it.add_to_current_position(mat_val);
260 mat_not_finished = mat_it.move_ptr();
264 template<
typename Scalar>
265 void CSCMatrix<Scalar>::add_matrix(CSCMatrix<Scalar>* mat)
267 assert(this->get_size() == mat->get_size());
269 UMFPackIterator<Scalar> mat_it(mat);
270 UMFPackIterator<Scalar> this_it(
this);
276 bool mat_not_finished = mat_it.init();
277 bool this_not_finished = this_it.init();
278 while(mat_not_finished && this_not_finished)
280 mat_it.get_current_position(mat_i, mat_j, mat_val);
282 this_it.get_current_position(this_i, this_j, this_val);
284 while(mat_i != this_i || mat_j != this_j)
287 this_not_finished = this_it.move_ptr();
288 if(!this_not_finished)
290 printf(
"Entry %d %d does not exist in the matrix to which it is contributed.\n", mat_i, mat_j);
293 this_it.get_current_position(this_i, this_j, this_val);
295 this_it.add_to_current_position(mat_val);
296 mat_not_finished = mat_it.move_ptr();
297 this_not_finished = this_it.move_ptr();
298 if(mat_not_finished && !this_not_finished)
303 template<
typename Scalar>
304 void CSCMatrix<Scalar>::add_to_diagonal(Scalar v)
306 for (
unsigned int i = 0; i<this->size; i++)
312 template<
typename Scalar>
313 void CSCMatrix<Scalar>::add(
unsigned int m,
unsigned int n, Scalar **mat,
int *rows,
int *cols)
315 for (
unsigned int i = 0; i < m; i++)
316 for (
unsigned int j = 0; j < n; j++)
317 if(rows[i] >= 0 && cols[j] >= 0)
318 add(rows[i], cols[j], mat[i][j]);
321 double inline real(
double x)
326 double inline imag(
double x)
331 double inline real(std::complex<double> x)
336 double inline imag(std::complex<double> x)
342 bool CSCMatrix<double>::dump(FILE *file,
const char *var_name,
EMatrixDumpFormat fmt,
char* number_format)
347 fprintf(file,
"%% Size: %dx%d\n%% Nonzeros: %d\ntemp = zeros(%d, 3);\ntemp =[\n",
348 this->size, this->size, nnz, nnz);
349 for (
unsigned int j = 0; j < this->size; j++)
350 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
352 fprintf(file,
"%d %d ", Ai[i] + 1, j + 1);
353 Hermes::Helpers::fprint_num(file, Ax[i], number_format);
356 fprintf(file,
"];\n%s = spconvert(temp);\n", var_name);
362 fprintf(file,
"%%%%Matrix<Scalar>Market matrix coordinate real symmetric\n");
364 for (
unsigned int j = 0; j < this->size; j++)
365 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
366 if((
int)j <= Ai[i]) nnz_sym++;
367 fprintf(file,
"%d %d %d\n", this->size, this->size, nnz_sym);
368 for (
unsigned int j = 0; j < this->size; j++)
369 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
375 fprintf(file,
"%d %d ", Ai[i] + 1, (
int)j + 1);
376 Hermes::Helpers::fprint_num(file, Ax[i], number_format);
385 hermes_fwrite(
"HERMESX\001", 1, 8, file);
386 int ssize =
sizeof(double);
387 hermes_fwrite(&ssize,
sizeof(
int), 1, file);
388 hermes_fwrite(&this->size,
sizeof(
int), 1, file);
389 hermes_fwrite(&nnz,
sizeof(
int), 1, file);
390 hermes_fwrite(Ap,
sizeof(
int), this->size + 1, file);
391 hermes_fwrite(Ai,
sizeof(
int), nnz, file);
392 hermes_fwrite(Ax,
sizeof(
double), nnz, file);
399 const double zero_cutoff = 1e-10;
400 double *ascii_entry_buff =
new double[nnz];
401 int *ascii_entry_i =
new int[nnz];
402 int *ascii_entry_j =
new int[nnz];
407 for (
unsigned int j = 0; j < size; j++)
409 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
411 if(real(Ax[i]) > zero_cutoff || imag(Ax[i]) > zero_cutoff)
413 ascii_entry_buff[k] = Ax[i];
414 ascii_entry_i[k] = Ai[i];
415 ascii_entry_j[k] = j;
423 fprintf(file,
"%d\n", size);
424 fprintf(file,
"%d\n", nnz);
425 for (
unsigned int k = 0; k < nnz; k++)
426 fprintf(file,
"%d %d %f\n", ascii_entry_i[k], ascii_entry_j[k], ascii_entry_buff[k]);
429 delete [] ascii_entry_buff;
430 delete [] ascii_entry_i;
431 delete [] ascii_entry_j;
434 ascii_entry_buff = NULL;
435 ascii_entry_i = NULL;
436 ascii_entry_j = NULL;
447 bool CSCMatrix<std::complex<double> >::dump(FILE *file,
const char *var_name,
EMatrixDumpFormat fmt,
char* number_format)
452 fprintf(file,
"%% Size: %dx%d\n%% Nonzeros: %d\ntemp = zeros(%d, 3);\ntemp =[\n",
453 this->size, this->size, nnz, nnz);
454 for (
unsigned int j = 0; j < this->size; j++)
455 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
457 fprintf(file,
"%d %d ", Ai[i] + 1, j + 1);
458 Hermes::Helpers::fprint_num(file, Ax[i], number_format);
461 fprintf(file,
"];\n%s = spconvert(temp);\n", var_name);
467 fprintf(file,
"%%%%Matrix<Scalar>Market matrix coordinate real symmetric\n");
469 for (
unsigned int j = 0; j < this->size; j++)
470 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
471 if((
int)j <= Ai[i]) nnz_sym++;
472 fprintf(file,
"%d %d %d\n", this->size, this->size, nnz_sym);
473 for (
unsigned int j = 0; j < this->size; j++)
474 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
480 fprintf(file,
"%d %d ", Ai[i] + 1, (
int)j + 1);
481 Hermes::Helpers::fprint_num(file, Ax[i], number_format);
490 hermes_fwrite(
"HERMESX\001", 1, 8, file);
491 int ssize =
sizeof(std::complex<double>);
492 hermes_fwrite(&ssize,
sizeof(
int), 1, file);
493 hermes_fwrite(&this->size,
sizeof(
int), 1, file);
494 hermes_fwrite(&nnz,
sizeof(
int), 1, file);
495 hermes_fwrite(Ap,
sizeof(
int), this->size + 1, file);
496 hermes_fwrite(Ai,
sizeof(
int), nnz, file);
497 hermes_fwrite(Ax,
sizeof(std::complex<double>), nnz, file);
504 const double zero_cutoff = 1e-10;
505 std::complex<double> *ascii_entry_buff =
new std::complex<double>[nnz];
506 int *ascii_entry_i =
new int[nnz];
507 int *ascii_entry_j =
new int[nnz];
512 for (
unsigned int j = 0; j < size; j++)
514 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
516 if(real(Ax[i]) > zero_cutoff || imag(Ax[i]) > zero_cutoff)
518 ascii_entry_buff[k] = Ax[i];
519 ascii_entry_i[k] = Ai[i];
520 ascii_entry_j[k] = j;
528 fprintf(file,
"%d\n", size);
529 fprintf(file,
"%d\n", nnz);
530 for (
unsigned int k = 0; k < nnz; k++)
531 fprintf(file,
"%d %d %E %E\n", ascii_entry_i[k], ascii_entry_j[k], ascii_entry_buff[k].real(), ascii_entry_buff[k].imag());
534 delete [] ascii_entry_buff;
535 delete [] ascii_entry_i;
536 delete [] ascii_entry_j;
539 ascii_entry_buff = NULL;
540 ascii_entry_i = NULL;
541 ascii_entry_j = NULL;
551 template<
typename Scalar>
552 unsigned int CSCMatrix<Scalar>::get_matrix_size()
const
557 template<
typename Scalar>
558 double CSCMatrix<Scalar>::get_fill_in()
const
560 return nnz / (double) (this->size * this->size);
563 template<
typename Scalar>
564 void CSCMatrix<Scalar>::create(
unsigned int size,
unsigned int nnz,
int* ap,
int* ai, Scalar* ax)
568 this->Ap =
new int[this->size + 1]; assert(this->Ap != NULL);
569 this->Ai =
new int[nnz]; assert(this->Ai != NULL);
570 this->Ax =
new Scalar[nnz]; assert(this->Ax != NULL);
571 for (
unsigned int i = 0; i < this->size + 1; i++) this->Ap[i] = ap[i];
572 for (
unsigned int i = 0; i < nnz; i++)
579 template<
typename Scalar>
580 CSCMatrix<Scalar>* CSCMatrix<Scalar>::duplicate()
582 CSCMatrix<Scalar>*
new_matrix =
new CSCMatrix<Scalar>();
583 new_matrix->create(this->get_size(), this->get_nnz(), this->get_Ap(), this->get_Ai(), this->get_Ax());
587 template<
typename Scalar>
588 int *CSCMatrix<Scalar>::get_Ap()
593 template<
typename Scalar>
594 int *CSCMatrix<Scalar>::get_Ai()
599 template<
typename Scalar>
600 Scalar *CSCMatrix<Scalar>::get_Ax()
605 template<
typename Scalar>
606 UMFPackVector<Scalar>::UMFPackVector()
612 template<
typename Scalar>
613 UMFPackVector<Scalar>::UMFPackVector(
unsigned int size)
620 template<
typename Scalar>
621 UMFPackVector<Scalar>::~UMFPackVector()
626 template<
typename Scalar>
627 void UMFPackVector<Scalar>::alloc(
unsigned int n)
635 template<
typename Scalar>
636 void UMFPackVector<Scalar>::zero()
638 memset(v, 0, this->size *
sizeof(Scalar));
641 template<
typename Scalar>
642 void UMFPackVector<Scalar>::change_sign()
644 for (
unsigned int i = 0; i < this->size; i++) v[i] *= -1.;
647 template<
typename Scalar>
648 void UMFPackVector<Scalar>::free()
655 template<
typename Scalar>
656 void UMFPackVector<Scalar>::set(
unsigned int idx, Scalar y)
662 void UMFPackVector<double>::add(
unsigned int idx,
double y)
669 void UMFPackVector<std::complex<double> >::add(
unsigned int idx, std::complex<double> y)
671 #pragma omp critical(UMFPackVector_add)
675 template<
typename Scalar>
676 void UMFPackVector<Scalar>::add(
unsigned int n,
unsigned int *idx, Scalar *y)
678 for (
unsigned int i = 0; i < n; i++)
682 template<
typename Scalar>
683 Scalar UMFPackVector<Scalar>::get(
unsigned int idx)
688 template<
typename Scalar>
689 void UMFPackVector<Scalar>::extract(Scalar *v)
const
691 memcpy(v, this->v, this->size *
sizeof(Scalar));
694 template<
typename Scalar>
695 void UMFPackVector<Scalar>::add_vector(Vector<Scalar>* vec)
697 assert(this->length() == vec->length());
698 for (
unsigned int i = 0; i < this->length(); i++) this->v[i] += vec->get(i);
701 template<
typename Scalar>
702 void UMFPackVector<Scalar>::add_vector(Scalar* vec)
704 for (
unsigned int i = 0; i < this->length(); i++) this->v[i] += vec[i];
707 template<
typename Scalar>
708 Scalar *UMFPackVector<Scalar>::get_c_array()
714 bool UMFPackVector<double>::dump(FILE *file,
const char *var_name,
EMatrixDumpFormat fmt,
char* number_format)
719 fprintf(file,
"%% Size: %dx1\n%s =[\n", this->size, var_name);
720 for (
unsigned int i = 0; i < this->size; i++)
722 Hermes::Helpers::fprint_num(file, v[i], number_format);
725 fprintf(file,
" ];\n");
730 hermes_fwrite(
"HERMESR\001", 1, 8, file);
731 int ssize =
sizeof(double);
732 hermes_fwrite(&ssize,
sizeof(
int), 1, file);
733 hermes_fwrite(&this->size,
sizeof(
int), 1, file);
734 hermes_fwrite(v,
sizeof(
double), this->size, file);
741 for (
unsigned int i = 0; i < size; i++)
743 Hermes::Helpers::fprint_num(file, v[i], number_format);
756 bool UMFPackVector<std::complex<double> >::dump(FILE *file,
const char *var_name,
EMatrixDumpFormat fmt,
char* number_format)
761 fprintf(file,
"%% Size: %dx1\n%s =[\n", this->size, var_name);
762 for (
unsigned int i = 0; i < this->size; i++)
764 Hermes::Helpers::fprint_num(file, v[i], number_format);
767 fprintf(file,
" ];\n");
772 hermes_fwrite(
"HERMESR\001", 1, 8, file);
773 int ssize =
sizeof(std::complex<double>);
774 hermes_fwrite(&ssize,
sizeof(
int), 1, file);
775 hermes_fwrite(&this->size,
sizeof(
int), 1, file);
776 hermes_fwrite(v,
sizeof(std::complex<double>), this->size, file);
783 for (
unsigned int i = 0; i < size; i++)
785 fprintf(file,
"%E %E\n", v[i].real(), v[i].imag());
796 template class HERMES_API CSCMatrix<double>;
797 template class HERMES_API CSCMatrix<std::complex<double> >;
798 template class HERMES_API UMFPackMatrix<double>;
799 template class HERMES_API UMFPackMatrix<std::complex<double> >;
800 template class HERMES_API UMFPackVector<double>;
801 template class HERMES_API UMFPackVector<std::complex<double> >;
806 template<
typename Scalar>
807 bool UMFPackIterator<Scalar>::init()
809 if(this->size == 0 || this->nnz == 0)
return false;
815 template<
typename Scalar>
816 UMFPackIterator<Scalar>::UMFPackIterator(CSCMatrix<Scalar>* mat)
818 this->size = mat->get_size();
819 this->nnz = mat->get_nnz();
820 this->Ai = mat->get_Ai();
821 this->Ap = mat->get_Ap();
822 this->Ax = mat->get_Ax();
827 template<
typename Scalar>
828 void UMFPackIterator<Scalar>::get_current_position(
int& i,
int& j, Scalar& val)
835 template<
typename Scalar>
836 bool UMFPackIterator<Scalar>::move_to_position(
int i,
int j)
840 get_current_position(ii, jj, val);
841 while (!(ii == i && jj == j))
843 if(!this->move_ptr())
return false;
844 get_current_position(ii, jj, val);
849 template<
typename Scalar>
850 bool UMFPackIterator<Scalar>::move_ptr()
852 if(Ai_pos >= nnz - 1)
return false;
853 if(Ai_pos + 1 >= Ap[Ap_pos + 1])
861 template<
typename Scalar>
862 void UMFPackIterator<Scalar>::add_to_current_position(Scalar val)
864 this->Ax[this->Ai_pos] += val;
868 bool UMFPackLinearMatrixSolver<double>::setup_factorization()
875 eff_fact_scheme = factorization_scheme;
878 switch(eff_fact_scheme)
881 if(symbolic != NULL) umfpack_di_free_symbolic(&symbolic);
884 status = umfpack_di_symbolic(m->get_size(), m->get_size(), m->get_Ap(), m->get_Ai(), m->get_Ax(), &symbolic, NULL, NULL);
885 if(status != UMFPACK_OK)
887 check_status(
"umfpack_di_symbolic", status);
891 throw Exceptions::Exception(
"umfpack_di_symbolic error: symbolic == NULL");
895 if(numeric != NULL) umfpack_di_free_numeric(&numeric);
898 status = umfpack_di_numeric(m->get_Ap(), m->get_Ai(), m->get_Ax(), symbolic, &numeric, NULL, NULL);
899 if(status != UMFPACK_OK)
901 check_status(
"umfpack_di_numeric", status);
905 throw Exceptions::Exception(
"umfpack_di_numeric error: numeric == NULL");
911 template<
typename Scalar>
912 UMFPackLinearMatrixSolver<Scalar>::UMFPackLinearMatrixSolver(UMFPackMatrix<Scalar> *m, UMFPackVector<Scalar> *rhs)
917 template<
typename Scalar>
918 UMFPackLinearMatrixSolver<Scalar>::~UMFPackLinearMatrixSolver()
920 free_factorization_data();
923 template<
typename Scalar>
924 int UMFPackLinearMatrixSolver<Scalar>::get_matrix_size()
926 return m->get_size();
930 bool UMFPackLinearMatrixSolver<std::complex<double> >::setup_factorization()
934 if(factorization_scheme != HERMES_FACTORIZE_FROM_SCRATCH && symbolic == NULL && numeric == NULL)
937 eff_fact_scheme = factorization_scheme;
940 switch(eff_fact_scheme)
944 umfpack_zi_free_symbolic(&symbolic);
946 status = umfpack_zi_symbolic(m->get_size(), m->get_size(), m->get_Ap(), m->get_Ai(), (
double *)m->get_Ax(), NULL, &symbolic, NULL, NULL);
947 if(status != UMFPACK_OK)
949 check_status(
"umfpack_di_symbolic", status);
953 throw Exceptions::Exception(
"umfpack_di_symbolic error: symbolic == NULL");
958 umfpack_zi_free_numeric(&numeric);
960 status = umfpack_zi_numeric(m->get_Ap(), m->get_Ai(), (
double *) m->get_Ax(), NULL, symbolic, &numeric, NULL, NULL);
961 if(status != UMFPACK_OK)
963 check_status(
"umfpack_di_numeric", status);
967 throw Exceptions::Exception(
"umfpack_di_numeric error: numeric == NULL");
974 void UMFPackLinearMatrixSolver<double>::free_factorization_data()
976 if(symbolic != NULL) umfpack_di_free_symbolic(&symbolic);
978 if(numeric != NULL) umfpack_di_free_numeric(&numeric);
983 void UMFPackLinearMatrixSolver<std::complex<double> >::free_factorization_data()
985 if(symbolic != NULL) umfpack_zi_free_symbolic(&symbolic);
987 if(numeric != NULL) umfpack_zi_free_numeric(&numeric);
992 bool UMFPackLinearMatrixSolver<double>::solve()
996 assert(m->get_size() == rhs->length());
1000 if( !setup_factorization() )
1001 throw Exceptions::LinearMatrixSolverException(
"LU factorization could not be completed.");
1005 sln =
new double[m->get_size()];
1006 memset(sln, 0, m->get_size() *
sizeof(double));
1007 int status = umfpack_di_solve(UMFPACK_A, m->get_Ap(), m->get_Ai(), m->get_Ax(), sln, rhs->get_c_array(), numeric, NULL, NULL);
1008 if(status != UMFPACK_OK)
1010 check_status(
"umfpack_di_solve", status);
1015 time = this->accumulated();
1021 bool UMFPackLinearMatrixSolver<std::complex<double> >::solve()
1024 assert(rhs != NULL);
1025 assert(m->get_size() == rhs->length());
1028 if( !setup_factorization() )
1030 this->warn(
"LU factorization could not be completed.");
1036 sln =
new std::complex<double>[m->get_size()];
1037 memset(sln, 0, m->get_size() *
sizeof(std::complex<double>));
1038 int status = umfpack_zi_solve(UMFPACK_A, m->get_Ap(), m->get_Ai(), (
double *)m->get_Ax(), NULL, (
double*) sln, NULL, (
double *)rhs->get_c_array(), NULL, numeric, NULL, NULL);
1039 if(status != UMFPACK_OK)
1041 check_status(
"umfpack_di_solve", status);
1046 time = this->accumulated();
1051 template<
typename Scalar>
1052 void UMFPackLinearMatrixSolver<Scalar>::check_status(
const char *fn_name,
int status)
1056 case UMFPACK_OK:
break;
1057 case UMFPACK_WARNING_singular_matrix: this->warn(
"%s: singular matrix!", fn_name);
break;
1058 case UMFPACK_ERROR_out_of_memory: this->warn(
"%s: out of memory!", fn_name);
break;
1059 case UMFPACK_ERROR_argument_missing: this->warn(
"%s: argument missing", fn_name);
break;
1060 case UMFPACK_ERROR_invalid_Symbolic_object: this->warn(
"%s: invalid Symbolic object", fn_name);
break;
1061 case UMFPACK_ERROR_invalid_Numeric_object: this->warn(
"%s: invalid Numeric object", fn_name);
break;
1062 case UMFPACK_ERROR_different_pattern: this->warn(
"%s: different pattern", fn_name);
break;
1063 case UMFPACK_ERROR_invalid_system: this->warn(
"%s: invalid system", fn_name);
break;
1064 case UMFPACK_ERROR_n_nonpositive: this->warn(
"%s: n nonpositive", fn_name);
break;
1065 case UMFPACK_ERROR_invalid_matrix: this->warn(
"%s: invalid matrix", fn_name);
break;
1066 case UMFPACK_ERROR_internal_error: this->warn(
"%s: internal error", fn_name);
break;
1067 default: this->warn(
"%s: unknown error (%d)", fn_name, status);
break;
1071 template class HERMES_API UMFPackLinearMatrixSolver<double>;
1072 template class HERMES_API UMFPackLinearMatrixSolver<std::complex<double> >;