Chaste Release::3.1
CompareHdf5ResultsFiles.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, 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)
00047 {
00048     Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1);
00049     Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2);
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     unsigned num_vars = variable_names1.size();
00063     if (num_vars != variable_names2.size())
00064     {
00065         std::cout << "Number of variables " << variable_names1.size()
00066                   << " and " << variable_names2.size() << " don't match\n";
00067         return false;
00068     }
00069     for (unsigned var=0; var<num_vars; var++)
00070     {
00071         std::string var_name = variable_names1[var];
00072         if (var_name != variable_names2[var])
00073         {
00074             std::cout << "Variable names " << var_name << " and "
00075                       << variable_names2[var] << " don't match\n";
00076             return false;
00077         }
00078         if (reader1.GetUnit(var_name) != reader2.GetUnit(var_name))
00079         {
00080             std::cout << "Units names " << reader1.GetUnit(var_name)
00081                       << " and " << reader2.GetUnit(var_name) << " don't match\n";
00082             return false;
00083         }
00084     }
00085 
00086     // Check the timestep vectors
00087     std::vector<double> times1 = reader1.GetUnlimitedDimensionValues();
00088     std::vector<double> times2 = reader2.GetUnlimitedDimensionValues();
00089 
00090     if (times1.size() != times2.size())
00091     {
00092         std::cout << "Number of time steps " << times1.size()
00093                   << " and " << times2.size() << " don't match\n";
00094         return false;
00095     }
00096 
00097     for (unsigned timestep=0; timestep<times1.size(); timestep++)
00098     {
00100         if (fabs(times1[timestep]-times2[timestep]) > 1e-8)
00101         {
00102             std::cout << "Time steps " << times1[timestep]
00103                       << " and " << times2[timestep] << " don't match\n";
00104             return false;
00105         }
00106     }
00107 
00108     bool is_complete1 = reader1.IsDataComplete();
00109     bool is_complete2 = reader2.IsDataComplete();
00110 
00111     if (is_complete1 != is_complete2)
00112     {
00113         std::cout<<"One of the readers has incomplete data and the other doesn't\n";
00114         return false;
00115     }
00116 
00117     if (is_complete1)
00118     {
00119         DistributedVectorFactory factory(number_nodes1);
00120 
00121         Vec data1 = factory.CreateVec();
00122         Vec data2 = factory.CreateVec();
00123 
00124         for (unsigned timestep=0; timestep<times1.size(); timestep++)
00125         {
00126             for (unsigned var=0; var<num_vars; var++)
00127             {
00128                 reader1.GetVariableOverNodes(data1, variable_names1[var], timestep);
00129                 reader2.GetVariableOverNodes(data2, variable_names2[var], timestep);
00130 
00131 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00132                 double minus_one = -1.0;
00133                 VecAXPY(&minus_one, data2, data1);
00134 #else
00135                 //[note: VecAXPY(y,a,x) computes y = ax+y]
00136                 VecAXPY(data1, -1.0, data2);
00137 #endif
00138 
00139                 PetscReal difference_norm;
00140                 VecNorm(data1, NORM_2, &difference_norm);
00141 
00142                 if (difference_norm > tol)
00143                 {
00144                     std::cout << "Vectors differ in NORM_2 by " << difference_norm << std::endl;
00145                     return false;
00146                 }
00147             }
00148         }
00149         PetscTools::Destroy(data1);
00150         PetscTools::Destroy(data2);
00151     }
00152     else
00153     {
00154         // Incomplete data
00155 
00156         // Check the index vectors
00157         std::vector<unsigned> indices1 = reader1.GetIncompleteNodeMap();
00158         std::vector<unsigned> indices2 = reader2.GetIncompleteNodeMap();
00159 
00160         if (indices1.size() != indices2.size())
00161         {
00162             std::cout << "Index map sizes " << indices1.size() << " and " << indices2.size() << " don't match\n";
00163             return false;
00164         }
00165 
00166         for (unsigned index=0; index<indices1.size(); index++)
00167         {
00168             if (indices1[index]!=indices2[index])
00169             {
00170                std::cout << "Time steps " << indices1[index] << " and " << indices2[index] << " don't match\n";
00171                return false;
00172             }
00173         }
00174 
00175         // Check all the data
00176         for (unsigned index=0; index<indices1.size(); index++)
00177         {
00178             unsigned node_index = indices1[index];
00179             for (unsigned var=0; var<num_vars; var++)
00180             {
00181                 std::vector<double> var_over_time1 = reader1.GetVariableOverTime(variable_names1[var], node_index);
00182                 std::vector<double> var_over_time2 = reader2.GetVariableOverTime(variable_names1[var], node_index);
00183                 for (unsigned time_step=0;time_step< var_over_time1.size(); time_step++)
00184                 {
00185                     if (fabs(var_over_time1[time_step] - var_over_time2[time_step]) > tol)
00186                     {
00187                         std::cout<<"Node "<<node_index<<" at time step "<<time_step<<" variable "<<variable_names1[var]<<
00188                             " differs ("<<var_over_time1[time_step]<<" != "<<var_over_time2[time_step]<<")\n";
00189                         return false;
00190                     }
00191                 }
00192             }
00193         }
00194     }
00195     return true;
00196 }
00197 
00198 bool CompareFilesViaHdf5DataReaderGlobalNorm(std::string pathname1, std::string filename1, bool makeAbsolute1,
00199                                              std::string pathname2, std::string filename2, bool makeAbsolute2,
00200                                              double tol)
00201 {
00202     Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1);
00203     Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2);
00204 
00205     unsigned number_nodes1 = reader1.GetNumberOfRows();
00206     bool is_the_same = true;
00207     std::vector<std::string> variable_names1 = reader1.GetVariableNames();
00208     std::vector<std::string> variable_names2 = reader2.GetVariableNames();
00209     std::vector<double> times1 = reader1.GetUnlimitedDimensionValues();
00210     unsigned num_vars = variable_names1.size();
00211     DistributedVectorFactory factory(number_nodes1);
00212 
00213     Vec data1 = factory.CreateVec();
00214     Vec data2 = factory.CreateVec();
00215 
00216     for (unsigned timestep=0; timestep<times1.size(); timestep++)
00217     {
00218         for (unsigned var=0; var<num_vars; var++)
00219         {
00220             reader1.GetVariableOverNodes(data1, variable_names1[var], timestep);
00221             reader2.GetVariableOverNodes(data2, variable_names2[var], timestep);
00222 
00223             PetscReal data1_norm;
00224             PetscReal data2_norm;
00225             VecNorm(data1, NORM_2, &data1_norm);
00226             VecNorm(data2, NORM_2, &data2_norm);
00227             PetscReal norm = fabs(data1_norm-data2_norm);
00228             if (norm > tol)
00229             {
00230                 is_the_same = false;
00231                 std::cout << "Vectors differ in global NORM_2 by " << norm << std::endl;
00232             }
00233         }
00234     }
00235 
00236     PetscTools::Destroy(data1);
00237     PetscTools::Destroy(data2);
00238 
00239     return is_the_same;
00240 }