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-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 <set>
8 
9 #include "common/Builder.hpp"
11 #include "common/OptionList.hpp"
12 #include "common/PropertyList.hpp"
13 #include "common/Signal.hpp"
14 #include "common/PE/Comm.hpp"
15 
16 #include "math/MatrixTypes.hpp"
17 
18 #include "mesh/Mesh.hpp"
19 #include "mesh/Region.hpp"
20 #include "mesh/Space.hpp"
21 #include "mesh/Field.hpp"
22 #include "mesh/ShapeFunction.hpp"
23 #include "mesh/ElementType.hpp"
24 #include "mesh/Entities.hpp"
25 #include "mesh/Quadrature.hpp"
26 #include "mesh/Connectivity.hpp"
27 
29 
31 
32 namespace cf3 {
33 namespace mesh {
34 namespace actions {
35 
36 using namespace common;
37 using namespace common::PE;
38 
40 
42 
44 
46 : Action(name)
47 {
48 
49  properties()["brief"] = std::string("Compute surface-integral of field");
50  std::string desc;
51  desc =
52  "Compute surface integral of a field, given surface regions";
53  properties()["description"] = desc;
54 
55  m_order = 2.;
56  options().add("order", m_order)
57  .description("order of integration")
58  .pretty_name("Order")
59  .mark_basic()
60  .link_to(&m_order);
61 
62  options().add("field", m_field)
63  .description("Field to integrate")
64  .pretty_name("Field")
65  .mark_basic()
66  .link_to(&m_field);
67 
68  options().add("regions", m_regions)
69  .description("Regions to integrate")
70  .pretty_name("Regions")
71  .mark_basic()
72  .link_to(&m_regions);
73 
74  regist_signal ( "integrate" )
75  .description( "SurfaceIntegral" )
76  .pretty_name("SurfaceIntegral" )
77  .connect ( boost::bind ( &SurfaceIntegral::signal_integrate, this, _1 ) )
78  .signature ( boost::bind ( &SurfaceIntegral::signature_integrate, this, _1 ) );
79 
80 }
81 
83 
85 {
86  if (is_null(m_field))
87  throw SetupError(FromHere(),uri().string()+": field not configured");
88 
89  if (m_regions.empty())
90  throw SetupError(FromHere(),uri().string()+": regions not configured");
91 
93 }
94 
96 
97 Real SurfaceIntegral::integrate(const Field& field, const std::vector< Handle<Region> >& regions)
98 {
99  // Create a set, so that we have no duplicate entities
100  std::set< Handle<Entities> > entities_set;
101  boost_foreach( const Handle<Region>& region, regions)
102  {
103  boost_foreach( Entities& patch, find_components_recursively<Entities>(*region) )
104  {
105  // only surface elements are added
106  if( patch.element_type().dimensionality() == patch.element_type().dimension()-1 )
107  entities_set.insert(patch.handle<Entities>());
108  }
109  }
110 
111  // Transform the set to a vector
112  std::vector< Handle<Entities> > entities; entities.reserve(entities_set.size());
113  boost_foreach( const Handle<Entities>& patch, entities_set)
114  {
115  entities.push_back(patch);
116  }
117  return integrate(field, entities);
118 }
119 
120 Real SurfaceIntegral::integrate(const Field& field, const std::vector< Handle<Entities> >& entities)
121 {
122  Real local_integral = 0.;
123  boost_foreach( const Handle<Entities>& patch, entities )
124  {
125  if( patch->element_type().dimensionality() >= patch->element_type().dimension() )
126  throw SetupError( FromHere(), "Cannot compute surface integral of volume element");
127 
129  remove_component("quadrature");
130  m_quadrature = create_component<Quadrature>("quadrature",
131  "cf3.mesh.gausslegendre."+GeoShape::Convert::instance().to_str(patch->element_type().shape())+"P"+common::to_str(m_order));
132 
134  const Space& space = field.space(*patch);
135  const Uint nb_elems = space.size();
136  const Uint nb_nodes_per_elem = space.shape_function().nb_nodes();
137  const Uint nb_qdr_pts = m_quadrature->nb_nodes();
138  const Uint nb_vars = field.row_size();
139 
140  RealMatrix qdr_pt_values( nb_qdr_pts, nb_vars );
141  RealMatrix interpolate( nb_qdr_pts, nb_nodes_per_elem );
142  RealMatrix field_pt_values( nb_nodes_per_elem, nb_vars );
143  RealMatrix elem_coords;
144 
145  patch->geometry_space().allocate_coordinates(elem_coords);
146 
147  for( Uint qn=0; qn<nb_qdr_pts; ++qn)
148  {
149  interpolate.row(qn) = space.shape_function().value( m_quadrature->local_coordinates().row(qn) );
150  }
151 
153  for (Uint e=0; e<nb_elems; ++e)
154  {
155  if( ! patch->is_ghost(e) )
156  {
157  patch->geometry_space().put_coordinates(elem_coords,e);
158 
159  // interpolate
160  for (Uint n=0; n<nb_nodes_per_elem; ++n)
161  {
162  const Uint p = space.connectivity()[e][n];
163  for (Uint v=0; v<nb_vars; ++v)
164  {
165  field_pt_values(n,v) = field[p][v];
166  }
167  }
168  qdr_pt_values = interpolate * field_pt_values;
169 
170  // integrate
171  for( Uint qn=0; qn<nb_qdr_pts; ++qn)
172  {
173  const Real Jdet = patch->element_type().jacobian_determinant( m_quadrature->local_coordinates().row(qn), elem_coords );
174  local_integral += Jdet * m_quadrature->weights()[qn] * qdr_pt_values(qn,0);
175  }
176  }
177  }
178  }
179  Real global_integral;
180  PE::Comm::instance().all_reduce(PE::plus(), &local_integral, 1, &global_integral);
181  return global_integral;
182 }
183 
185 
187 {
189 
190  Field& field = *options.value< Handle<Field> >("field");
191  std::vector< Handle<Region> > regions = options.value< std::vector<Handle<Region> > >("regions");
192 
193  Real integral = integrate(field,regions);
194 
195  SignalFrame reply = node.create_reply(uri());
196  SignalOptions reply_options(reply);
197  reply_options.add("return_value", integral);
198 }
199 
201 
203 {
205 
206  options.add("field", Handle<Field>() )
207  .description("Field to integrate");
208 
209  options.add("regions",std::vector< Handle<Region> >())
210  .description("Regions to integrate");
211 }
212 
214 
215 } // actions
216 } // mesh
217 } // cf3
Abstracts the use of XML when adding options to a signal frame.
std::string name(ComponentWrapper &self)
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
std::vector< Handle< Region > > m_regions
void signature_integrate(common::SignalArgs &node)
Helper class to create the Builder and place it in the factory.
Definition: Builder.hpp:212
Signal & description(const std::string &desc)
sets the description of this signal
Definition: Signal.cpp:42
Real integrate(const Field &field, const std::vector< Handle< Region > > &regions)
common::ComponentBuilder< SurfaceIntegral, Action, mesh::actions::LibActions > SurfaceIntegral_Builder
Signal & connect(const Signal::slot_type &subscriber)
connects to a subscribing slot
Definition: Signal.cpp:92
ElementType & element_type() const
return the elementType
Definition: Entities.cpp:116
URI uri() const
Construct the full path.
Definition: Component.cpp:248
#define boost_foreach
lowercase version of BOOST_FOREACH
Definition: Foreach.hpp:16
Real e()
Definition of the Unit charge [C].
Definition: Consts.hpp:30
SignalFrame create_reply(const URI &sender=URI())
Common_API std::string to_str(const T &v)
Converts to std::string.
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > RealMatrix
Dynamic sized matrix of Real scalars.
Definition: MatrixTypes.hpp:22
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
Uint dimensionality() const
Definition: ElementType.hpp:79
static Convert & instance()
get the unique instance of the converter class
Definition: GeoShape.cpp:20
PropertyList & properties()
Definition: Component.cpp:842
Signal & signature(const Signal::slot_type &subscriber)
connects to a subscribing signature
Definition: Signal.cpp:107
const Handle< Space const > & space(const Handle< Entities const > &entities) const
Definition: Field.cpp:248
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 signal_integrate(common::SignalArgs &node)
Uint row_size(Uint i=0) const
Definition: Table.hpp:133
SurfaceIntegral(const std::string &name)
constructor
LoadBalance::LoadBalance(const std::string &name) std::string desc
Definition: LoadBalance.cpp:35
Component that executes an action. Implementation of the IAction interface as a component, exposing the execute function as a signal.
Definition: Action.hpp:21
boost::shared_ptr< Component > remove_component(const std::string &name)
Remove a (sub)component of this component.
Definition: Component.cpp:357
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
virtual void execute()
execute the action
Handle< Component > handle()
Get a handle to the component.
Definition: Component.hpp:179
std::string to_str(const EnumType &in)
conversion from enum to string
Definition: EnumT.hpp:47
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
Space component class.
Definition: Space.hpp:59
std::string string() const
Definition: URI.cpp:258
Uint dimension() const
Definition: ElementType.hpp:82
bool is_not_null(T ptr)
predicate for comparison to nullptr
Definition: CF.hpp:147
boost::proto::result_of::make_expr< boost::proto::tag::function, IntegralTag< boost::mpl::int_< Order > >, ExprT const & >::type const integral(ExprT const &expr)
#define FromHere()
Send comments to:
COOLFluiD Web Admin