/*****************************************************************************
 * Zoltan Library for Parallel Applications                                  *
 * Copyright (c) 2000,2001,2002, Sandia National Laboratories.               *
 * For more info, see the README file in the top-level Zoltan directory.     *  
 *****************************************************************************/
/*****************************************************************************
 * CVS File Information :
 *    $RCSfile: dr_dd.c,v $
 *    $Author: dneckels $
 *    $Date: 2007/11/28 16:13:47 $
 *    Revision: 1.4 $
 ****************************************************************************/


#include "dr_const.h"
#include "dr_util_const.h"
#include "dr_err_const.h"
#include "dr_dd.h"

#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif


/****************************************************************************/
int build_elem_dd(MESH_INFO_PTR mesh) 
{
/* Create a distributed directory of the elements so we can track their
 * processor assignment after migrations.
 */

  if (Zoltan_DD_Create(&(mesh->dd), MPI_COMM_WORLD, 1, 0, 0, 0, 0) != 0) {
    Gen_Error(0, "fatal:  NULL returned from Zoltan_DD_Create()\n");
    return 0;
  }

  return update_elem_dd(mesh);
}

/****************************************************************************/
int update_elem_dd(MESH_INFO_PTR mesh)
{
/*  Update a distributed directory of the elements with processor
 *  assignments initially and after migration.
 */
ELEM_INFO_PTR current_elem;
ZOLTAN_ID_PTR gids; 
int *parts;
int i, j;

  gids = (ZOLTAN_ID_PTR) malloc(mesh->num_elems * sizeof(ZOLTAN_ID_TYPE));
  parts = (int *) malloc(mesh->num_elems * sizeof(int));

  for (j = 0, i = 0; i < mesh->elem_array_len; i++) {
    current_elem = &(mesh->elements[i]);
    if (current_elem->globalID >= 0) {
      gids[j] = current_elem->globalID;
      parts[j] = current_elem->my_part;
      j++;
    }
  }

  if (Zoltan_DD_Update(mesh->dd, gids, NULL,NULL, parts, mesh->num_elems)!=0) {
    Gen_Error(0, "fatal:  NULL returned from Zoltan_DD_Update()\n");
    return 0;
  }

  safe_free((void **) &gids);
  safe_free((void **) &parts);
  return 1;
}


/****************************************************************************/
int update_hvertex_proc(MESH_INFO_PTR mesh)
{
  if (Zoltan_DD_Find(mesh->dd, (ZOLTAN_ID_PTR)mesh->hvertex, NULL, NULL, NULL,
                     mesh->hindex[mesh->nhedges], mesh->hvertex_proc) != 0) {

    Gen_Error(0, "fatal:  NULL returned from Zoltan_DD_Find()\n");
    return 0;
  }
  return 1;
}

#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
