/*============================================================================
 * Append sections to a nodal representation associated with a mesh
 *============================================================================*/

/*
  This file is part of the "Finite Volume Mesh" library, intended to provide
  finite volume mesh and associated fields I/O and manipulation services.

  Copyright (C) 2004-2006  EDF

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/*----------------------------------------------------------------------------
 * Standard C library headers
 *----------------------------------------------------------------------------*/

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*----------------------------------------------------------------------------
 * BFT library headers
 *----------------------------------------------------------------------------*/

#include <bft_mem.h>
#include <bft_printf.h>

/*----------------------------------------------------------------------------
 *  Local headers
 *----------------------------------------------------------------------------*/

#include <fvm_config_defs.h>
#include <fvm_defs.h>
#include <fvm_io_num.h>
#include <fvm_nodal.h>
#include <fvm_nodal_priv.h>
#include <fvm_parall.h>

/*----------------------------------------------------------------------------
 *  Header for the current file
 *----------------------------------------------------------------------------*/

#include <fvm_nodal_append.h>

/*----------------------------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#if 0
} /* Fake brace to force back Emacs auto-indentation back to column 0 */
#endif
#endif /* __cplusplus */

/*============================================================================
 * Static global variables
 *============================================================================*/

/*============================================================================
 * Private function definitions
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Create new section, transferring ownership of the given connectivity
 * and optional parent number arrays to that section.
 *
 * parameters:
 *   n_elements         <-- number of elements in section
 *   type               <-- type of elements to add
 *   face_index         <-- polyhedron -> faces index (O to n-1)
 *                          size: n_elements + 1
 *   face_num           <-- polyhedron -> face numbers (1 to n, signed,
 *                          > 0 for outwards pointing face normal
 *                          < 0 for inwards pointing face normal);
 *                          size: face_index[n_elements]
 *   vertex_index       <-- polygon face -> vertices index (O to n-1)
 *                          size: face_index[n_elements]
 *   vertex_num         <-- element -> vertex connectivity
 *   parent_element_num <-- element -> parent element number (1 to n) if non
 *                          trivial (i.e. if element definitions correspond
 *                          to a subset of the parent mesh), NULL otherwise
 *----------------------------------------------------------------------------*/

static fvm_nodal_section_t *
_transfer_to_section(fvm_lnum_t      n_elements,
                     fvm_element_t   type,
                     fvm_lnum_t      face_index[],
                     fvm_lnum_t      face_num[],
                     fvm_lnum_t      vertex_index[],
                     fvm_lnum_t      vertex_num[],
                     fvm_lnum_t      parent_element_num[])
{
  fvm_nodal_section_t  *this_section = NULL;

  this_section = fvm_nodal_section_create(type);

  this_section->n_elements = n_elements;

  /* Connectivity */

  if (type == FVM_CELL_POLY) {
    this_section->_face_index = face_index;
    this_section->_face_num = face_num;
  }

  if (type == FVM_FACE_POLY || type == FVM_CELL_POLY)
    this_section->_vertex_index = vertex_index;

  this_section->_vertex_num = vertex_num;

  this_section->_parent_element_num = parent_element_num;

  /* Shared arrays */

  this_section->face_index = this_section->_face_index;
  this_section->face_num = this_section->_face_num;
  this_section->vertex_index = this_section->_vertex_index;
  this_section->vertex_num = this_section->_vertex_num;
  this_section->parent_element_num = this_section->_parent_element_num;

  /* Connectivity size */

  if (this_section->stride != 0)
    this_section->connectivity_size
      = this_section->n_elements * this_section->stride;

  else if (this_section->type == FVM_FACE_POLY)
    this_section->connectivity_size
      = this_section->vertex_index[this_section->n_elements] - 1;

  else if (this_section->type == FVM_CELL_POLY) {
    fvm_lnum_t i, _face_num;
    for (i = 0;
         i < this_section->face_index[this_section->n_elements];
         i++) {
      _face_num = FVM_ABS(this_section->face_num[i]);
      if (_face_num > this_section->n_faces)
        this_section->n_faces = _face_num;
    }
    this_section->connectivity_size
      = this_section->vertex_index[this_section->n_faces] - 1;
  }

  return this_section;
}

/*============================================================================
 * Public function definitions
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Append a new section to an existing fvm_nodal mesh, and transfer
 * ownership of the given connectivity and optional parent number arrays to
 * that section.
 *
 * parameters:
 *   this_nodal         <-> nodal mesh structure
 *   n_elements         <-- number of elements to add
 *   type               <-- type of elements to add
 *   face_index         <-- polyhedron -> faces index (O to n-1)
 *                          size: n_elements + 1
 *   face_num           <-- polyhedron -> face numbers (1 to n, signed,
 *                          > 0 for outwards pointing face normal
 *                          < 0 for inwards pointing face normal);
 *                          size: face_index[n_elements]
 *   vertex_index       <-- polygon face -> vertices index (O to n-1)
 *                          size: face_index[n_elements]
 *   vertex_num         <-- element -> vertex connectivity
 *   parent_element_num <-- element -> parent element number (1 to n) if non
 *                          trivial (i.e. if element definitions correspond
 *                          to a subset of the parent mesh), NULL otherwise
 *----------------------------------------------------------------------------*/

void
fvm_nodal_append_by_transfer(fvm_nodal_t    *this_nodal,
                             fvm_lnum_t      n_elements,
                             fvm_element_t   type,
                             fvm_lnum_t      face_index[],
                             fvm_lnum_t      face_num[],
                             fvm_lnum_t      vertex_index[],
                             fvm_lnum_t      vertex_num[],
                             fvm_lnum_t      parent_element_num[])
{
  fvm_nodal_section_t  *new_section = NULL;
  int  n_sections = 0;

  assert(this_nodal != NULL);

  n_sections = this_nodal->n_sections;

  /* Create new section */

  BFT_REALLOC(this_nodal->sections, n_sections + 1, fvm_nodal_section_t *);

  new_section = _transfer_to_section(n_elements,
                                     type,
                                     face_index,
                                     face_num,
                                     vertex_index,
                                     vertex_num,
                                     parent_element_num);

  this_nodal->sections[n_sections] = new_section;
  this_nodal->n_sections += 1;

  /* Update main structure information */

  switch(new_section->entity_dim) {
  case 3:
    this_nodal->n_cells += n_elements;
    break;
  case 2:
    this_nodal->n_faces += n_elements;
    break;
  case 1:
    this_nodal->n_edges += n_elements;
    break;
  default:
    assert(0);
  }

}

/*----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif /* __cplusplus */


syntax highlighted by Code2HTML, v. 0.9.1