COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
SurfaceIntegral.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2011 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/bind.hpp>
8 #include <boost/function.hpp>
9 
10 #include "common/Core.hpp"
12 #include "common/Foreach.hpp"
13 #include "common/Log.hpp"
14 #include "common/OptionList.hpp"
15 #include "common/Signal.hpp"
16 #include "common/Builder.hpp"
17 #include "common/OptionT.hpp"
18 #include "common/EventHandler.hpp"
20 
21 #include "math/LSS/System.hpp"
22 
23 #include "mesh/Region.hpp"
26 #include "mesh/LagrangeP0/Line.hpp"
27 #include "mesh/LagrangeP0/Quad.hpp"
29 
30 #include "SurfaceIntegral.hpp"
31 #include "AdjacentCellToFace.hpp"
32 #include "Tags.hpp"
33 
36 
37 namespace cf3
38 {
39 
40 namespace UFEM
41 {
42 
43 using namespace solver::actions::Proto;
44 
46 
48  ProtoAction(name),
49  m_changing_result(false)
50 {
51  options().add("history",m_history)
52  .pretty_name("History")
53  .description("History component used to log the history of the integral value.")
54  .link_to(&m_history)
55  .mark_basic();
56 
57  regist_signal ( "set_field" )
58  .connect( boost::bind ( &SurfaceIntegral::signal_set_field, this, _1 ) )
59  .description( "Set up the model using a specific solver" )
60  .pretty_name( "Setup" )
61  .signature( boost::bind ( &SurfaceIntegral::signature_set_field, this, _1 ) );
62 }
63 
65 {
66 }
67 
68 void SurfaceIntegral::set_field(const std::string& variable_name, const std::string& tag)
69 {
70  using boost::proto::lit;
71 
72  const Uint dim = physical_model().ndim();
73  if(options().check("result"))
74  options().erase("result");
75 
76  typedef boost::mpl::vector6<mesh::LagrangeP1::Line2D, mesh::LagrangeP1::Quad3D, mesh::LagrangeP1::Triag3D, mesh::LagrangeP0::Line, mesh::LagrangeP0::Quad, mesh::LagrangeP0::Triag> element_types;
77 
78  // Indicate is an element is a owned by the current process
79  FieldVariable<1, ScalarField> local("is_local_element", "surface_integrator", mesh::LagrangeP0::LibLagrangeP0::library_namespace());
80 
81  math::VariablesDescriptor& descriptor = common::find_component_with_tag<math::VariablesDescriptor>(physical_model().variable_manager(), tag);
83  {
84  if(dim == 1)
85  options().add("result", 0.).pretty_name("Result").description("Result of the last integral computation").mark_basic().attach_trigger(boost::bind(&SurfaceIntegral::trigger_result, this));
86  else
87  options().add("result", std::vector<Real>(dim)).pretty_name("Result").description("Result of the last integral computation").mark_basic().attach_trigger(boost::bind(&SurfaceIntegral::trigger_result, this));
88 
89  FieldVariable<0, ScalarField> s(variable_name, tag);
90 
91  m_integral_value.resize(dim);
92  m_integral_value.setZero();
93 
94  set_expression(elements_expression(element_types(),
95  lit(m_integral_value) += local*integral<1>(s * normal)));
96  }
97  else if(descriptor.dimensionality(variable_name) == math::VariablesDescriptor::Dimensionalities::VECTOR)
98  {
99  m_integral_value.resize(1);
100  m_integral_value.setZero();
101  options().add("result", 0.).pretty_name("Result").description("Result of the last integral computation").mark_basic().attach_trigger(boost::bind(&SurfaceIntegral::trigger_result, this));
102 
103  FieldVariable<0, VectorField> v(variable_name, tag);
104 
105  set_expression(elements_expression(element_types(),
106  lit(m_integral_value) += local*integral<1>(v * normal)));
107  }
108  else
109  {
110  throw common::SetupError(FromHere(), "Variable type " + math::VariablesDescriptor::Dimensionalities::Convert::instance().to_str(descriptor.dimensionality(variable_name)) + " for variable " + variable_name + " is neither SCALAR nor VECTOR");
111  }
112 }
113 
115 {
117  set_field(options.value<std::string>("variable_name"), options.value<std::string>("field_tag"));
118 }
119 
121 {
123 
124  options.add("variable_name", "SomeScalar")
125  .pretty_name("Variable Name")
126  .description("Name of the variable to use");
127 
128  options.add("field_tag", "SomeFieldTag")
129  .pretty_name("Field Tag")
130  .description("Tag for the field to use");
131 }
132 
133 
135 {
136  m_integral_value.setZero();
137  if(m_loop_regions.empty())
138  {
139  CFwarn << "SurfaceIntegral has no regions" << CFendl;
140  return;
141  }
142 
143  mesh::Mesh& mesh = common::find_parent_component<mesh::Mesh>(*m_loop_regions.front());
144 
145  const std::string elems_name = "cf3.mesh.LagrangeP0";
146  Handle<mesh::Dictionary> elems_P0_handle(mesh.get_child(elems_name));
147  mesh::Dictionary& elems_P0 = is_null(elems_P0_handle) ? mesh.create_discontinuous_space(elems_name,"cf3.mesh.LagrangeP0") : *elems_P0_handle;
148  if(!elems_P0.has_tag("ufem_dict"))
149  elems_P0.add_tag("ufem_dict");
150 
151  Handle<mesh::Field> is_local_element(elems_P0.get_child("surface_integrator"));
152  if(is_null(is_local_element))
153  {
154  is_local_element = elems_P0.create_field("surface_integrator", "is_local_element").handle<mesh::Field>();
155  is_local_element->add_tag("surface_integrator");
156  }
157  if(!is_local_element->has_tag("local_element_initialized"))
158  {
159  const Uint nb_elems = is_local_element->size();
160  for(Uint i = 0; i != nb_elems; ++i)
161  {
162  is_local_element->array()[i][0] = !elems_P0.is_ghost(i);
163  }
164  }
165 
167 
168  const Uint dim = m_integral_value.size();
169 
170  std::vector<Real> local_v(dim);
171  for(Uint i = 0; i != dim; ++i)
172  local_v[i] = m_integral_value[i];
173  std::vector<Real> global_v(local_v.begin(), local_v.end());
174 
176  {
177  common::PE::Comm::instance().all_reduce(common::PE::plus(), local_v, global_v);
178  }
179 
180  m_changing_result = true;
181  if(dim == 1)
182  options().set("result", global_v[0]);
183  else
184  options().set("result", global_v);
185  m_changing_result = false;
186 
188  {
189  m_history->set(m_variable_name, global_v);
190  m_history->save_entry();
191  }
192 }
193 
195 {
196  if(!m_changing_result)
197  throw common::BadValue(FromHere(), "Option result was changed, but this is not allowed!");
198 }
199 
200 } // namespace UFEM
201 
202 } // namespace cf3
T * all_reduce(const Op &op, const T *in_values, const int in_n, T *out_values, const int stride=1)
Definition: Comm.hpp:282
Abstracts the use of XML when adding options to a signal frame.
std::string name(ComponentWrapper &self)
boost::proto::terminal< SFOp< NormalOp > >::type const normal
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
Dictionary & create_discontinuous_space(const std::string &space_name, const std::string &space_lib_name, const std::vector< Handle< Entities > > &entities)
Definition: Mesh.cpp:316
Helper class to create the Builder and place it in the factory.
Definition: Builder.hpp:212
void set_expression(const boost::shared_ptr< Expression > &expression)
void erase(const std::string &name)
Definition: OptionList.cpp:78
This header collects all the headers needed for the linear system solver, also including configure-ti...
Signal & description(const std::string &desc)
sets the description of this signal
Definition: Signal.cpp:42
Class to encapsulate Proto actions.
Definition: ProtoAction.hpp:26
Signal & connect(const Signal::slot_type &subscriber)
connects to a subscribing slot
Definition: Signal.cpp:92
Definition: check.py:1
boost::shared_ptr< ElementsExpression< ExprT, ElementTypes > > elements_expression(ElementTypes, const ExprT &expr)
Definition: Expression.hpp:292
#define CFendl
Definition: Log.hpp:109
Dimensionalities::Type dimensionality(const std::string &name) const
Common_API std::string to_str(const T &v)
Converts to std::string.
void signal_set_field(common::SignalArgs &args)
common::ComponentBuilder< SurfaceIntegral, common::Action, LibUFEM > SurfaceIntegral_Builder
Manages a set of maps.
Definition: SignalFrame.hpp:31
Signal & pretty_name(const std::string &name)
sets the pretty name of this signal
Definition: Signal.cpp:48
SurfaceIntegral(const std::string &name)
void set_field(const std::string &variable_name, const std::string &tag)
Set up the field to use. This builds either a vector or a scalar expression, depending on the variabl...
void signature_set_field(common::SignalArgs &args)
bool is_active() const
Definition: Comm.hpp:83
Signal & signature(const Signal::slot_type &subscriber)
connects to a subscribing signature
Definition: Signal.cpp:107
void trigger_result()
Trigger on a change of the result.
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
#define CFwarn
Definition: Log.hpp:106
virtual void execute()
execute the action
void add_tag(const std::string &tag)
static Convert & instance()
get the unique instance of the converter class
std::string m_variable_name
Name of the variable to use.
static std::string library_namespace()
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
Handle< solver::History > m_history
RealVector m_integral_value
Storage for the value of the surface integral.
Signal & regist_signal(const SignalID &sname)
Regist signal.
OptionList & options()
Definition: Component.cpp:856
SelectOptionType< T >::type & add(const std::string &name, const T &default_value=T())
Definition: OptionList.hpp:45
static Comm & instance()
Return a reference to the current PE.
Definition: Comm.cpp:44
virtual void execute()
execute the action
void set(const std::string &pname, const boost::any &val)
Definition: OptionList.cpp:132
bool is_not_null(T ptr)
predicate for comparison to nullptr
Definition: CF.hpp:147
#define FromHere()
Send comments to:
COOLFluiD Web Admin