예제 #1
0
int MAIN__()
{
	int argc = 1;
	char * name = "c_example";
	char ** argv;
#else
int main(int argc, char ** argv)
{
#endif
	DMUMPS_STRUC_C id;
	MUMPS_INT n = 2;
	MUMPS_INT nz = 2;
	MUMPS_INT irn[] = { 1, 2 };
	MUMPS_INT jcn[] = { 1, 2 };
	double a[2];
	double rhs[2];

	MUMPS_INT myid, ierr;
#if defined(MAIN_COMP)
	argv = &name;
#endif
	ierr = MPI_Init(&argc, &argv);
	ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
	/* Define A and rhs */
	rhs[0] = 1.0; rhs[1] = 4.0;
	a[0] = 1.0; a[1] = 2.0;

	/* Initialize a MUMPS instance. Use MPI_COMM_WORLD */
	id.job = JOB_INIT; id.par = 1; id.sym = 0; id.comm_fortran = USE_COMM_WORLD;
	dmumps_c(&id);
	/* Define the problem on the host */
	if (myid == 0) {
		id.n = n; id.nz = nz; id.irn = irn; id.jcn = jcn;
		id.a = a; id.rhs = rhs;
	}
#define ICNTL(I) icntl[(I)-1] /* macro s.t. indices match documentation */
	/* No outputs */
	id.ICNTL(1) = -1; id.ICNTL(2) = -1; id.ICNTL(3) = -1; id.ICNTL(4) = 0;
	/* Call the MUMPS package. */
	id.job = 6;
	dmumps_c(&id);
	id.job = JOB_END; dmumps_c(&id); /* Terminate instance */
	if (myid == 0) {
		printf("Solution is : (%8.2f  %8.2f)\n", rhs[0], rhs[1]);
	}
	ierr = MPI_Finalize();
	getchar();
	return 0;
}
예제 #2
0
int MAIN__()
{
  int argc=1;
  char * name = "c_example";
  char ** argv ;
#else
int main(int argc, char ** argv)
{
#endif
  DMUMPS_STRUC_C id;

  int n = 6;
  int nz = 21;
  int irnL[] = {1,2,3,4,5,6,2,3,4,5,6,3,4,5,6,4,5,6,5,6,6};
  int jcnL[] = {1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,5,5,6};
  int irnS[] = {1,2,3,2,3,3};
  int jcnS[] = {1,1,1,2,2,3};

  int *irn = irnL;
  int *jcn = jcnL;

  double a[21];
  double rhs[6];

  int myid, ierr, numP;
#if defined(MAIN_COMP)
  argv = &name;
#endif
  ierr = MPI_Init(&argc, &argv);
  ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  ierr = MPI_Comm_size(MPI_COMM_WORLD, &numP);
  
  double nump = numP * 1.0;

  /* Define A and rhs */
  rhs[0]=2.0;rhs[1]=2.0;rhs[2]=2.0;rhs[3]=2.0;rhs[4]=2.0;rhs[5]=2.0;

  a[0]=4169.95/nump;
  a[1]=0.0;
  a[2]=10075.0/nump;
  a[3]=-4030;
  a[4]=0.0;
  a[5]=0.0;
  a[6]=10084.0/nump;
  a[7]=-1612.0/nump;
  a[8]=0.0;
  a[9]=-8.9556;
  a[10]=-1612;
  a[11]=1354080.0/nump;
  a[12]=0.0;
  a[13]=1612.0;
  a[14]=193440.0;
  a[15]=4169.93;
  a[16]=0.0;
  a[17]=10075;
  a[18]=10084;
  a[19]=1612;
  a[20]=1354000;

  if (myid != 0) {
      nz = 6;

      a[0]=4169.95/nump;
      a[1]=0.0;
      a[2]=10075.0/nump;

      a[3]=10084.0/nump;
      a[4]=-1612.0/nump;

      a[5]=1354080.0/nump;

      irn = irnS;
      jcn = jcnS;
  }

#define ICNTL(I) icntl[(I)-1] /* macro s.t. indices match documentation */

  /* Initialize a MUMPS instance. Use MPI_COMM_WORLD */
  id.job=JOB_INIT; id.par=1; id.sym=2; id.comm_fortran=USE_COMM_WORLD;

  /* parallel solver; distributed i/p matrix A */
  id.ICNTL(5)=0; id.ICNTL(18)=3;  
  dmumps_c(&id);

  /* Define the problem on the host */
  /*
  id.n = n; id.nz =nz; id.irn=irn; id.jcn=jcn;
  id.a = a; id.rhs = rhs;
  */

  /* parallel solver; distributed i/p matrix A */

  id.ICNTL(5)=0; id.ICNTL(18)=3;  

  id.n = n; id.nz_loc =nz; id.irn_loc=irn; id.jcn_loc=jcn;
  id.a_loc = a; id.rhs = rhs;

  /* No outputs */
  id.ICNTL(1)=-1; id.ICNTL(2)=-1; id.ICNTL(3)=-1; id.ICNTL(4)=0; 

  id.job=1;
  dmumps_c(&id);


  id.job=5;
  dmumps_c(&id);

  if (myid == 0) {
    printf("Solution is : (%8.6e %8.6e %8.6e %8.6e %8.6e %8.6e \n", rhs[0],rhs[1], rhs[2], rhs[3], rhs[4], rhs[5]);
  }

  rhs[0]=2.0;rhs[1]=2.0;rhs[2]=2.0;rhs[3]=1.0;rhs[4]=1.0;rhs[5]=1.0;


  id.job=3;
  dmumps_c(&id);

  /* Terminate instance */
  id.job=JOB_END; 
  dmumps_c(&id); 

  if (myid == 0) {
    printf("Solution is : (%8.6e %8.6e %8.6e %8.6e %8.6e %8.6e \n", rhs[0],rhs[1], rhs[2], rhs[3], rhs[4], rhs[5]);
  }

  ierr = MPI_Finalize();
  return 0;
}
예제 #3
0
파일: Matrix.cpp 프로젝트: ninge/YOHAN
/* Solve Mx = b */
DATA* yohan::matrix::solveLinearEquation(SquareSparseMatrix* M, DATA* b)
{
	//for SymmetricUpperSquareSparseMatrix, using MUMPS
	if (M->getType() == SquareSparseMatrix::TYPE_SymmetricMumpsSquareSparse)
	{
		/* Platform MUMPS relatives*/
		DMUMPS_STRUC_C id;

		/* JOB_INIT */

		id.job = -1;	// step: JOB_INIT
		id.par = 1;		// the host will participate the factorisation/solve phase, in SEQ version, 1 is better
		id.sym = 0;		// 2 - general symmetric; 1 - symmetric positive definite; 0 - unsymmetric
		//id.comm_fortran = -987654;
		dmumps_c(&id);

		/* Define the problem on the host */

		SymmetricMumpsSquareSparseMatrix* A = (SymmetricMumpsSquareSparseMatrix*)M;
		id.n = A->order;	//order
		id.nz = A->size;	//count of non-element
		id.irn = A->rows;
		id.jcn = A->columns;
		id.a = A->values;
		id.rhs = b;

		/* Configuration of the solver */
		//id.ICNTL(5) = 0;	// the matrix is defined in an "assembled format", (i, j, val)

		id.ICNTL(1) = -1;
		id.ICNTL(2) = -1;
		id.ICNTL(3) = -1;
		id.ICNTL(4) = 0;	// all these are for the dignostic display, put on -1 if not necessary

		/* Call the solver */
		id.job = 6;

		dmumps_c(&id);

		/* We should consider here whether we desallocate the M and the b */

		/* JOB_END */
		id.job=-2;
		dmumps_c(&id);
		
		
		/* Return */
		return b;

	}
	else if (M->getType() == SquareSparseMatrix::TYPE_SymmetricMumpsSquareSparse2)
	{
		/* Platform MUMPS relatives*/
		DMUMPS_STRUC_C id;

		/* JOB_INIT */

		id.job = -1;	// step: JOB_INIT
		id.par = 1;		// the host will participate the factorisation/solve phase, in SEQ version, 1 is better
		id.sym = 0;		// 2 - general symmetric; 1 - symmetric positive definite; 0 - unsymmetric
		//id.comm_fortran = -987654;
		dmumps_c(&id);

		/* Define the problem on the host */

		SymmetricMumpsSquareSparseMatrix2* A = (SymmetricMumpsSquareSparseMatrix2*)M;
		id.n = A->order;	//order
		id.nz = A->size;	//count of non-element
		id.irn = A->rows;
		id.jcn = A->columns;
		id.a = A->values;
		id.rhs = b;

		/* Configuration of the solver */
		//id.ICNTL(5) = 0;	// the matrix is defined in an "assembled format", (i, j, val)

		id.ICNTL(1) = -1;
		id.ICNTL(2) = -1;
		id.ICNTL(3) = -1;
		id.ICNTL(4) = 0;	// all these are for the dignostic display, put on -1 if not necessary

		/* Call the solver */
		id.job = 6;

		dmumps_c(&id);

		/* We should consider here whether we desallocate the M and the b */

		/* JOB_END */
		id.job=-2;
		dmumps_c(&id);
		
		
		/* Return */
		return b;

	}
	else
		return NULL;

	//if (A->getType() == SquareSparseMatrix::TYPE_SymmetricIntelSquareSparse)

}
예제 #4
0
//-----------------------------------------------------------------------------
std::size_t MUMPSLUSolver::solve(GenericVector& x, const GenericVector& b)
{
  dolfin_assert(_matA);

  DMUMPS_STRUC_C data;

  data.comm_fortran = -987654;

  // Initialise
  data.job = -1;

  // Host participates in solve
  data.par = 1;

  // Output related parameters
  //data.ICNTL(1) = 6; // error messages
  //data.ICNTL(2) = 0;
  //data.ICNTL(3) = 6; // Global information
  //data.ICNTL(3) = 6; // Global information
  if (parameters["verbose"])
    data.ICNTL(4) = 2;
  else
    data.ICNTL(4) = 1;

  // Matrix symmetry (0=non-symmetric, 2=symmetric positive defn, 2=symmetric)
  data.sym = 0;
  if (parameters["symmetric"])
    data.sym = 2;

  // Initialise MUMPS
  dmumps_c(&data);

  // Related to use of ScaLAPACK (+/-. Negative is faster?)
  //data.ICNTL(13) = -1;

  // Solve transpose (1: A x = b, otherwise A^T x = b)
  data.ICNTL(9) = 1;

  // FIXME (20=default)
  data.ICNTL(14) = 20;

  // Reordering (7=automatic)
  data.ICNTL(7) = 7;

  // Control solution vector (0=solution on root, 1=solution distributed)
  data.ICNTL(21) = 1;

  // Distributed matrix
  data.ICNTL(18) = 3;

  // Parallel/serial analysis (0=auto, 1=serial, 2=parallel)
  if (MPI::size(_matA->mpi_comm()) > 1)
    data.ICNTL(28) = 2;
  else
    data.ICNTL(28) = 0;

  // Parallel graph partitioning library (0=auto, 1=pt-scotch, 2=parmetis)
  data.ICNTL(29) = 0;

  // Global size
  dolfin_assert(_matA->size(0) == _matA->size(1));
  data.n = _matA->size(0);

  if (!_matA->base_one())
    dolfin_error("MUMPSLUSolver.cpp",
                 "initialize solver",
                 "MUMPS requires a CoordinateMatrix with Fortran-style "
                 "base 1 indexing");

  // Get matrix coordinate and value data
  const std::vector<std::size_t>& rows = _matA->rows();
  const std::vector<std::size_t>& cols = _matA->columns();
  const std::vector<double>& vals = _matA->values();

  // Number of non-zero entries on this process
  data.nz_loc = rows.size();

  // Pass matrix data to MUMPS. Trust MUMPS not to change it
  data.irn_loc = const_cast<int*>(reinterpret_cast<const int*>(rows.data()));
  data.jcn_loc = const_cast<int*>(reinterpret_cast<const int*>(cols.data()));
  data.a_loc   = const_cast<double*>(vals.data());

  // Analyse and factorize
  data.job = 4;
  dmumps_c(&data);
  if (data.INFOG(1) < 0)
    dolfin_error("MUMPSLUSolver.cpp",
                 "compute matrix factors",
                 "MUMPS reported an error during the analysis and "
                 "factorisation");

  cout << "Factorisation finished" << endl;

  // Gather RHS on root process and attach
  std::vector<double> _b;
  b.gather_on_zero(_b);
  data.rhs = _b.data();

  // Scaling strategy (77 is default)
  data.ICNTL(8) = 77;

  // Get size of local solution vector x and create objects to hold solution
  const std::size_t local_x_size = data.INFO(23);
  std::vector<int> x_local_indices(local_x_size);
  std::vector<double> x_local_vals(local_x_size);

  // Attach solution data to MUMPS object
  data.lsol_loc = local_x_size;
  data.sol_loc  = x_local_vals.data();
  data.isol_loc = x_local_indices.data();

  // Solve problem
  data.job = 3;
  dmumps_c(&data);
  if (data.INFOG(1) < 0)
    dolfin_error("MUMPSLUSolver.cpp",
                 "compute matrix factors",
                 "MUMPS reported an error during the solve");

  // Shift indices by -1
  for (std::size_t i = 0; i < local_x_size ; ++i)
    x_local_indices[i]--;

  // Set x values
  #if defined(PETSC_USE_64BIT_INDICES)
  // Cast indices to 64 bit
  std::vector<dolfin::la_index> _x_local_indices(x_local_indices.begin(),
                                                 x_local_indices.end());
  x.set_local(x_local_vals.data(), x_local_indices.size(),
              _x_local_indices.data());
  #else
  x.set_local(x_local_vals.data(), x_local_indices.size(),
              x_local_indices.data());
  #endif
  x.apply("insert");

  // Clean up
  data.job = -2;
  dmumps_c(&data);

  return 1;
}