Hi everyone,

I am working on a finite element problem and wanted to ask if anyone of you
have tried using UMFPACK for the linear algebra. I have following findings
when using sparse matrix module from gsl-2.5.

1. In CCS the row indices are not sorted so UMFPACK gives error (see
attached example)
2. Adding boundary conditions were also difficult once compressed, so I
couldn't utilize gsl_spmatrix_add() to add mass matrix with stiffness
matrix. Instead I had to do it with triplet and calling the get/set
routines. Could only add boundary condition at triplet level and compressed
at the end and passed the pointers to UMFPACK routines.
3. Another thing (not related to gsl) was that UMFPACK don't use (size_t
*), instead it has (int *) and (long *) for column pointers and row
indices. I tried to cast (size_t *) to (long *) to utilize the pointers of
gsl_spmatrix object.

I am bit curious to know if anyone have a better experience. I wanted to
use direct solver instead of iterative solver.

King Regards,
Brijesh
/* test_lsolver.c
 *
 * Test UMFPACK (V5.7.1) example
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <gsl/gsl_cblas.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_spmatrix.h>
#include <umfpack.h>


static int
test_lumfpack (gsl_spmatrix *A, gsl_vector *X, const gsl_vector *F)
{
  const long int n = (const long int) X->size;
  const long int m = (const long int) X->size;
  const long int *Ap = (const long int *) A->p;
  const long int *Ai = (const long int *) A->i;
  const double *Ax = (const double *) A->data;

  double *x = X->data;
  const double *b = F->data;

  double Info[UMFPACK_INFO], Control[UMFPACK_CONTROL];
  void *Symbolic, *Numeric;

  umfpack_dl_defaults (Control);

  int status = umfpack_dl_symbolic (n, m, Ap, Ai, Ax, &Symbolic, Control, Info);
  if (status)
    {
      umfpack_dl_free_symbolic (&Symbolic);
      umfpack_dl_report_info (Control, Info);
      umfpack_dl_report_status (Control, status);
      return status;
    }

  status = umfpack_dl_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control, Info);
  if (status)
    {
      umfpack_dl_free_symbolic (&Symbolic);
      umfpack_dl_free_numeric (&Numeric);
      umfpack_dl_report_info (Control, Info);
      umfpack_dl_report_status (Control, status);
      return status;
    }

  status = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b, Numeric, Control, Info);
  if (status)
    {
      umfpack_dl_free_symbolic (&Symbolic);
      umfpack_dl_free_numeric (&Numeric);
      umfpack_dl_report_info (Control, Info);
      umfpack_dl_report_status (Control, status);
      return status;
    }

  umfpack_dl_free_symbolic (&Symbolic);
  umfpack_dl_free_numeric (&Numeric);

  return status;
}


/*=============================================================================*/
int 
main (void)
{
  int status;
  size_t Ap[] = { 0, 2, 5, 9, 10, 12 };
  size_t Ai[] = { 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4 };
  double Ax[] = { 2., 3., 3., -1., 4., 4., -3., 1., 2., 2., 6., 1. };
  double b[] = { 8., 45., -3., 3., 19. };
  double u[] = { [0] = 0.0, [4] = 0.0 };
  const size_t n = sizeof (b) / sizeof (double);
  size_t j, p;

  if (1)
    {
      // In practical finite element assembly this happens 
      // Swap row indices and corrosponding data 
      gsl_vector_ulong_view vi = gsl_vector_ulong_view_array (Ai, n);
      gsl_vector_ulong_swap_elements (&vi.vector, 2, 3);
      cblas_dswap (1, &Ax[2], 1, &Ax[3], 1); 
    }
  
  gsl_spmatrix *K = gsl_spmatrix_alloc (n, n);

  for (j = 0; j < n; j++)
    for (p = Ap[j]; p < Ap[j + 1]; p++)
      gsl_spmatrix_set (K, Ai[p], j, Ax[p]);
  
  gsl_spmatrix *A = gsl_spmatrix_ccs (K);

  gsl_vector_view x = gsl_vector_view_array (u, n);
  gsl_vector_const_view f = gsl_vector_const_view_array (b, n);
  
  // Solve system
  status = test_lumfpack (A, &x.vector, &f.vector);
  
  if (!status)
    gsl_vector_fprintf (stdout, &x.vector, "%f");

  if (0)
    gsl_spmatrix_fprintf (stderr, K, "%f");
  else if (1)
    gsl_spmatrix_fprintf (stderr, A, "%f"); 

  gsl_spmatrix_free (K);
  gsl_spmatrix_free (A);

  return 0;
}

Reply via email to