CompareHdf5ResultsFiles.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "CompareHdf5ResultsFiles.hpp"
00030 
00031 #include <iostream>
00032 #include <vector>
00033 #include "petscvec.h"
00034 #include "Hdf5DataReader.hpp"
00035 #include "DistributedVectorFactory.hpp"
00036 
00037 
00038 bool CompareFilesViaHdf5DataReader(std::string pathname1, std::string filename1, bool makeAbsolute1,
00039                                    std::string pathname2, std::string filename2, bool makeAbsolute2)
00040 {
00041     Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1);
00042     Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2);
00043 
00044     unsigned number_nodes1 = reader1.GetNumberOfRows();
00045     unsigned number_nodes2 = reader2.GetNumberOfRows();
00046     if (number_nodes1 != number_nodes2)
00047     {
00048         std::cout << "Number of nodes " << number_nodes1 << " and " << number_nodes2 << " don't match\n";
00049         return false;
00050     }
00051     // Check the variable names and units
00052     std::vector<std::string> variable_names1 = reader1.GetVariableNames();
00053     std::vector<std::string> variable_names2 = reader2.GetVariableNames();
00054     unsigned num_vars = variable_names1.size();
00055     if (num_vars != variable_names2.size())
00056     {
00057         std::cout << "Number of variables " << variable_names1.size()
00058                   << " and " << variable_names2.size() << " don't match\n";
00059         return false;
00060     }
00061     for (unsigned var=0; var<num_vars; var++)
00062     {
00063         std::string var_name = variable_names1[var];
00064         if (var_name != variable_names2[var])
00065         {
00066             std::cout << "Variable names " << var_name << " and "
00067                       << variable_names2[var] << " don't match\n";
00068             return false;
00069         }
00070         if (reader1.GetUnit(var_name) != reader2.GetUnit(var_name))
00071         {
00072             std::cout << "Units names " << reader1.GetUnit(var_name)
00073                       << " and " << reader2.GetUnit(var_name) << " don't match\n";
00074             return false;
00075         }
00076     }
00077     // Check the timestep vectors
00078     std::vector<double> times1 = reader1.GetUnlimitedDimensionValues();
00079     std::vector<double> times2 = reader2.GetUnlimitedDimensionValues();
00080 
00081     if (times1.size() != times2.size())
00082     {
00083         std::cout << "Time step sizes " << times1.size()
00084                   << " and " << times2.size() << " don't match\n";
00085         return false;
00086     }
00087 
00088     for (unsigned timestep=0; timestep<times1.size(); timestep++)
00089     {
00090         if (fabs(times1[timestep]-times2[timestep]) > 1e-8)
00091         {
00092             std::cout << "Time steps " << times1[timestep]
00093                       << " and " << times2[timestep] << " don't match\n";
00094             return false;
00095         }
00096     }
00097 
00098     bool is_complete1 = reader1.IsDataComplete();
00099     bool is_complete2 = reader2.IsDataComplete();
00100 
00101     if (is_complete1 != is_complete2)
00102     {
00103         std::cout<<"One of the readers has incomplete data and the other doesn't\n";
00104         return false;
00105     }
00106 
00107     if (is_complete1)
00108     {
00109         DistributedVectorFactory factory(number_nodes1);
00110 
00111         Vec data1 = factory.CreateVec();
00112         Vec data2 = factory.CreateVec();
00113 
00114         for (unsigned timestep=0; timestep<times1.size(); timestep++)
00115         {
00116             for (unsigned var=0; var<num_vars; var++)
00117             {
00118                 reader1.GetVariableOverNodes(data1, variable_names1[var], timestep);
00119                 reader2.GetVariableOverNodes(data2, variable_names2[var], timestep);
00120 
00121 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00122                 double minus_one = -1.0;
00123                 VecAXPY(&minus_one, data2, data1);
00124 #else
00125                 //[note: VecAXPY(y,a,x) computes y = ax+y]
00126                 VecAXPY(data1, -1.0, data2);
00127 #endif
00128 
00129                 PetscReal difference_norm;
00130                 VecNorm(data1, NORM_2, &difference_norm);
00131 
00132                 if (difference_norm > 1e-10)
00133                 {
00134                     std::cout << "Vectors differ in NORM_2 by " << difference_norm << std::endl;
00135                     return false;
00136                 }
00137             }
00138         }
00139         VecDestroy(data1);
00140         VecDestroy(data2);
00141     }
00142     else
00143     {
00144         // Incomplete data
00145 
00146         // Check the index vectors
00147         std::vector<unsigned> indices1 = reader1.GetIncompleteNodeMap();
00148         std::vector<unsigned> indices2 = reader2.GetIncompleteNodeMap();
00149 
00150         if (indices1.size() != indices2.size())
00151         {
00152             std::cout << "Index map sizes " << indices1.size() << " and " << indices2.size() << " don't match\n";
00153             return false;
00154         }
00155 
00156         for (unsigned index=0; index<indices1.size(); index++)
00157         {
00158             if (indices1[index]!=indices2[index])
00159             {
00160                std::cout << "Time steps " << indices1[index] << " and " << indices2[index] << " don't match\n";
00161                return false;
00162             }
00163         }
00164 
00165         // Check all the data
00166         for (unsigned index=0; index<indices1.size(); index++)
00167         {
00168             unsigned node_index = indices1[index];
00169             for (unsigned var=0; var<num_vars; var++)
00170             {
00171               std::vector<double> var_over_time1 = reader1.GetVariableOverTime(variable_names1[var], node_index);
00172               std::vector<double> var_over_time2 = reader2.GetVariableOverTime(variable_names1[var], node_index);
00173               for (unsigned time_step=0;time_step< var_over_time1.size(); time_step++)
00174               {
00175                  if (var_over_time1[time_step] != var_over_time2[time_step])
00176                  {
00177                     std::cout<<"Node "<<node_index<<" at time step "<<time_step<<" variable "<<variable_names1[var]<<
00178                         " differs ("<<var_over_time1[time_step]<<" != "<<var_over_time2[time_step]<<")\n";
00179                  }
00180               }
00181             }
00182         }
00183     }
00184    return true;
00185 }
00186 
00187 bool CompareFilesViaHdf5DataReaderGlobalNorm(std::string pathname1, std::string filename1, bool makeAbsolute1,
00188                                              std::string pathname2, std::string filename2, bool makeAbsolute2)
00189 {
00190         Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1);
00191         Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2);
00192 
00193         unsigned number_nodes1 = reader1.GetNumberOfRows();
00194         bool is_the_same = true;
00195         std::vector<std::string> variable_names1 = reader1.GetVariableNames();
00196         std::vector<std::string> variable_names2 = reader2.GetVariableNames();
00197         std::vector<double> times1 = reader1.GetUnlimitedDimensionValues();
00198         unsigned num_vars = variable_names1.size();
00199         DistributedVectorFactory factory(number_nodes1);
00200 
00201         Vec data1 = factory.CreateVec();
00202         Vec data2 = factory.CreateVec();
00203 
00204         for (unsigned timestep=0; timestep<times1.size(); timestep++)
00205         {
00206             for (unsigned var=0; var<num_vars; var++)
00207             {
00208                 reader1.GetVariableOverNodes(data1, variable_names1[var], timestep);
00209                 reader2.GetVariableOverNodes(data2, variable_names2[var], timestep);
00210 
00211                 PetscReal data1_norm;
00212                 PetscReal data2_norm;
00213                 VecNorm(data1, NORM_2, &data1_norm);
00214                 VecNorm(data2, NORM_2, &data2_norm);
00215                 PetscReal norm = fabs(data1_norm-data2_norm);
00216                 if (norm > 1e-10)
00217                 {
00218                     is_the_same = false;
00219                     std::cout << "Vectors differ in global NORM_2 by " << norm << std::endl;
00220                 }
00221             }
00222         }
00223 
00224         VecDestroy(data1);
00225         VecDestroy(data2);
00226 
00227         return is_the_same;
00228 }

Generated by  doxygen 1.6.2