7 #include <boost/algorithm/string.hpp>
44 using namespace common;
48 using namespace solver::actions;
49 using namespace solver::actions::Proto;
62 timeloop = parent.
create_component(
"TimeLoop",
"cf3.solver.actions.Iterate");
63 timeloop->create_component(
"CriterionTime",
"cf3.solver.CriterionTime");
64 timeloop->create_component(
"AdvanceTime",
"cf3.solver.actions.AdvanceTime");
65 timeloop->mark_basic();
74 m_need_field_creation(true)
76 regist_signal(
"add_direct_solver" )
77 .connect( boost::bind( &Solver::signal_add_direct_solver,
this, _1 ) )
78 .description(
"Create a solver needing only one LSS solve")
79 .pretty_name(
"Create Direct Solver")
80 .signature( boost::bind ( &Solver::signature_add_solver,
this, _1) );
82 regist_signal(
"add_unsteady_solver" )
83 .connect( boost::bind( &Solver::signal_add_unsteady_solver,
this, _1 ) )
84 .description(
"Create an unsteady solver, solving a linear system once every time step")
85 .pretty_name(
"Create Unsteady Solver")
86 .signature( boost::bind ( &Solver::signature_add_solver,
this, _1) );
88 regist_signal(
"add_unsteady_advance_solver" )
89 .connect( boost::bind( &Solver::signal_add_unsteady_solver,
this, _1 ) )
90 .description(
"Create an unsteady solver, solving a linear system once for several time steps")
91 .pretty_name(
"Create Advance Unsteady Solver")
92 .signature( boost::bind ( &Solver::signature_add_solver,
this, _1) );
94 regist_signal(
"add_iteration_solver" )
95 .connect( boost::bind( &Solver::signal_add_iteration_solver,
this, _1 ) )
96 .description(
"Create an iteration solver, solving a linear system more than once every time step")
97 .pretty_name(
"Create iteration Solver")
98 .signature( boost::bind ( &Solver::signature_add_solver,
this, _1) );
100 regist_signal(
"add_restart_writer" )
101 .connect( boost::bind( &Solver::signal_add_restart_writer,
this, _1 ) )
102 .description(
"Create a component that writes restart information for all solvers added up to now.")
103 .pretty_name(
"Add restart writer");
105 regist_signal(
"create_initial_conditions" )
106 .connect( boost::bind( &Solver::signal_create_initial_conditions,
this, _1 ) )
107 .description(
"Create initial conditions.")
108 .pretty_name(
"Create Initial Conditions");
110 regist_signal(
"create_fields" )
111 .connect( boost::bind( &Solver::signal_create_fields,
this, _1 ) )
112 .description(
"Create the fields required for the solver.")
113 .pretty_name(
"Create Fields");
115 regist_signal(
"add_probe" )
116 .connect( boost::bind( &Solver::signal_add_probe,
this, _1 ) )
117 .description(
"Add a probe to log data")
118 .pretty_name(
"Add Probe")
119 .signature( boost::bind ( &Solver::signature_add_probe,
this, _1) );
130 if(
is_null(m_initial_conditions))
132 create_initial_conditions();
135 return add_solver(builder_name, *
this);
140 if(
is_null(m_initial_conditions))
142 create_initial_conditions();
146 std::vector< boost::shared_ptr<Component> > removed_components;
147 BOOST_FOREACH(
Component& comp, *timeloop)
149 if(comp.
name() ==
"AdvanceTime" || !removed_components.empty())
150 removed_components.push_back(timeloop->remove_component(comp.
name()));
157 BOOST_FOREACH(
const boost::shared_ptr<Component> comp, removed_components)
159 timeloop->add_component(comp);
167 if(
is_null(m_initial_conditions))
169 create_initial_conditions();
176 timeloop->mark_basic();
177 timeloop->create_component(
"CriterionTime",
"cf3.solver.CriterionTime");
178 timeloop->create_component(
"SelfIteration",
"cf3.solver.actions.Iterate")->mark_basic();
182 timeloop->remove_component(
"AdvanceTime");
190 timeloop->create_component(
"AdvanceTime",
"cf3.solver.actions.AdvanceTime");
197 if(
is_null(m_initial_conditions))
199 create_initial_conditions();
206 timeloop->mark_basic();
207 timeloop->create_component(
"CriterionTime",
"cf3.solver.CriterionTime");
208 timeloop->create_component(
"CouplingIteration",
"cf3.solver.actions.Iterate")->mark_basic();
209 timeloop->create_component(
"AdvanceTime",
"cf3.solver.actions.AdvanceTime");
215 boost::shared_ptr<Component>
advance_time = timeloop->remove_component(
"AdvanceTime");
216 coupling = timeloop->create_component(
"CouplingIteration",
"cf3.solver.actions.Iterate");
217 coupling->mark_basic();
218 timeloop->add_component(advance_time);
229 std::vector<std::string> field_tags;
230 BOOST_FOREACH(
const common::Action& action, common::find_components_recursively<common::Action>(*
this))
234 const std::vector<std::string> restart_field_tags = action.
properties().
value< std::vector<std::string> >(
"restart_field_tags");
235 field_tags.insert(field_tags.end(), restart_field_tags.begin(), restart_field_tags.end());
240 writer->options().set(
"field_tags", field_tags);
241 if(!m_need_field_creation)
242 writer->options().set(
"mesh", m_mesh);
252 CFwarn <<
"InitialConditions were created already, returning handle to previously created component" <<
CFendl;
253 return m_initial_conditions;
256 m_initial_conditions = create_component<InitialConditions>(
"InitialConditions");
258 m_initial_conditions->configure_option_recursively(solver::Tags::physical_model(),
m_physics);
260 m_initial_conditions->mark_basic();
262 return m_initial_conditions;
268 options.
add(
"builder_name",
"")
269 .pretty_name(
"Builder Names")
270 .description(
"List the names of the builders that should be used to construct inner actions");
280 reply_options.
add(
"created_component", result->uri());
290 reply_options.
add(
"created_component", result->uri());
293 void Solver::signal_add_unsteady_advance_solver(
SignalArgs& args)
300 reply_options.
add(
"created_component", result->uri());
310 reply_options.
add(
"created_component", result->uri());
320 reply_options.
add(
"created_component", result->uri());
324 void Solver::signal_create_initial_conditions(
SignalArgs& args)
330 reply_options.
add(
"created_component", ic->uri());
348 m_need_field_creation =
true;
354 CFdebug <<
"UFEM::Solver: Reacting to ufem_variables_added event" <<
CFendl;
355 m_need_field_creation =
true;
358 void Solver::create_fields()
360 if(!m_need_field_creation)
367 BOOST_FOREACH(
Dictionary& dict, find_components_recursively<Dictionary>(*m_mesh))
376 std::map<std::string, std::string> tags;
377 BOOST_FOREACH(
const ProtoAction& action, find_components_recursively<ProtoAction>(*
this))
384 for(std::map<std::string, std::string>::const_iterator it = tags.begin(); it != tags.end(); ++it)
386 const std::string& tag = it->first;
387 const std::string& space_lib_name = it->second;
391 if(space_lib_name ==
"geometry")
397 BOOST_FOREACH(
Dictionary& tagged_dict, find_components_recursively_with_tag<Dictionary>(
mesh(),
"ufem_dict"))
399 if(tagged_dict.
spaces().empty())
401 CFwarn <<
"Found empty dict while looking for dictionaries with tag ufem_dict" <<
CFendl;
404 const std::string sf_name = tagged_dict.
spaces().front()->shape_function().derived_type_name();
405 if(boost::algorithm::starts_with(sf_name, space_lib_name))
424 if(boost::ends_with(space_lib_name,
"P0"))
426 dict =
mesh().create_discontinuous_space(space_lib_name, space_lib_name).handle<
Dictionary>();
430 dict =
mesh().create_continuous_space(space_lib_name, space_lib_name).handle<
Dictionary>();
432 dict->add_tag(
"ufem_dict");
433 CFinfo <<
"Created ufem_dict " << dict->uri().path() <<
CFendl;
439 if(!dict->has_tag(tag))
442 Handle< Field > field = find_component_ptr_with_tag<Field>(*dict, tag);
446 field = find_component_ptr_with_tag<Field>(*dict, tag);
452 CFdebug <<
"parallelizing field " << field->uri().path() <<
CFendl;
453 field->parallelize_with(dict->comm_pattern());
462 m_need_field_creation =
false;
467 std::vector<std::string> builder_parts;
468 boost::split(builder_parts, builder_name, boost::is_any_of(
"."));
475 result->configure_option_recursively(solver::Tags::physical_model(),
m_physics);
477 result->configure_option_recursively(
"initial_conditions", m_initial_conditions);
487 probe->options().set(
"dict",
mesh().geometry_fields().handle<Dictionary>());
491 probe->options().set(
"dict", dict);
497 hist->options().set(
"dimension",1u);
500 pp->options().set(
"history", hist);
509 if(options.
check(
"dict"))
512 const std::string name = options.
option(
"name").
value<std::string>();
522 reply_options.
add(
"created_component", probe->uri());
528 options.
add(
"name",
"SomeProbe").pretty_name(
"Name").description(
"Name of the probe to add").mark_basic();
529 options.
add(
"parent",
Handle<Component>()).pretty_name(
"Parent").description(
"Component that will be the parent of the probe").mark_basic();
530 options.
add(
"dict",
Handle<Component>()).pretty_name(
"Dictionary").description(
"Dictionary to use for the fields");
541 Uint nb_owned_nodes = 0;
542 Uint nb_ghost_nodes = 0;
543 BOOST_FOREACH(
const Uint rank,
mesh().geometry_fields().rank().array())
545 if(rank == comm.
rank())
551 std::vector<Uint> owned_recv;
552 std::vector<Uint> ghost_recv;
558 const Uint total_nb_owned = std::accumulate(owned_recv.begin(),owned_recv.end(),0);
560 Uint min_nb_nodes = nb_owned_nodes;
561 Uint max_nb_nodes = 0;
562 for(
Uint i = 0; i != comm.
size(); ++i)
564 min_nb_nodes = owned_recv[i] < min_nb_nodes ? owned_recv[i] : min_nb_nodes;
565 max_nb_nodes = owned_recv[i] > max_nb_nodes ? owned_recv[i] : max_nb_nodes;
566 CFinfo <<
" rank " << i <<
": " << owned_recv[i] <<
" nodes (" <<
static_cast<Real
>(owned_recv[i]) / static_cast<Real>(total_nb_owned)*100. <<
"%) with " << ghost_recv[i] <<
" ghosts" <<
CFendl;
568 CFinfo <<
" maximum: " << max_nb_nodes <<
"(" <<
static_cast<Real
>(max_nb_nodes) / static_cast<Real>(total_nb_owned)*100. <<
"%), minimum: " << min_nb_nodes <<
"(" <<
static_cast<Real
>(min_nb_nodes) / static_cast<Real>(total_nb_owned)*100. <<
"%)" <<
CFendl;
573 CFinfo <<
"Running the solver over a mesh with " <<
mesh().geometry_fields().size() <<
" nodes." <<
CFendl;
Probe to interpolate field values to a given coordinate.
#define CFinfo
these are always defined
Handle< Component > timeloop(Component &parent)
Get the timeloop, creating it if needed.
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
Safe pointer to an object. This is the supported method for referring to components.
Helper class to create the Builder and place it in the factory.
This header collects all the headers needed for the linear system solver, also including configure-ti...
Class to encapsulate Proto actions.
mesh::FieldManager & field_manager()
Access to the FieldManager, which is a static subcomponent of Solver.
Stores History of variables.
Handle< physics::PhysModel > m_physics
Raw access to the physics.
URI uri() const
Construct the full path.
const std::string & name() const
Access the name of the component.
void insert_field_info(std::map< std::string, std::string > &tags) const
Append the tags used in the expression.
Uint rank() const
Return rank, additionally, if is_init==0.
SignalFrame create_reply(const URI &sender=URI())
const std::vector< Handle< Space > > & spaces() const
Uint size() const
Return the number of processes, or 1 if is_init==0.
bool check(const std::string &prop_name) const
common::ComponentBuilder< UFEM::Solver, solver::Solver, LibUFEM > UFEMSolver_Builder
PropertyList & properties()
Handle< Component > parent() const
TYPE value(const std::string &pname) const
Signal * connect_to_event(const std::string &sname, PTYPE *ptr, FTYPE pfunc)
Regists a signal on this EventHandler.
Handle< Component > get_child(const std::string &name)
Top-level namespace for coolfluid.
Solver(const std::string &name)
Component that executes an action. Implementation of the IAction interface as a component, exposing the execute function as a signal.
common::EventHandler & event_handler() const
boost::shared_ptr< Component > remove_component(const std::string &name)
Remove a (sub)component of this component.
unsigned int Uint
typedef for unsigned int
bool check(const std::string &opt_name) const
virtual void mesh_loaded(mesh::Mesh &mesh)
Called when a mesh is loaded into the domain that is associated with this solver. ...
virtual ~Solver()
Virtual destructor.
virtual void mesh_changed(mesh::Mesh &mesh)
Called when a mesh is changed into the domain that is associated with this solver.
Handle< Component > handle()
Get a handle to the component.
void create_field(const std::string &tag, cf3::mesh::Dictionary &dict)
Create fields. Looks up the VariablesDescriptor with the given tag, and creates a field with the same...
virtual void execute()
Execute all active child actions.
Helper class to manage the writing of restart files.
SelectOptionType< T >::type & add(const std::string &name, const T &default_value=T())
static Comm & instance()
Return a reference to the current PE.
virtual void mesh_loaded(mesh::Mesh &mesh)
Base class for defining CF components.
void set(const std::string &pname, const boost::any &val)
TYPE value() const
Casts the value to the provided TYPE.
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.
const Option & option(const std::string &pname) const
get a constant option from the list
T * all_gather(const T *in_values, const int in_n, T *out_values, const int stride=1)
bool is_not_null(T ptr)
predicate for comparison to nullptr