Exemplo n.º 1
0
void PETSC_STDCALL  dmaddagetmatrixns_(DM dm,DM dmc,MatType *mtype,Mat *mat, int *__ierr ){
*__ierr = DMADDAGetMatrixNS(
	(DM)PetscToPointer((dm) ),
	(DM)PetscToPointer((dmc) ),*mtype,mat);
}
Exemplo n.º 2
0
PetscErrorCode  DMCreateAggregates_ADDA(DM dmc,DM dmf,Mat *rest)
{
  PetscErrorCode ierr=0;
  PetscInt       i;
  PetscInt       dim;
  PetscInt       dofc, doff;
  PetscInt       *lcs_c, *lce_c;
  PetscInt       *lcs_f, *lce_f;
  PetscInt       *fgs, *fge;
  PetscInt       fgdofs, fgdofe;
  ADDAIdx        iter_c, iter_f;
  PetscInt       max_agg_size;
  PetscMPIInt    comm_size;
  ADDAIdx        *fine_nodes;
  PetscInt       fn_idx;
  PetscScalar    *one_vec;
  DM_ADDA        *ddc = (DM_ADDA*)dmc->data;
  DM_ADDA        *ddf = (DM_ADDA*)dmf->data;

  PetscFunctionBegin;
  PetscValidHeaderSpecific(dmc, DM_CLASSID, 1);
  PetscValidHeaderSpecific(dmf, DM_CLASSID, 2);
  PetscValidPointer(rest,3);
  if (ddc->dim != ddf->dim) SETERRQ2(PetscObjectComm((PetscObject)dmf),PETSC_ERR_ARG_INCOMP,"Dimensions of ADDA do not match %D %D", ddc->dim, ddf->dim);CHKERRQ(ierr);
/*   if (dmc->dof != dmf->dof) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"DOF of ADDA do not match %D %D", dmc->dof, dmf->dof);CHKERRQ(ierr); */
  dim  = ddc->dim;
  dofc = ddc->dof;
  doff = ddf->dof;

  ierr = DMADDAGetCorners(dmc, &lcs_c, &lce_c);CHKERRQ(ierr);
  ierr = DMADDAGetCorners(dmf, &lcs_f, &lce_f);CHKERRQ(ierr);

  /* compute maximum size of aggregate */
  max_agg_size = 1;
  for (i=0; i<dim; i++) {
    max_agg_size *= ddf->nodes[i] / ddc->nodes[i] + 1;
  }
  max_agg_size *= doff / dofc + 1;

  /* create the matrix that will contain the restriction operator */
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&comm_size);CHKERRQ(ierr);

  /* construct matrix */
  if (comm_size == 1) {
    ierr = DMADDAGetMatrixNS(dmc, dmf, MATSEQAIJ, rest);CHKERRQ(ierr);
    ierr = MatSeqAIJSetPreallocation(*rest, max_agg_size, NULL);CHKERRQ(ierr);
  } else {
    ierr = DMADDAGetMatrixNS(dmc, dmf, MATMPIAIJ, rest);CHKERRQ(ierr);
    ierr = MatMPIAIJSetPreallocation(*rest, max_agg_size, NULL, max_agg_size, NULL);CHKERRQ(ierr);
  }
  /* store nodes in the fine grid here */
  ierr = PetscMalloc(sizeof(ADDAIdx)*max_agg_size, &fine_nodes);CHKERRQ(ierr);
  /* these are the values to set to, a collection of 1's */
  ierr = PetscMalloc(sizeof(PetscScalar)*max_agg_size, &one_vec);CHKERRQ(ierr);
  /* initialize */
  for (i=0; i<max_agg_size; i++) {
    ierr       = PetscMalloc(sizeof(PetscInt)*dim, &(fine_nodes[i].x));CHKERRQ(ierr);
    one_vec[i] = 1.0;
  }

  /* get iterators */
  ierr = PetscMalloc(sizeof(PetscInt)*dim, &(iter_c.x));CHKERRQ(ierr);
  ierr = PetscMalloc(sizeof(PetscInt)*dim, &(iter_f.x));CHKERRQ(ierr);

  /* the fine grid node corner for each coarse grid node */
  ierr = PetscMalloc(sizeof(PetscInt)*dim, &fgs);CHKERRQ(ierr);
  ierr = PetscMalloc(sizeof(PetscInt)*dim, &fge);CHKERRQ(ierr);

  /* loop over all coarse nodes */
  ierr = PetscMemcpy(iter_c.x, lcs_c, sizeof(PetscInt)*dim);CHKERRQ(ierr);
  if (ADDAHCiterStartup(dim, lcs_c, lce_c, iter_c.x)) {
    do {
      /* find corresponding fine grid nodes */
      for (i=0; i<dim; i++) {
        fgs[i] = iter_c.x[i]*ddf->nodes[i]/ddc->nodes[i];
        fge[i] = PetscMin((iter_c.x[i]+1)*ddf->nodes[i]/ddc->nodes[i], ddf->nodes[i]);
      }
      /* treat all dof of the coarse grid */
      for (iter_c.d=0; iter_c.d<dofc; iter_c.d++) {
        /* find corresponding fine grid dof's */
        fgdofs = iter_c.d*doff/dofc;
        fgdofe = PetscMin((iter_c.d+1)*doff/dofc, doff);
        /* we now know the "box" of all the fine grid nodes that are mapped to one coarse grid node */
        fn_idx = 0;
        /* loop over those corresponding fine grid nodes */
        if (ADDAHCiterStartup(dim, fgs, fge, iter_f.x)) {
          do {
            /* loop over all corresponding fine grid dof */
            for (iter_f.d=fgdofs; iter_f.d<fgdofe; iter_f.d++) {
              ierr = PetscMemcpy(fine_nodes[fn_idx].x, iter_f.x, sizeof(PetscInt)*dim);CHKERRQ(ierr);

              fine_nodes[fn_idx].d = iter_f.d;
              fn_idx++;
            }
          } while (ADDAHCiter(dim, fgs, fge, iter_f.x));
        }
        /* add all these points to one aggregate */
        ierr = DMADDAMatSetValues(*rest, dmc, 1, &iter_c, dmf, fn_idx, fine_nodes, one_vec, INSERT_VALUES);CHKERRQ(ierr);
      }
    } while (ADDAHCiter(dim, lcs_c, lce_c, iter_c.x));
  }

  /* free memory */
  ierr = PetscFree(fgs);CHKERRQ(ierr);
  ierr = PetscFree(fge);CHKERRQ(ierr);
  ierr = PetscFree(iter_c.x);CHKERRQ(ierr);
  ierr = PetscFree(iter_f.x);CHKERRQ(ierr);
  ierr = PetscFree(lcs_c);CHKERRQ(ierr);
  ierr = PetscFree(lce_c);CHKERRQ(ierr);
  ierr = PetscFree(lcs_f);CHKERRQ(ierr);
  ierr = PetscFree(lce_f);CHKERRQ(ierr);
  ierr = PetscFree(one_vec);CHKERRQ(ierr);
  for (i=0; i<max_agg_size; i++) {
    ierr = PetscFree(fine_nodes[i].x);CHKERRQ(ierr);
  }
  ierr = PetscFree(fine_nodes);CHKERRQ(ierr);

  ierr = MatAssemblyBegin(*rest, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(*rest, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}