COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
ComputeCFL.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/array.hpp>
8 #include <boost/bind.hpp>
9 #include <boost/function.hpp>
10 
11 #include "common/Core.hpp"
13 #include "common/Foreach.hpp"
14 #include "common/Log.hpp"
15 #include "common/OptionList.hpp"
16 #include "common/PE/Comm.hpp"
17 #include "common/Signal.hpp"
18 #include "common/Builder.hpp"
19 #include "common/OptionT.hpp"
20 #include "common/EventHandler.hpp"
21 
22 #include "math/LSS/System.hpp"
23 
24 #include "mesh/Region.hpp"
26 #include "mesh/LagrangeP0/Quad.hpp"
27 #include "mesh/LagrangeP0/Line.hpp"
29 #include "mesh/LagrangeP0/Hexa.hpp"
32 
33 #include "ComputeCFL.hpp"
34 #include "AdjacentCellToFace.hpp"
35 #include "Tags.hpp"
36 
37 #include "solver/Time.hpp"
38 
41 #include "solver/Tags.hpp"
42 
43 namespace cf3
44 {
45 
46 namespace UFEM
47 {
48 
49 using namespace solver::actions::Proto;
50 
52 
53 ComputeCFL::ComputeCFL(const std::string& name) :
54  ProtoAction(name),
55  m_max_cfl(0.8),
56  m_dt(0.)
57 {
58  options().add("velocity_field_tag", "navier_stokes_u_solution")
59  .pretty_name("Velocity Field Tag")
60  .description("Tag for the field containing the velocity")
61  .attach_trigger(boost::bind(&ComputeCFL::trigger_variable, this));
62 
63  options().add("velocity_variable_name", "Velocity")
64  .pretty_name("Velocity Variable Name")
65  .description("Name of the velocity to use")
66  .attach_trigger(boost::bind(&ComputeCFL::trigger_variable, this));
67 
68  options().add("max_cfl", m_max_cfl)
69  .pretty_name("Max CFL")
70  .description("Maximum allowed CFL number")
71  .link_to(&m_max_cfl);
72 
73  options().add(solver::Tags::time(), m_time)
74  .pretty_name("Time")
75  .description("Time component for the simulation")
76  .link_to(&m_time);
77 
78  trigger_variable();
79 }
80 
81 ComputeCFL::~ComputeCFL()
82 {
83 }
84 
85 struct CFLOp
86 {
87  typedef void result_type;
88 
89  template<typename T>
90  struct ShapeType
91  {
92  typedef boost::mpl::int_<T::shape> type;
93  };
94 
95  template<Uint Dim>
97  {
98  typedef boost::mpl::void_ type;
99  };
100 
101  template<typename UT>
102  void operator()(const UT& u, Real& cfl_scale) const
103  {
104  typedef typename UT::EtypeT ElementT;
105  get_scale(typename ShapeType<ElementT>::type(), u, cfl_scale);
106  }
107 
108  template<typename UT, typename NodesT, unsigned long N>
109  Real max_edge_projection(const UT& u, const NodesT& nodes, const boost::array<int, N>& a_nodes, const boost::array<int, N>& b_nodes) const
110  {
111  Real result = 0.;
112  for(int i = 0; i != N; ++i)
113  {
114  const UT diff = nodes.row(a_nodes[i]) - nodes.row(b_nodes[i]);
115  const Real projection = fabs(u.dot(diff) / diff.squaredNorm());
116  result = projection > result ? projection : result;
117  }
118 
119  return result;
120  }
121 
122  template<typename UT>
123  void get_scale(boost::mpl::int_<cf3::mesh::GeoShape::TRIAG>, const UT& u, Real& cfl_scale) const
124  {
125  static const RealVector2 center(1./3., 1./3.);
126  const boost::array<int, 3> a_nodes = { 0, 1, 2 };
127  const boost::array<int, 3> b_nodes = { 1, 2, 0 };
128  cfl_scale = max_edge_projection(u.eval(center), u.support().nodes(), a_nodes, b_nodes);
129  }
130 
131  template<typename UT>
132  void get_scale(boost::mpl::int_<cf3::mesh::GeoShape::TETRA>, const UT& u, Real& cfl_scale) const
133  {
134  static const RealVector3 center(1./3., 1./3., 1./3.);
135  const boost::array<int, 6> a_nodes = { 0, 1, 2, 0, 1, 2 };
136  const boost::array<int, 6> b_nodes = { 1, 2, 0, 3, 3, 3 };
137  cfl_scale = max_edge_projection(u.eval(center), u.support().nodes(), a_nodes, b_nodes);
138  }
139 
140  template<typename UT>
141  void get_scale(boost::mpl::int_<cf3::mesh::GeoShape::PRISM>, const UT& u, Real& cfl_scale) const
142  {
143  static const RealVector3 center(1./3., 1./3., 0.);
144  const boost::array<int, 9> a_nodes = { 0, 1, 2, 3, 4, 5, 0, 1, 2 };
145  const boost::array<int, 9> b_nodes = { 1, 2, 0, 4, 5, 3, 3, 4, 5 };
146  cfl_scale = max_edge_projection(u.eval(center), u.support().nodes(), a_nodes, b_nodes);
147  }
148 
149  template<typename UT>
150  void get_scale(boost::mpl::int_<cf3::mesh::GeoShape::QUAD>, const UT& u, Real& cfl_scale) const
151  {
152  static const RealVector2 center(0., 0.);
153  const boost::array<int, 4> a_nodes = { 0, 1, 2, 3 };
154  const boost::array<int, 4> b_nodes = { 1, 2, 3, 0 };
155  cfl_scale = max_edge_projection(u.eval(center), u.support().nodes(), a_nodes, b_nodes);
156  }
157 
158  template<typename UT>
159  void get_scale(boost::mpl::int_<cf3::mesh::GeoShape::HEXA>, const UT& u, Real& cfl_scale) const
160  {
161  static const RealVector3 center(0., 0., 0.);
162  const boost::array<int, 12> a_nodes = { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 };
163  const boost::array<int, 12> b_nodes = { 1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7 };
164  cfl_scale = max_edge_projection(u.eval(center), u.support().nodes(), a_nodes, b_nodes);
165  }
166 
167  template<typename UT>
168  inline void get_scale(boost::mpl::void_, const UT& u, Real& cfl_scale) const
169  {
170  }
171 };
172 
174 
175 void ComputeCFL::trigger_variable()
176 {
177  using boost::proto::lit;
178 
179  const std::string tag = options().option("velocity_field_tag").value<std::string>();
180  const std::string var = options().option("velocity_variable_name").value<std::string>();
181 
182  FieldVariable<0, VectorField> u(var, tag);
184 
185  set_expression(elements_expression
186  (
187  boost::mpl::vector10<mesh::LagrangeP0::Triag, mesh::LagrangeP1::Triag2D, mesh::LagrangeP0::Quad, mesh::LagrangeP1::Quad2D, mesh::LagrangeP0::Hexa, mesh::LagrangeP1::Hexa3D, mesh::LagrangeP0::Tetra, mesh::LagrangeP1::Tetra3D, mesh::LagrangeP0::Prism, mesh::LagrangeP1::Prism3D>(),
188  group
189  (
190  compute_cfl(u, lit(m_cfl_scaling)),
191  cfl = lit(m_dt) * lit(m_cfl_scaling),
192  lit(m_max_computed_cfl) = _max(lit(m_max_computed_cfl), cfl)
193  )
194  ));
195 }
196 
197 void ComputeCFL::execute()
198 {
199  if(is_null(m_time))
200  throw common::SetupError(FromHere(), "No time component configured for ComputeCFL");
201 
202  m_dt = m_time->dt();
203 
204  m_max_computed_cfl = 0.;
205  ProtoAction::execute();
206 
207  Real global_max_cfl = m_max_computed_cfl;
208  if(common::PE::Comm::instance().is_active())
209  {
210  common::PE::Comm::instance().all_reduce(common::PE::max(), &m_max_computed_cfl, 1, &global_max_cfl);
211  }
212 
213  CFinfo << "CFL for time step " << m_dt << " is " << global_max_cfl << CFendl;
214 }
215 
216 
217 
218 } // namespace UFEM
219 
220 } // namespace cf3
boost::proto::terminal< SFOp< ShapeFunctionOp > >::type const N
static solver::actions::Proto::MakeSFOp< CFLOp >::type const compute_cfl
Definition: ComputeCFL.cpp:173
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
#define CFinfo
these are always defined
Definition: Log.hpp:104
std::string name(ComponentWrapper &self)
void get_scale(boost::mpl::int_< cf3::mesh::GeoShape::TRIAG >, const UT &u, Real &cfl_scale) const
Definition: ComputeCFL.cpp:123
bool is_null(T ptr)
predicate for comparison to nullptr
Definition: CF.hpp:151
void get_scale(boost::mpl::int_< cf3::mesh::GeoShape::PRISM >, const UT &u, Real &cfl_scale) const
Definition: ComputeCFL.cpp:141
Helper class to create the Builder and place it in the factory.
Definition: Builder.hpp:212
common::ComponentBuilder< ComputeCFL, common::Action, LibUFEM > ComputeCFL_Builder
Definition: ComputeCFL.cpp:51
This header collects all the headers needed for the linear system solver, also including configure-ti...
Class to encapsulate Proto actions.
Definition: ProtoAction.hpp:26
boost::shared_ptr< ElementsExpression< ExprT, ElementTypes > > elements_expression(ElementTypes, const ExprT &expr)
Definition: Expression.hpp:292
Dim
Enumeration of the dimensions.
Definition: Defs.hpp:15
void get_scale(boost::mpl::void_, const UT &u, Real &cfl_scale) const
Definition: ComputeCFL.cpp:168
#define CFendl
Definition: Log.hpp:109
Real max(const Real a, const Real b)
Maximum between two scalars.
Definition: Terminals.hpp:228
boost::proto::terminal< SFOp< NodesOp > >::type const nodes
boost::proto::terminal< SFOp< CustomSFOp< OpT > > >::type type
boost::mpl::int_< T::shape > type
Definition: ComputeCFL.cpp:92
void get_scale(boost::mpl::int_< cf3::mesh::GeoShape::HEXA >, const UT &u, Real &cfl_scale) const
Definition: ComputeCFL.cpp:159
bool diff(const mesh::Mesh &a, const mesh::Mesh &b, const Uint max_ulps)
Calculates the difference between two meshes.
Definition: MeshDiff.cpp:128
Top-level namespace for coolfluid.
Definition: Action.cpp:18
void get_scale(boost::mpl::int_< cf3::mesh::GeoShape::QUAD >, const UT &u, Real &cfl_scale) const
Definition: ComputeCFL.cpp:150
static std::string library_namespace()
void operator()(const UT &u, Real &cfl_scale) const
Definition: ComputeCFL.cpp:102
static boost::proto::terminal< ExpressionGroupTag >::type group
Use group(expr1, expr2, ..., exprN) to evaluate a group of expressions.
Eigen::Matrix< Real, 2, 1 > RealVector2
Fixed size 2x1 column vector.
Definition: MatrixTypes.hpp:40
static boost::proto::terminal< double(*)(double, double) >::type const _max
Definition: Terminals.hpp:246
Dummy shape function type used for element-based fields.
Definition: Terminals.hpp:42
Real max_edge_projection(const UT &u, const NodesT &nodes, const boost::array< int, N > &a_nodes, const boost::array< int, N > &b_nodes) const
Definition: ComputeCFL.cpp:109
static Comm & instance()
Return a reference to the current PE.
Definition: Comm.cpp:44
ComputeCFL(const std::string &name)
Contructor.
Definition: ComputeCFL.cpp:36
Eigen::Matrix< Real, 3, 1 > RealVector3
Fixed size 3x1 column vector.
Definition: MatrixTypes.hpp:41
void get_scale(boost::mpl::int_< cf3::mesh::GeoShape::TETRA >, const UT &u, Real &cfl_scale) const
Definition: ComputeCFL.cpp:132
#define FromHere()
Send comments to:
COOLFluiD Web Admin