void PETSC_STDCALL dmaddagetcorners_(DM dm,PetscInt **lcorner,PetscInt **ucorner, int *__ierr ){ *__ierr = DMADDAGetCorners( (DM)PetscToPointer((dm) ),lcorner,ucorner); }
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); }