From 1943efeefdc6a052ce6375013a5f3a8922fc42d0 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Wed, 26 Jul 2017 18:39:09 +0200 Subject: [PATCH] Fix write_hdf5_parallel without MPI --- doc/news/changes/minor/20170726DanielArndt | 4 + source/base/data_out_base.cc | 30 +- tests/mpi/data_out_hdf5_01.cc | 9 +- tests/mpi/data_out_hdf5_02.cc | 9 +- tests/numerics/data_out_hdf5_01.cc | 104 +++++ .../data_out_hdf5_01.with_hdf5=true.output | 29 ++ tests/numerics/data_out_hdf5_02.cc | 195 ++++++++++ .../data_out_hdf5_02.with_hdf5=true.output | 359 ++++++++++++++++++ 8 files changed, 718 insertions(+), 21 deletions(-) create mode 100644 doc/news/changes/minor/20170726DanielArndt create mode 100644 tests/numerics/data_out_hdf5_01.cc create mode 100644 tests/numerics/data_out_hdf5_01.with_hdf5=true.output create mode 100644 tests/numerics/data_out_hdf5_02.cc create mode 100644 tests/numerics/data_out_hdf5_02.with_hdf5=true.output diff --git a/doc/news/changes/minor/20170726DanielArndt b/doc/news/changes/minor/20170726DanielArndt new file mode 100644 index 0000000000..42648f27b3 --- /dev/null +++ b/doc/news/changes/minor/20170726DanielArndt @@ -0,0 +1,4 @@ +Fixed: DataOutBase::write_hdf5_parallel() can also be used in case deal.II +and HDF5 are not compiled with MPI support. +
+(Daniel Arndt, 2017/07/26) diff --git a/source/base/data_out_base.cc b/source/base/data_out_base.cc index 7bdb0a58d7..0b9cfe9733 100644 --- a/source/base/data_out_base.cc +++ b/source/base/data_out_base.cc @@ -6554,6 +6554,7 @@ create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter, ierr = MPI_Allreduce(local_node_cell_count, global_node_cell_count, 2, MPI_UNSIGNED, MPI_SUM, comm); AssertThrowMPI(ierr); #else + (void)comm; myrank = 0; global_node_cell_count[0] = local_node_cell_count[0]; global_node_cell_count[1] = local_node_cell_count[1]; @@ -6780,8 +6781,7 @@ void DataOutBase::write_hdf5_parallel (const std::vector > & int ierr; (void)ierr; #ifndef DEAL_II_WITH_HDF5 - // throw an exception, but first make - // sure the compiler does not warn about + // throw an exception, but first make sure the compiler does not warn about // the now unused function arguments (void)data_filter; (void)write_mesh_file; @@ -6791,21 +6791,16 @@ void DataOutBase::write_hdf5_parallel (const std::vector > & AssertThrow(false, ExcMessage ("HDF5 support is disabled.")); #else #ifndef DEAL_II_WITH_MPI - // verify that there are indeed - // patches to be written out. most - // of the times, people just forget - // to call build_patches when there - // are no patches, so a warning is - // in order. that said, the - // assertion is disabled if we - // support MPI since then it can - // happen that on the coarsest - // mesh, a processor simply has no - // cells it actually owns, and in - // that case it is legit if there - // are no patches + // verify that there are indeed patches to be written out. + // most of the times, people just forget to call build_patches when there + // are no patches, so a warning is in order. that said, the assertion is + // disabled if we support MPI since then it can happen that on the coarsest + // mesh, a processor simply has no cells it actually owns, and in that case + // it is legit if there are no patches Assert (data_filter.n_nodes() > 0, ExcNoPatches()); -#else + (void)comm; +#endif + hid_t h5_mesh_file_id=-1, h5_solution_file_id, file_plist_id, plist_id; hid_t node_dataspace, node_dataset, node_file_dataspace, node_memory_dataspace; hid_t cell_dataspace, cell_dataset, cell_file_dataspace, cell_memory_dataspace; @@ -6852,6 +6847,8 @@ void DataOutBase::write_hdf5_parallel (const std::vector > & global_node_cell_offsets[0] -= local_node_cell_count[0]; global_node_cell_offsets[1] -= local_node_cell_count[1]; #else + global_node_cell_count[0] = local_node_cell_count[0]; + global_node_cell_count[1] = local_node_cell_count[1]; global_node_cell_offsets[0] = global_node_cell_offsets[1] = 0; #endif @@ -7051,7 +7048,6 @@ void DataOutBase::write_hdf5_parallel (const std::vector > & status = H5Fclose(h5_solution_file_id); AssertThrow(status >= 0, ExcIO()); #endif -#endif } diff --git a/tests/mpi/data_out_hdf5_01.cc b/tests/mpi/data_out_hdf5_01.cc index 5a3cf4a4b4..2fd9033eae 100644 --- a/tests/mpi/data_out_hdf5_01.cc +++ b/tests/mpi/data_out_hdf5_01.cc @@ -60,9 +60,14 @@ test () // Sadly hdf5 is binary and we can not use hd5dump because it might - // not be in the path. At least we can look at the xdmf: + // not be in the path. At least we can look at the xdmf + // and make sure that the h5 file is created: if (0==Utilities::MPI::this_mpi_process (MPI_COMM_WORLD)) - cat_file("out.xdmf"); + { + cat_file("out.xdmf"); + std::ifstream f("out.h5"); + AssertThrow(f.good(), ExcIO()); + } } diff --git a/tests/mpi/data_out_hdf5_02.cc b/tests/mpi/data_out_hdf5_02.cc index 03f00927fe..2615c554b7 100644 --- a/tests/mpi/data_out_hdf5_02.cc +++ b/tests/mpi/data_out_hdf5_02.cc @@ -137,14 +137,19 @@ void check() xdmf_file.close(); // Sadly hdf5 is binary and we can not use hd5dump because it might - // not be in the path. At least we can look at the xdmf: + // not be in the path. At least we can look at the xdmf + // and make sure that the h5 file is created: deallog << "\n==============================\n" << output_basename + ".xdmf" << "\n==============================" << std::endl; if (0==Utilities::MPI::this_mpi_process (MPI_COMM_WORLD)) - cat_file((output_basename+".xdmf").c_str()); + { + cat_file((output_basename+".xdmf").c_str()); + std::ifstream f((output_basename+".h5").c_str()); + AssertThrow(f.good(), ExcIO()); + } deallog << std::flush; } diff --git a/tests/numerics/data_out_hdf5_01.cc b/tests/numerics/data_out_hdf5_01.cc new file mode 100644 index 0000000000..d9511c1166 --- /dev/null +++ b/tests/numerics/data_out_hdf5_01.cc @@ -0,0 +1,104 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2003 - 2017 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +// tests DataOut with HDF5 + +#include "../tests.h" +#include +#include +#include +#include +#include +#include + + + + +template +void +test () +{ + Triangulation tria; + GridGenerator::hyper_cube(tria, 0., 1.); + tria.refine_global (1); + + FE_Q fe1(1); + + DoFHandler dof1(tria); + dof1.distribute_dofs(fe1); + + Vector v1(dof1.n_dofs()); + for (unsigned int i=0; i data_out; + data_out.add_data_vector (dof1, v1, "linear"); + data_out.build_patches (2); + + DataOutBase::DataOutFilter data_filter + (DataOutBase::DataOutFilterFlags (false, false)); + data_out.write_filtered_data (data_filter); + data_out.write_hdf5_parallel (data_filter, "out.h5", MPI_COMM_SELF); + std::vector xdmf_entries; + xdmf_entries.push_back + (data_out.create_xdmf_entry (data_filter, "out.h5", 0, MPI_COMM_SELF)); + + data_out.write_xdmf_file (xdmf_entries, "out.xdmf", MPI_COMM_SELF); + + deallog << "ok" << std::endl; + + + // Sadly hdf5 is binary and we can not use hd5dump because it might + // not be in the path. At least we can look at the xdmf + // and make sure that the h5 file is created: + cat_file("out.xdmf"); + std::ifstream f("out.h5"); + AssertThrow(f.good(), ExcIO()); +} + + +int main(int argc, char *argv[]) +{ + initlog(); + + try + { + test<2>(); + + return 0; + } + catch (std::exception &exc) + { + deallog << std::endl << std::endl + << "----------------------------------------------------" + << std::endl; + deallog << "Exception on processing: " << std::endl + << exc.what() << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" + << std::endl; + return 1; + } + catch (...) + { + deallog << std::endl << std::endl + << "----------------------------------------------------" + << std::endl; + deallog << "Unknown exception!" << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" + << std::endl; + return 1; + }; +} diff --git a/tests/numerics/data_out_hdf5_01.with_hdf5=true.output b/tests/numerics/data_out_hdf5_01.with_hdf5=true.output new file mode 100644 index 0000000000..911d9ff941 --- /dev/null +++ b/tests/numerics/data_out_hdf5_01.with_hdf5=true.output @@ -0,0 +1,29 @@ + +DEAL::ok + + + + + + + + + + + diff --git a/tests/numerics/data_out_hdf5_02.cc b/tests/numerics/data_out_hdf5_02.cc new file mode 100644 index 0000000000..36f1c003ee --- /dev/null +++ b/tests/numerics/data_out_hdf5_02.cc @@ -0,0 +1,195 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +// tests DataOut with HDF5 and zero-dimensional output (i.e. points) + +#include "../tests.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +double cell_coordinates [3][8] = +{ + { 0, 1, 0, 1, 0, 1, 0, 1 }, + { 0, 0, 1, 1, 0, 0, 1, 1 }, + { 0, 0, 0, 0, 1, 1, 1, 1 } +}; + + +// This function is a copy from tests/base/patches.h, included here +// to not introduce dependencies between different test targets +template +void +create_patches(std::vector > &patches) +{ + for (unsigned int p=0; p &patch = patches[p]; + + const unsigned int nsub = p+1; + const unsigned int nsubp = nsub+1; + + patch.n_subdivisions = nsub; + for (unsigned int v=0; v::vertices_per_cell; ++v) + for (unsigned int d=0; d=dim) ? v : 0); + + unsigned int n1 = (dim>0) ? nsubp : 1; + unsigned int n2 = (dim>1) ? nsubp : 1; + unsigned int n3 = (dim>2) ? nsubp : 1; + unsigned int n4 = (dim>3) ? nsubp : 1; + patch.data.reinit(5, n1*n2*n3*n4); + + for (unsigned int i4=0; i4 +void check() +{ + const unsigned int np = 4; + + std::vector > patches(np); + + create_patches(patches); + + std::vector names(5); + names[0] = "x1"; + names[1] = "x2"; + names[2] = "x3"; + names[3] = "x4"; + names[4] = "i"; + std::vector > vectors; + + DataOutBase::DataOutFilter data_filter + (DataOutBase::DataOutFilterFlags (false, false)); + + DataOutBase::write_filtered_data (patches,names,vectors,data_filter); + + std::string output_basename = std::to_string(dim) + std::to_string(spacedim); + + DataOutBase::write_hdf5_parallel(patches, data_filter, output_basename+".h5", MPI_COMM_SELF); + + const double current_time = 0.0; + XDMFEntry entry(output_basename+".h5", output_basename+".h5", current_time, data_filter.n_nodes(), data_filter.n_cells(), dim, spacedim); + unsigned int n_data_sets = data_filter.n_data_sets(); + + // The vector names generated here must match those generated in the HDF5 file + for (unsigned int i=0; i\n"; + xdmf_file << "\n"; + xdmf_file << "\n"; + xdmf_file << " \n"; + xdmf_file << " \n"; + + // Write out the entry + xdmf_file << entry.get_xdmf_content(3); + + xdmf_file << " \n"; + xdmf_file << " \n"; + xdmf_file << "\n"; + + xdmf_file.close(); + + // Sadly hdf5 is binary and we can not use hd5dump because it might + // not be in the path. At least we can look at the xdmf + // and make sure that the h5 file is created: + deallog << "\n==============================\n" + << output_basename + ".xdmf" + << "\n==============================" + << std::endl; + + cat_file((output_basename+".xdmf").c_str()); + std::ifstream f((output_basename+".h5").c_str()); + AssertThrow(f.good(), ExcIO()); + + deallog << std::flush; +} + + + +int main(int argc, char *argv[]) +{ + initlog(); + + try + { + check<0,2>(); + check<1,2>(); + check<2,2>(); + check<0,3>(); + check<1,3>(); + check<2,3>(); + check<3,3>(); + + return 0; + } + catch (std::exception &exc) + { + deallog << std::endl << std::endl + << "----------------------------------------------------" + << std::endl; + deallog << "Exception on processing: " << std::endl + << exc.what() << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" + << std::endl; + return 1; + } + catch (...) + { + deallog << std::endl << std::endl + << "----------------------------------------------------" + << std::endl; + deallog << "Unknown exception!" << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" + << std::endl; + return 1; + }; +} diff --git a/tests/numerics/data_out_hdf5_02.with_hdf5=true.output b/tests/numerics/data_out_hdf5_02.with_hdf5=true.output new file mode 100644 index 0000000000..a636cc7bec --- /dev/null +++ b/tests/numerics/data_out_hdf5_02.with_hdf5=true.output @@ -0,0 +1,359 @@ + +DEAL:: +============================== +02.xdmf +============================== + + + + + + + + + + + +DEAL:: +============================== +12.xdmf +============================== + + + + + + + + + + + +DEAL:: +============================== +22.xdmf +============================== + + + + + + + + + + + +DEAL:: +============================== +03.xdmf +============================== + + + + + + + + + + + +DEAL:: +============================== +13.xdmf +============================== + + + + + + + + + + + +DEAL:: +============================== +23.xdmf +============================== + + + + + + + + + + + +DEAL:: +============================== +33.xdmf +============================== + + + + + + + + + + + +DEAL:: \ No newline at end of file -- 2.39.5