1 /*************************************************************************
2 * COPYRIGHT (C) 1999 - 2002 EDF R&D
3 * THIS LIBRARY IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
4 * IT UNDER THE TERMS OF THE GNU LESSER GENERAL PUBLIC LICENSE
5 * AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION;
6 * EITHER VERSION 2.1 OF THE LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION.
8 * THIS LIBRARY IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
9 * WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
11 * LESSER GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 * YOU SHOULD HAVE RECEIVED A COPY OF THE GNU LESSER GENERAL PUBLIC LICENSE
14 * ALONG WITH THIS LIBRARY; IF NOT, WRITE TO THE FREE SOFTWARE FOUNDATION,
15 * INC., 59 TEMPLE PLACE, SUITE 330, BOSTON, MA 02111-1307 USA
17 *************************************************************************/
20 #include "med_outils.hxx"
23 * - Nom de la fonction : _MEDdatasetNumEcrire
24 * - Description : ecriture d'un dataset tableau numerique
26 * - pere (IN) : l'ID de l'objet HDF pere ou placer l'attribut
27 * - nom (IN) : le nom du dataset
28 * - type (IN) : type numerique MED { MED_REEL64 , MED_INT32 , MED_INT64 }
29 * - interlace (IN) : Choix du type d'entrelacement utilisé par l'appelant { MED_FULL_INTERLACE(x1,y1,z1,x2,...)) , MED_NO_INTERLACE(x1,x2,y1,y2,z1,z2) }
30 * - nbdim (IN) : Dimension des éléments
31 * - fixdim (IN) : MED_ALL ou n° de la dimension a enregistrer
32 * - psize (IN) : Taille du profil à utiliser, MED_NOPF si pas de profil
33 * (référence les élements, cette taille ne prend pas en compte le nombre de pts de gauss ni la dimension )
34 * - pfltab (IN) : Tableau contenant les n° déléments à traiter (1....oo)
35 * - pflmod (IN) : PARAMETRE A AJOUTER : Indique comment lire les informations en mémoire { MED_COMPACT, MED_GLOBALE }.
36 * - ngauss (IN) : Nombre de points de GAUSS par élément
37 * - size (IN) : Taille du tableau de valeurs
38 * (référence tous les élements, cette taille prend en compte le nombre de pts de gauss et la dimension )
39 * - val (IN) : valeurs du tableau
40 * - mode (IN) : mode d'ecriture MED (MED_ECRI | MED_REMP)
41 * - Resultat : 0 en cas de succes, -1 sinon
47 _MEDdatasetNumEcrire(med_idt pere,char *nom, med_type_champ type,
48 med_mode_switch interlace, med_size nbdim, med_size fixdim,
49 med_size psize, med_ssize * pfltab, med_int ngauss,
50 med_size *size, unsigned char *val, med_mode_acces mode)
52 med_idt dataset, dataspace = 0, memspace = 0;
53 med_ssize start_mem[1],start_data[1],*pflmem,*pfldsk;
54 med_size stride[1],count[1],pcount[1],pflsize[1];
56 int i,j,index,type_hdf;
57 int dim, firstdim, dimutil, lastdim ;
58 med_mode_profil pflmod;
60 /* Verify fixdim is between [0, nbdim] ( 0 is MED_ALL ) */
61 if ( ( fixdim < 0 ) || ( fixdim > nbdim ) )
64 /* block pflmod to MED_COMPACT (until med2.2) */
70 /* 1) IA32 is LE but due to an (?HDF convertion BUG?) when using H5T_NATIVE_DOUBLE/MED_REEL64? under PCLINUX
71 the file read under SGI is incorrect
72 2) Compaq OSF/1 is LE, since we force SGI64,SUN4SOL2,HP to write double in LE even if they are BE, mips OSF/1 must be BE
73 REM : Be careful of compatibility between MED files when changing this (med2.2) */
74 #if defined(PCLINUX) || defined(OSF1)
75 type_hdf = H5T_IEEE_F64BE;
77 type_hdf = H5T_IEEE_F64LE;
83 type_hdf = H5T_STD_I32BE;
84 if ((H5Tconvert(H5T_NATIVE_INT,H5T_STD_I32BE,(hsize_t)*size,(void *)val,NULL,NULL)) < 0)
87 type_hdf = H5T_NATIVE_INT;
92 type_hdf = H5T_NATIVE_LONG;
100 if ((dataset = H5Dopen(pere,nom)) < 0)
102 /* Whatever the size of the profil is we create a dataset with the size of the value array */
103 /* Then if we used the MED_REMP mode we can append a new dimension to a previous one in the dataset */
104 /* When we'll use the compression mode, the space used by unused values would be easily compressed */
106 if ((dataspace = H5Screate_simple(1,size,NULL)) < 0)
108 if ((dataset = H5Dcreate(pere,nom,type_hdf,dataspace,
113 if (mode != MED_REMP)
119 if ((dataspace = H5Dget_space(dataset)) <0)
124 { /* switch Interlace */
125 case MED_FULL_INTERLACE :
127 /*Initialisation des indices de boucle du traitement de l'entrelacement en fonction de la dimension fixee*/
128 if ( fixdim != MED_ALL)
139 count [0] = (*size)/(nbdim);
142 if ( psize == MED_NOPF ) {
144 /* Creation d'un data space mémoire de dimension 1, de longeur size, et de longeur maxi size */
145 if ( (memspace = H5Screate_simple (1, size, NULL)) <0)
150 for (dim=firstdim; dim < lastdim; dim++) {
153 if ( (ret = H5Sselect_hyperslab (memspace, H5S_SELECT_SET, start_mem, stride,
157 start_data[0] = dim*count[0];
158 if ( (ret = H5Sselect_hyperslab (dataspace, H5S_SELECT_SET, start_data, NULL,
162 if ((ret = H5Dwrite(dataset,type_hdf,memspace,dataspace,
163 H5P_DEFAULT, val)) < 0)
167 } else { /* psize != MED_NOPF */
169 pflsize [0] = psize*ngauss*nbdim;
170 pcount [0] = psize*ngauss*dimutil;
171 pflmem = (med_ssize *) malloc (sizeof(med_ssize)*pcount[0]);
172 pfldsk = (med_ssize *) malloc (sizeof(med_ssize)*pcount[0]);
175 { /* switch pflmod pout FULL_INTERLACE*/
178 /* Creation d'un data space mémoire de dimension 1, de longeur size, et de longeur maxi size */
179 if ( (memspace = H5Screate_simple (1, size, NULL)) <0)
182 for (dim=firstdim; dim < lastdim; dim++) {
184 for (i=0; i < psize; i++) /* i balaye les élements du profil */
185 for (j=0; j < ngauss; j++) {
186 index = i*ngauss+j + (dim-firstdim)*(psize*ngauss);
187 pflmem[index] = (pfltab[i]-1)*ngauss*nbdim + j*nbdim+dim;
188 pfldsk[index] = dim*count[0] + (pfltab[i]-1)*ngauss+j;
192 if ( (ret = H5Sselect_elements(memspace,H5S_SELECT_SET, pcount[0], (const hssize_t **) pflmem ) ) <0)
195 if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, pcount[0], (const hssize_t **) pfldsk ) ) <0)
202 /* Creation d'un data space mémoire de dimension 1, de la longeur du profil */
203 /* La dimension utilisée est ici nbdim, même pour un profil compact on suppose */
204 /* que l'utilisateur a toutes les coordonées stockées, même si il en demande qu'une */
206 if ( (memspace = H5Screate_simple (1, pflsize, NULL)) <0)
209 for (dim=firstdim; dim < lastdim; dim++) {
211 for (i=0; i < psize; i++) /* i balaye les élements du profil */
212 for (j=0; j < ngauss; j++) {
213 index = i*ngauss+j + (dim-firstdim)*(psize*ngauss);
214 pflmem[index] = i*ngauss*nbdim + j*nbdim+dim;
215 pfldsk[index] = dim*count[0] + (pfltab[i]-1)*ngauss+j;
219 if ( (ret = H5Sselect_elements(memspace,H5S_SELECT_SET, pcount[0], (const hssize_t **) pflmem ) ) <0)
222 if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, pcount[0], (const hssize_t **) pfldsk ) ) <0)
231 if ((ret = H5Dwrite(dataset,type_hdf,memspace,dataspace,H5P_DEFAULT, val)) < 0)
241 case MED_NO_INTERLACE :
243 /*Initialisation des indices de boucle du traitement de l'entrelacement en fonction de la dimension fixee*/
245 count[0] = (*size)/nbdim;
247 if ( psize == MED_NOPF ) {
249 if ( fixdim != MED_ALL)
250 start_data[0] = (fixdim-1)*count[0];
256 if ( (ret = H5Sselect_hyperslab (dataspace, H5S_SELECT_SET, start_data, NULL,
260 if ((ret = H5Dwrite(dataset,type_hdf,dataspace,dataspace,
261 H5P_DEFAULT, val)) < 0)
266 if ( fixdim != MED_ALL)
277 pflsize [0] = psize*ngauss*nbdim;
278 pcount [0] = psize*ngauss*dimutil; /* nom pas très coherent avec count !!! A revoir */
279 pfldsk = (med_ssize *) malloc(sizeof(med_ssize)*pcount[0]);
282 { /*switch plfmod pour NO_INTERLACE */
285 for (dim=firstdim; dim < lastdim; dim++) {
287 for (i=0; i < psize; i++) /* i balaye le nbre d'élements du profil */
288 for (j=0; j < ngauss; j++) {
289 index = i*ngauss+j + (dim-firstdim)*(psize*ngauss);
290 pfldsk[index] = dim*count[0]+(pfltab[i]-1)*ngauss+j;
294 if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hssize_t **) pfldsk ) ) <0)
297 if ((ret = H5Dwrite(dataset,type_hdf,dataspace,dataspace,H5P_DEFAULT, val)) < 0)
304 /* Creation d'un data space mémoire de dimension 1, de la longeur du profil */
305 /* La dimension utilisée est ici nbdim, même pour un profil compact on suppose */
306 /* que l'utilisateur a toutes les coordonées stockées, même si il en demande qu'une */
308 if ( (memspace = H5Screate_simple (1, pflsize, NULL)) <0)
311 pflmem = (med_ssize *) malloc (sizeof(med_ssize)*pcount[0]);
313 /* Le profil COMPACT est contigüe, mais il est possible que l'on selectionne uniquemenent une dimension*/
315 for (dim=firstdim; dim < lastdim; dim++) {
317 for (i=0; i < psize; i++) /* i balaye le nbre d'élements du profil */
318 for (j=0; j < ngauss; j++) {
319 index = i*ngauss+j + (dim-firstdim)*(psize*ngauss);
320 pflmem[index] = dim*(psize*ngauss) + (pfltab[i]-1)*ngauss+j;
321 pfldsk[index] = dim*count[0] + (pfltab[i]-1)*ngauss+j;
325 if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET,pcount[0], (const hssize_t **) pflmem ) ) <0)
328 if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hssize_t **) pfldsk ) ) <0)
331 if ((ret = H5Dwrite(dataset,type_hdf,memspace,dataspace,H5P_DEFAULT, val)) < 0)
355 if ((ret = H5Sclose(memspace)) < 0)
358 if ((ret = H5Sclose(dataspace)) < 0)
361 if ((ret = H5Dclose(dataset)) < 0)
365 if (type == MED_INT32)
366 if ((H5Tconvert(H5T_STD_I32BE,H5T_NATIVE_INT,(hsize_t)*size,(void *)val,NULL,NULL)) < 0)