diff --git a/.gitattributes b/.gitattributes index 75c9013..4f7adb9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -378,14 +378,23 @@ src/h5_core/h5_core_private.h -text src/h5_core/h5_errorhandling.c -text src/h5_core/h5_errorhandling.h -text src/h5_core/h5_errorhandling_private.h -text +src/h5_core/h5_hdf5.c -text +src/h5_core/h5_hdf5.h -text src/h5_core/h5_maps.c -text src/h5_core/h5_maps.h -text src/h5_core/h5_openclose.c -text +src/h5_core/h5_openclose.h -text +src/h5_core/h5_qsort.c -text +src/h5_core/h5_qsort_private.h -text +src/h5_core/h5_qsort_r.c -text src/h5_core/h5_readwrite.c -text src/h5_core/h5_readwrite.h -text +src/h5_core/h5_readwrite_private.h -text src/h5_core/h5_types.h -text +src/h5_core/h5b_errorhandling_private.h -text src/h5_core/h5t_boundaries.c -text src/h5_core/h5t_boundaries.h -text +src/h5_core/h5t_boundaries_private.h -text src/h5_core/h5t_errorhandling.c -text src/h5_core/h5t_errorhandling_private.h -text src/h5_core/h5t_map.c -text @@ -395,6 +404,11 @@ src/h5_core/h5t_openclose.c -text src/h5_core/h5t_openclose.h -text src/h5_core/h5t_readwrite.c -text src/h5_core/h5t_readwrite.h -text +src/h5_core/h5t_readwrite_private.h -text +src/h5_core/h5t_storemesh.c -text +src/h5_core/h5t_storemesh.h -text +src/h5_core/h5t_storemesh_private.h -text +src/h5_core/h5u_errorhandling_private.h -text src/h5_core/h5u_readwrite.c -text src/h5_core/h5u_readwrite.h -text test/H5Block/BlockTestSpecs.txt -text diff --git a/src/h5_core/h5_hdf5.c b/src/h5_core/h5_hdf5.c new file mode 100644 index 0000000..5ac1257 --- /dev/null +++ b/src/h5_core/h5_hdf5.c @@ -0,0 +1,52 @@ +#include + +#include "h5_core/h5_core.h" +#include "h5_core/h5_core_private.h" + +hid_t +_h5_open_group ( + h5_file * f, + const hid_t parent_gid, + const char * const grpname + ) { + hid_t gid; + herr_t herr = H5Gget_objinfo( + parent_gid, grpname, 1, NULL ); + + if ( herr >= 0 ) { + h5_info ( + "Opening group %s/%s.", + h5_get_objname(parent_gid), + grpname ); + gid = H5Gopen ( parent_gid, grpname, H5P_DEFAULT ); + } else { + h5_info ( + "Creating group %s/%s.", + h5_get_objname(parent_gid), + grpname ); + gid = H5Gcreate ( parent_gid, grpname, 0, + H5P_DEFAULT, H5P_DEFAULT ); + } + if ( gid < 0 ) + return HANDLE_H5G_OPEN_ERR ( + h5_get_objname(parent_gid), + grpname ); + + return gid; +} + +h5_err_t +_h5_close_group ( + hid_t group_id + ) { + const char *group_name = h5_get_objname( group_id ); + herr_t herr = H5Gclose ( group_id ); + if ( herr < 0 ) { + return (*h5_get_errorhandler()) ( + h5_get_funcname(), + H5_ERR_HDF5, + "Cannot terminate access to group \"%s\".", + group_name ); + } + return H5_SUCCESS; +} diff --git a/src/h5_core/h5_hdf5.h b/src/h5_core/h5_hdf5.h new file mode 100644 index 0000000..1354fae --- /dev/null +++ b/src/h5_core/h5_hdf5.h @@ -0,0 +1,15 @@ +#ifndef __H5_HDF5_H +#define __H5_HDF5_H + +hid_t +_h5_open_group ( + h5_file *f, + const hid_t parent_gid, + const char * const grpname + ); + +h5_err_t +_h5_close_group ( + hid_t group_id + ); +#endif diff --git a/src/h5_core/h5_openclose.h b/src/h5_core/h5_openclose.h new file mode 100644 index 0000000..edf70e4 --- /dev/null +++ b/src/h5_core/h5_openclose.h @@ -0,0 +1,52 @@ +#ifndef __H5_OPENCLOSE_H +#define __H5_OPENCLOSE_H + +h5_file* +h5_open_file ( + const char *filename, + unsigned flags, + MPI_Comm comm + ); + +h5part_int64_t +h5_check_filehandle ( + const h5_file *f + ); + +h5part_int64_t +h5_close_file ( + h5_file *f + ); + +h5part_int64_t +h5_define_stepname_fmt ( + h5_file *f, + const char *name, + const h5part_int64_t width + ); + +h5_err_t +h5_get_stepname_fmt ( + h5_file *f, + char *name, + const h5_size_t l_name, + h5_size_t *width + ); + +h5_err_t +_h5_close_step ( + h5_file *f + ); + +h5_int64_t +h5_has_step ( + h5_file * f, + h5_int64_t step + ); + +h5_int64_t +h5_get_step ( + h5_file *f + ); + +#endif diff --git a/src/h5_core/h5_qsort.c b/src/h5_core/h5_qsort.c new file mode 100644 index 0000000..b37e1e1 --- /dev/null +++ b/src/h5_core/h5_qsort.c @@ -0,0 +1,196 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include + +#include + +#ifdef I_AM_QSORT_R +typedef int cmp_t(void *, const void *, const void *); +#else +typedef int cmp_t(const void *, const void *); +#endif +static inline char *med3(char *, char *, char *, cmp_t *, void *); +static inline void swapfunc(char *, char *, int, int); + +#define min(a, b) (a) < (b) ? a : b + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static inline void +swapfunc(a, b, n, swaptype) + char *a, *b; + int n, swaptype; +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#ifdef I_AM_QSORT_R +#define CMP(t, x, y) (cmp((t), (x), (y))) +#else +#define CMP(t, x, y) (cmp((x), (y))) +#endif + +static inline char * +med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk +#ifndef I_AM_QSORT_R +__unused +#endif +) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#ifdef I_AM_QSORT_R +void +_h5_qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) +#else +#define thunk NULL +void +_h5_qsort(void *a, size_t n, size_t es, cmp_t *cmp) +#endif +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int d, r, swaptype, swap_cnt; + +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - es); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > es) +#ifdef I_AM_QSORT_R + _h5_qsort_r(a, r / es, es, thunk, cmp); +#else + _h5_qsort(a, r / es, es, cmp); +#endif + if ((r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* qsort(pn - r, r / es, es, cmp);*/ +} diff --git a/src/h5_core/h5_qsort_private.h b/src/h5_core/h5_qsort_private.h new file mode 100644 index 0000000..c3565ff --- /dev/null +++ b/src/h5_core/h5_qsort_private.h @@ -0,0 +1,21 @@ +#ifndef __H5_QSORT_PRIVATE_H +#define __H5_QSORT_PRIVATE_H + +void +_h5_qsort_r ( + void *a, + size_t n, + size_t es, + void *thunk, + int (*compar)(void *, const void *, const void *) + ); + +void +_h5_qsort ( + void *a, + size_t n, + size_t es, + int (*compar)(const void *, const void *) + ); + +#endif diff --git a/src/h5_core/h5_qsort_r.c b/src/h5_core/h5_qsort_r.c new file mode 100644 index 0000000..704a7a2 --- /dev/null +++ b/src/h5_core/h5_qsort_r.c @@ -0,0 +1,8 @@ +/* + * This file is in the public domain. Originally written by Garrett + * A. Wollman. + * + * $FreeBSD: src/lib/libc/stdlib/qsort_r.c,v 1.1 2002/09/10 02:04:49 wollman Exp $ + */ +#define I_AM_QSORT_R +#include "h5_qsort.c" diff --git a/src/h5_core/h5_readwrite_private.h b/src/h5_core/h5_readwrite_private.h new file mode 100644 index 0000000..23395bb --- /dev/null +++ b/src/h5_core/h5_readwrite_private.h @@ -0,0 +1,13 @@ +#ifndef __H5_READWRITE_PRIVATE_H +#define __H5_READWRITE_PRIVATE_H + +h5_err_t +_h5_read_dataset ( + h5_file * const f, + hid_t dataset_id, + hid_t type_id, + hid_t memspace_id, + hid_t diskspace_id, + void * const data ); + +#endif diff --git a/src/h5_core/h5b_errorhandling_private.h b/src/h5_core/h5b_errorhandling_private.h new file mode 100644 index 0000000..3c9d4b8 --- /dev/null +++ b/src/h5_core/h5b_errorhandling_private.h @@ -0,0 +1,15 @@ +#ifndef __H5B_ERRORHANDLING_PRIVATE_H +#define __H5B_ERRORHANDLING_PRIVATE_H + +#define CHECK_LAYOUT( f ) \ + if ( ! f->block->have_layout ) \ + return h5_error( \ + H5PART_ERR_LAYOUT, \ + "No layout defined." ) + +#define HANDLE_H5_LAYOUT_ERR \ + h5_error( \ + H5PART_ERR_LAYOUT, \ + "Bad layout." ); + +#endif diff --git a/src/h5_core/h5t_boundaries_private.h b/src/h5_core/h5t_boundaries_private.h new file mode 100644 index 0000000..d360270 --- /dev/null +++ b/src/h5_core/h5t_boundaries_private.h @@ -0,0 +1,6 @@ +#ifndef __H5T_BOUNDARIES_PRIVATE_H +#define __H5T_BOUNDARIES_PRIVATE_H + +#define H5T_BOUNDARYMESH_GRPNAME "Boundaries" + +#endif diff --git a/src/h5_core/h5t_readwrite_private.h b/src/h5_core/h5t_readwrite_private.h new file mode 100644 index 0000000..04df279 --- /dev/null +++ b/src/h5_core/h5t_readwrite_private.h @@ -0,0 +1,20 @@ +#ifndef __H5T_READWRITE_PRIVATE_H +#define __H5T_READWRITE_PRIVATE_H + +h5_err_t +_h5t_write_obj ( + h5_file * f, + const hid_t gid, + const hsize_t current_dims, + const hsize_t max_dims, + const hid_t tid, + const void * const object, + const char * const dsname + ); + +h5_err_t +_h5t_read_mesh ( + h5_file *f + ); + +#endif diff --git a/src/h5_core/h5t_storemesh.c b/src/h5_core/h5t_storemesh.c new file mode 100644 index 0000000..4ce4233 --- /dev/null +++ b/src/h5_core/h5t_storemesh.c @@ -0,0 +1,397 @@ +#include +#include +#include /* va_arg - System dependent ?! */ +#include +#include +#include +#include + +#include "h5_core/h5_core.h" +#include "h5_core/h5_core_private.h" + +h5_id_t +h5t_add_level ( + h5_file_t * const f + ) { + struct h5t_fdata *t = &f->t; + + if ( f->mode == H5_O_RDONLY ) { + return H5_ERR_INVAL; + } + + /* t->num_levels will be set to zero on file creation(!) */ + if ( t->num_levels == -1 ) { /* unknown number of levels */ + /* determine number of levels */ + return -1; /* not implemented */ + } + t->cur_level = t->num_levels++; + + ssize_t num_bytes = t->num_levels*sizeof ( h5_size_t ); + t->num_vertices = realloc ( t->num_vertices, num_bytes ); + t->num_vertices[t->cur_level] = -1; + + t->num_entities = realloc ( t->num_entities, num_bytes ); + t->num_entities[t->cur_level] = -1; + t->num_entities_on_level = realloc ( t->num_entities_on_level, num_bytes ); + t->num_entities_on_level[t->cur_level] = -1; + + t->new_level = t->cur_level; + if ( t->cur_level == 0 ) { + /* nothing stored yet */ + t->last_stored_vertex_id = -1; + t->last_stored_entity_id = -1; + } + return t->cur_level; +} + +h5_err_t +_h5t_alloc_num_vertices ( + h5_file_t * const f, + const h5_size_t num_vertices + ) { + struct h5t_fdata *t = &f->t; + + ssize_t num_bytes = num_vertices*sizeof ( t->vertices[0] ); + h5_debug ( "Allocating %ld bytes.", num_bytes ); + t->vertices = realloc ( t->vertices, num_bytes ); + if ( t->vertices == NULL ) { + return HANDLE_H5_NOMEM_ERR; + } + + TRY( _h5_alloc_idmap (&t->map_vertex_g2l, num_vertices ), error_exit ); + TRY( _h5_alloc_smap (&t->sorted_lvertices, num_vertices ), error_exit ); + + return H5_SUCCESS; + +error_exit: + return h5_get_errno(); +} + +h5_err_t +_h5t_add_num_vertices ( + h5_file_t * const f, + const h5_size_t num + ) { + struct h5t_fdata *t = &f->t; + + if ( t->cur_level < 0 ) { + return _h5t_error_undef_level( f ); + } + ssize_t num_vertices = (t->cur_level > 0 ? + t->num_vertices[t->cur_level-1] + num : num); + t->num_vertices[t->cur_level] = num_vertices; + + return _h5t_alloc_num_vertices ( f, num_vertices ); +} + +h5_id_t +h5t_store_vertex ( + h5_file_t * const f, /*!< file handle */ + const h5_id_t global_id, /*!< global vertex id or -1 */ + const h5_float64_t P[3] /*!< coordinates */ + ) { + struct h5t_fdata *t = &f->t; + + /* + more than allocated + */ + if ( t->last_stored_vertex_id+1 >= t->num_vertices[t->cur_level] ) + return HANDLE_H5_OVERFLOW_ERR( "vertex", + t->num_vertices[t->cur_level] ); + + /* + missing call to add the first level + */ + if ( t->cur_level < 0 ) + return _h5t_error_undef_level( f ); + + /* + check id + */ + if ( (t->cur_level == 0) && ( + (global_id < 0) || (global_id >= t->num_vertices[0]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "vertex", global_id ); + } + if ( (t->cur_level > 0) && ( + (global_id < t->num_vertices[t->cur_level-1]) || + (global_id >= t->num_vertices[t->cur_level]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "vertex", global_id ); + } + + h5_id_t local_id = ++t->last_stored_vertex_id; + h5_vertex *vertex = &t->vertices[local_id]; + vertex->id = global_id; + memcpy ( &vertex->P, P, sizeof ( vertex->P ) ); + + _h5_insert_idmap ( &t->map_vertex_g2l, global_id, local_id ); + + return local_id; +} + +h5_err_t +_h5t_alloc_num_entities ( + h5_file_t * const f, + const size_t cur_num_entities, + const size_t new_num_entities + ) { + struct h5t_fdata *t = &f->t; + size_t sizeof_entity = 0; + size_t sizeof_lentity = 0; + + switch ( t->mesh_type ) { + case H5_OID_TETRAHEDRON: + sizeof_entity = sizeof ( t->entities.tets[0] ); + sizeof_lentity = sizeof ( t->lentities.tets[0] ); + break; + case H5_OID_TRIANGLE: + sizeof_entity = sizeof ( t->entities.tris[0] ); + sizeof_lentity = sizeof ( t->lentities.tris[0] ); + break; + default: + return -1; + } + + t->entities.data = realloc ( + t->entities.data, new_num_entities * sizeof_entity ); + if ( t->entities.data == NULL ) { + return H5_ERR_NOMEM; + } + + t->lentities.data = realloc ( + t->lentities.data, new_num_entities*sizeof_lentity ); + if ( t->lentities.data == NULL ) { + return H5_ERR_NOMEM; + } + memset ( + t->lentities.data+cur_num_entities*sizeof_lentity, + -1, + (new_num_entities-cur_num_entities) * sizeof_lentity ); + + return _h5_alloc_idmap (&t->map_entity_g2l, new_num_entities ); +} + +h5_err_t +h5_add_num_tets ( + h5_file_t * const f, + const h5_size_t num + ) { + struct h5t_fdata *t = &f->t; + + if ( t->mesh_type != H5_OID_TETRAHEDRON ) { + _h5t_error_illegal_object_type ( f, H5_OID_TETRAHEDRON ); + } + + TRY( _h5t_add_num_vertices ( f, num+3 ), error_exit ); + TRY( _h5t_add_num_entities ( f, num ), error_exit ); + return H5_SUCCESS; +error_exit: + return h5_get_errno(); +} + +h5_err_t +h5_add_num_triangles ( + h5_file_t * const f, + const h5_size_t num + ) { + struct h5t_fdata *t = &f->t; + + if ( t->mesh_type != H5_OID_TRIANGLE ) { + _h5t_error_illegal_object_type ( f, H5_OID_TRIANGLE ); + } + TRY( _h5t_add_num_vertices ( f, num+2 ), error_exit ); + TRY( _h5t_add_num_entities ( f, num ), error_exit ); + return H5_SUCCESS; +error_exit: + return h5_get_errno(); +} + +h5_err_t +_h5t_add_num_entities ( + h5_file_t * const f, + const h5_size_t num + ) { + struct h5t_fdata *t = &f->t; + + size_t cur_num_entities = t->cur_level > 0 ? + t->num_entities[t->cur_level-1] : 0; + size_t new_num_entities = t->cur_level > 0 ? + num + t->num_entities[t->cur_level-1] : num; + t->num_entities[t->cur_level] = new_num_entities; + + t->num_entities_on_level[t->cur_level] = t->cur_level > 0 ? + num + t->num_entities_on_level[t->cur_level-1] : num; + + return _h5t_alloc_num_entities ( f, cur_num_entities, new_num_entities ); +} + +h5_id_t +h5t_store_tet ( + h5_file_t * const f, + const h5_id_t global_id, /*!< global tetrahedron id */ + const h5_id_t parent_id, /*!< global parent id + if level \c >0 else \c -1 */ + const h5_id_t vertex_ids[4] /*!< tuple with vertex id's */ + ) { + + struct h5t_fdata *t = &f->t; + + /* + more than allocated + */ + if ( t->last_stored_entity_id+1 >= t->num_entities[t->cur_level] ) + return HANDLE_H5_OVERFLOW_ERR( + "tet", t->num_entities[t->cur_level] ); + + /* + missing call to add the first level + */ + if ( t->cur_level < 0 ) + return _h5t_error_undef_level( f ); + + /* + check parent id + */ + if ( (t->cur_level == 0) && + (parent_id != -1) ) { + return HANDLE_H5_PARENT_ID_ERR ( "tet", global_id, parent_id ); + } + if ( (t->cur_level > 0) && + (parent_id < 0) ) { + return HANDLE_H5_PARENT_ID_ERR ( "tet", global_id, parent_id ); + } + if ( (t->cur_level > 0) && + (parent_id >= t->num_entities[t->cur_level-1]) ) { + return HANDLE_H5_PARENT_ID_ERR ( "tet", global_id, parent_id ); + } + /* + check id + */ + if ( (t->cur_level == 0) && ( + (global_id < 0) || (global_id >= t->num_entities[0]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "tet", global_id ); + } + if ( (t->cur_level > 0) && ( + (global_id < t->num_entities[t->cur_level-1]) || + (global_id >= t->num_entities[t->cur_level]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "tet", global_id ); + } + + h5_id_t local_id = ++t->last_stored_entity_id; + h5_tetrahedron *tet = &t->entities.tets[local_id]; + tet->id = global_id; + tet->parent_id = parent_id; + tet->refined_on_level = -1; + tet->unused = 0; + + memcpy ( &tet->vertex_ids, vertex_ids, sizeof ( tet->vertex_ids ) ); + + _h5t_sort_global_vertex_ids ( f, tet->vertex_ids, 4 ); + _h5_insert_idmap ( &t->map_entity_g2l, global_id, local_id ); + + if ( parent_id >= 0 ) { + h5_id_t local_parent_id = _h5_search_idmap ( + &t->map_entity_g2l, parent_id ); + if ( t->entities.tets[local_parent_id].refined_on_level < 0 ) { + t->entities.tets[local_parent_id].refined_on_level = + t->cur_level; + t->num_entities_on_level[t->cur_level]--; + } + } + return local_id; +} + + +h5_id_t +h5t_store_triangle ( + h5_file_t * const f, + const h5_id_t global_id, /*!< global triangle id */ + const h5_id_t parent_id, /*!< global parent id + if level \c >0 else \c -1 */ + const h5_id_t vertex_ids[3] /*!< tuple with vertex id's */ + ) { + + struct h5t_fdata *t = &f->t; + + /* + more than allocated + */ + if ( t->last_stored_entity_id+1 >= t->num_entities[t->cur_level] ) + return HANDLE_H5_OVERFLOW_ERR( + "triangle", t->num_entities[t->cur_level] ); + + /* + missing call to add the first level + */ + if ( t->cur_level < 0 ) + return _h5t_error_undef_level( f ); + + /* + check parent id + */ + if ( (t->cur_level == 0) && (parent_id != -1) ) { + return HANDLE_H5_PARENT_ID_ERR ( + "triangle", global_id, parent_id ); + } + if ( (t->cur_level > 0) && (parent_id < 0) ) { + return HANDLE_H5_PARENT_ID_ERR ( + "triangle", global_id, parent_id ); + } + if ( (t->cur_level>0) && (parent_id >= t->num_entities[t->cur_level-1]) ) { + return HANDLE_H5_PARENT_ID_ERR ( + "triangle", global_id, parent_id ); + } + /* + check id + */ + if ( (t->cur_level == 0) && ( + (global_id < 0) || (global_id >= t->num_entities[0]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "triangle", global_id ); + } + if ( (t->cur_level > 0) && ( + (global_id < t->num_entities[t->cur_level-1]) || + (global_id >= t->num_entities[t->cur_level]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "triangle", global_id ); + } + + h5_id_t local_id = ++t->last_stored_entity_id; + h5_triangle *tri = &t->entities.tris[local_id]; + tri->id = global_id; + tri->parent_id = parent_id; + tri->refined_on_level = -1; + memcpy ( &tri->vertex_ids, vertex_ids, sizeof ( tri->vertex_ids ) ); + + _h5_insert_idmap ( &t->map_entity_g2l, global_id, local_id ); + + if ( parent_id >= 0 ) { + h5_id_t local_parent_id = _h5_search_idmap ( + &t->map_entity_g2l, parent_id ); + if ( t->entities.tris[local_parent_id].refined_on_level < 0 ) { + t->entities.tris[local_parent_id].refined_on_level = + t->cur_level; + t->num_entities_on_level[t->cur_level]--; + } + } + return local_id; +} + +/*! + Refine tetrahedron \c global_tid + + \return Local id of first new tetrahedron or \c -1 +*/ +h5_id_t +h5t_refine_tet ( + h5_file_t * const f, + const h5_id_t global_tid + ) { + /* + get local id of tet + compute vertices + add new vertices + add new tets + */ + +error_exit: + return h5_get_errno(); +} + diff --git a/src/h5_core/h5t_storemesh.h b/src/h5_core/h5t_storemesh.h new file mode 100644 index 0000000..f7c685d --- /dev/null +++ b/src/h5_core/h5t_storemesh.h @@ -0,0 +1,43 @@ +#ifndef __H5T_STOREMESH_H +#define __H5T_STOREMESH_H + +h5_id_t +h5t_add_level ( + h5_file_t * const f + ); + +h5_id_t +h5t_store_vertex ( + h5_file_t * const f, + const h5_id_t global_id, + const h5_float64_t P[3] + ); + +h5_err_t +h5_add_num_tets ( + h5_file_t * const f, + const h5_size_t num + ); + +h5_err_t +h5_add_num_triangles ( + h5_file_t * const f, + const h5_size_t num + ); + +h5_id_t +h5t_store_tet ( + h5_file_t * const f, + const h5_id_t global_id, + const h5_id_t parent_id, + const h5_id_t vertex_ids[4] + ); + +h5_id_t +h5t_store_triangle ( + h5_file_t * const f, + const h5_id_t global_id, + const h5_id_t parent_id, + const h5_id_t vertex_ids[3] + ); +#endif diff --git a/src/h5_core/h5t_storemesh_private.h b/src/h5_core/h5t_storemesh_private.h new file mode 100644 index 0000000..49021a2 --- /dev/null +++ b/src/h5_core/h5t_storemesh_private.h @@ -0,0 +1,28 @@ +#ifndef __H5T_STOREMESH_PRIVATE_H +#define __H5T_STOREMESH_PRIVATE_H + +h5_err_t +_h5t_alloc_num_vertices ( + h5_file_t * const f, + const h5_size_t num_vertices + ); + +h5_size_t +_h5t_add_num_vertices ( + h5_file_t * const f, + const h5_size_t num + ); + +h5_err_t +_h5t_add_num_entities ( + h5_file_t * const f, + const h5_size_t num + ); + +h5_err_t +_h5t_alloc_num_entities ( + h5_file_t * const f, + const size_t cur_num_entities, + const size_t new_num_entities + ); +#endif diff --git a/src/h5_core/h5u_errorhandling_private.h b/src/h5_core/h5u_errorhandling_private.h new file mode 100644 index 0000000..5ac8c97 --- /dev/null +++ b/src/h5_core/h5u_errorhandling_private.h @@ -0,0 +1,15 @@ +#ifndef __H5U_ERRORHANDLING_PRIVATE_H +#define __H5U_ERRORHANDLING_PRIVATE_H + +#define HANDLE_H5_SET_VIEW_ERR( rc, start, end ) \ + h5_error( \ + rc, \ + "Cannot set view to (%lld, %lld).", \ + (long long)start, (long long)end ); + +#define HANDLE_H5_GET_NUM_PARTICLES_ERR( rc ) \ + h5_error( \ + rc, \ + "Cannot get number of particles." ); + +#endif