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
00144
00145
00146
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
00153
00154
00155
00156 herr_t status;
00157 hsize_t one = 1;
00158 hid_t dataspace_id, dataset_id;
00159
00160
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
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
00204 hid_t file_id, group_id;
00205 herr_t status;
00206
00207 file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
00208
00209
00210 group_id = H5Gcreate(file_id, "/parameters", 0);
00211
00212
00213 h5_write_param_list_recursive(params, group_id);
00214
00215
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
00230
00231
00232
00233 H5Gget_objinfo(loc_id, name, 0, &statbuf);
00234 switch (statbuf.type) {
00235 case H5G_GROUP:
00236 sublist = ¶ms->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
00282 hid_t file_id, group_id;
00283 herr_t status;
00284 file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
00285
00286
00287 group_id = H5Gopen(file_id, "/parameters");
00288
00289
00290 status = H5Giterate(group_id, "/parameters" , NULL, f_operator, ¶ms);
00291
00292
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;
00300 hid_t filespace, memspace;
00301 hid_t plist_id;
00302 herr_t status;
00303
00304
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
00311
00312 file_id = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, plist_id);
00313 H5Pclose(plist_id);
00314
00315
00316 group_id = H5Gcreate(file_id, "/modes", 0);
00317
00318
00319
00320
00321
00322
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
00329 for (int k = 0; k < Q0.NumVectors(); ++ k) {
00330 Epetra_Vector& q0 = *Q0(k);
00331 int sign = 1;
00332
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
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 }
00347
00348 #if 0
00349
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
00354 #endif
00355
00356
00357 hsize_t q_dimsf[] = {Q0.NumVectors(), Q0.GlobalLength()};
00358 filespace = H5Screate_simple(2, q_dimsf, NULL);
00359
00360
00361 dset_id = H5Dcreate(group_id, "eigenvectors", H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT);
00362
00363
00364 plist_id = H5Pcreate(H5P_DATASET_XFER);
00365 H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);
00366
00367
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
00376 hsize_t dimsm[] = {Q0.NumVectors()*Q0.MyLength()};
00377 memspace = H5Screate_simple(1, dimsm, NULL);
00378
00379
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
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
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;
00470 hid_t filespace, memspace;
00471 hid_t plist_id;
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
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;
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
00588
00589
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;
00652 hid_t filespace, memspace;
00653 hid_t plist_id;
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)
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;
00802 int res;
00803 int ntet;
00804 int gntet;
00805 int nmode;
00806 int mpirank=0;
00807 int mpisize=0;
00809 hid_t file_id, group_id, dset_id, plist_id;
00810
00812 mesh::ParallelTetMesh* ptetmesh=dynamic_cast<mesh::ParallelTetMesh*>(tetmesh);
00813
00815
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
00832
00833 Epetra_Map* targetmap=h5_write_eigenfield_retrieve_DoF_robust(Q,comm);
00834
00836 Epetra_MultiVector Q0(*targetmap, Q.NumVectors());
00837
00839 Epetra_Import importer(*targetmap,Q.Map());
00840
00841
00843 Q0.Import(Q,importer,Insert);
00844
00845
00846
00847
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();
00861
00862
00863 double* sloc=new double[NREALCOORD3D*ntet];
00864
00865 k=0;
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
00884 efield[i].x=0.0;
00885 efield[i].y=0.0;
00886 efield[i].z=0.0;
00887
00888
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 ;
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
00999 Epetra_Map* targetmap=new Epetra_Map(NumMyElements_target, NumMyElements_target, 0, comm);;
01000
01001
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;
01012 int res;
01013 int ntet;
01014 int gntet;
01015 int nmode;
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;
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
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;
01132 int res;
01133 int ncol=NREALCOORD3D;
01134 hid_t file_id, group_id, dset_id;
01135 hid_t filespace, memspace;
01136 hid_t plist_id;
01137 herr_t status;
01138 std::string mtheigenfieldbasename(H5_NAME_FEMAX_EIGENFIELD);
01139
01146
01147
01148
01149
01150
01152
01153
01154
01155
01156
01157
01160
01161
01162
01163
01164
01165
01167
01168
01169
01170
01171
01172
01173
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;
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
01237 delete []ntetlist;
01238
01239
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;
01250 int res;
01251 int ncol=NREALCOORD3D;
01252 hid_t file_id, group_id, dset_id;
01253 hid_t filespace, memspace;
01254 hid_t plist_id;
01255 herr_t status;
01256 std::string mtheigencurlbasename(H5_NAME_FEMAX_EIGENCURL);
01257
01264
01265
01266
01267
01268
01270
01271
01272
01273
01274
01275
01278
01279
01280
01281
01282
01283
01285
01286
01287
01288
01295
01296
01297
01301
01302
01303
01304
01305
01306
01307
01309
01310
01311
01312
01313
01316
01317
01318
01320
01321
01322
01323
01324
01325
01326
01327
01328
01330
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
01350 delete []ntetlist;
01351
01352
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;
01365 int res;
01366 int ncol=NREALCOORD3D;
01367 hid_t file_id, group_id, dset_id;
01368 hid_t filespace, memspace;
01369 hid_t plist_id;
01370 herr_t status;
01371 std::string slocbasename(H5_NAME_FEMAX_SLOCBASENAME);
01372
01379
01380
01381
01382
01383
01385
01386
01387
01388
01389
01390
01393
01394
01395
01396
01397
01398
01400
01401
01402
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;
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
01464 delete []ntetlist;
01465
01466
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;
01487 int res;
01488 int ncol=3;
01489 hid_t file_id, group_id, dset_id;
01490 hid_t dataspace, filespace, memspace;
01491 hid_t plist_id;
01492 herr_t status;
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
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)
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
01518 hsize_t count[]={Q.NumVectors(),ncol};
01519 hsize_t dimsf[]={Q.NumVectors(),ncol};
01520
01521
01522 int nlambda=dimsf[0];
01523 double* lambdafres=new double[nlambda*ncol];
01524 for(i=0;i<nlambda;i++)
01525 {
01526
01527 lambdafres[i*ncol]=lambda[i];
01528
01529
01530 lambdafres[i*ncol+1]=sqrt(lambda[i])*(SPEED_OF_LIGHT_VACUUM/(2*PI));
01531
01532
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
01544 H5Dclose(dset_id);
01545 H5Gclose(group_id);
01546 H5Fclose(file_id);
01547
01548
01549 delete []lambdafres;
01550
01551 }
01552
01553
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;
01579 int res;
01580 int ntet;
01581 int gntet;
01582 int nmode=Q.NumVectors();
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
01607 Epetra_Map* targetmap=h5_write_eigenfield_retrieve_DoF_robust(Q,comm);
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
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];
01630 double rintegral=0.0;
01631 double tintegral=0.0;
01632
01633 double* omega=new double[nmode];
01634 double* fres=new double[nmode];
01635 double* skindepth=new double[nmode];
01636 double* surfaceresistance=new double[nmode];
01637 double* avgpowerloss=new double[nmode];
01638
01639 id_t t0,t1;
01640 t0=t1=mesh::ID_NONE;
01641
01642
01643 for(m=0;m<nmode;m++)
01644 {
01645
01646
01647 Epetra_Vector mthmode(Copy, Q0,m);
01648 tintegral=0.0;
01649 rintegral=0.0;
01650 nface=0;
01651
01652 for(fit=tetmesh->surface_begin(); fit != tetmesh->surface_end(); ++fit)
01653 {
01654 face = *fit;
01655
01656
01657 tetid = face->get_tet_id();
01658 nedelecelem = nedelecmesh.get_element(tetid);
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669 face->get_tet_ids(&t0,&t1);
01670 if(( (face->on_boundary() == true ) && ( face->on_symmetry_planes() == 0) ) )
01671 {
01672
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
01693 tintegral += nedelecelem->surface_integral_curl(tetmesh->get_tet(tetid), face, dofs);
01694
01695
01696 nface++;
01697 }
01698 }
01699
01700
01701
01702 res=MPI_Allreduce(&tintegral,&rintegral,1, MPI_DOUBLE, MPI_SUM, mpi_comm);
01703 integral[m]=rintegral;
01704 rInfo("computed mode[%d] quality factor",m);
01705
01706 }
01707
01708
01709 double cintegral=0.0;
01710 double cquality=0.0;
01711 double cfres=0.0;
01712 double cskindepth=0.0;
01713 double csurfaceresistance=0.0;
01714 double cavgpowerloss=0.0;
01715
01716
01717
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));
01723 surfaceresistance[m]=(1.0/(SIGMA_CU_PSI*skindepth[m]));
01724 integral[m] = integral[m] / ( MU_ZERO * MU_ZERO *omega[m] * omega[m]);
01725 avgpowerloss[m]=(surfaceresistance[m] / 2.0) * integral[m];
01726
01727
01728
01729
01730 storedenergy=EPSILON_ZERO / 2.0;
01731 quality[m]=omega[m] * storedenergy / avgpowerloss[m];
01732
01733
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
01741
01742 }
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 delete []integral;
01759 delete []omega;
01760 delete []fres;
01761 delete []skindepth;
01762 delete []surfaceresistance;
01763 delete []avgpowerloss;
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
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
01869 Epetra_Map* targetmap=h5_write_eigenfield_retrieve_DoF_robust(Q,comm);
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
01962
01963
01964
01965
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;
02127 int mpisize=0;
02128 int res;
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;
02135 hid_t dataspace;
02136 herr_t status;
02137
02138
02143 if(mpirank==MPIROOTPROCESS)
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;
02236
02237 hid_t memspace_electric, memspace_magnetic;
02238 hid_t dataspace_electric, dataspace_magnetic;
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
02294 unsigned int ncsample=nx*ny*nz;
02295 hsize_t dim2[]={ncsample,DIM3D};
02296
02297
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
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;
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)
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
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