COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
MeshDiff.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2013 von Karman Institute for Fluid Dynamics, Belgium
2 //
3 // This software is distributed under the terms of the
4 // GNU Lesser General Public License version 3 (LGPLv3).
5 // See doc/lgpl.txt and doc/gpl.txt for the license text.
6 
7 #include <boost/mpl/vector.hpp>
8 #include <boost/mpl/for_each.hpp>
9 
10 #include "common/Builder.hpp"
11 
13 #include "common/Foreach.hpp"
14 
15 #include "common/PE/Comm.hpp"
16 #include "common/OptionList.hpp"
17 #include "common/PropertyList.hpp"
18 
20 #include "mesh/Faces.hpp"
21 #include "mesh/Region.hpp"
22 #include "mesh/Space.hpp"
23 #include "mesh/Mesh.hpp"
24 #include "mesh/MeshAdaptor.hpp"
25 #include "mesh/Field.hpp"
26 #include "mesh/Functions.hpp"
27 #include "mesh/Connectivity.hpp"
28 #include "mesh/ElementData.hpp"
29 
30 #include "MeshDiff.hpp"
31 
33 
34 namespace cf3 {
35 namespace mesh {
36 namespace actions {
37 
39 
41 
43 
44 namespace detail
45 {
46 
47 struct DoDiff
48 {
49  DoDiff(const Mesh& left, const Mesh& right, common::Action& differ, bool& mesh_equal) :
50  m_left(left),
51  m_right(right),
52  m_differ(differ),
53  m_mesh_equal(mesh_equal)
54  {
55  m_mesh_equal = true;
56  m_prefix = "rank " + common::to_str(common::PE::Comm::instance().rank()) + ": ";
57  }
58 
59  template<typename NumberT>
60  void operator()(const NumberT)
61  {
62  apply< common::List<NumberT> >();
63  apply< common::Table<NumberT> >();
64  }
65 
66  template<typename ArrayT>
67  void apply()
68  {
69  BOOST_FOREACH(const ArrayT& left_array, common::find_components_recursively<ArrayT>(m_left))
70  {
71  std::string relative_path = left_array.uri().path();
72  boost::replace_first(relative_path, m_left.uri().path() + "/", "");
74  if(is_null(right_array))
75  {
76  CFdebug << m_prefix << "Array " << relative_path << " was found in " << m_left.uri().path() << " but is missing in " << m_right.uri().path() << CFendl;
77  m_mesh_equal = false;
78  continue;
79  }
80 
81  m_differ.options().set("left", left_array.handle());
82  m_differ.options().set("right", right_array->handle());
83  m_differ.execute();
84  if(!m_differ.properties().value<bool>("arrays_equal"))
85  m_mesh_equal = false;
86  }
87 
88  BOOST_FOREACH(const ArrayT& right_array, common::find_components_recursively<ArrayT>(m_right))
89  {
90  std::string relative_path = right_array.uri().path();
91  boost::replace_first(relative_path, m_right.uri().path() + "/", "");
93  if(is_null(left_array))
94  {
95  CFdebug << m_prefix << "Array " << relative_path << " was missing in " << m_left.uri().path() << " but is present in " << m_right.uri().path() << CFendl;
96  m_mesh_equal = false;
97  }
98  }
99  }
100 
101  const Mesh& m_left;
102  const Mesh& m_right;
105  std::string m_prefix;
106 };
107 
108 }
109 
110 MeshDiff::MeshDiff(const std::string& name) : common::Action(name)
111 {
112  options().add("left", Handle<Mesh>())
113  .pretty_name("Left")
114  .description("Left mesh in the comparison")
115  .mark_basic();
116 
117  options().add("right", Handle<Mesh>())
118  .pretty_name("Right")
119  .description("Right mesh in the comparison")
120  .mark_basic();
121 
122  options().add("max_ulps", 10u)
123  .pretty_name("Max ULPs")
124  .description("Maximum distance allowed between floating point numbers")
125  .mark_basic();
126 
127  options().add("zero_threshold", 1e-16)
128  .pretty_name("Zero Threshold")
129  .description("Floating point numbers smaller than this are considered to be zero")
130  .mark_basic();
131 
132  properties().add("mesh_equal", false);
133 }
134 
136 {
137  Handle<Mesh> left = options().value< Handle<Mesh> >("left");
138  Handle<Mesh> right = options().value< Handle<Mesh> >("right");
139 
140  if(is_null(left))
141  throw common::SetupError(FromHere(), "Left mesh is not set in " + uri().path());
142 
143  if(is_null(right))
144  throw common::SetupError(FromHere(), "Right mesh is not set in " + uri().path());
145 
146  // Setup a differ for the arrays
147  Handle<common::Action> array_differ(get_child("ArrayDiff"));
148  if(is_null(array_differ))
149  array_differ = Handle<common::Action>(create_component("ArrayDiff", "cf3.common.ArrayDiff"));
150  array_differ->options().set("max_ulps", options().value<Uint>("max_ulps"));
151  array_differ->options().set("zero_threshold", options().value<Real>("zero_threshold"));
152 
153  // Compare all arrays and lists in the mesh
154  typedef boost::mpl::vector5<int, Uint, float, double, bool> allowed_types;
155  bool mesh_equal = true;
156  boost::mpl::for_each<allowed_types>(detail::DoDiff(*left, *right, *array_differ, mesh_equal));
157  properties().set("mesh_equal", mesh_equal);
158 }
159 
161 
162 
163 } // actions
164 } // mesh
165 } // cf3
std::string name(ComponentWrapper &self)
virtual void execute()
execute the action
Definition: MeshDiff.cpp:135
bool is_null(T ptr)
predicate for comparison to nullptr
Definition: CF.hpp:151
Safe pointer to an object. This is the supported method for referring to components.
Definition: Handle.hpp:39
Helper class to create the Builder and place it in the factory.
Definition: Builder.hpp:212
MeshDiff(const std::string &name)
Definition: MeshDiff.cpp:110
common::ComponentBuilder< MeshDiff, common::Action, mesh::actions::LibActions > MeshDiff_Builder
Definition: MeshDiff.cpp:40
std::string path() const
Definition: URI.cpp:253
URI uri() const
Construct the full path.
Definition: Component.cpp:248
DoDiff(const Mesh &left, const Mesh &right, common::Action &differ, bool &mesh_equal)
Definition: MeshDiff.cpp:49
PropertyList & add(const std::string &name, const boost::any &value)
adds a property to the list
#define CFendl
Definition: Log.hpp:109
Real e()
Definition of the Unit charge [C].
Definition: Consts.hpp:30
void operator()(const NumberT)
Definition: MeshDiff.cpp:60
Handle< Component > access_component(const URI &path) const
Definition: Component.cpp:487
Common_API std::string to_str(const T &v)
Converts to std::string.
PropertyList & properties()
Definition: Component.cpp:842
TYPE value(const std::string &pname) const
Handle< Component > get_child(const std::string &name)
Definition: Component.cpp:441
Top-level namespace for coolfluid.
Definition: Action.cpp:18
const TYPE value(const std::string &opt_name) const
Get the value of the option with given name.
Definition: OptionList.hpp:104
void set(const std::string &pname, const boost::any &val)
Component that executes an action. Implementation of the IAction interface as a component, exposing the execute function as a signal.
Definition: Action.hpp:21
virtual void execute()=0
execute the action
OptionList & options()
Definition: Component.cpp:856
SelectOptionType< T >::type & add(const std::string &name, const T &default_value=T())
Definition: OptionList.hpp:45
#define CFdebug
Definition: Log.hpp:107
static Comm & instance()
Return a reference to the current PE.
Definition: Comm.cpp:44
void set(const std::string &pname, const boost::any &val)
Definition: OptionList.cpp:132
Handle< Component > create_component(const std::string &name, const std::string &builder)
Build a (sub)component of this component using the extended type_name of the component.
Definition: Component.cpp:568
#define FromHere()
Send comments to:
COOLFluiD Web Admin