CompareHdf5ResultsFiles.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "CompareHdf5ResultsFiles.hpp"
00037 
00038 #include <iostream>
00039 #include <vector>
00040 #include "petscvec.h"
00041 #include "Hdf5DataReader.hpp"
00042 #include "DistributedVectorFactory.hpp"
00043 
00044 bool CompareFilesViaHdf5DataReader(std::string pathname1, std::string filename1, bool makeAbsolute1,
00045                                    std::string pathname2, std::string filename2, bool makeAbsolute2,
00046                                    double tol, std::string datasetName)
00047 {
00048     Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1, datasetName);
00049     Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2, datasetName);
00050 
00051     unsigned number_nodes1 = reader1.GetNumberOfRows();
00052     unsigned number_nodes2 = reader2.GetNumberOfRows();
00053     if (number_nodes1 != number_nodes2)
00054     {
00055         std::cout << "Number of nodes " << number_nodes1 << " and " << number_nodes2 << " don't match\n";
00056         return false;
00057     }
00058 
00059     // Check the variable names and units
00060     std::vector<std::string> variable_names1 = reader1.GetVariableNames();
00061     std::vector<std::string> variable_names2 = reader2.GetVariableNames();
00062     std::string unlimited_variable1 = reader1.GetUnlimitedDimensionName();
00063     std::string unlimited_variable2 = reader2.GetUnlimitedDimensionName();
00064     std::string unlimited_variable_unit1 = reader1.GetUnlimitedDimensionUnit();
00065     std::string unlimited_variable_unit2 = reader2.GetUnlimitedDimensionUnit();
00066 
00067     unsigned num_vars = variable_names1.size();
00068     if (num_vars != variable_names2.size())
00069     {
00070         std::cout << "Number of variables " << variable_names1.size()
00071                   << " and " << variable_names2.size() << " don't match\n";
00072         return false;
00073     }
00074     if (unlimited_variable1 != unlimited_variable2)
00075     {
00076         std::cout << "Unlimited variable names " << unlimited_variable1 << " and "
00077                   << unlimited_variable2 << " don't match\n";
00078         return false;
00079     }
00080     if (unlimited_variable_unit1 != unlimited_variable_unit2)
00081     {
00082         std::cout << "Unlimited variable units " << unlimited_variable_unit1 << " and "
00083                   << unlimited_variable_unit2 << " don't match\n";
00084         return false;
00085     }
00086     for (unsigned var=0; var<num_vars; var++)
00087     {
00088         std::string var_name = variable_names1[var];
00089         if (var_name != variable_names2[var])
00090         {
00091             std::cout << "Variable names " << var_name << " and "
00092                       << variable_names2[var] << " don't match\n";
00093             return false;
00094         }
00095         if (reader1.GetUnit(var_name) != reader2.GetUnit(var_name))
00096         {
00097             std::cout << "Units names " << reader1.GetUnit(var_name)
00098                       << " and " << reader2.GetUnit(var_name) << " don't match\n";
00099             return false;
00100         }
00101     }
00102 
00103     // Check the timestep vectors
00104     std::vector<double> times1 = reader1.GetUnlimitedDimensionValues();
00105     std::vector<double> times2 = reader2.GetUnlimitedDimensionValues();
00106 
00107     if (times1.size() != times2.size())
00108     {
00109         std::cout << "Number of time steps " << times1.size()
00110                   << " and " << times2.size() << " don't match\n";
00111         return false;
00112     }
00113 
00114     for (unsigned timestep=0; timestep<times1.size(); timestep++)
00115     {
00117         if (fabs(times1[timestep]-times2[timestep]) > 1e-8)
00118         {
00119             std::cout << "Time steps " << times1[timestep]
00120                       << " and " << times2[timestep] << " don't match\n";
00121             return false;
00122         }
00123     }
00124 
00125     bool is_complete1 = reader1.IsDataComplete();
00126     bool is_complete2 = reader2.IsDataComplete();
00127 
00128     if (is_complete1 != is_complete2)
00129     {
00130         std::cout<<"One of the readers has incomplete data and the other doesn't\n";
00131         return false;
00132     }
00133 
00134     if (is_complete1)
00135     {
00136         DistributedVectorFactory factory(number_nodes1);
00137 
00138         Vec data1 = factory.CreateVec();
00139         Vec data2 = factory.CreateVec();
00140 
00141         for (unsigned timestep=0; timestep<times1.size(); timestep++)
00142         {
00143             for (unsigned var=0; var<num_vars; var++)
00144             {
00145                 reader1.GetVariableOverNodes(data1, variable_names1[var], timestep);
00146                 reader2.GetVariableOverNodes(data2, variable_names2[var], timestep);
00147 
00148 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00149                 double minus_one = -1.0;
00150                 VecAXPY(&minus_one, data2, data1);
00151 #else
00152                 //[note: VecAXPY(y,a,x) computes y = ax+y]
00153                 VecAXPY(data1, -1.0, data2);
00154 #endif
00155 
00156                 PetscReal difference_norm;
00157                 VecNorm(data1, NORM_2, &difference_norm);
00158 
00159                 if (difference_norm > tol)
00160                 {
00161                     std::cout << "Time " << times1[timestep] << ": vectors differ in NORM_2 by " << difference_norm << std::endl;
00162                     return false;
00163                 }
00164             }
00165         }
00166         PetscTools::Destroy(data1);
00167         PetscTools::Destroy(data2);
00168     }
00169     else
00170     {
00171         // Incomplete data
00172 
00173         // Check the index vectors
00174         std::vector<unsigned> indices1 = reader1.GetIncompleteNodeMap();
00175         std::vector<unsigned> indices2 = reader2.GetIncompleteNodeMap();
00176 
00177         if (indices1.size() != indices2.size())
00178         {
00179             std::cout << "Index map sizes " << indices1.size() << " and " << indices2.size() << " don't match\n";
00180             return false;
00181         }
00182 
00183         for (unsigned index=0; index<indices1.size(); index++)
00184         {
00185             if (indices1[index]!=indices2[index])
00186             {
00187                std::cout << "Time steps " << indices1[index] << " and " << indices2[index] << " don't match\n";
00188                return false;
00189             }
00190         }
00191 
00192         // Check all the data
00193         for (unsigned index=0; index<indices1.size(); index++)
00194         {
00195             unsigned node_index = indices1[index];
00196             for (unsigned var=0; var<num_vars; var++)
00197             {
00198                 std::vector<double> var_over_time1 = reader1.GetVariableOverTime(variable_names1[var], node_index);
00199                 std::vector<double> var_over_time2 = reader2.GetVariableOverTime(variable_names1[var], node_index);
00200                 for (unsigned time_step=0;time_step< var_over_time1.size(); time_step++)
00201                 {
00202                     if (fabs(var_over_time1[time_step] - var_over_time2[time_step]) > tol)
00203                     {
00204                         std::cout<<"Node "<<node_index<<" at time step "<<time_step<<" variable "<<variable_names1[var]<<
00205                             " differs ("<<var_over_time1[time_step]<<" != "<<var_over_time2[time_step]<<")\n";
00206                         return false;
00207                     }
00208                 }
00209             }
00210         }
00211     }
00212     return true;
00213 }
00214 
00215 bool CompareFilesViaHdf5DataReaderGlobalNorm(std::string pathname1, std::string filename1, bool makeAbsolute1,
00216                                              std::string pathname2, std::string filename2, bool makeAbsolute2,
00217                                              double tol, std::string datasetName)
00218 {
00219     Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1, datasetName);
00220     Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2, datasetName);
00221 
00222     unsigned number_nodes1 = reader1.GetNumberOfRows();
00223     bool is_the_same = true;
00224     std::vector<std::string> variable_names1 = reader1.GetVariableNames();
00225     std::vector<std::string> variable_names2 = reader2.GetVariableNames();
00226     std::vector<double> times1 = reader1.GetUnlimitedDimensionValues();
00227     unsigned num_vars = variable_names1.size();
00228     DistributedVectorFactory factory(number_nodes1);
00229 
00230     Vec data1 = factory.CreateVec();
00231     Vec data2 = factory.CreateVec();
00232 
00233     for (unsigned timestep=0; timestep<times1.size(); timestep++)
00234     {
00235         for (unsigned var=0; var<num_vars; var++)
00236         {
00237             reader1.GetVariableOverNodes(data1, variable_names1[var], timestep);
00238             reader2.GetVariableOverNodes(data2, variable_names2[var], timestep);
00239 
00240             PetscReal data1_norm;
00241             PetscReal data2_norm;
00242             VecNorm(data1, NORM_2, &data1_norm);
00243             VecNorm(data2, NORM_2, &data2_norm);
00244             PetscReal norm = fabs(data1_norm-data2_norm);
00245             if (norm > tol)
00246             {
00247                 is_the_same = false;
00248                 std::cout << "Vectors differ in global NORM_2 by " << norm << std::endl;
00249             }
00250         }
00251     }
00252 
00253     PetscTools::Destroy(data1);
00254     PetscTools::Destroy(data2);
00255 
00256     return is_the_same;
00257 }

Generated by  doxygen 1.6.2