CompareHdf5ResultsFiles.cpp

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