PetscErrorCode MatHeaderMerge(Mat A,Mat C)
{
    PetscErrorCode ierr;
    PetscInt       refct;
    PetscOps       *Abops;
    MatOps         Aops;
    char           *mtype,*mname;
    void           *spptr;

    PetscFunctionBegin;
    /* save the parts of A we need */
    Abops = ((PetscObject)A)->bops;
    Aops  = A->ops;
    refct = ((PetscObject)A)->refct;
    mtype = ((PetscObject)A)->type_name;
    mname = ((PetscObject)A)->name;
    spptr = A->spptr;

    /* zero these so the destroy below does not free them */
    ((PetscObject)A)->type_name = 0;
    ((PetscObject)A)->name      = 0;

    /* free all the interior data structures from mat */
    ierr = (*A->ops->destroy)(A);
    CHKERRQ(ierr);

    ierr = PetscFree(C->spptr);
    CHKERRQ(ierr);

    ierr = PetscLayoutDestroy(&A->rmap);
    CHKERRQ(ierr);
    ierr = PetscLayoutDestroy(&A->cmap);
    CHKERRQ(ierr);
    ierr = PetscFunctionListDestroy(&((PetscObject)A)->qlist);
    CHKERRQ(ierr);
    ierr = PetscObjectListDestroy(&((PetscObject)A)->olist);
    CHKERRQ(ierr);

    /* copy C over to A */
    ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));
    CHKERRQ(ierr);

    /* return the parts of A we saved */
    ((PetscObject)A)->bops      = Abops;
    A->ops                      = Aops;
    ((PetscObject)A)->refct     = refct;
    ((PetscObject)A)->type_name = mtype;
    ((PetscObject)A)->name      = mname;
    A->spptr                    = spptr;

    /* since these two are copied into A we do not want them destroyed in C */
    ((PetscObject)C)->qlist = 0;
    ((PetscObject)C)->olist = 0;

    ierr = PetscHeaderDestroy(&C);
    CHKERRQ(ierr);
    PetscFunctionReturn(0);
}
Beispiel #2
0
/*
    PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
    the macro PetscHeaderDestroy().
*/
PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
{
  PetscErrorCode ierr;

  PetscFunctionBegin;
  PetscValidHeader(h,1);
  ierr = PetscLogObjectDestroy(h);CHKERRQ(ierr);
  ierr = PetscComposedQuantitiesDestroy(h);CHKERRQ(ierr);
  if (PetscMemoryCollectMaximumUsage) {
    PetscLogDouble usage;
    ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr);
    if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
  }
  /* first destroy things that could execute arbitrary code */
  if (h->python_destroy) {
    void           *python_context = h->python_context;
    PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
    h->python_context = 0;
    h->python_destroy = 0;

    ierr = (*python_destroy)(python_context);CHKERRQ(ierr);
  }
  ierr = PetscObjectDestroyOptionsHandlers(h);CHKERRQ(ierr);
  ierr = PetscObjectListDestroy(&h->olist);CHKERRQ(ierr);
  ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr);
  /* next destroy other things */
  h->classid = PETSCFREEDHEADER;

  ierr = PetscFunctionListDestroy(&h->qlist);CHKERRQ(ierr);
  ierr = PetscFree(h->type_name);CHKERRQ(ierr);
  ierr = PetscFree(h->name);CHKERRQ(ierr);
  ierr = PetscFree(h->prefix);CHKERRQ(ierr);
  ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr);
  ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);CHKERRQ(ierr);
  ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr);

#if defined(PETSC_USE_LOG)
  if (PetscObjectsLog) {
    PetscInt i;
    /* Record object removal from list of all objects */
    for (i=0; i<PetscObjectsMaxCounts; i++) {
      if (PetscObjects[i] == h) {
        PetscObjects[i] = 0;
        PetscObjectsCounts--;
        break;
      }
    }
    if (!PetscObjectsCounts) {
      ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
      PetscObjectsMaxCounts = 0;
    }
  }
#endif
  PetscFunctionReturn(0);
}