avtH5NimrodFileFormat.C 22.9 KB
Newer Older
1
/*****************************************************************************
2 3 4 5 6
 *
 * Copyright (c) 2000 - 2006, The Regents of the University of California
 * Produced at the Lawrence Berkeley National Laboratory
 * All rights reserved.
 *
7
 * This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
8 9 10 11 12 13 14 15 16 17
 * full copyright notice is contained in the file COPYRIGHT located at the root
 * of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
 *
 * Redistribution  and  use  in  source  and  binary  forms,  with  or  without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of  source code must  retain the above  copyright notice,
 *    this list of conditions and the disclaimer below.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
18
 *    documentation and/or other materials provided with the distribution.
19
 *  - Neither the name of the UC/LBNL nor  the names of its contributors may be
20
 *    be used to endorse or promote products derived from this software without
21 22 23 24 25
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS 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
26 27 28
 * ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
 * LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
 * DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
29 30 31 32 33 34 35 36
 * 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.
 *
 *****************************************************************************/
37 38

// ************************************************************************* //
39
//                            avtH5NimrodFileFormat.C                        //
40 41 42 43 44 45 46 47 48 49 50 51 52 53
// ************************************************************************* //

#include <avtH5NimrodFileFormat.h>

#include <string>

#include <vtkFloatArray.h>
#include <vtkRectilinearGrid.h>
#include <vtkStructuredGrid.h>
#include <vtkUnstructuredGrid.h>

#include <avtDatabaseMetaData.h>

#include <Expression.h>
54
#include <NonCompliantException.h>
55 56 57 58 59 60 61
#include <InvalidFilesException.h>
#include <vtkStructuredGrid.h>
#include <vtkPoints.h>
#include <vtkCellType.h>

#include <vector>

62 63
#include <DebugStream.h>

64
using
65
std::string;
66
using
67
std::vector;
68

fogal1's avatar
fogal1 committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
// ****************************************************************************
//  Function: dbg_string_attrib
//
//  Purpose:
//    Look up a string attribute from within the hdf5 file.  Echo it's value to
//    our debug logs.
//
//  Arguments:
//    id   hdf5 identifier; should be the return value from an H5GOpen call.
//    str  string to both lookup and include in the debug line.
//
//  Programmer: Tom Fogal
//  Creation:   Wed Apr 29 15:59:41 MDT 2009
//
//  Modifications:
//
// ****************************************************************************
static void dbg_string_attrib(hid_t id, const std::string &str)
{
    char *attrib = NULL;
    int h5err = H5NIMROD_read_string_attrib(id, str.c_str(), &attrib);
    if(h5err == H5NIMROD_ERR)
    {
        debug1 << "Reading '" << str << "' string in H5Nimrod gave an error!"
               << " Is this attribute guaranteed to exist for all H5Nimrod "
                  "files?" << std::endl;
    }

    // The read_string_attrib call can fail, but failure doesn't give any
    // information about whether or not the string given in the 3rd argument
    // was actually allocated.  Thus we set the string to NULL and check if it
    // got changed during the call.
    if(NULL != attrib)
    {
        debug5 << str << ": " << attrib << std::endl;
        free(attrib);
    }
}
107 108 109 110 111 112 113

// ****************************************************************************
//  Method: avtH5Nimrod constructor
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Fri Feb 9 08:26:27 PDT 2007
//
114 115 116 117
//  Modifications:
//    Kathleen Bonnell, Wed Jul 2 08:43:22 PDT 2008
//    Removed unreferenced variables.
//
fogal1's avatar
fogal1 committed
118 119 120
//    Tom Fogal, Wed Apr 29 16:11:41 MDT 2009
//    Handle errors when reading string attributes.
//
121 122 123
//    Jeremy Meredith, Thu Jan  7 15:36:19 EST 2010
//    Close all open ids when returning an exception.  Added error detection.
//
124 125 126
// ****************************************************************************

avtH5NimrodFileFormat::avtH5NimrodFileFormat (const char *filename):
127
    avtMTSDFileFormat (&filename, 1)
128
{
129 130
    // INITIALIZE DATA MEMBERS
    fname = filename;
131
    hid_t file_id, root_id, group_id, dataset_id;
132 133
    char *string_attrib;
    float time;
134

135 136 137 138 139 140 141
    // Check for a valid H5NIMROD file
    if( H5Fis_hdf5( filename ) < 0 )
        EXCEPTION1( InvalidFilesException, filename );

    if ((file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
      EXCEPTION1( InvalidFilesException, filename );

142 143
    // Open a couple temporary groups/datasets to verify the file is
    // really a H5Nimrod file.
144 145 146 147 148 149
    group_id = H5Gopen(file_id, "/GRID");
    if (group_id < 0)
    {
      H5Fclose(file_id);
      EXCEPTION1( InvalidFilesException, filename );
    }
150 151 152 153 154
    else
    {
      H5Gclose(group_id);
      group_id = -1;
    }
155

156 157
    dataset_id = H5Dopen(file_id, "/GRID/phi");
    if (dataset_id < 0)
158
    {
159 160
      H5Fclose(file_id);
      EXCEPTION1( InvalidFilesException, filename );
161
    }
162 163 164 165 166 167 168 169
    else
    {
      H5Dclose(dataset_id);
      dataset_id = -1;
    }

    // At this point consider the file to truly be a H5Nimrod file. If
    // some other file NonCompliantExceptions will be thrown.
170

171
    // Continue as normal reporting NonCompliantExceptions
fogal1's avatar
fogal1 committed
172
    hsize_t i, npoints;
173 174

    // Read attributes
175
    root_id = H5Gopen (file_id, "/");
fogal1's avatar
fogal1 committed
176

177 178
    if ( root_id < 0 )
    {
179
        H5Fclose(file_id);        
180 181 182 183
        EXCEPTION2( NonCompliantException, "H5NIMROD Group Open",
                    "The root group '/' was not found" );
    }

fogal1's avatar
fogal1 committed
184 185 186
    dbg_string_attrib(root_id, "Description");
    dbg_string_attrib(root_id, "Source");

187 188 189
    if (H5NIMROD_read_attrib (root_id, "time", &time) == H5NIMROD_ERR)
    {
        H5Gclose(root_id);
190
        H5Fclose(file_id);
191 192
        EXCEPTION2( NonCompliantException, "H5NIMROD Read Attribute",
                  "Attribute 'time' was not found or was the wrong type." );
193 194
    }

195
    debug5 << "time: " << time << std::endl;
196
    hid_t grid_id = H5Gopen (file_id, "/GRID");
197 198 199
    if (grid_id < 0)
    {
        H5Gclose(root_id);
200
        H5Fclose(file_id);
201 202
        EXCEPTION2( NonCompliantException, "H5NIMROD Group Open",
                    "The group '/GRID' was not found" );
203
    }
fogal1's avatar
fogal1 committed
204 205

    string_attrib = NULL;
206
    H5NIMROD_read_string_attrib (grid_id, "Coordinate System", &string_attrib);
fogal1's avatar
fogal1 committed
207
    if(string_attrib != NULL)
208
    {
fogal1's avatar
fogal1 committed
209 210 211 212
        debug5 << "Coordinate System: " << string_attrib << std::endl;
        if (strstr(string_attrib, "Cartesian - XYZ") == NULL)
        {
            debug5 << "Cannot handle non cartesian coordinates" << std::endl;
213 214
            H5Gclose(root_id);
            H5Gclose(grid_id);
215
            H5Fclose(file_id);
216 217
            EXCEPTION2( NonCompliantException, "H5NIMROD Read Attribute",
                  "Attribute 'Cartesian - XYZ' was not found or was the wrong type." );
fogal1's avatar
fogal1 committed
218 219
        }
        free(string_attrib);
220
    }
fogal1's avatar
fogal1 committed
221 222

    string_attrib = NULL;
223
    H5NIMROD_read_string_attrib (grid_id, "Topology", &string_attrib);
fogal1's avatar
fogal1 committed
224
    if (string_attrib && strstr(string_attrib, "Structured") != NULL)
225
    {
226 227
        structured = 1;
        debug5 << "Grid is structured!" << std::endl;
228 229
    }
    else
230
    {
231 232
        structured = 0;
        debug5 << "Cannot handle unstructured mesh" << std::endl;
233 234
        H5Gclose(root_id);
        H5Gclose(grid_id);
235
        H5Fclose (file_id);
236 237
        EXCEPTION2( NonCompliantException, "H5NIMROD Read Attribute",
                    "Attribute 'Topology' was not found or not 'Structured'" );
238
    }
fogal1's avatar
fogal1 committed
239 240 241 242 243 244 245
    if(string_attrib)
    {
        free (string_attrib);
    }

    dbg_string_attrib(grid_id, "Geometry");

246 247
    H5NIMROD_read_dims (grid_id, "X", &ndims, grid_dims);
    if (ndims != 3)
248
    {
249
        debug5 << "Cannot handle other than 3 dimensional data" << std::endl;
250 251
        H5Gclose(root_id);
        H5Gclose(grid_id);
252
        H5Fclose (file_id);
253 254
        EXCEPTION2( NonCompliantException, "H5NIMROD Read Dimensions",
                    "Grid dataset 'X' does not have three dimensions" );
255
    }
256 257
    // points
    for (i = 0, npoints = 1; i < ndims; i++)
258
    {
259 260
        debug5 << "ndims: " << ndims << " " << grid_dims[i] << std::endl;
        npoints *= grid_dims[i];
261
    }
262 263 264 265
    npoints *= ndims;
    // connectivity is implicit
    // point vars
    int num_groups = H5NIMROD_get_num_objects_matching_pattern (root_id,
266 267 268 269
            "/",
            H5G_GROUP,
            NULL);
    debug5<< "num_groups = "<<num_groups <<endl;
allens's avatar
allens committed
270 271
    char name[MAXLENGTH], name1[MAXLENGTH], name2[MAXLENGTH],
      stepnumber[MAXLENGTH];
272 273

    nsteps = 0;
allens's avatar
allens committed
274

275
    for (int idx = 0; idx < num_groups; idx++)
276
    {
277 278 279 280 281 282 283 284
        int len_of_name = MAXLENGTH;
        H5NIMROD_get_object_name (root_id,
                "/", H5G_GROUP, idx, name, len_of_name);
        debug5<<idx<<": name= "<<name<<endl;
        if (strncmp (name, "step_", strlen ("step_")) == 0)
        {
            sprintf (name1, "/%s", name);
            stepnames.push_back( name );
allens's avatar
allens committed
285

286
            nsteps++;
allens's avatar
allens committed
287

288
            group_id = H5Gopen (root_id, name1);
allens's avatar
allens committed
289 290 291 292 293 294

            memset( stepnumber, 0, MAXLENGTH );

            if (H5NIMROD_read_attrib (group_id, "Step number", &stepnumber) == H5NIMROD_ERR)
            {
              H5Gclose(group_id);
295
              H5Fclose(file_id);
296 297
              EXCEPTION2( NonCompliantException, "H5NIMROD Read Attribute",
                          "Attribute 'Step number' was not found or wrong type" );
allens's avatar
allens committed
298 299 300 301 302 303 304 305 306
            }

            cycles.push_back( atoi(stepnumber) );

            debug5 << "step number: " << stepnumber << std::endl;

            if (H5NIMROD_read_attrib (group_id, "time", &time) == H5NIMROD_ERR)
            {
              H5Gclose(group_id);
307
              H5Fclose(file_id);
308 309
              EXCEPTION2( NonCompliantException, "H5NIMROD Read Attribute",
                          "Attribute 'time' was not found or wrong type" );
allens's avatar
allens committed
310 311 312 313 314 315
            }

            times.push_back( time );

            debug5 << "time: " << time << std::endl;

316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
            nvectorvars = H5NIMROD_get_num_objects_matching_pattern (group_id,
                    name1,
                    H5G_GROUP,
                    NULL);
            vectorvars.resize (nvectorvars);
            vectorvarnames.resize (nvectorvars);
            vectorvardims.resize (nvectorvars);
            for (int kdx = 0; kdx < nvectorvars; kdx++)
            {
                H5NIMROD_get_object_name (group_id,
                        name1,
                        H5G_GROUP, kdx, name2, len_of_name);
                vectorvarnames[kdx] = name2;
                vectorvardims[kdx] =
                    H5NIMROD_get_num_objects_matching_pattern (group_id, name2,
                            H5G_DATASET, NULL);
            }

            nscalarvars = H5NIMROD_get_num_objects_matching_pattern (group_id,
                    name1,
                    H5G_DATASET,
                    NULL);
            scalarvars.resize (nscalarvars);
            scalarvarnames.resize (nscalarvars);
            for (int kdx = 0; kdx < nscalarvars; kdx++)
            {
                H5NIMROD_get_object_name (group_id,
                        name1,
                        H5G_DATASET, kdx, name, len_of_name);
                scalarvarnames[kdx] = name;
            }
        }        
348
    }
349

350 351 352 353 354
    debug5 << "num scalarvars: " << nscalarvars << std::endl;
    debug5 << "num vectorvars: " << nvectorvars << std::endl;
    H5Gclose (group_id);
    H5Gclose (grid_id);
    H5Gclose (root_id);
355
    H5Fclose (file_id);
356 357 358 359 360 361 362 363 364 365 366 367 368 369
}


// ****************************************************************************
//  Method: avtEMSTDFileFormat::GetNTimesteps
//
//  Purpose:
//      Tells the rest of the code how many timesteps there are in this file.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Fri Feb 9 08:26:27 PDT 2007
//
// ****************************************************************************

370
int
371 372
avtH5NimrodFileFormat::GetNTimesteps (void)
{
373
    return nsteps;
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
}


// ****************************************************************************
//  Method: avtH5NimrodFileFormat::FreeUpResources
//
//  Purpose:
//      When VisIt is done focusing on a particular timestep, it asks that
//      timestep to free up any resources (memory, file descriptors) that
//      it has associated with it.  This method is the mechanism for doing
//      that.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Fri Feb 9 08:26:27 PDT 2007
//
// ****************************************************************************

391
void
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
avtH5NimrodFileFormat::FreeUpResources (void)
{
}


// ****************************************************************************
//  Method: avtH5NimrodFileFormat::PopulateDatabaseMetaData
//
//  Purpose:
//      This database meta-data object is like a table of contents for the
//      file.  By populating it, you are telling the rest of VisIt what
//      information it can request from you.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Fri Feb 9 08:26:27 PDT 2007
//
fogal1's avatar
fogal1 committed
408 409 410 411 412
//  Modifications:
//
//    Tom Fogal, Wed Apr 29 16:09:52 MDT 2009
//    Removed an unused variable.
//
413 414
// ****************************************************************************

415
void
416
avtH5NimrodFileFormat::PopulateDatabaseMetaData (avtDatabaseMetaData * md,
417
        int timeState)
418
{
419
    int nblocks = 1;                //  <-- this must be 1 for MTSD
420 421 422 423
    int block_origin = 0;
    int spatial_dimension = ndims;
    int topological_dimension = ndims;
    double *extents = NULL;
424 425


426
    AddMeshToMetaData (md, "Mesh", AVT_CURVILINEAR_MESH, extents, nblocks,
427
            block_origin, spatial_dimension, topological_dimension);
428

429
    for (int idx = 0; idx < nscalarvars; idx++)
430
    {
431 432 433 434 435
        string mesh_for_this_var = "Mesh";        // ??? -- could be multiple meshes
        string varname = scalarvarnames[idx];
        // AVT_NODECENT, AVT_ZONECENT, AVT_UNKNOWN_CENT
        avtCentering cent = AVT_NODECENT;
        AddScalarVarToMetaData (md, varname, mesh_for_this_var, cent);
436
    }
437
    for (int idx = 0; idx < nvectorvars; idx++)
438
    {
439 440 441 442 443 444
        string mesh_for_this_var = "Mesh";        // ??? -- could be multiple meshes
        string varname = vectorvarnames[idx];
        // AVT_NODECENT, AVT_ZONECENT, AVT_UNKNOWN_CENT
        avtCentering cent = AVT_NODECENT;
        AddVectorVarToMetaData (md, varname, mesh_for_this_var, cent,
                vectorvardims[idx]);
445 446
    }

allens's avatar
allens committed
447 448
    md->SetCyclesAreAccurate(true);
    md->SetCycles( cycles );
449

allens's avatar
allens committed
450 451
    md->SetTimesAreAccurate(true);
    md->SetTimes( times );
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
}


// ****************************************************************************
//  Method: avtH5NimrodFileFormat::GetMesh
//
//  Purpose:
//      Gets the mesh associated with this file.  The mesh is returned as a
//      derived type of vtkDataSet (ie vtkRectilinearGrid, vtkStructuredGrid,
//      vtkUnstructuredGrid, etc).
//
//  Arguments:
//      timestate   The index of the timestate.  If GetNTimesteps returned
//                  'N' time steps, this is guaranteed to be between 0 and N-1.
//      meshname    The name of the mesh of interest.  This can be ignored if
//                  there is only one mesh.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Fri Feb 9 08:26:27 PDT 2007
//
// ****************************************************************************

474
vtkDataSet *
475 476
avtH5NimrodFileFormat::GetMesh (int timestate, const char *meshname)
{
477 478 479 480
    vtkStructuredGrid *dataset = vtkStructuredGrid::New ();
    vtkPoints *vtkpoints = vtkPoints::New ();
    vtkpoints->SetDataTypeToFloat ();
    int dims[3];
481

482 483
    hsize_t npoints = 1;
    for (int i = 0; i < ndims; i++)
484
    {
485 486
        dims[i] = (int) grid_dims[i];
        npoints *= grid_dims[i];
487 488
    }

489 490 491 492
    dataset->SetDimensions (dims);
    hid_t file;
    file = H5Fopen (fname.c_str (), H5F_ACC_RDONLY, H5P_DEFAULT);
    if (file < 0)
493 494 495 496
    {
      EXCEPTION2( NonCompliantException, "H5NIMROD File Open",
                  "File '" + fname + "' can not be opened" );
    }
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516

    hid_t grid_id = H5Gopen (file, "/GRID");
    vtkpoints->SetNumberOfPoints (npoints);

    float *Xcoord;
    Xcoord = (float *) malloc (sizeof (float) * npoints);
    H5NIMROD_read_float32_array (grid_id, "X", NULL, ndims, NULL, Xcoord);
    _transpose_3D(Xcoord, grid_dims);
    float *Ycoord;
    Ycoord = (float *) malloc (sizeof (float) * npoints);
    H5NIMROD_read_float32_array (grid_id, "Y", NULL, ndims, NULL, Ycoord);
    _transpose_3D(Ycoord, grid_dims);
    float *Zcoord;
    Zcoord = (float *) malloc (sizeof (float) * npoints);
    H5NIMROD_read_float32_array (grid_id, "Z", NULL, ndims, NULL, Zcoord);
    _transpose_3D(Zcoord, grid_dims);

    float *pts = (float *) vtkpoints->GetVoidPointer (0);
    hsize_t idx = 0;
    for (hsize_t i = 0; i < npoints; i++)
517
    {
518 519 520 521
        pts[idx] = Xcoord[i];
        pts[idx + 1] = Ycoord[i];
        pts[idx + 2] = Zcoord[i];
        idx += 3;
522
    }
523
    dataset->SetPoints (vtkpoints);
524

525 526 527
    free (Xcoord);
    free (Ycoord);
    free (Zcoord);
528

529 530
    H5Gclose (grid_id);
    H5Fclose (file);
531

532
    return dataset;
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
}


// ****************************************************************************
//  Method: avtH5NimrodFileFormat::GetVar
//
//  Purpose:
//      Gets a scalar variable associated with this file.  Although VTK has
//      support for many different types, the best bet is vtkFloatArray, since
//      that is supported everywhere through VisIt.
//
//  Arguments:
//      timestate  The index of the timestate.  If GetNTimesteps returned
//                 'N' time steps, this is guaranteed to be between 0 and N-1.
//      varname    The name of the variable requested.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Fri Feb 9 08:26:27 PDT 2007
//
// ****************************************************************************

554
vtkDataArray *
555 556
avtH5NimrodFileFormat::GetVar (int timestate, const char *varname)
{
557 558
    hid_t file;
    file = H5Fopen (fname.c_str (), H5F_ACC_RDONLY, H5P_DEFAULT);
559

560
    if (file < 0)
561 562 563 564
    {
      EXCEPTION2( NonCompliantException, "H5NIMROD File Open",
                  "File '" + fname + "' can not be opened" );
    }
565

566 567 568
    hid_t root_id, group_id;
    root_id = H5Gopen (file, "/");
    group_id = H5Gopen (root_id, stepnames[timestate].c_str ());
569

570 571 572
    float *var;
    hsize_t npoints = 1;
    for (hsize_t i = 0; i < ndims; i++)
573
    {
574
        npoints *= grid_dims[i];
575
    }
576 577 578
    var = (float *) malloc (sizeof (float) * npoints);
    H5NIMROD_read_float32_array (group_id, varname, NULL, ndims, NULL, var);
    _transpose_3D(var, grid_dims);
579

580 581 582 583 584
    hsize_t ntuples = npoints;
    vtkFloatArray *scalars = vtkFloatArray::New ();
    scalars->SetNumberOfTuples (ntuples);
    float *ptr = (float *) scalars->GetVoidPointer (0);
    memcpy (ptr, var, sizeof (float) * npoints);
585

586 587 588 589
    free (var);
    H5Gclose (group_id);
    H5Gclose (root_id);
    H5Fclose (file);
590

591
    return scalars;
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613

}


// ****************************************************************************
//  Method: avtH5NimrodFileFormat::GetVectorVar
//
//  Purpose:
//      Gets a vector variable associated with this file.  Although VTK has
//      support for many different types, the best bet is vtkFloatArray, since
//      that is supported everywhere through VisIt.
//
//  Arguments:
//      timestate  The index of the timestate.  If GetNTimesteps returned
//                 'N' time steps, this is guaranteed to be between 0 and N-1.
//      varname    The name of the variable requested.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Fri Feb 9 08:26:27 PDT 2007
//
// ****************************************************************************

614
vtkDataArray *
615 616
avtH5NimrodFileFormat::GetVectorVar (int timestate, const char *varname)
{
617 618 619 620
    hid_t file;
    file = H5Fopen (fname.c_str (), H5F_ACC_RDONLY, H5P_DEFAULT);

    if (file < 0)
621 622 623 624
    {
      EXCEPTION2( NonCompliantException, "H5NIMROD File Open",
                  "File '" + fname + "' can not be opened" );
    }
625 626 627 628 629

    hid_t root_id, group_id;
    root_id = H5Gopen (file, "/");
    group_id = H5Gopen (root_id, stepnames[timestate].c_str ());
    int num_comp = H5NIMROD_get_num_objects_matching_pattern (group_id,
630 631 632
            varname,
            H5G_DATASET,
            NULL);
633 634 635

    hsize_t npoints = 1;
    for (hsize_t i = 0; i < ndims; i++)
636
    {
637
        npoints *= grid_dims[i];
638 639
    }

640 641 642
    float **comp;
    comp = (float **) malloc (sizeof (float *) * num_comp);
    for (int idx = 0; idx < num_comp; idx++)
643
        comp[idx] = (float *) malloc (sizeof (float) * npoints);
644

645 646 647 648
    hid_t vector_id = H5Gopen (group_id, varname);
    char name[MAXLENGTH];
    int len_of_name = MAXLENGTH;
    for (int idx = 0; idx < num_comp; idx++)
649
    {
650 651 652 653 654
        H5NIMROD_get_object_name (group_id,
                varname, H5G_DATASET, idx, name, len_of_name);
        H5NIMROD_read_float32_array (vector_id,
                name, NULL, ndims, NULL, comp[idx]);
        _transpose_3D(comp[idx], grid_dims);
655 656
    }

657 658 659 660 661 662 663
    vtkFloatArray *vector = vtkFloatArray::New ();
    hsize_t ntuples = npoints;
    vector->SetNumberOfComponents (num_comp);
    vector->SetNumberOfTuples (ntuples);
    float *ptr = (float *) vector->GetVoidPointer (0);
    hsize_t count = 0;
    for (hsize_t idx = 0; idx < ntuples; idx++)
664
    {
665 666 667 668 669
        for (int jdx = 0; jdx < num_comp; jdx++)
        {
            ptr[count + jdx] = comp[jdx][idx];
        }
        count += num_comp;
670
    }
671
    for (int idx = 0; idx < num_comp; idx++)
672
    {
673 674
        if (comp[idx] != NULL)
            free (comp[idx]);
675
    }
676
    if (comp != NULL)
677
        free (comp);
678

679
    return vector;
680

681 682 683 684
    H5Gclose (vector_id);
    H5Gclose (group_id);
    H5Gclose (root_id);
    H5Fclose (file);
685
}
686 687


allens's avatar
allens committed
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
// ****************************************************************************
//  Method: avtH5NimrodFileFormat::GetCycles
//
//  Purpose:
//      Returns the cycles
//
//  Arguments:
//      c          the cycles
//
//  Programmer: allen
//  Creation:   
//
// ****************************************************************************


void avtH5NimrodFileFormat::GetCycles(std::vector<int> &c)
{
    c = cycles;
}

708

allens's avatar
allens committed
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
// ****************************************************************************
//  Method: avtH5NimrodFileFormat::GetTimes
//
//  Purpose:
//      Returns the times
//
//  Arguments:
//      t          the times
//
//  Programmer: allen
//  Creation:   
//
// ****************************************************************************

void avtH5NimrodFileFormat::GetTimes(std::vector<double> &t)
{
    t = times;
}