src/h5_tools.cpp

Go to the documentation of this file.
00001 
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <iostream>
00020 #include <ostream>
00021 #include "mpi.h"
00022 #include "hdf5.h"
00023 #include <Epetra_Comm.h>
00024 #include <Epetra_MpiComm.h>
00025 #include <Epetra_Map.h>
00026 #include <Epetra_Vector.h>
00027 #include <Epetra_MultiVector.h>
00028 #include <Epetra_SerialDenseVector.h>
00029 #include <Epetra_Import.h>
00030 #include <Epetra_Export.h>
00031 #include <Teuchos_ParameterList.hpp>
00032 #include "rlog/rlog.h"
00033 #include "colarray/matrix.h"
00034 #include "colarray/vector.h"
00035 #include "tetmesh.h"
00036 #include "femaxmesh.h"
00037 #include "nedelecelement.h"
00038 #include "nedelecelement1.h"
00039 #include "nedelecelement2.h"
00040 #include "nedelecmesh.h"
00041 #include "paralleltetmesh.h"
00042 #include "vector3.h"
00043 #include "vector4.h"
00044 #include "fmxxtopology.h"
00045 #include "fmxxphysicomath.h"
00046 #include "nonsciconst.h"
00047 #include "dbgsupport.h"
00048 
00052 Epetra_Map* h5_write_eigenfield_retrieve_DoF_robust(const Epetra_MultiVector& Q,  const Epetra_Comm& comm);
00053 
00055 Epetra_Map* h5_write_eigenfeield_retrieve_DoF_efficient(const std::string& file_name,  const Epetra_Comm& comm,
00056                                                                                                         mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
00057                                                                                                         const Epetra_MultiVector& Q, double* lambda);
00058 
00060 void h5_write_eigenfield_write_hdf5e(const std::string& file_name,
00061                                                                 const Epetra_Comm& comm,
00062                                                                 int lntet,
00063                                                                 int gntet,
00064                                                                 int mthmode,
00065                                                                 double* ev);
00066 
00067 void h5_write_eigenfield_write_hdf5h(const std::string& file_name,
00068                                                                 const Epetra_Comm& comm,
00069                                                                 int lntet,
00070                                                                 int gntet,
00071                                                                 int mthmode,
00072                                                                 double* hv);
00073 
00074 void h5_write_eigenfield_writehdf5sloc(const std::string& file_name,
00075                                                                 const Epetra_Comm& comm,
00076                                                                 int ntet,
00077                                                                 int gntet,
00078                                                                 double* sloc);
00079 
00095 void h5_compute_eigenquality(const std::string& file_name,  const Epetra_Comm& comm,
00096                                                                                 mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
00097                                                                                 const Epetra_MultiVector& Q, double* lambda, double* &quality);
00098 
00099 
00101 void h5_cartesian_sampling(const std::string& file_name,  const Epetra_Comm& comm,
00102                             mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
00103                             const Epetra_MultiVector& Q, double* lambda,
00104                             double xmin, double xmax, int nx,
00105                             double ymin, double ymax, int ny,
00106                             double zmin, double zmax, int nz);
00107 
00115 void h5_cartesian_sampling_write_hdf5(const Epetra_Comm& comm, const std::string& file_name, unsigned int nmode,
00116                     std::vector<std::vector<std::vector<unsigned int> > >& exists,
00117                     std::vector<std::vector<std::vector<std::vector<mesh::Vector3> > > >& efield,
00118                     std::vector<std::vector<std::vector<std::vector<mesh::Vector3> > > >& hfield,
00119                     double xmin, double xmax, const int nx,
00120                     double ymin, double ymax, const int ny,
00121                     double zmin, double zmax, const int nz);
00122 
00123 
00124 
00125 
00126 
00127 
00130 void h5_create_empty_file(const std::string& file_name) {
00131     hid_t file_id = H5Fcreate(file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
00132     if (file_id < 0)
00133         rError("Unable to create hdf5 file \"%s\".", file_name.c_str());
00134     H5Fclose(file_id);
00135 }
00136 
00137 static void h5_write_param_list_recursive(const Teuchos::ParameterList& params, hid_t group_id) {
00138     Teuchos::ParameterList::ConstIterator it = params.begin();
00139     for (; it != params.end(); ++ it) {
00140         std::string key(params.name(it));
00141         if (params.isSublist(key)) {
00142             //
00143             // Sublist
00144             //
00145             
00146             // Create subgroup for sublist.
00147             hid_t child_group_id = H5Gcreate(group_id, key.c_str(), 0);
00148             h5_write_param_list_recursive(params.sublist(key), child_group_id);
00149             H5Gclose(child_group_id);
00150         } else {
00151             //
00152             // Regular parameter
00153             //
00154             
00155             // Create dataspace/dataset.
00156             herr_t status;
00157             hsize_t one = 1;
00158             hid_t dataspace_id, dataset_id;
00159 
00160             // Write the dataset.
00161             if (params.isType<int>(key)) {
00162                 int value = params.get<int>(key);
00163                 dataspace_id = H5Screate_simple(1, &one, NULL);
00164                 dataset_id = H5Dcreate(group_id, key.c_str(), H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT);
00165                 status = H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, 
00166                                   H5P_DEFAULT, &value);
00167                 status = H5Dclose(dataset_id);
00168                 status = H5Sclose(dataspace_id);
00169             } else if (params.isType<double>(key)) {
00170                 double value = params.get<double>(key);
00171                 dataspace_id = H5Screate_simple(1, &one, NULL);
00172                 dataset_id = H5Dcreate(group_id, key.c_str(), H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
00173                 status = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, 
00174                                   H5P_DEFAULT, &value);
00175                 status = H5Dclose(dataset_id);
00176                 status = H5Sclose(dataspace_id);
00177             } else if (params.isType<std::string>(key)) {
00178                 std::string value = params.get<std::string>(key);
00179                 hsize_t len = value.size() + 1;
00180                 dataspace_id = H5Screate_simple(1, &len, NULL);
00181                 dataset_id = H5Dcreate(group_id, key.c_str(), H5T_C_S1, dataspace_id, H5P_DEFAULT);
00182                 status = H5Dwrite(dataset_id, H5T_C_S1, H5S_ALL, H5S_ALL, 
00183                                   H5P_DEFAULT, value.c_str());
00184                 status = H5Dclose(dataset_id);
00185                 status = H5Sclose(dataspace_id);
00186             } else if (params.isType<bool>(key)) {
00187                 // Use H5T_NATIVE_USHORT to store a bool value
00188                 unsigned short value = params.get<bool>(key) ? 1 : 0;
00189                 dataspace_id = H5Screate_simple(1, &one, NULL);
00190                 dataset_id = H5Dcreate(group_id, key.c_str(), H5T_NATIVE_USHORT, dataspace_id, H5P_DEFAULT);
00191                 status = H5Dwrite(dataset_id, H5T_NATIVE_USHORT, H5S_ALL, H5S_ALL, 
00192                                   H5P_DEFAULT, &value);
00193                 status = H5Dclose(dataset_id);
00194                 status = H5Sclose(dataspace_id);
00195             } else {
00196                 rError("Unable to export parameter \"%s\" to hdf5 file: Unsupported type.", key.c_str());        
00197             }
00198         }
00199     }
00200 }
00201 
00202 void h5_write_param_list(const std::string& file_name, const Teuchos::ParameterList& params) {
00203     // Open hdf5 file
00204     hid_t       file_id, group_id;  /* identifiers */
00205     herr_t      status;
00206     // file_id = H5Fcreate(file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
00207     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
00208 
00209     // Create group "parameters" in the root group using absolute name.
00210     group_id = H5Gcreate(file_id, "/parameters", 0);
00211 
00212     // Iterate through parameter list 
00213     h5_write_param_list_recursive(params, group_id);
00214     
00215     // Finalize hdf5 file
00216     status = H5Gclose(group_id);
00217     status = H5Fclose(file_id);
00218  }
00219 
00223 static herr_t f_operator(hid_t loc_id, const char *name, void *opdata) {
00224     H5G_stat_t statbuf;
00225     hid_t dataset_id, space_id, type_id;
00226     Teuchos::ParameterList* sublist;
00227     Teuchos::ParameterList* params = (Teuchos::ParameterList*)opdata;
00228     /*
00229      * Get type of the object and display its name and type.
00230      * The name of the object is passed to this function by 
00231      * the Library. Some magic :-)
00232      */
00233     H5Gget_objinfo(loc_id, name, 0, &statbuf);
00234     switch (statbuf.type) {
00235     case H5G_GROUP:
00236         sublist = &params->sublist(name);
00237         H5Giterate(loc_id, name , NULL, f_operator, sublist);
00238         break;
00239     case H5G_DATASET:
00240         hsize_t len;
00241         dataset_id = H5Dopen(loc_id, name);
00242         space_id = H5Dget_space(dataset_id);
00243         if (H5Sget_simple_extent_ndims(space_id) != 1)
00244             rError("Dimensionality of parameters must be 1.");
00245         H5Sget_simple_extent_dims(space_id, &len, NULL);
00246         type_id = H5Dget_type(dataset_id);
00247         if (H5Tequal(type_id, H5T_NATIVE_DOUBLE) > 0) {
00248             double value;
00249             rAssert(len == 1);
00250             H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
00251             params->set(name, value);
00252         } else if (H5Tequal(type_id, H5T_NATIVE_INT) > 0) {
00253             int value;
00254             rAssert(len == 1);
00255             H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
00256             params->set(name, value);
00257         } else if (H5Tequal(type_id, H5T_C_S1) > 0) {
00258             char* buf = new char[len];
00259             H5Dread(dataset_id, H5T_C_S1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
00260             params->set(name, std::string(buf));
00261             delete[] buf;
00262         } else if (H5Tequal(type_id, H5T_NATIVE_USHORT) > 0) {
00263             unsigned short value;
00264             rAssert(len == 1);
00265             H5Dread(dataset_id, H5T_NATIVE_USHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
00266             params->set(name, value != 0 ? true : false);
00267         } else {
00268             rError("Unsupported datatype for parameter \"%s\".", name);   
00269         }
00270         H5Tclose(type_id);
00271         H5Sclose(space_id);  
00272         H5Dclose(dataset_id);  
00273         break;
00274     default:
00275         rError("Unsupported type for parameter \"%s\".", name);
00276     }
00277     return 0;
00278 }
00279 
00280 void h5_read_param_list(const std::string& file_name, Teuchos::ParameterList& params) {
00281     // Open hdf5 file
00282     hid_t       file_id, group_id;  /* identifiers */
00283     herr_t      status;
00284     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
00285 
00286     // Create group "parameters" in the root group using absolute name.
00287     group_id = H5Gopen(file_id, "/parameters");
00288 
00289     // Iterate through parameter list 
00290     status = H5Giterate(group_id, "/parameters" , NULL, f_operator, &params);
00291     
00292     // Finalize hdf5 file
00293     status = H5Gclose(group_id);
00294     status = H5Fclose(file_id);
00295  }
00296 
00297 void h5_write_eigenmodes(const std::string& file_name, const Epetra_MultiVector& Q, const Epetra_SerialDenseVector& lambda)
00298 {
00299         hid_t       file_id, group_id, dset_id;       /* file and dataset identifiers */
00300         hid_t       filespace, memspace;              /* file and memory dataspace identifiers */
00301         hid_t       plist_id;                         /* property list identifier */
00302         herr_t      status;
00303 
00304         // Set up file access property list with parallel I/O access
00305         plist_id = H5Pcreate(H5P_FILE_ACCESS);
00306     MPI_Comm mpi_comm  = dynamic_cast<const Epetra_MpiComm&>(Q.Comm()).GetMpiComm();
00307     MPI_Info mpi_info  = MPI_INFO_NULL;
00308     H5Pset_fapl_mpio(plist_id, mpi_comm, mpi_info);
00309 
00310     // Open file collectively and release property list identifier.
00311     // file_id = H5Fcreate(file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, plist_id);
00312     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
00313     H5Pclose(plist_id);
00314 
00315     // Create a group named /modes in the file.
00316     group_id = H5Gcreate(file_id, "/modes", 0);
00317 
00318     //
00319     // Eigenvectors
00320     //
00321 
00322     // Redistribute eigenvectors to force linear map
00323     Epetra_Map target_map(Q.GlobalLength(), 0, Q.Comm());
00324     Epetra_MultiVector Q0(target_map, Q.NumVectors());
00325     Q0.Export(Q, Epetra_Export(Q.Map(), target_map), Add);
00326     assert(Q0.Map().LinearMap());
00327 
00328     // Enforce defined direction for all eigenvectors
00329     for (int k = 0; k < Q0.NumVectors(); ++ k) {
00330         Epetra_Vector& q0 = *Q0(k);
00331         int sign = 1;
00332         // Proc 0 determines whether vector will be negated
00333         if (Q0.Comm().MyPID() == 0) {
00334             int i;
00335             double val;
00336             for (i = 0; i < Q0.MyLength() && (val = q0[i]) == 0.0; ++ i);
00337             if (i < Q0.MyLength() && val < 0.0)
00338                 sign = -1;
00339         }
00340         // Brodcast sign to all procs and negate if necessary
00341         Q0.Comm().Broadcast(&sign, 1, 0);
00342         if (sign == -1) {
00343             for (int i = 0; i < Q0.MyLength(); ++ i)
00344                 q0[i] = -q0[i];
00345         }
00346     } // for k
00347 
00348 #if 0
00349     // For debugging: fill eigenvectors
00350     for (int j = 0; j < Q0.NumVectors(); ++ j)
00351         for (int i = 0; i < Q0.MyLength(); ++ i)
00352             Q0.Values()[j*Q0.MyLength() + i] = 10000*(j+1) + Q0.Map().GID(i);
00353     // cout << *(Q0(1)) << "\n";
00354 #endif
00355 
00356     // Create the dataspace for the dataset.
00357     hsize_t q_dimsf[] = {Q0.NumVectors(), Q0.GlobalLength()};                 /* dataset dimensions */
00358     filespace = H5Screate_simple(2, q_dimsf, NULL);
00359 
00360     // Create the dataset with default properties and close filespace.
00361     dset_id = H5Dcreate(group_id, "eigenvectors", H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT);
00362 
00363     // Create property list for collective dataset write.
00364     plist_id = H5Pcreate(H5P_DATASET_XFER);
00365     H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);
00366 
00367     // Select hyperslab in the file.
00368     hsize_t offset[] = {0, Q0.Map().GID(0)};
00369     hsize_t stride[] = {1, 1};
00370     hsize_t count[] = {Q0.NumVectors(), 1};
00371     hsize_t block[] = {1, Q0.MyLength()};
00372     filespace = H5Dget_space(dset_id);
00373     H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, stride, count, block);
00374 
00375     // Each process defines dataset in memory and writes it to the hyperslab in the file.
00376     hsize_t dimsm[] = {Q0.NumVectors()*Q0.MyLength()};
00377     memspace = H5Screate_simple(1, dimsm, NULL);
00378 
00379     // Write hyperslab
00380     status = H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, memspace, filespace, plist_id, Q0.Values());
00381     H5Sclose(memspace);
00382     H5Sclose(filespace);
00383     H5Dclose(dset_id);
00384 
00385     //
00386     // Eigenvalues
00387     //
00388     hsize_t lambda_dimsf = lambda.Length();
00389     filespace = H5Screate_simple(1, &lambda_dimsf, NULL);
00390     dset_id = H5Dcreate(group_id, "eigenvalues", H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT);
00391     status = H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, plist_id, lambda.Values());
00392     H5Dclose(dset_id);
00393     H5Sclose(filespace);
00394 
00395     // Close/release resources.
00396     H5Pclose(plist_id);
00397     H5Gclose(group_id);
00398     H5Fclose(file_id);
00399 }
00400 
00401 void h5_read_eigenmodes(const std::string& file_name, Epetra_MultiVector** Q, Epetra_SerialDenseVector** lambda) {
00402 }
00403 
00404 void h5_read_eigenmodes(const std::string& file_name, 
00405                         colarray::Matrix<double>& Q, 
00406                         colarray::ColumnVector<double>& lambda) 
00407 {
00408     hid_t file_id, group_id, dataset_id, space_id;
00409     hsize_t num_eigenpairs, dims[2];
00410     herr_t status;
00411     
00412     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
00413         group_id = H5Gopen(file_id, "/modes");
00414     
00415         dataset_id = H5Dopen(group_id, "eigenvalues");
00416         space_id = H5Dget_space(dataset_id);
00417         if (H5Sget_simple_extent_ndims(space_id) != 1)
00418         {
00419                 rError("Dimensionality of modes/eigenvalues must be 1.");
00420         }
00421         
00422         status = H5Sget_simple_extent_dims(space_id, &num_eigenpairs, NULL);
00423         lambda = colarray::ColumnVector<double>(num_eigenpairs);
00424         status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
00425                      lambda._v);
00426     H5Sclose(space_id);  
00427     H5Dclose(dataset_id);  
00428 
00429     dataset_id = H5Dopen(group_id, "eigenvectors");
00430     space_id = H5Dget_space(dataset_id);
00431     if (H5Sget_simple_extent_ndims(space_id) != 2)
00432         rError("Dimensionality of modes/eigenvectors must be 2.");
00433     status = H5Sget_simple_extent_dims(space_id, dims, NULL);
00434     if (dims[0] != num_eigenpairs)
00435         rError("Number of eigenvalues (%d) does not match number of eigenvectors (%d).", 
00436                static_cast<int>(num_eigenpairs), 
00437                static_cast<int>(dims[0]));
00438     Q = colarray::Matrix<double>(dims[1], dims[0]);
00439     status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
00440                      Q._v);
00441     H5Sclose(space_id);  
00442     H5Dclose(dataset_id);  
00443 
00444     H5Gclose(group_id);
00445     H5Fclose(file_id);
00446 }
00447 
00449  void h5_read_eigenmesh(const std::string& file_name)
00450  {
00451         ;
00452  }
00453 
00455 void h5_write_eigenmesh(const std::string& file_name,const Epetra_Comm& comm, mesh::TetMesh* tetmesh)
00456 {
00457         int i,j,k; 
00458         int res=0; 
00459         id_t gntet=0; 
00460         id_t ntet=0; 
00461         id_t gpointid; 
00462         int ncol=NCORNERTET+2; 
00465         mesh::ParallelTetMesh* ptetmesh=NULL;
00466         ptetmesh=dynamic_cast<mesh::ParallelTetMesh*>(tetmesh);
00467 
00469         hid_t       file_id, group_id, dset_id;       /* file and dataset identifiers */
00470         hid_t       filespace, memspace;              /* file and memory dataspace identifiers */
00471         hid_t       plist_id;                         /* property list identifier */
00472         herr_t      status;
00473 
00475         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
00476         MPI_Info mpi_info  = MPI_INFO_NULL; 
00477         
00478         int mpirank=0; 
00479         int mpisize=0; 
00481         res=MPI_Comm_rank(mpi_comm, &mpirank);
00482         res=MPI_Comm_size(mpi_comm, &mpisize);
00483 
00484 #ifdef __DEBUG__VERBOSE__
00485         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << __LINE__  << " reached " << endl;
00486 #endif 
00489         plist_id = H5Pcreate(H5P_FILE_ACCESS);
00490         H5Pset_fapl_mpio(plist_id, mpi_comm, mpi_info);
00491 
00492     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
00493     H5Pclose(plist_id);
00494 
00496     group_id = H5Gcreate(file_id, H5_GROUP_FEMAX_EIGENMESH.c_str(), 0);
00497 
00505         ntet=tetmesh->get_nof_tets();
00506          
00507         /* retrieve global number of tetrahedra, required for allocating dimensions of dataset */
00508         gntet=ptetmesh->get_num_global_tets();
00509          
00510         hsize_t dimsf[]={gntet,ncol};
00511         filespace = H5Screate_simple(DIM2D, dimsf, NULL);
00512 
00515         dset_id = H5Dcreate(group_id, H5_NAME_FEMAX_TETVID.c_str(), H5T_NATIVE_UINT, filespace, H5P_DEFAULT);
00516         H5Sclose(filespace);
00517 
00519         hsize_t count[2];
00520         hsize_t offset[2];
00521         
00522         count[0]=tetmesh->get_nof_tets();
00523         count[1]=dimsf[1]; 
00526         id_t* ntetlist=new id_t[mpisize]; 
00527         res=MPI_Allgather(&ntet,1,MPI_UNSIGNED, ntetlist, 1, MPI_UNSIGNED, mpi_comm);
00528 
00530         offset[0]=0;
00531         for(i=0;i<mpirank;i++)
00532         {
00533                 offset[0]+=ntetlist[i];
00534         }
00535 
00536 #ifdef __DEBUG__VERBOSE__
00537         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << __LINE__  << " offset[0] " << offset[0] << endl;
00538  #endif 
00541         offset[1]=0; /* no offset w.r.t columns */
00542         memspace=H5Screate_simple(DIM2D,count,NULL);
00543 
00545         filespace=H5Dget_space(dset_id);
00546         H5Sselect_hyperslab(filespace, H5S_SELECT_SET,offset,NULL,count,NULL);
00547         
00549         unsigned int *tvertexid=new unsigned int [ntet*ncol];
00550         for(i=0;i<ntet*ncol;i++)
00551         {
00552                 tvertexid[i]=0;
00553         }
00554         
00572         mesh::TetMesh::tet_iterator tit;
00573         i=0;
00574         
00575         for(tit=tetmesh->tet_begin(); tit != tetmesh->tet_end(); tit++ )
00576         {
00577                 for(j=0; j<NCORNERTET;j++)
00578                         {
00579                                 gpointid=ptetmesh->point_gid(tit->get_corner_id(j));
00580                                 
00581                                 tvertexid[i*ncol+j]=gpointid;
00582                         }
00583                         
00584                         tvertexid[i*ncol+NCORNERTET]=mpirank;
00585                         tvertexid[i*ncol+NCORNERTET+1]=mpisize;
00586  
00587 //#ifdef __DEBUG__VERBOSE__
00588 //                              cout << "global vertex id: " << tvertexid[i][0] << " : " <<tvertexid[i][1] << " : " << tvertexid[i][2] << " : " << tvertexid[i][3] << endl;
00589 // #endif /**  __DEBUG__VERBOSE__ */
00590                         
00592                         i++;
00593         }
00594         
00596         plist_id=H5Pcreate(H5P_DATASET_XFER);
00597         H5Pset_dxpl_mpio(plist_id,H5FD_MPIO_COLLECTIVE);
00598         
00599 #ifdef __DEBUG__VERBOSE__
00600         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << __LINE__  << " reached " << endl;
00601  #endif 
00603         status=H5Dwrite(dset_id, H5T_NATIVE_UINT, memspace, filespace,plist_id, tvertexid);
00604 
00605 #ifdef __DEBUG__VERBOSE__
00606         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << __LINE__  << " reached " << endl;
00607 #endif 
00611         delete []tvertexid;
00612         delete []ntetlist;
00613 
00615         H5Dclose(dset_id);
00616         H5Sclose(filespace);
00617         H5Pclose(plist_id);
00618         H5Gclose(group_id);
00619         H5Fclose(file_id);      
00620  }
00621  
00622  
00623  
00638 void h5_write_eigenpoint(const std::string& file_name,  const Epetra_Comm& comm, mesh::TetMesh* tetmesh)
00639 {
00640         int i,j,k; 
00641         int res=0; 
00642         id_t gntet=0; 
00643         id_t ntet=0; 
00644         int ncol=NCORNERTET+2; 
00647         mesh::ParallelTetMesh* ptetmesh=NULL;
00648         ptetmesh=dynamic_cast<mesh::ParallelTetMesh*>(tetmesh);
00649 
00651         hid_t           file_id, group_id, dset_id;       /* file and dataset identifiers */
00652         hid_t           filespace, memspace;              /* file and memory dataspace identifiers */
00653         hid_t           plist_id;                         /* property list identifier */
00654         herr_t  status;
00655 
00657         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
00658         MPI_Info mpi_info  = MPI_INFO_NULL; 
00659         
00660         int mpirank=0; 
00661         int mpisize=0; 
00663         res=MPI_Comm_rank(mpi_comm, &mpirank);
00664         res=MPI_Comm_size(mpi_comm, &mpisize);
00665 
00667         plist_id = H5Pcreate(H5P_FILE_ACCESS);
00668         H5Pset_fapl_mpio(plist_id, mpi_comm, mpi_info);
00669 
00670   file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
00671   H5Pclose(plist_id);
00672 
00674   group_id = H5Gopen(file_id, H5_GROUP_FEMAX_EIGENMESH.c_str());
00675   
00676         if(group_id < 0) /* there is no such group yet, create one */
00677         {
00678                 group_id = H5Gcreate(file_id, H5_GROUP_FEMAX_EIGENMESH.c_str(), 0);
00679         }
00680 
00682         id_t gnpoint=0; 
00683         gnpoint=ptetmesh->get_num_global_points();
00684  
00685         hsize_t dimsf[]={gnpoint,NREALCOORD3D};
00686         filespace = H5Screate_simple(DIM2D, dimsf, NULL);
00687 
00690         dset_id = H5Dcreate(group_id, H5_NAME_FEMAX_POINTS.c_str(), H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT);
00691         H5Sclose(filespace);
00692 
00694         hsize_t count[2];
00695         hsize_t offset[2];
00696         
00698         id_t npoint=0;
00699         id_t npowned=0; 
00702         mesh::TetMesh::point_iterator pit;
00703         id_t gpointid=0;
00704         npoint=tetmesh->get_nof_points();
00705         bool powned=false;
00706         double coords3d[NREALCOORD3D];
00707 
00709         npowned=0;                      
00710         for(pit=tetmesh->point_begin(); pit != tetmesh->point_end(); pit++ )
00711         {
00712                 gpointid=ptetmesh->point_gid(pit->get_id());
00713                 powned=ptetmesh-> is_owned_point(gpointid);
00714                 if(powned == true)
00715                 {
00716                         npowned++;
00717                 }
00718         }
00719         double* xfercoords=new double[npowned*NREALCOORD3D];
00720         for(i=0;i<npowned*NREALCOORD3D;i++){xfercoords[i]=0.0; }
00721 
00722         count[0]=npowned;
00723         count[1]=NREALCOORD3D;
00724         memspace=H5Screate_simple(DIM2D,count,NULL);
00725         filespace=H5Dget_space(dset_id);
00726         
00727         hsize_t scount[2];
00728         scount[0]=1;
00729         scount[1]=NREALCOORD3D;
00730         
00731         
00733         i=0;
00734         npowned=0;
00735         
00736         for(pit=tetmesh->point_begin(); pit != tetmesh->point_end(); pit++ )
00737         {
00738                 gpointid=ptetmesh->point_gid(pit->get_id());
00739                 powned=ptetmesh-> is_owned_point(gpointid);
00740                 
00741                 if(powned == true)
00742                 {
00744                         offset[0]=gpointid;
00745                         offset[1]=0;
00746 
00748                         if(npowned == 0)
00749                         {
00750                                 H5Sselect_hyperslab(filespace, H5S_SELECT_SET,offset,NULL,scount,NULL);
00751                         }
00752                         else
00753                         {
00754                                 H5Sselect_hyperslab(filespace, H5S_SELECT_OR,offset,NULL,scount,NULL);
00755                         }
00757                         for(j=0;j<NREALCOORD3D;j++)
00758                         {
00759                                 xfercoords[i*NREALCOORD3D+j]=pit->get_coord()[j];
00760                         }
00761 
00762                         npowned++; 
00763                         i++;  
00764                 }
00765         }
00766         
00767 #ifdef __DEBUG__VERBOSE__
00768         cout << "[DEBUGOUT]  : h5_tools->h5_write_eigenpoints : process : " << mpirank << " with " << npowned << " points " << endl;
00769 #endif 
00772         plist_id=H5Pcreate(H5P_DATASET_XFER);
00773         H5Pset_dxpl_mpio(plist_id,H5FD_MPIO_COLLECTIVE);
00774         status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, memspace, filespace,plist_id, xfercoords);
00775 
00777         delete []xfercoords;
00778         
00780         H5Pclose(plist_id);
00781         H5Sclose(filespace);
00782         H5Dclose(dset_id);
00783         H5Gclose(group_id);
00784         H5Fclose(file_id);
00785 }
00786  
00797 void h5_write_eigenfield(const std::string& file_name,  const Epetra_Comm& comm,
00798                                                         mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
00799                                                         const Epetra_MultiVector& Q, double* lambda)
00800 {
00801         int i,j,k,m; /* standard loop indices */
00802         int res; /* return code */
00803         int ntet; /* number of tetrahedra local to this process */
00804         int gntet; /* global number of tetrahedra */
00805         int nmode; /* store number of calulated eigenmodes */
00806   int mpirank=0; 
00807   int mpisize=0; 
00809   hid_t       file_id, group_id, dset_id, plist_id;       /* file and dataset identifiers */
00810 
00812         mesh::ParallelTetMesh* ptetmesh=dynamic_cast<mesh::ParallelTetMesh*>(tetmesh);
00813 
00815 //      NedelecMesh nedelecmesh=femaxmesh->get_nedelec_mesh();
00816         NedelecElement* nedelecelem=nedelecmesh.get_element(0); 
00819         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
00820         MPI_Info mpi_info  = MPI_INFO_NULL; 
00821  
00822   res=MPI_Comm_rank(mpi_comm, &mpirank);
00823   res=MPI_Comm_size(mpi_comm, &mpisize);
00824 
00825 
00827         int order=nedelecelem->get_order(); 
00828         int ndofelem=nedelecelem->get_nof_dofs(); 
00831         /* compute an Epetra_Map */
00832 //      Epetra_Map* targetmap=h5_write_eigenfeield_retrieve_DoF_efficient(file_name,comm, tetmesh, nedelecmesh, Q,lambda); /* the efficient way */
00833         Epetra_Map* targetmap=h5_write_eigenfield_retrieve_DoF_robust(Q,comm); /* the robust way */
00834                                                                                                                 
00836         Epetra_MultiVector Q0(*targetmap, Q.NumVectors());
00837         
00839         Epetra_Import importer(*targetmap,Q.Map());
00840 //      Epetra_Export exporter(Q.Map(),*targetmap);
00841         
00843         Q0.Import(Q,importer,Insert);
00844 //      Q0.Export(Q, exporter,Add);
00845                  
00846 
00847         /* evaluate the modal fields by looping over all Epetra_Multivector components */
00848         mesh::TetMesh::tet_iterator tit;
00849         mesh::Vector3* efield=NULL;
00850         mesh::Vector3* hfield=NULL;
00851 
00852         const int* tldofid=NULL;
00853         colarray::Vector<double> dofs(nedelecelem->get_nof_dofs());
00854         int mapped_id=0;
00855 
00856         mesh::Vector3 samploc(0,0,0);
00857         mesh::Tet* ttet=NULL;
00858 
00859         ntet=tetmesh->get_nof_tets(); 
00860         gntet=ptetmesh->get_num_global_tets(); /* retrieve global number of tetrahedra, required for allocating dimensions of dataset */
00861 
00862         /* calculate sampling locations */
00863         double* sloc=new double[NREALCOORD3D*ntet];
00864         
00865         k=0; /* used as index over tetrahedral sampling locations */
00866         for(tit=tetmesh->tet_begin(); tit != tetmesh->tet_end(); tit++ )
00867         {
00869                 samploc=tit->get_center_of_gravity();
00870                         
00871                 sloc[k*NREALCOORD3D]=samploc.x;
00872                 sloc[k*NREALCOORD3D+1]=samploc.y;
00873                 sloc[k*NREALCOORD3D+2]=samploc.z;
00874                 
00875                 k++;
00876         }       
00877 
00878         efield=new mesh::Vector3[ntet]; 
00879         hfield=new mesh::Vector3[ntet]; 
00881         for(i=0;i<ntet;i++)
00882         {
00883                 /* initialize the electric field */
00884                 efield[i].x=0.0;
00885                 efield[i].y=0.0;
00886                 efield[i].z=0.0;
00887                 
00888                 /* initialize the magnetic field */
00889                 hfield[i].x=0.0;
00890                 hfield[i].y=0.0;
00891                 hfield[i].z=0.0;        
00892         }
00893 
00894         nmode=Q.NumVectors();
00895         int nev=NREALCOORD3D*ntet;
00896         double* ev=new double[nev]; 
00897         double* hv=new double[nev]; 
00898         for(i=0;i<nev;i++)
00899         {
00900                 ev[i]=0.0;
00901                 hv[i]=0.0;              
00902         }
00903 
00904         int tlid=0;
00905 
00906         for(m=0;m<nmode;m++)
00907         {
00908                 Epetra_Vector mthmode(Copy, Q0,m);
00909                 
00910                 k=0; 
00912                 for(tit=tetmesh->tet_begin(); tit != tetmesh->tet_end(); tit++ )
00913                 {
00915                         samploc=tit->get_center_of_gravity();
00916                         
00917                         sloc[k*NREALCOORD3D]=samploc.x;
00918                         sloc[k*NREALCOORD3D+1]=samploc.y;
00919                         sloc[k*NREALCOORD3D+2]=samploc.z;
00920                 
00922                         nedelecelem=nedelecmesh.get_element(tit->get_id());
00923                 
00924                         ttet=&(*tit); 
00926                         tldofid=nedelecelem->get_dof_ids(tetmesh,ttet);
00927                 
00928                         for (i=0; i < nedelecelem->get_nof_dofs(); i ++) 
00929                         {
00930                                 mapped_id=nedelecmesh.map_dof(tldofid[i]);
00931                         
00932                                 if (mapped_id == mesh::ID_NONE)
00933                                 {
00934                                         dofs(i) = 0.0;
00935                                 }
00936                                 else
00937                                 {                               
00938                                         tlid=targetmap->LID(mapped_id);
00939                                         dofs(i) = mthmode[tlid];
00940                                 }
00941       }
00942         
00944                         efield[k].x=nedelecelem->eval(ttet, samploc, dofs).x;
00945                         efield[k].y=nedelecelem->eval(ttet, samploc, dofs).y;
00946                         efield[k].z=nedelecelem->eval(ttet, samploc, dofs).z;
00947 
00949                         hfield[k].x=nedelecelem->eval_curl(ttet, samploc, dofs).x;
00950                         hfield[k].y=nedelecelem->eval_curl(ttet, samploc, dofs).y;
00951                         hfield[k].z=nedelecelem->eval_curl(ttet, samploc, dofs).z;
00952                         
00953                         k++;
00954                 }
00955         
00961                 i=0;
00962                 for(tit=tetmesh->tet_begin(); tit != tetmesh->tet_end(); tit++ )
00963                 {
00964                         for(j=0;j<NREALCOORD3D;j++)
00965                         {
00966                                 ev[i*NREALCOORD3D+j]=efield[i][j];
00967                                 hv[i*NREALCOORD3D+j]=hfield[i][j];
00968                         }
00969                         i++;
00970                 }
00971 
00972                 h5_write_eigenfield_write_hdf5e(file_name, comm, ntet, gntet, m, ev);
00973                 h5_write_eigenfield_write_hdf5h(file_name, comm, ntet, gntet, m, hv);
00974         }
00975 
00976         h5_write_eigenfield_writehdf5sloc(file_name, comm, ntet, gntet, sloc);
00977 
00979         delete []efield;
00980         delete []hfield;
00981         delete []ev;
00982         delete []hv;
00983         
00984         /* we are done */;
00985 } 
00986 
00987 
00992 Epetra_Map* h5_write_eigenfield_retrieve_DoF_robust(const Epetra_MultiVector& Q, const Epetra_Comm& comm)
00993 {
00994         
00995         int NumMyElements_target = Q.GlobalLength();
00996                 
00998 //      Epetra_Map* targetmap=new Epetra_Map(-1, NumMyElements_target, 0, comm);;
00999         Epetra_Map* targetmap=new Epetra_Map(NumMyElements_target, NumMyElements_target, 0, comm);;
01000 
01001         /* we are done */
01002         return(targetmap);
01003 }
01004 
01005 
01007 Epetra_Map* h5_write_eigenfeield_retrieve_DoF_efficient(const std::string& file_name,  const Epetra_Comm& comm,
01008                                                                                                         mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
01009                                                                                                         const Epetra_MultiVector& Q, double* lambda)
01010 {
01011         int i,j,k,m; /* standard loop indices */
01012         int res; /* return code */
01013         int ntet; /* number of tetrahedra local to this process */
01014         int gntet; /* global number of tetrahedra */
01015         int nmode; /* store number of calulated eigenmodes */
01016         
01018         mesh::ParallelTetMesh* ptetmesh=NULL;
01019         ptetmesh=dynamic_cast<mesh::ParallelTetMesh*>(tetmesh);
01020 
01022         NedelecElement* nedelecelem=nedelecmesh.get_element(0); 
01025         int order=nedelecelem->get_order(); 
01026         int ndofelem=nedelecelem->get_nof_dofs(); 
01028         id_t nmyedgdofu=0; 
01029         id_t nmyfacdofu=0; 
01030         id_t nmydof=0; 
01031         id_t tmpid=0; 
01032         id_t* ldofid=NULL; /* pointer to array of local DoF id's */
01033         id_t edgeoffset=0; 
01034         id_t geid=0; 
01036         mesh::TetMesh::edge_iterator eit;
01037         mesh::TetMesh::face_iterator fit;
01038         mesh::TetMesh::tet_iterator tit;
01039 
01041         if(order == FIRST_ORDER_FE) 
01042         {
01043                 nmyedgdofu=tetmesh->get_nof_edges(); 
01044                 nmyfacdofu=0; 
01045                 nmydof=nmyedgdofu+nmyfacdofu;
01046                 tmpid=0;
01047                 ldofid=new id_t[nmydof];
01048 
01049                 for(i=0;i<nmydof;i++){ ldofid[i]=0; }
01050 
01051                 for(eit=tetmesh->edge_begin(); eit != tetmesh->edge_end();eit++)
01052                 {
01053                         ldofid[tmpid]=eit->get_id(); 
01054                         tmpid++;
01055                 }
01056         }
01057         else if(order == SECOND_ORDER_FE)
01058         {
01059                 nmyedgdofu=2*tetmesh->get_nof_edges(); 
01060                 nmyfacdofu=3*tetmesh->get_nof_faces(); 
01061                 nmydof=nmyedgdofu+nmyfacdofu;
01062                 tmpid=0;
01063                 ldofid=new id_t[nmydof];
01064                 
01066                 for(i=0;i<nmydof;i++){ ldofid[i]=0; }
01067 
01068                 edgeoffset=tetmesh->get_nof_edges(); 
01070                 for(eit=tetmesh->edge_begin(); eit != tetmesh->edge_end();eit++)
01071                 {
01072                         ldofid[tmpid]=eit->get_id();
01073                         ldofid[tmpid+edgeoffset]=ldofid[tmpid]+edgeoffset;
01074                         tmpid++;
01075                 }
01076                 
01077         id_t face_id=0;
01078         int base_face_dof=0;
01079         
01080                 for(fit=tetmesh->face_begin(); fit != tetmesh->face_end();fit++)
01081                 {
01082                         face_id=fit->get_id();
01083                         base_face_dof = 3*face_id + 2*tetmesh->get_nof_edges();
01084                         
01086                         for(i=0;i<NCORNERTRIANGLE;i++)
01087                         {
01088                                 ldofid[tmpid]=base_face_dof + i;
01089                         }
01090                 }
01091         }
01092 
01094         int* gdofid=NULL;
01095         int nmapmydof=0;
01096         
01097         for(i=0;i<nmydof;i++)
01098         {
01099                 if(nedelecmesh.map_dof(ldofid[i]) != mesh::ID_NONE)
01100                 {
01101                         nmapmydof++;
01102                 }
01103         }
01104         
01106         gdofid=new int[nmapmydof];
01107         j=0;
01108         
01109         for(i=0;i<nmydof;i++)
01110         {
01111                 if(nedelecmesh.map_dof(ldofid[i]) != mesh::ID_NONE)
01112                 {
01113                         gdofid[j]=nedelecmesh.gdof(ldofid[i]);
01114                         j++;
01115                 }
01116         }
01117 
01119         Epetra_Map* targetmap=new Epetra_Map(-1,nmapmydof,gdofid,0,comm);
01120         
01121         /* we are done */
01122         return(targetmap);
01123 }
01124 
01126 void h5_write_eigenfield_write_hdf5e(const std::string& file_name,  const Epetra_Comm& comm,
01127                                                                         int ntet, int gntet, int mthmode, double* ev)
01128 {
01129   rInfo("storing electric mode[%d] into HDF5 output file",mthmode);
01130   
01131         int i,j,k; /* standard loop indices */
01132         int res; /* standard return code */
01133         int ncol=NREALCOORD3D; 
01134         hid_t       file_id, group_id, dset_id;       /* file and dataset identifiers */
01135         hid_t       filespace, memspace;              /* file and memory dataspace identifiers */
01136         hid_t       plist_id;                         /* property list identifier */
01137         herr_t      status;
01138         std::string mtheigenfieldbasename(H5_NAME_FEMAX_EIGENFIELD); /* base dataset name
01139 
01146         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
01147         MPI_Info mpi_info  = MPI_INFO_NULL; 
01148         
01149         int mpirank=0; 
01150         int mpisize=0; 
01152         res=MPI_Comm_rank(mpi_comm, &mpirank);
01153         res=MPI_Comm_size(mpi_comm, &mpisize);
01154 
01155 #ifdef __DEBUG__VERBOSE__
01156         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << " reached line" << __LINE__  << " reached " << endl;
01157 #endif 
01160         plist_id = H5Pcreate(H5P_FILE_ACCESS);
01161         H5Pset_fapl_mpio(plist_id, mpi_comm, mpi_info);
01162 
01163   file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
01164   H5Pclose(plist_id);
01165 
01167   rInfo("opening group in HDF5 file = %s",H5_GROUP_FEMAX_EIGENMODES.c_str());
01168   group_id = H5Gopen(file_id, H5_GROUP_FEMAX_EIGENMODES.c_str());
01169   rInfo("opened group in HDF5 file = %s",H5_GROUP_FEMAX_EIGENMODES.c_str());
01170 
01171 //      if(group_id < 0) /* there is no such group yet, create one */
01172 //      {
01173 //              group_id = H5Gcreate(file_id, H5_GROUP_FEMAX_EIGENMODES.c_str(), 0);
01174 //      }
01175 
01182         hsize_t dimsf[]={gntet,ncol};
01183         filespace = H5Screate_simple(DIM2D, dimsf, NULL);
01184 
01188         std::ostringstream out;
01189         out << mthmode;
01190         mtheigenfieldbasename.append(out.str());
01191                 
01192         dset_id = H5Dcreate(group_id, mtheigenfieldbasename.c_str(), H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT);
01193         H5Sclose(filespace);
01194 
01196         hsize_t count[2];
01197         hsize_t offset[2];
01198         
01199         count[0]=ntet;
01200         count[1]=dimsf[1]; 
01203         id_t* ntetlist=new id_t[mpisize]; 
01204         res=MPI_Allgather(&ntet,1,MPI_UNSIGNED, ntetlist, 1, MPI_UNSIGNED, mpi_comm);
01205 
01207         offset[0]=0;
01208         for(i=0;i<mpirank;i++)
01209         {
01210                 offset[0]+=ntetlist[i];
01211         }
01212 
01213 #ifdef __DEBUG__VERBOSE__
01214         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << __LINE__  << " offset[0] " << offset[0] << endl;
01215 #endif 
01217         offset[1]=0; /* no offset w.r.t columns */
01218         memspace=H5Screate_simple(DIM2D,count,NULL);
01219 
01221         filespace=H5Dget_space(dset_id);
01222         H5Sselect_hyperslab(filespace, H5S_SELECT_SET,offset,NULL,count,NULL);
01223         
01225         plist_id=H5Pcreate(H5P_DATASET_XFER);
01226         H5Pset_dxpl_mpio(plist_id,H5FD_MPIO_COLLECTIVE);
01227         status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, memspace, filespace,plist_id, ev);
01228 
01230         H5Dclose(dset_id);
01231         H5Sclose(filespace);
01232         H5Sclose(memspace);
01233         H5Gclose(group_id);
01234         H5Fclose(file_id);
01235 
01236         /* deletey dynamically allocated variables if any */
01237         delete []ntetlist;
01238         
01239         /* we are done */
01240   rInfo("stored electric mode[%d] into HDF5 output file",mthmode);
01241 }
01242 
01244 void h5_write_eigenfield_write_hdf5h(const std::string& file_name,  const Epetra_Comm& comm,
01245                                                                         int ntet, int gntet, int mthmode, double* hv)
01246 {
01247   rInfo("storing magnetic field of mode[%d] into HDF5 output file",mthmode);
01248   
01249         int i,j,k; /* standard loop indices */
01250         int res; /* standard return code */
01251         int ncol=NREALCOORD3D; 
01252         hid_t       file_id, group_id, dset_id;       /* file and dataset identifiers */
01253         hid_t       filespace, memspace;              /* file and memory dataspace identifiers */
01254         hid_t       plist_id;                         /* property list identifier */
01255         herr_t      status;
01256         std::string mtheigencurlbasename(H5_NAME_FEMAX_EIGENCURL); /* base dataset name
01257 
01264         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
01265         MPI_Info mpi_info  = MPI_INFO_NULL; 
01266         
01267         int mpirank=0; 
01268         int mpisize=0; 
01270         res=MPI_Comm_rank(mpi_comm, &mpirank);
01271         res=MPI_Comm_size(mpi_comm, &mpisize);
01272 
01273 #ifdef __DEBUG__VERBOSE__
01274         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << " reached line" << __LINE__  << " reached " << endl;
01275 #endif 
01278         plist_id = H5Pcreate(H5P_FILE_ACCESS);
01279         H5Pset_fapl_mpio(plist_id, mpi_comm, mpi_info);
01280 
01281   file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
01282   H5Pclose(plist_id);
01283 
01285   rInfo("opening group in HDF5 file = %s",H5_GROUP_FEMAX_EIGENMODES.c_str());
01286   group_id = H5Gopen(file_id, H5_GROUP_FEMAX_EIGENMODES.c_str());
01287   rInfo("opened group in HDF5 file = %s",H5_GROUP_FEMAX_EIGENMODES.c_str());
01288   
01295         hsize_t dimsf[]={gntet,ncol};
01296         filespace = H5Screate_simple(DIM2D, dimsf, NULL);
01297 
01301         std::ostringstream out;
01302         out << mthmode;
01303         mtheigencurlbasename.append(out.str());
01304                 
01305         dset_id = H5Dcreate(group_id, mtheigencurlbasename.c_str(), H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT);
01306         H5Sclose(filespace);
01307 
01309         hsize_t count[2];
01310         hsize_t offset[2];
01311         
01312         count[0]=ntet;
01313         count[1]=dimsf[1]; 
01316         id_t* ntetlist=new id_t[mpisize]; 
01317         res=MPI_Allgather(&ntet,1,MPI_UNSIGNED, ntetlist, 1, MPI_UNSIGNED, mpi_comm);
01318 
01320         offset[0]=0;
01321         for(i=0;i<mpirank;i++)
01322         {
01323                 offset[0]+=ntetlist[i];
01324         }
01325 
01326 #ifdef __DEBUG__VERBOSE__
01327         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << __LINE__  << " offset[0] " << offset[0] << endl;
01328 #endif 
01330         offset[1]=0; /* no offset w.r.t columns */
01331         memspace=H5Screate_simple(DIM2D,count,NULL);
01332 
01334         filespace=H5Dget_space(dset_id);
01335         H5Sselect_hyperslab(filespace, H5S_SELECT_SET,offset,NULL,count,NULL);
01336         
01338         plist_id=H5Pcreate(H5P_DATASET_XFER);
01339         H5Pset_dxpl_mpio(plist_id,H5FD_MPIO_COLLECTIVE);
01340         status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, memspace, filespace,plist_id, hv);
01341 
01343         H5Dclose(dset_id);
01344         H5Sclose(filespace);
01345         H5Sclose(memspace);
01346         H5Gclose(group_id);
01347         H5Fclose(file_id);
01348 
01349         /* deletey dynamically allocated variables if any */
01350         delete []ntetlist;
01351         
01352         /* we are done */
01353   rInfo("stored magnetic mode[%d] into HDF5 output file",mthmode);
01354 }
01355 
01356 
01358 void h5_write_eigenfield_writehdf5sloc(const std::string& file_name,
01359                                                                 const Epetra_Comm& comm,
01360                                                                 int ntet,
01361                                                                 int gntet,
01362                                                                 double* slocv)
01363 {
01364         int i,j,k; /* standard loop indices */
01365         int res; /* standard return code */
01366         int ncol=NREALCOORD3D; 
01367         hid_t       file_id, group_id, dset_id;       /* file and dataset identifiers */
01368         hid_t       filespace, memspace;              /* file and memory dataspace identifiers */
01369         hid_t       plist_id;                         /* property list identifier */
01370         herr_t      status;
01371         std::string slocbasename(H5_NAME_FEMAX_SLOCBASENAME); /* base dataset name
01372 
01379         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
01380         MPI_Info mpi_info  = MPI_INFO_NULL; 
01381         
01382         int mpirank=0; 
01383         int mpisize=0; 
01385         res=MPI_Comm_rank(mpi_comm, &mpirank);
01386         res=MPI_Comm_size(mpi_comm, &mpisize);
01387 
01388 #ifdef __DEBUG__VERBOSE__
01389         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << " reached line" << __LINE__  << " reached " << endl;
01390 #endif 
01393         plist_id = H5Pcreate(H5P_FILE_ACCESS);
01394         H5Pset_fapl_mpio(plist_id, mpi_comm, mpi_info);
01395 
01396     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
01397     H5Pclose(plist_id);
01398 
01400     group_id = H5Gopen(file_id, H5_GROUP_FEMAX_EIGENMODES.c_str());
01401   
01402         if(group_id < 0) /* there is no such group yet, create one */
01403         {
01404                 group_id = H5Gcreate(file_id, H5_GROUP_FEMAX_EIGENMODES.c_str(), 0);
01405         }
01406 
01413         hsize_t dimsf[]={gntet,ncol};
01414         filespace = H5Screate_simple(DIM2D, dimsf, NULL);
01415 
01419         dset_id = H5Dcreate(group_id, slocbasename.c_str(), H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT);
01420         H5Sclose(filespace);
01421 
01423         hsize_t count[2];
01424         hsize_t offset[2];
01425         
01426         count[0]=ntet;
01427         count[1]=dimsf[1]; 
01430         id_t* ntetlist=new id_t[mpisize]; 
01431         res=MPI_Allgather(&ntet,1,MPI_UNSIGNED, ntetlist, 1, MPI_UNSIGNED, mpi_comm);
01432 
01434         offset[0]=0;
01435         for(i=0;i<mpirank;i++)
01436         {
01437                 offset[0]+=ntetlist[i];
01438         }
01439 
01440 #ifdef __DEBUG__VERBOSE__
01441         cout << "[DEBUGOUT]  : " << __FILE__  << " : " << __LINE__  << " offset[0] " << offset[0] << endl;
01442 #endif 
01444         offset[1]=0; /* no offset w.r.t columns */
01445         memspace=H5Screate_simple(DIM2D,count,NULL);
01446 
01448         filespace=H5Dget_space(dset_id);
01449         H5Sselect_hyperslab(filespace, H5S_SELECT_SET,offset,NULL,count,NULL);
01450         
01452         plist_id=H5Pcreate(H5P_DATASET_XFER);
01453         H5Pset_dxpl_mpio(plist_id,H5FD_MPIO_COLLECTIVE);
01454         status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, memspace, filespace,plist_id, slocv);
01455 
01457         H5Dclose(dset_id);
01458         H5Sclose(filespace);
01459         H5Sclose(memspace);
01460         H5Gclose(group_id);
01461         H5Fclose(file_id);
01462 
01463         /* deletey dynamically allocated variables if any */
01464         delete []ntetlist;
01465         
01466         /* we are done */       
01467         
01468         
01469 }
01470 
01471 
01482 void h5_write_eigenvalue(const std::string& file_name,  const Epetra_Comm& comm,
01483                                                                                 mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
01484                                                                                 const Epetra_MultiVector& Q, double* lambda)
01485 {
01486         int i,j,k; /* standard loop indices */
01487         int res; /* standard return code */
01488         int ncol=3; /* number of columns to be written; at present we write the eigenvalue lambda, its associated eigenfrequency f [Hz] and the quality factor */
01489         hid_t file_id, group_id, dset_id; /* file and dataset identifiers */
01490         hid_t dataspace, filespace, memspace; /* file and memory dataspace identifiers */
01491         hid_t plist_id; /* property list identifier */
01492         herr_t status; /* error signal */
01493         
01494         int mpirank=0; 
01495         int mpisize=0; 
01497         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
01498         MPI_Info mpi_info  = MPI_INFO_NULL; 
01499         
01500         res=MPI_Comm_rank(mpi_comm, &mpirank);
01501         res=MPI_Comm_size(mpi_comm, &mpisize);
01502         
01503         /* go and compute the quality factors of the respective modes */
01504         int nlambda=Q.NumVectors();
01505         double* quality=new double[nlambda];
01506         for(i=0;i<nlambda;i++){quality[i]=0.0; }
01507         h5_compute_eigenquality(file_name, comm, tetmesh, nedelecmesh, Q, lambda, quality);
01508         
01509         if(mpirank==MPIROOTPROCESS) /* if I am the root process then I write the eigenvalue array into the HDF5 file */
01510         {
01512     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
01513   
01515     group_id = H5Gcreate(file_id, H5_GROUP_FEMAX_EIGENMODES.c_str(), 0);
01516                 
01517                 /* handle HDF5 related stuff for storing the array */
01518                 hsize_t count[]={Q.NumVectors(),ncol};
01519                 hsize_t dimsf[]={Q.NumVectors(),ncol};
01520         
01521                 /* store eigenvalues and associated eigenfrequencies in 2d array */
01522                 int nlambda=dimsf[0];
01523                 double* lambdafres=new double[nlambda*ncol];
01524                 for(i=0;i<nlambda;i++)
01525                 {
01526                         /* store eigenvalues into 2d array */
01527                         lambdafres[i*ncol]=lambda[i];
01528                         
01529                         /* calculate associated resonance frequency and store it into the 2d array */
01530                         lambdafres[i*ncol+1]=sqrt(lambda[i])*(SPEED_OF_LIGHT_VACUUM/(2*PI));
01531                         
01532                         /* store the associated quality factir into the 2d array */
01533                         lambdafres[i*ncol+2]=quality[i];
01534                 }
01535                 
01536                 dataspace = H5Screate_simple(DIM2D, dimsf, NULL);               
01537                 dset_id = H5Dcreate(group_id, H5_NAME_FEMAX_EIGENVALUE.c_str(), H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
01538                 H5Sclose(dataspace);
01539                 
01541                 status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, lambdafres);
01542                 
01543                 /* close down HDF5 operations */
01544                 H5Dclose(dset_id);
01545                 H5Gclose(group_id);
01546                 H5Fclose(file_id);
01547                 
01548                 /* delete dynamically allocate memory if any */
01549                 delete []lambdafres;
01550                         
01551         }
01552         
01553         /* we are done */
01554 }
01555 
01574 void h5_compute_eigenquality(const std::string& file_name,  const Epetra_Comm& comm,
01575                                                                                 mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
01576                                                                                 const Epetra_MultiVector& Q, double* lambda, double* &quality)
01577 {
01578         int i,j,k,m; /* standard loop indices */
01579         int res; /* return code */
01580         int ntet; /* number of tetrahedra local to this process */
01581         int gntet; /* global number of tetrahedra */
01582         int nmode=Q.NumVectors(); /* store number of calulated eigenmodes */
01583   
01584   rInfo("computing quality factor of eigenmodal solutions for %d modes",nmode);
01585   
01587         mesh::ParallelTetMesh* ptetmesh=dynamic_cast<mesh::ParallelTetMesh*>(tetmesh);
01588 
01590         NedelecElement* nedelecelem=nedelecmesh.get_element(0); 
01593         MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
01594         MPI_Info mpi_info  = MPI_INFO_NULL; 
01595 
01596         int mpirank=0; 
01597         int mpisize=0; 
01599         res=MPI_Comm_rank(mpi_comm, &mpirank);
01600         res=MPI_Comm_size(mpi_comm, &mpisize);
01601 
01603         int order=nedelecelem->get_order(); 
01604         int ndofelem=nedelecelem->get_nof_dofs(); 
01606         /* compute an Epetra_Map */
01607         Epetra_Map* targetmap=h5_write_eigenfield_retrieve_DoF_robust(Q,comm); /* the robust way */
01608                                                                                                                 
01610         Epetra_MultiVector Q0(*targetmap, Q.NumVectors());
01611         
01613         Epetra_Import importer(*targetmap,Q.Map());
01614         
01616         Q0.Import(Q,importer,Insert);
01617 
01618         /* nested loop over all modes and all faces for computing the surface integrals */
01619         mesh::id_t tetid=mesh::ID_NONE;
01620         mesh::TetMesh::surface_iterator fit;
01621         mesh::Face* face=NULL;
01622         const int* tldofid=NULL;
01623         int tlid=0;
01624         int mapped_id=0;
01625         int nface=0;
01626         
01627         double storedenergy=0.0;
01628         
01629         double* integral=new double[nmode]; /* provide memory for the respective surface integral contributions of the processes */
01630         double rintegral=0.0; /* used for storing result of reduction operation */
01631         double tintegral=0.0;
01632         
01633         double* omega=new double[nmode]; /* provide memory for the angular resonance frequencies */
01634         double* fres=new double[nmode]; /* provide memory for the resonance frequencies in Hz */
01635         double* skindepth=new double[nmode]; /* provide memory for the skin depths at the respective resonance frequencies */
01636         double* surfaceresistance=new double[nmode]; /* provide memory for surfaceresistance */
01637         double* avgpowerloss=new double[nmode]; /* provide memory for the average power losses */
01638         
01639         id_t t0,t1; /* store id's of tetrahedra adjacent to a face */
01640         t0=t1=mesh::ID_NONE;
01641         
01642         /* loop over modes */
01643         for(m=0;m<nmode;m++)
01644         {
01645 //    rInfo("computing mode[%d] quality factor",m);
01646     
01647                 Epetra_Vector mthmode(Copy, Q0,m);
01648                 tintegral=0.0; /* initialize integral value */
01649                 rintegral=0.0; /* initiaize reduced integral value */
01650                 nface=0; /* initialize number of faces looped over */
01651 
01652                 for(fit=tetmesh->surface_begin(); fit != tetmesh->surface_end(); ++fit)
01653                 {
01654                         face = *fit;
01655 
01656                         /* find tet and elem belonging to boundary face */
01657                         tetid = face->get_tet_id();
01658                         nedelecelem = nedelecmesh.get_element(tetid);
01659 
01660                         /* The surface integral evaluates the n x H over all boundary faces;
01661                          * there are different types of boundary faces, i.e. PEC, PMC, symmetry
01662                          * boundary faces and interpocessor boundary faces; faces of the type
01663                          * PEC, PMC and symmetry only have one adjacent tetrahedron while
01664                          * faces of the interprocessor type have actually two boundary
01665                          * faces; therefore, we must make sure that the faces for which the
01666                          * integral is evaluated, has only one single adjacent tetrahedron.
01667                          * 
01668                          */
01669                         face->get_tet_ids(&t0,&t1);
01670                         if(( (face->on_boundary() == true ) && ( face->on_symmetry_planes() == 0) ) )
01671                         {
01672                                 /* obtain memory for storing DoF */
01673                                 colarray::Vector<double> dofs(nedelecelem->get_nof_dofs());
01674                                                                 
01675                                 tldofid=nedelecelem->get_dof_ids(tetmesh,tetmesh->get_tet(tetid));
01676                 
01677                                 for (i=0; i < nedelecelem->get_nof_dofs(); i ++) 
01678                                 {
01679                                         mapped_id=nedelecmesh.map_dof(tldofid[i]);
01680                         
01681                                         if (mapped_id == mesh::ID_NONE)
01682                                         {
01683                                                 dofs(i) = 0.0;
01684                                         }
01685                                         else
01686                                         {                               
01687                                                 tlid=targetmap->LID(mapped_id);
01688                                                 dofs(i) = mthmode[tlid];
01689                                         }
01690         }
01691                         
01692                                 /* calculate the contribution of a face to the integral: int_(face)(curl N_i * curl N_j, ds) */
01693                                 tintegral += nedelecelem->surface_integral_curl(tetmesh->get_tet(tetid), face, dofs);
01694                                 
01695                                 /* increase number of processed faces */
01696                                 nface++;
01697                         }
01698                 }
01699         
01700     /* 1st, we need to reduce the processes' contribution to the surface integral */
01701 //    rInfo("collecting contributions for integral from all processors");
01702     res=MPI_Allreduce(&tintegral,&rintegral,1, MPI_DOUBLE, MPI_SUM, mpi_comm);
01703     integral[m]=rintegral; /* save result of modewise integration */
01704     rInfo("computed mode[%d] quality factor",m);
01705   
01706         }
01707         
01708         /* compute the quality factor */
01709         double cintegral=0.0; /*DEBUGING USE ONLY */
01710         double cquality=0.0;  /* DEBUGGING USE ONLY */
01711         double cfres=0.0;/*DEBUGING USE ONLY */
01712         double cskindepth=0.0; /*DEBUGING USE ONLY */
01713         double csurfaceresistance=0.0; /*DEBUGING USE ONLY */
01714         double cavgpowerloss=0.0; /*DEBUGING USE ONLY */
01715         
01716         /* loop over the modal surface integrals and compute resonance freuencies, skindepths
01717          * and quality factors */
01718         for(m=0;m<nmode;m++)
01719         {
01720                 omega[m]=sqrt(lambda[m])*SPEED_OF_LIGHT_VACUUM;
01721                 fres[m]=sqrt(lambda[m])*SPEED_OF_LIGHT_VACUUM/(2.0*PI);
01722                 skindepth[m]=1.0/(sqrt(PI*fres[m]*MU_ZERO*SIGMA_CU_PSI)); /* Ramo et al., p. 151, eq. 3.16(11) */
01723                 surfaceresistance[m]=(1.0/(SIGMA_CU_PSI*skindepth[m])); /* Ramo et. al., p. 154, eq. 3.17(5) */
01724                 integral[m] = integral[m] / ( MU_ZERO * MU_ZERO *omega[m] * omega[m]);
01725                 avgpowerloss[m]=(surfaceresistance[m] / 2.0) * integral[m]; /* Ramo et al. p. 446, eq. 8.13(19) */
01726                 
01727 //                      const int nofSym = 0;
01728 //                      avgpowerloss[m]*= (1 << nofSym);
01729                 
01730                 storedenergy=EPSILON_ZERO / 2.0;
01731                 quality[m]=omega[m] * storedenergy / avgpowerloss[m]; /* Ramo et al., p. 258. eq. 5.14(4) */
01732                 
01733                 /*DEBUGING USE ONLY */  
01734                 cintegral=integral[m];
01735                 cquality=quality[m];
01736                 cfres=fres[m];
01737                 cskindepth=skindepth[m];
01738                 csurfaceresistance=surfaceresistance[m];
01739                 cavgpowerloss=avgpowerloss[m];
01740                 /*DEBUGING USE ONLY */
01741                 
01742         }
01743                 
01744                 
01745 //    const int nofSym = 0;           // nofSym is not necessary since it cancels out
01746 //    integral *= (1 << nofSym);
01747 //    double omega = ::sqrt(lambda) * cLight;
01748 //    // double f = omega / 2.0 / pi;
01749 //    double intJpower2 = integral / mu0 / mu0 / omega / omega;
01750 //    double delta = sqrt(2.0 / (mu0 * omega * sigmaCu));
01751 //    double reZs = 1.0 / sigmaCu / delta;
01752 //    double W = reZs / 2 * intJpower2;          // Wall power loss
01753 //    double U = (1 << nofSym) * eps0 / 2;       // stored total energy
01754 //    double Q = omega * U / W;                  // unloaded quality factor
01755                 
01756         
01757         /* free dynamically allocated memory if any */
01758         delete []integral;
01759         delete []omega;
01760         delete []fres;
01761         delete []skindepth;
01762         delete []surfaceresistance;
01763         delete []avgpowerloss;
01764                                 
01765                 //    mesh::TetMesh::surface_iterator it;
01766 //    for (it = _mesh->surface_begin(); it != _mesh->surface_end(); ++ it) {
01767 //        Face* face = *it;
01768 //
01769 //        // find tet and elem belonging to boundary face
01770 //        mesh::id_t tet = face->get_tet_id();
01771 //        NedelecElement* elem = get_element(tet);
01772 //        // dofs for elem
01773 //        colarray::Vector<double> dofs(elem->get_nof_dofs());
01774 //        for (int i = 0; i < elem->get_nof_dofs(); ++ i) {
01775 //            const int* dof_ids = elem->get_dof_ids(_mesh, _mesh->get_tet(tet));
01776 //            int mapped_id = map_dof(dof_ids[i]);
01777 //            if (mapped_id == -1)
01778 //                dofs(i) = 0.0;
01779 //            else
01780 //                dofs(i) = q[mapped_id];
01781 //        }
01782 //        // calculate int_(face)(curl N_i * curl N_j, ds)
01783 //        integral += elem->surface_integral_curl(_mesh->get_tet(tet), face, dofs);
01784 //    }
01785                 
01786                 
01787                 
01788                 
01789         
01790 
01791         
01792 //    double integral = 0.0;
01793 //
01794 //    mesh::TetMesh::surface_iterator it;
01795 //    for (it = _mesh->surface_begin(); it != _mesh->surface_end(); ++ it) {
01796 //        Face* face = *it;
01797 //
01798 //        // find tet and elem belonging to boundary face
01799 //        mesh::id_t tet = face->get_tet_id();
01800 //        NedelecElement* elem = get_element(tet);
01801 //        // dofs for elem
01802 //        colarray::Vector<double> dofs(elem->get_nof_dofs());
01803 //        for (int i = 0; i < elem->get_nof_dofs(); ++ i) {
01804 //            const int* dof_ids = elem->get_dof_ids(_mesh, _mesh->get_tet(tet));
01805 //            int mapped_id = map_dof(dof_ids[i]);
01806 //            if (mapped_id == -1)
01807 //                dofs(i) = 0.0;
01808 //            else
01809 //                dofs(i) = q[mapped_id];
01810 //        }
01811 //        // calculate int_(face)(curl N_i * curl N_j, ds)
01812 //        integral += elem->surface_integral_curl(_mesh->get_tet(tet), face, dofs);
01813 //    }
01814 //  
01815 //    const int nofSym = 0;           // nofSym is not necessary since it cancels out
01816 //    integral *= (1 << nofSym);
01817 //    double omega = ::sqrt(lambda) * cLight;
01818 //    // double f = omega / 2.0 / pi;
01819 //    double intJpower2 = integral / mu0 / mu0 / omega / omega;
01820 //    double delta = sqrt(2.0 / (mu0 * omega * sigmaCu));
01821 //    double reZs = 1.0 / sigmaCu / delta;
01822 //    double W = reZs / 2 * intJpower2;          // Wall power loss
01823 //    double U = (1 << nofSym) * eps0 / 2;       // stored total energy
01824 //    double Q = omega * U / W;                  // unloaded quality factor
01825 //#if 0
01826 //    cout << "lambda=" << lambda << endl;
01827 //    cout << "integral=" << integral << endl;
01828 //    cout << "omega=" << omega << endl;
01829 //    cout << "intJpower2=" << intJpower2 << endl;
01830 //    cout << "delta=" << delta << endl;
01831 //    cout << "reZs=" << reZs << endl;
01832 //    cout << "W=" << W << endl;
01833 //    cout << "U=" << U << endl;
01834 //#endif
01835 //    return Q;
01836         
01837         
01838         
01839         
01840   rInfo("computed quality factor of eigenmodal solutions");
01841         
01842         
01843 }
01844 
01845 
01847 void h5_cartesian_sampling(const std::string& file_name,  const Epetra_Comm& comm,
01848                     mesh::TetMesh* tetmesh, NedelecMesh& nedelecmesh,
01849                     const Epetra_MultiVector& Q, double* lambda,
01850                     double xmin, double xmax, const int nx,
01851                     double ymin, double ymax, const int ny,
01852                     double zmin, double zmax, const int nz)
01853 {
01854   rInfo("evaluating eigenmodal solution on cartesian grid for %d modes",Q.NumVectors());
01855   
01859   mesh::ParallelTetMesh* ptetmesh=dynamic_cast<mesh::ParallelTetMesh*>(tetmesh);
01860   
01862   NedelecElement* nedelecelem=nedelecmesh.get_element(0); 
01865   int order=nedelecelem->get_order(); 
01866   int ndofelem=nedelecelem->get_nof_dofs(); 
01868   /* compute an Epetra_Map */
01869   Epetra_Map* targetmap=h5_write_eigenfield_retrieve_DoF_robust(Q,comm); /* the robust way */
01870                             
01872   Epetra_MultiVector Q0(*targetmap, Q.NumVectors());
01873   
01875   Epetra_Import importer(*targetmap,Q.Map());
01876 
01878   Q0.Import(Q,importer,Insert);
01879 
01880 
01886   std::vector<std::vector<std::vector<unsigned int> > > positionExists;
01887   positionExists.resize(nx);
01888   
01889   for(std::vector<std::vector<std::vector<unsigned int> > >::iterator it=positionExists.begin(); it != positionExists.end();it++)
01890   {
01891     (*it).resize(ny);
01892     for(std::vector<std::vector<unsigned int> >::iterator it2=(*it).begin(); it2 != (*it).end(); it2++)
01893     {
01894       (*it2).resize(nz);
01895       for(std::vector<unsigned int>::iterator it3=(*it2).begin(); it3 != (*it2).end(); it3++)
01896       {
01897         (*it3)=0;
01898       }
01899     }
01900   }
01901 
01902 
01909   unsigned int nmode=Q.NumVectors();
01910   
01913   std::vector<std::vector<std::vector<std::vector<mesh::Vector3> > > > efield;
01914   std::vector<std::vector<std::vector<std::vector<mesh::Vector3> > > > hfield;
01915 
01916     efield.resize(nmode);
01917     hfield.resize(nmode);
01918     
01919     for(unsigned int m=0;m<nmode;m++)
01920     {
01921       efield[m].resize(nx);
01922       hfield[m].resize(nx);
01923       
01924       for(unsigned int i=0;i<nx;i++)
01925       {
01926         efield[m][i].resize(ny);
01927         hfield[m][i].resize(ny);
01928   
01929         for(unsigned int j=0;j<ny;j++)
01930         {
01931           efield[m][i][j].resize(nz);
01932           hfield[m][i][j].resize(nz);
01933           
01934           for(unsigned int k=0;k<nz;k++)
01935           {
01936             efield[m][i][j][k]=mesh::Vector3(0,0,0); 
01937             hfield[m][i][j][k]=mesh::Vector3(0,0,0); 
01938           }        
01939         }
01940       }
01941     }
01942 
01943 
01944 
01945 
01946   rInfo("constructing octree for the terahedral mesh");
01947   tetmesh->construct_octree();
01948 
01949   rInfo("sampling eigenmodal solution on cartesian grid for %d modes", nmode);
01950     
01952   double dx=(xmax-xmin)/((double)(nx-1));
01953   double dy=(ymax-ymin)/((double)(ny-1));
01954   double dz=(zmax-zmin)/((double)(nz-1));
01955   
01956   rInfo("cartesian sampling interval on x-axis dx = %12.9e", dx);
01957   rInfo("cartesian sampling interval on y-axis dx = %12.9e", dy);
01958   rInfo("cartesian sampling interval on z-axis dx = %12.9e", dz);
01959 
01961 //  Epetra_Vector* mthmode=NULL;
01962 //  for(unsigned int m=0;m<nmode;m++)
01963 //  {
01964 //    mthmode[m]=new Epetra_Vector;
01965 //    mthmode[m](Copy, Q0,m);
01966 //    
01967 //  }
01968 
01969   std::vector<Epetra_Vector> mthmode;
01970     for(unsigned int m=0;m<nmode;m++)
01971     {
01972       mthmode.push_back(Epetra_Vector(Copy, Q0,0)); 
01973     }
01974 
01975 
01976 
01980   for(unsigned int i=0;i<nx;i++)
01981   {
01982     for(unsigned int j=0;j<ny;j++)
01983     {
01984       for(unsigned int k=0;k<nz;k++)
01985       {
01987         double x=xmin+(i*dx);
01988         double y=ymin+(j*dy);
01989         double z=zmin+(k*dz);
01990         
01991         mesh::Vector3 pos(x,y,z);
01992         
01993         std::vector<mesh::Tet*> tet;
01994         
01995         tetmesh->find_tets_by_point(pos,tet);
01996         
01997         unsigned int ntetfound=tet.size();
01998  
01999         if(ntetfound != 0)
02000         {
02001           positionExists[i][j][k]=1;
02002 
02004           for(unsigned int m=0; m < nmode; m++)
02005           {
02006             
02007             const int* tldofid=NULL;
02008             colarray::Vector<double> dofs(nedelecelem->get_nof_dofs());
02009             int mapped_id=0;
02010             mesh::Tet* ttet=tet[0];
02011             int tlid=0;
02012 
02015             nedelecelem=nedelecmesh.get_element(ttet->get_id());
02016             tldofid=nedelecelem->get_dof_ids(tetmesh,ttet);
02017 
02018             for (unsigned int d=0; d < nedelecelem->get_nof_dofs(); d++) 
02019             {
02020               mapped_id=nedelecmesh.map_dof(tldofid[d]);
02021             
02022               if (mapped_id == mesh::ID_NONE)
02023               {
02024                 dofs(d) = 0.0;
02025               }
02026               else
02027               {       
02028                 tlid=targetmap->LID(mapped_id);
02029                 dofs(d) = mthmode[m][tlid];
02030               }
02031             }
02032             
02034             efield[m][i][j][k].x=nedelecelem->eval(ttet, pos, dofs).x;
02035             efield[m][i][j][k].y=nedelecelem->eval(ttet, pos, dofs).y;          
02036             efield[m][i][j][k].z=nedelecelem->eval(ttet, pos, dofs).z;
02037                         
02039             hfield[m][i][j][k].x=nedelecelem->eval_curl(ttet, pos, dofs).x;
02040             hfield[m][i][j][k].y=nedelecelem->eval_curl(ttet, pos, dofs).y; 
02041             hfield[m][i][j][k].z=nedelecelem->eval_curl(ttet, pos, dofs).z;
02042           }
02043         }
02044         else
02045         {
02047           positionExists[i][j][k]=0;
02048         }
02049       }   
02050     }   
02051   }   
02055   rInfo("now going to write sampled field into HDF5 file", nmode);
02056   h5_cartesian_sampling_write_hdf5(comm, file_name, nmode,
02057                     positionExists,
02058                     efield,
02059                     hfield,
02060                     xmin, xmax, nx,
02061                     ymin, ymax, ny,
02062                     zmin, zmax, nz);
02063 }
02064 
02072 void h5_cartesian_sampling_write_hdf5(const Epetra_Comm& comm, const std::string& file_name, unsigned int nmode,
02073                     std::vector<std::vector<std::vector<unsigned int> > >& exists,
02074                     std::vector<std::vector<std::vector<std::vector<mesh::Vector3> > > >& efield,
02075                     std::vector<std::vector<std::vector<std::vector<mesh::Vector3> > > >& hfield,
02076                     double xmin, double xmax, const int nx,
02077                     double ymin, double ymax, const int ny,
02078                     double zmin, double zmax, const int nz)
02079 {
02080   rInfo("storing eigenmodal solution sampled on cartesian grid into hdf5 file");  
02081   
02123   MPI_Comm mpi_comm=dynamic_cast<const Epetra_MpiComm&>(comm).GetMpiComm();
02124   MPI_Info mpi_info  = MPI_INFO_NULL; 
02125   
02126   int mpirank=0; /* store the rank of this prcocess within this MPI communicator */
02127   int mpisize=0; /* store the size of an MPI communicator, i.e. the number of processes engaged */
02128   int res;       /* standard return code */ 
02129   
02130   res=MPI_Comm_rank(mpi_comm, &mpirank);
02131   res=MPI_Comm_size(mpi_comm, &mpisize);
02132 
02134   hid_t file_id, group_id, dset_id, plist_id;               /* file and dataset identifiers */
02135   hid_t dataspace;                                          /* file and memory dataspace identifiers */
02136   herr_t status;                                                                                  /* error signal */
02137 
02138 
02143   if(mpirank==MPIROOTPROCESS) /* if I am the root process then I initialize cartesian sampling storage */
02144   {
02145     rInfo("initializing cartesian sampling storage of eigenmodal solution");  
02146       
02148     file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
02149   
02151     group_id = H5Gcreate(file_id, H5_GROUP_NAME_EIGENMODES_CARTESIAN.c_str(), 0);
02152     rInfo("creating HDF5 group = %s",H5_GROUP_NAME_EIGENMODES_CARTESIAN.c_str());  
02153     
02156     hsize_t dimsf[]={3,2};    
02157     dataspace = H5Screate_simple(DIM2D, dimsf, NULL);
02158     
02159     dset_id = H5Dcreate(group_id, H5_NAME_FEMAX_EIGENOMDES_CARTESIAN_LIMITS.c_str(), H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
02160     H5Sclose(dataspace);
02161     
02163     double limit[]={xmin,xmax,ymin,ymax,zmin,zmax};
02164     status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, limit); 
02165     
02167     H5Dclose(dset_id);
02168 
02170     dimsf[0]=3;
02171     dimsf[1]=1;
02172     
02173     dataspace = H5Screate_simple(DIM2D, dimsf, NULL);
02174     
02175     dset_id = H5Dcreate(group_id, H5_NAME_FEMAX_EIGENOMDES_CARTESIAN_NUMBER_SAMPLES.c_str(),
02176                         H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
02177                         
02178     H5Sclose(dataspace);
02179     
02181     double nsample[]={nx,ny,nz};
02182     status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, nsample); 
02183     
02185     H5Dclose(dset_id);
02186 
02188     dimsf[0]=1;
02189     dimsf[1]=1;
02190     
02191     dataspace = H5Screate_simple(DIM2D, dimsf, NULL);
02192     
02193     dset_id = H5Dcreate(group_id, H5_NAME_FEMAX_EIGENOMDES_CARTESIAN_NMODE.c_str(),
02194                         H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
02195                         
02196     H5Sclose(dataspace);
02197     
02199     double nmode_[]={nmode};
02200     status=H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, nmode_); 
02201     
02203     H5Dclose(dset_id);
02204 
02205     rInfo("now initializing the array which indicates if a position exists");  
02206 
02207     hsize_t dims3Darray[]={nx,ny,nz};
02208     
02209     dataspace = H5Screate_simple(DIM3D, dims3Darray, NULL);
02210 
02211     dset_id = H5Dcreate(group_id, H5_NAME_FEMAX_EIGENOMDES_CARTESIAN_EXISTS.c_str(),
02212                         H5T_NATIVE_UINT, dataspace, H5P_DEFAULT);
02213 
02214     H5Sclose(dataspace);
02215 
02217     unsigned int nbool=nx*ny*nz;
02218     unsigned int* exists_=new unsigned int[nbool];
02219     for(unsigned int i=0;i<nbool;i++){exists_[i]=0;}
02220 
02221     status=H5Dwrite(dset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, exists_);
02222 
02224     H5Dclose(dset_id);
02225     H5Gclose(group_id);
02226     H5Fclose(file_id);
02227   }
02228   
02235   hid_t dset_id_electric, dset_id_magnetic;                 /* file and dataset identifiers */
02236 //  hid_t filespace_electric, filespace_magnetic;             /* file and memory dataspace identifiers */
02237   hid_t memspace_electric, memspace_magnetic;               /* file and memory dataspace identifiers */
02238   hid_t dataspace_electric, dataspace_magnetic;             /* file and memory dataspace identifiers */
02239   
02240   
02241   rInfo("transferring cartesian eigenmodal solution into HDF5 file");  
02242 
02246   unsigned int nlcartesian=0;   
02248   for(unsigned int i=0;i<nx;i++)
02249   {
02250     for(unsigned int j=0;j<ny;j++)
02251     {
02252       for(unsigned int k=0;k<nz;k++)
02253       {
02254         if(exists[i][j][k] != 0)
02255         {
02256           nlcartesian++;
02257         }     
02258       }
02259     }
02260   }
02261 
02262   rInfo("#[actually used local cartesian samples]=%d",nlcartesian);  
02263 
02268   plist_id = H5Pcreate(H5P_FILE_ACCESS);
02269   H5Pset_fapl_mpio(plist_id, mpi_comm, mpi_info);
02270 
02271   file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
02272   H5Pclose(plist_id);
02273 
02275   rInfo("opening HDF5 group = %s",H5_GROUP_NAME_EIGENMODES_CARTESIAN.c_str());  
02276   group_id = H5Gopen(file_id, H5_GROUP_NAME_EIGENMODES_CARTESIAN.c_str());
02277 
02278 
02280   for(unsigned int m=0;m<nmode;m++)
02281   {
02283     std::ostringstream out;
02284     out << m;
02285     std::string electricMthCartEigenfield(H5_NAME_FEMAX_EIGENOMDES_CARTESIAN_EFIELD_MODE);
02286     std::string magneticMthCartEigenfield(H5_NAME_FEMAX_EIGENOMDES_CARTESIAN_HFIELD_MODE);  
02287     
02289     electricMthCartEigenfield.append(out.str());
02290     magneticMthCartEigenfield.append(out.str());
02291 
02293 //    hsize_t dims4[]={nx,ny,nz,DIM3D};
02294     unsigned int ncsample=nx*ny*nz;
02295     hsize_t dim2[]={ncsample,DIM3D};
02296     
02297 //    rInfo("dim2[0] = %d ; dim2[1] = %d",dim2[0],dim2[1]);  
02298     
02299     dataspace_electric = H5Screate_simple(DIM2D, dim2, NULL);
02300     dataspace_magnetic = H5Screate_simple(DIM2D, dim2, NULL);
02301 
02302     dset_id_electric = H5Dcreate(group_id, electricMthCartEigenfield.c_str(), H5T_NATIVE_DOUBLE, dataspace_electric, H5P_DEFAULT);
02303     dset_id_magnetic = H5Dcreate(group_id, magneticMthCartEigenfield.c_str(), H5T_NATIVE_DOUBLE, dataspace_magnetic, H5P_DEFAULT);
02304 
02305     H5Sclose(dataspace_electric);
02306     H5Sclose(dataspace_magnetic);
02307     
02312     double* xfer3dEfield=new double[nlcartesian*NREALCOORD3D];
02313     double* xfer3dHfield=new double[nlcartesian*NREALCOORD3D];
02314     
02315     for(unsigned int i=0;i<(nlcartesian*NREALCOORD3D);i++)
02316     {
02317       xfer3dEfield[i]=0.0;
02318       xfer3dHfield[i]=0.0;
02319     }
02320 
02322     hsize_t count[]={nlcartesian,DIM3D};
02323     
02324 //    rInfo("count[0] = %d ; count[1] = %d",count[0],count[1]);  
02325     
02326     
02327     hsize_t offset[DIM2D];
02328     
02329     
02330     
02331     memspace_electric=H5Screate_simple(DIM2D,count,NULL);
02332     memspace_magnetic=H5Screate_simple(DIM2D,count,NULL);
02333         
02334     dataspace_electric=H5Dget_space(dset_id_electric);
02335     dataspace_magnetic=H5Dget_space(dset_id_magnetic);
02336   
02338     hsize_t scount[2];
02339     scount[0]=1;
02340     scount[1]=NREALCOORD3D;
02341   
02343     unsigned int nlcartesianprocessed=0;  /* count number of locally processed cartesian sampling locations */
02344     
02345     for(unsigned int i=0;i<nx;i++)
02346     {
02347       for(unsigned int j=0;j<ny;j++)
02348       {
02349         for(unsigned int k=0;k<nz;k++)
02350         {
02351           
02353           if(exists[i][j][k] != 0)
02354           {
02356             offset[0]=(i * ny * nz) + (j * nz ) + k;
02357             offset[1]=0;
02358 
02359             if(nlcartesianprocessed == 0) /* the very first hyperslab uses a different logic for construction */
02360             {
02361               H5Sselect_hyperslab(dataspace_electric, H5S_SELECT_SET,offset,NULL,scount,NULL);
02362               H5Sselect_hyperslab(dataspace_magnetic, H5S_SELECT_SET,offset,NULL,scount,NULL);         
02363             }
02364             else
02365             {
02366               H5Sselect_hyperslab(dataspace_electric, H5S_SELECT_OR,offset,NULL,scount,NULL);
02367               H5Sselect_hyperslab(dataspace_magnetic, H5S_SELECT_OR,offset,NULL,scount,NULL);
02368             }
02369             
02371             for(unsigned int n=0;n<NREALCOORD3D;n++)
02372             {
02373               xfer3dEfield[nlcartesianprocessed*NREALCOORD3D+n]=efield[m][i][j][k][n];
02374               xfer3dHfield[nlcartesianprocessed*NREALCOORD3D+n]=hfield[m][i][j][k][n];
02375             }
02376             
02377             nlcartesianprocessed++;
02378           }
02379            
02380         }
02381       }
02382     }
02383     
02385     plist_id=H5Pcreate(H5P_DATASET_XFER);
02386     H5Pset_dxpl_mpio(plist_id,H5FD_MPIO_COLLECTIVE);
02387     
02388     status=H5Dwrite(dset_id_electric, H5T_NATIVE_DOUBLE, memspace_electric, dataspace_electric, plist_id, xfer3dEfield);
02389 //    status=H5Dwrite(dset_id_magnetic, H5T_NATIVE_DOUBLE, memspace_magnetic, filespace_magnetic, plist_id, xfer3dHfield);
02390     
02392     delete []xfer3dEfield;
02393     delete []xfer3dHfield;
02394     
02395 
02397     H5Pclose(plist_id);
02398 
02399     H5Sclose(memspace_electric);
02400     H5Sclose(memspace_magnetic);
02401     
02402     H5Dclose(dset_id_electric);
02403     H5Dclose(dset_id_magnetic);
02404     
02405   }
02406 
02407 
02409   H5Gclose(group_id);
02410   H5Fclose(file_id);  
02411 }
02412 
02413 
02414 
02415 
02416 
02417 
02418 
02419 

Generated on Fri Oct 26 13:35:12 2007 for FEMAXX (Finite Element Maxwell Eigensolver) by  doxygen 1.4.7