Example #1
0
NumericsMatrix* createNumericsMatrix(int storageType, int size0, int size1)
{
    NumericsMatrix* M = newNumericsMatrix();

    void* data;

    switch (storageType)
    {
    case NM_DENSE:
        data = malloc(size0*size1*sizeof(double));
        break;
    case NM_SPARSE_BLOCK:
        data = newSBM();
        break;
    case NM_SPARSE:
        data = newNumericsSparseMatrix();
        break;
    default:
        printf("createNumericsMatrix :: storageType value %d not implemented yet !", storageType);
        exit(EXIT_FAILURE);
    }

    fillNumericsMatrix(M, storageType, size0, size1, data);

    return M;
}
Example #2
0
FrictionContactProblem* from_fclib_local(const struct fclib_local* fclib_problem)
{
  FrictionContactProblem* problem;

  problem = malloc(sizeof(FrictionContactProblem));

  problem->dimension = fclib_problem->spacedim;
  problem->mu = fclib_problem->mu;
  problem->q = fclib_problem->q;

  problem->numberOfContacts = fclib_problem->W->m / fclib_problem->spacedim; /* cf fclib spec */

  problem->M = newNumericsMatrix();

  problem->M->storageType = 1; /* sparse */
  problem->M->size0 = fclib_problem->W->m;
  problem->M->size1 = fclib_problem->W->n;

  problem->M->matrix0 = NULL;
  problem->M->matrix1 = newSBM();

  problem->M->matrix1->block = NULL;
  problem->M->matrix1->index1_data = NULL;
  problem->M->matrix1->index2_data = NULL;

  sparseToSBM(problem->dimension, (CSparseMatrix*)fclib_problem->W, problem->M->matrix1);

  return problem;

}
Example #3
0
int newFromFile(NumericsMatrix* const m, FILE *file)
{
    if (! m)
    {
        fprintf(stderr, "Numerics, NumericsMatrix newFromFile failed, NULL input.\n");
        exit(EXIT_FAILURE);
    }

    int storageType;
    size_t size0;
    size_t size1;
    int info = 0;
    void* data = NULL;

    CHECK_IO(fscanf(file, "%d", &storageType), &info);
    CHECK_IO(fscanf(file, SN_SIZE_T_F, &size0), &info);
    CHECK_IO(fscanf(file, SN_SIZE_T_F, &size1), &info);

    if (storageType == NM_DENSE)
    {
        CHECK_IO(fscanf(file, SN_SIZE_T_F "\t" SN_SIZE_T_F "\n", &size0, &size1), &info);

        data = malloc(size1 * size0 * sizeof(double));
        double* data_d = (double*) data;

        for (size_t i = 0; i < size1 * size0; ++i)
        {
            CHECK_IO(fscanf(file, "%le ", &(data_d[i])), &info);
        }
    }
    else if (storageType == NM_SPARSE_BLOCK)
    {
        data = newSBM();
        newFromFileSBM((SparseBlockStructuredMatrix*)data, file);
    }

    fillNumericsMatrix(m, storageType, (int)size0, (int)size1, data);

    return info;
}
int main(int argc, char* argv[])
{


  // Problem Definition
  int info = -1;



  int NC = 1;//Number of contacts
  int Ndof = 9;//Number of DOF
  // Problem Definition
  double M11[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // Warning Fortran Storage
  double M22[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // Warning Fortran Storage
  double M33[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // Warning Fortran Storage
  /*     double M[81] = {1, 0, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 1, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 1, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 1, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 1, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 1, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 1, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 1, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 0, 1}; */


  double H00[9] =  {1, 0, 0, 0, 1, 0, 0, 0, 1};
  double H20[9] =  { -1, 0, 0, 0, -1, 0, 0, 0, -1};

  /*     double H[27] = {1, 0, 0, 0, 0, 0, -1, 0, 0, */
  /*        0, 1, 0, 0, 0, 0, 0, -1, 0, */
  /*        0, 0, 1, 0, 0, 0, 0, 0, -1}; */


  double q[9] = { -3, -3, -3, -1, 1, 3, -1, 1, 3};
  double b[3] = {0, 0, 0};
  double mu[1] = {0.1};

  /*    DSCAL(9,-1.0,q,1); */




  /*     int NC = 3;//Number of contacts  */
  /*     int Ndof = 9;//Number of DOF  */
  /*     double M[81] = {1, 0, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 1, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 1, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 1, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 1, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 1, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 1, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 1, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 0, 1}; */
  /*     double H[81] = {1, 0, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 1, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 1, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 1, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 1, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 1, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 1, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 1, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 0, 1}; */


  /*     double q[9] = {-1, 1, 3, -1, 1, 3, -1, 1, 3}; */
  /*     double b[9] = {0, 0, 0,0, 0, 0,0, 0, 0 }; */
  /*     double mu[3] = {0.1,0.1,0.1};    */


  int k;
  int m = 3 * NC;
  int n = Ndof;

  GlobalFrictionContactProblem numericsProblem;
  globalFrictionContact_null(&numericsProblem);
  numericsProblem.numberOfContacts = NC;
  numericsProblem.dimension = 3;
  numericsProblem.mu = mu;
  numericsProblem.q = q;
  numericsProblem.b = b;

  numericsProblem.M = newNumericsMatrix();
  NumericsMatrix *MM =  numericsProblem.M;
  MM->storageType = NM_SPARSE_BLOCK;
  MM->size0 = Ndof;
  MM->size1 = Ndof;


  MM->matrix1 = newSBM();
  SparseBlockStructuredMatrix *MBlockMatrix = MM->matrix1;
  MBlockMatrix->nbblocks = 3;
  double * block[3] = {M11, M22, M33};
  MBlockMatrix->block = block;
  MBlockMatrix->blocknumber0 = 3;
  MBlockMatrix->blocknumber1 = 3;
  unsigned int blocksize[3] = {3, 6, 9} ;
  MBlockMatrix->blocksize0 = blocksize;
  MBlockMatrix->blocksize1 = blocksize;
  MBlockMatrix->filled1 = 4;
  MBlockMatrix->filled2 = 3;
  size_t index1_data[4] = {0, 1, 2, 3} ;
  size_t index2_data[3] = {0, 1, 2} ;
  MBlockMatrix->index1_data =  index1_data;
  MBlockMatrix->index2_data =  index2_data;


  numericsProblem.H = newNumericsMatrix();
  NumericsMatrix *HH =  numericsProblem.H;
  HH->storageType = 1;
  HH->size0 = Ndof;
  HH->size1 = 3 * NC;

  HH->matrix1 = (SparseBlockStructuredMatrix*)malloc(sizeof(SparseBlockStructuredMatrix));
  SparseBlockStructuredMatrix *HBlockMatrix = HH->matrix1;
  HBlockMatrix->nbblocks = 2;
  double * hblock[3] = {H00, H20};
  HBlockMatrix->block = hblock;
  HBlockMatrix->blocknumber0 = 3;
  HBlockMatrix->blocknumber1 = 1;
  unsigned int blocksize0[3] = {3, 6, 9} ;
  unsigned int blocksize1[1] = {3} ;
  HBlockMatrix->blocksize0 = blocksize0;
  HBlockMatrix->blocksize1 = blocksize1;
  HBlockMatrix->filled1 = 4;
  HBlockMatrix->filled2 = 2;
  size_t hindex1_data[4] = {0, 1, 1, 2} ;
  size_t hindex2_data[3] = {0, 0} ;
  HBlockMatrix->index1_data =  hindex1_data;
  HBlockMatrix->index2_data =  hindex2_data;

  FILE * foutput = fopen("Example_GlobalFrictionContact_SBM.dat", "w");
  globalFrictionContact_printInFile(&numericsProblem,  foutput);
  fclose(foutput);


  // Unknown Declaration

  double *reaction = (double*)calloc(m, sizeof(double));
  double *velocity = (double*)calloc(m, sizeof(double));
  double *globalVelocity = (double*)calloc(n, sizeof(double));
  // Solver Options
  SolverOptions * numerics_solver_options = (SolverOptions *)malloc(sizeof(SolverOptions));
  //    char solvername[10]= "NSGS";

  /*\warning Must be adpated  for future globalFrictionContact3D_setDefaultSolverOptions*/
  gfc3d_setDefaultSolverOptions(numerics_solver_options, SICONOS_GLOBAL_FRICTION_3D_NSGS);
  numerics_solver_options->dparam[0] = 1e-14;
  numerics_solver_options->iparam[0] = 100000;

  //Driver call
  info = gfc3d_driver(&numericsProblem,
		      reaction , velocity, globalVelocity,
		      numerics_solver_options);
  solver_options_delete(numerics_solver_options);

  free(numerics_solver_options);
  // Solver output
  printf("\n");
  for (k = 0 ; k < m; k++) printf("velocity[%i] = %12.8e \t \t reaction[%i] = %12.8e \n ", k, velocity[k], k , reaction[k]);
  for (k = 0 ; k < n; k++) printf("globalVelocity[%i] = %12.8e \t \n ", k, globalVelocity[k]);
  printf("\n");


  free(reaction);
  free(velocity);
  free(globalVelocity);

  //     freeSBM(MM->matrix1);
  //     freeSBM(HH->matrix1);
  free(MM->matrix1);
  MM->matrix1 = NULL;
  free(HH->matrix1);
  HH->matrix1 = NULL;
  freeNumericsMatrix(MM);
  freeNumericsMatrix(HH);
  free(MM);
  free(HH);
  gfc3d_free_workspace(&numericsProblem);


  /*     while (1) sleep(60); */


  return info;


}
Example #5
0
FrictionContactProblem* from_fclib_local(const struct fclib_local* fclib_problem)
{
  FrictionContactProblem* problem;

  problem = malloc(sizeof(FrictionContactProblem));

  problem->dimension = fclib_problem->spacedim;
  problem->mu = fclib_problem->mu;
  problem->q = fclib_problem->q;

  problem->numberOfContacts = fclib_problem->W->m / fclib_problem->spacedim; /* cf fclib spec */

  problem->M = newNumericsMatrix();

  problem->M->storageType = 1; /* sparse */
  problem->M->size0 = fclib_problem->W->m;
  problem->M->size1 = fclib_problem->W->n;

  problem->M->matrix0 = NULL;
  problem->M->matrix1 = newSBM();

  problem->M->matrix1->block = NULL;
  problem->M->matrix1->index1_data = NULL;
  problem->M->matrix1->index2_data = NULL;

  CSparseMatrix W;

  W.nzmax = (csi) fclib_problem->W->nzmax;
  W.m = (csi) fclib_problem->W->m;
  W.n = (csi) fclib_problem->W->n;

  if (fclib_problem->W->nz == -1)
  {
    /* compressed colums */
    W.p = (csi*) malloc(sizeof(csi)*(W.n+1));
    int_to_csi(fclib_problem->W->p, W.p, (unsigned) (W.n+1));
  }
  else if (fclib_problem->W->nz == -2)
  {
    /* compressed rows */
    W.p = (csi*) malloc(sizeof(csi)*(W.m+1));
    int_to_csi(fclib_problem->W->p, W.p, (unsigned) (W.m+1));
  }
  else
  {
    /* triplet */
    W.p = (csi*) malloc(sizeof(csi)*W.nzmax);
    int_to_csi(fclib_problem->W->p, W.p, (unsigned) W.nzmax);
  }

  W.i = (csi*) malloc(sizeof(csi)*W.nzmax);
  int_to_csi(fclib_problem->W->i, W.i, (unsigned) W.nzmax);

  W.x = fclib_problem->W->x;

  W.nz = fclib_problem->W->nz;

  sparseToSBM(problem->dimension, &W, problem->M->matrix1);

  free(W.p);
  free(W.i);

  return problem;

}
Example #6
0
int main(int argc, char* argv[])
{


  // Problem Definition
  int info = -1;



  int NC = 2;//Number of contacts
  int Ndof = 12;//Number of DOF
  // Problem Definition
  double M11[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // Warning Fortran Storage
  double M22[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // Warning Fortran Storage
  double M33[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // Warning Fortran Storage
  double M44[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // Warning Fortran Storage
  /*     double M[81] = {1, 0, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 1, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 1, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 1, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 1, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 1, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 1, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 1, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 0, 1}; */


  double H00[9] =  {1, 0, 0, 0, 1, 0, 0, 0, 1};
  double H20[9] =  { -1, 0, 0, 0, -1, 0, 0, 0, -1};
  double H11[9] =  {1, 0, 0, 0, 1, 0, 0, 0, 1};
  double H31[9] =  { -1, 0, 0, 0, -1, 0, 0, 0, -1};

  /*     double H[27] = {1, 0, 0, 0, 0, 0, -1, 0, 0, */
  /*        0, 1, 0, 0, 0, 0, 0, -1, 0, */
  /*        0, 0, 1, 0, 0, 0, 0, 0, -1}; */


  double q[12] = { -3, -3, -3, -3, -3, -3, -1, 1, 3, -10, 1, 3};
  double b[6] = {0, 0, 0, 0, 0, 0};
  double mu[2] = {0.1, 0.1};

  /*    DSCAL(9,-1.0,q,1); */




  /*     int NC = 3;//Number of contacts  */
  /*     int Ndof = 9;//Number of DOF  */
  /*     double M[81] = {1, 0, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 1, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 1, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 1, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 1, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 1, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 1, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 1, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 0, 1}; */
  /*     double H[81] = {1, 0, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 1, 0, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 1, 0, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 1, 0, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 1, 0, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 1, 0, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 1, 0, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 1, 0,  */
  /*        0, 0, 0, 0, 0, 0, 0, 0, 1}; */


  /*     double q[9] = {-1, 1, 3, -1, 1, 3, -1, 1, 3}; */
  /*     double b[9] = {0, 0, 0,0, 0, 0,0, 0, 0 }; */
  /*     double mu[3] = {0.1,0.1,0.1};    */


  int i, j, k;
  int m = 3 * NC;
  int n = Ndof;

  GlobalFrictionContactProblem NumericsProblem;
  NumericsProblem.numberOfContacts = NC;
  NumericsProblem.dimension = 3;
  NumericsProblem.mu = mu;
  NumericsProblem.q = q;
  NumericsProblem.b = b;

  NumericsProblem.M = newNumericsMatrix();
  NumericsMatrix *MM =  NumericsProblem.M;
  MM->storageType = 1;
  MM->size0 = Ndof;
  MM->size1 = Ndof;


  MM->matrix1 = newSBM();
  MM->matrix0 = NULL;
  SparseBlockStructuredMatrix *MBlockMatrix = MM->matrix1;
  MBlockMatrix->nbblocks = 4;
  double * block[4] = {M11, M22, M33, M44};
  MBlockMatrix->block = block;
  MBlockMatrix->blocknumber0 = 4;
  MBlockMatrix->blocknumber1 = 4;
  int blocksize[4] = {3, 6, 9, 12} ;
  MBlockMatrix->blocksize0 = blocksize;
  MBlockMatrix->blocksize1 = blocksize;
  MBlockMatrix->filled1 = 5;
  MBlockMatrix->filled2 = 4;
  size_t index1_data[5] = {0, 1, 2, 3, 4} ;
  size_t index2_data[4] = {0, 1, 2, 3} ;
  MBlockMatrix->index1_data =  index1_data;
  MBlockMatrix->index2_data =  index2_data;


  NumericsProblem.H = newSBM();
  NumericsMatrix *HH =  NumericsProblem.H;
  HH->storageType = 1;
  HH->size0 = Ndof;
  HH->size1 = 3 * NC;

  HH->matrix1 = (SparseBlockStructuredMatrix*)malloc(sizeof(SparseBlockStructuredMatrix));
  HH->matrix0 = NULL;
  SparseBlockStructuredMatrix *HBlockMatrix = HH->matrix1;
  HBlockMatrix->nbblocks = 4;
  double * hblock[4] = {H00, H11, H20, H31};
  HBlockMatrix->block = hblock;
  HBlockMatrix->blocknumber0 = 4;
  HBlockMatrix->blocknumber1 = 2;
  int blocksize0[4] = {3, 6, 9, 12} ;
  int blocksize1[3] = {3, 6, 9} ;
  HBlockMatrix->blocksize0 = blocksize0;
  HBlockMatrix->blocksize1 = blocksize1;
  HBlockMatrix->filled1 = 5;
  HBlockMatrix->filled2 = 4;
  size_t hindex1_data[5] = {0, 1, 2, 3, 4} ;
  size_t hindex2_data[4] = {0, 1, 0, 1} ;
  HBlockMatrix->index1_data =  hindex1_data;
  HBlockMatrix->index2_data =  hindex2_data;
  printSBM(HBlockMatrix);


  // Unknown Declaration

  double *reaction = (double*)malloc(m * sizeof(double));
  double *velocity = (double*)malloc(m * sizeof(double));
  double *globalVelocity = (double*)malloc(n * sizeof(double));
  for (k = 0 ; k < m; k++)
  {
    velocity[k] = 0.0;
    reaction[k] = 0.0;
  }
  for (k = 0 ; k < n; k++) globalVelocity[k] = 0.0;
  // Numerics and Solver Options

  SolverOzptions numerics_solver_options;
  numerics_solver_options.filterOn = 0;
  numerics_solver_options.isSet = 1;

  //    strcpy(numerics_solver_optionslverName,"NSGS_WR");
  //    strcpy(numerics_solver_optionslverName,"NSGS");
  //    strcpy(numerics_solver_optionslverName,"NSGSV_WR");
  numerics_solver_optionslverId = SICONOS_FRICTION_3D_NSGS;

  numerics_solver_options.iSize = 5;
  numerics_solver_options.iparam = (int*)malloc(numerics_solver_options.iSize * sizeof(int));
  int ii ;
  for (ii = 0; ii < numerics_solver_options.iSize; ii++)
    numerics_solver_options.iparam[ii] = 0;
  numerics_solver_options.dSize = 5;
  numerics_solver_options.dparam = (double*)malloc(numerics_solver_options.dSize * sizeof(double));
  for (ii = 0; ii < numerics_solver_options.dSize; ii++)
    numerics_solver_options.dparam[ii] = 0;

  int nmax = 100; // Max number of iteration
  int localsolver = 0; // 0: projection on Cone, 1: Newton/AlartCurnier,  2: projection on Cone with local iteration, 2: projection on Disk  with diagonalization,
  double tolerance = 1e-10;
  double localtolerance = 1e-12;



  numerics_solver_options.iparam[0] = nmax ;
  numerics_solver_options.iparam[4] = localsolver ;
  numerics_solver_options.dparam[0] = tolerance ;
  numerics_solver_options.dparam[2] = localtolerance ;

  //Driver call
  info = primalFrictionContact3D_driver(&NumericsProblem,
                                        reaction , velocity, globalVelocity,
                                        &numerics_solver_options);



  // Solver output
  printf("\n");
  for (k = 0 ; k < m; k++) printf("velocity[%i] = %12.8e \t \t reaction[%i] = %12.8e \n ", k, velocity[k], k , reaction[k]);
  for (k = 0 ; k < n; k++) printf("globalVelocity[%i] = %12.8e \t \n ", k, globalVelocity[k]);
  printf("\n");


  free(reaction);
  free(velocity);
  free(globalVelocity);

  //     freeSBM(MM->matrix1);
  //     freeSBM(HH->matrix1);
  free(MM->matrix1);
  free(HH->matrix1);
  free(MM);
  free(HH);

  free(numerics_solver_options.iparam);
  free(numerics_solver_options.dparam);

  /*     while (1) sleep(60); */


  return info;


}
Example #7
0
void NM_copy(const NumericsMatrix* const A, NumericsMatrix* B)
{
    int sizeA = A->size0 * A->size1;
    int sizeB = B->size0 * B->size1;
    B->size0 = A->size0;
    B->size1 = A->size1;

    switch (A->storageType)
    {
    case NM_DENSE:
    {
        if (B->matrix0)
        {
            if (sizeB < sizeA)
            {
                B->matrix0 = (double*) realloc(B->matrix0, sizeA * sizeof(double));
            }
        }
        else
        {
            B->matrix0 = (double*) malloc(sizeA * sizeof(double));
        }
        cblas_dcopy(sizeA, A->matrix0, 1, B->matrix0, 1);

        /* invalidations */
        NM_clearSparseBlock(B);
        NM_clearSparseStorage(B);

        break;
    }
    case NM_SPARSE_BLOCK:
    {
        int need_blocks = 0;

        SparseBlockStructuredMatrix* A_ = A->matrix1;
        SparseBlockStructuredMatrix* B_ = B->matrix1;

        if (B_)
        {
            if (B_->nbblocks < A_->nbblocks)
            {
                need_blocks = 1;
                for (unsigned i=0; i<B_->nbblocks; ++i)
                {
                    free(B_->block [i]);
                    B_->block [i] = NULL;
                }
                B_->block = (double **) realloc(B_->block, A_->nbblocks * sizeof(double *));
            }
            B_->nbblocks = A_->nbblocks;

            if (B_->blocknumber0 < A_->blocknumber0)
            {
                B_->blocksize0 = (unsigned int*) realloc(B_->blocksize0, A_->blocknumber0 * sizeof(unsigned int));
            }
            B_->blocknumber0 = A_->blocknumber0;

            if (B_->blocknumber1 < A_->blocknumber1)
            {
                B_->blocksize1 = (unsigned int*) realloc(B_->blocksize1, A_->blocknumber1 * sizeof(unsigned int));
            }
            B_->blocknumber1 = A_->blocknumber1;

            if (B_->filled1 < A_->filled1)
            {
                B_->index1_data = (size_t*) realloc(B_->index1_data, A_->filled1 * sizeof(size_t));
            }
            B_->filled1 = A_->filled1;

            if (B_->filled2 < A_->filled2)
            {
                B_->index2_data = (size_t*) realloc(B_->index2_data, A_->filled2 * sizeof(size_t));
            }
            B_->filled2 = A_->filled2;
        }
        else
        {
            B->matrix1 = newSBM();
            B_ = B->matrix1;

            B_->block = (double **) malloc(A_->nbblocks * sizeof(double *));
            B_->nbblocks = A_->nbblocks;

            B_->blocksize0 = (unsigned int*) malloc(A_->blocknumber0 * sizeof(unsigned int));
            B_->blocknumber0 = A_->blocknumber0;

            B_->blocksize1 = (unsigned int*) malloc(A_->blocknumber1 * sizeof(unsigned int));
            B_->blocknumber1 = A_->blocknumber1;

            B_->index1_data = (size_t*) malloc(A_->filled1 * sizeof(size_t));
            B_->filled1 = A_->filled1;

            B_->index2_data = (size_t*) malloc(A_->filled2 * sizeof(size_t));
            B_->filled2 = A_->filled2;
        }

        memcpy(B_->blocksize0, A_->blocksize0, A_->blocknumber0 * sizeof(unsigned int));
        memcpy(B_->blocksize1, A_->blocksize1, A_->blocknumber1 * sizeof(unsigned int));
        memcpy(B_->index1_data, A_->index1_data, A_->filled1 * sizeof(size_t));
        memcpy(B_->index2_data, A_->index2_data, A_->filled2 * sizeof(size_t));

        /* cf copySBM */
        unsigned int currentRowNumber ;
        size_t colNumber;
        unsigned int nbRows, nbColumns;
        for (currentRowNumber = 0 ; currentRowNumber < A_->filled1 - 1; ++currentRowNumber)
        {
            for (size_t blockNum = A_->index1_data[currentRowNumber];
                    blockNum < A_->index1_data[currentRowNumber + 1]; ++blockNum)
            {
                assert(blockNum < A_->filled2);
                colNumber = A_->index2_data[blockNum];
                /* Get dim. of the current block */
                nbRows = A_->blocksize0[currentRowNumber];
                if (currentRowNumber != 0)
                    nbRows -= A_->blocksize0[currentRowNumber - 1];
                nbColumns = A_->blocksize1[colNumber];

                if (colNumber != 0)
                    nbColumns -= A_->blocksize1[colNumber - 1];

                if (need_blocks)
                {
                    B_->block[blockNum] = (double*)malloc(nbRows * nbColumns * sizeof(double));
                }

                for (unsigned int i = 0; i < nbRows * nbColumns; i++)
                {
                    B_->block[blockNum] [i] = A_->block[blockNum] [i] ;
                }
            }
        }

        /* invalidations */
        NM_clearDense(B);
        NM_clearSparseStorage(B);

        break;
    }
    case NM_SPARSE:
    {
        CSparseMatrix* A_;
        CSparseMatrix* B_;

        if (!B->matrix2)
        {
            B->matrix2 = newNumericsSparseMatrix();
        }

        if (A->matrix2->triplet)
        {
            A_ = A->matrix2->triplet;

            if (!B->matrix2->triplet)
            {
                B->matrix2->triplet = cs_spalloc(A_->m, A_->n, A_->nzmax, 0, 1);
            }

            B_ = B->matrix2->triplet;
        }
        else
        {
            assert (A->matrix2->csc);

            A_ = A->matrix2->csc;

            if (!B->matrix2->csc)
            {
                B->matrix2->csc = cs_spalloc(A_->m, A_->n, A_->nzmax, 0, 0);
            }

            B_ = B->matrix2->csc;
        }

        assert (A_);
        assert (B_);

        if (B_ ->nzmax < A_ ->nzmax)
        {
            B_->x = (double *) realloc(B_->x, A_->nzmax * sizeof(double));
            B_->i = (csi *) realloc(B_->i, A_->nzmax * sizeof(csi));
        }
        else if (!(B_->x))
        {
            B_->x = (double *) malloc(A_->nzmax * sizeof(double));
        }

        if (A_->nz >= 0)
        {
            /* triplet */
            B_->p = (csi *) realloc(B_->p, A_->nzmax * sizeof(csi));
        }
        else
        {
            if (B_->n < A_->n)
            {
                /* csc */
                B_-> p = (csi *) realloc(B_->p, (A_->n + 1) * sizeof(csi));
            }
        }

        B_->nzmax = A_->nzmax;
        B_->nz = A_->nz;
        B_->m = A_->m;
        B_->n = A_->n;

        memcpy(B_->x, A_->x, A_->nzmax * sizeof(double));
        memcpy(B_->i, A_->i, A_->nzmax * sizeof(csi));

        if (A_->nz >= 0)
        {
            memcpy(B_->p, A_->p, A_->nzmax * sizeof(csi));
        }
        else
        {
            memcpy(B_->p, A_->p, (A_->n + 1) * sizeof(csi));
        }


        /* invalidations */
        NM_clearDense(B);
        NM_clearSparseBlock(B);

        if (B_->nz >= 0)
        {
            NM_clearCSC(B);
            NM_clearCSCTranspose(B);
        }
        else
        {
            NM_clearTriplet(B);
        }

        break;
    }
    }
}