13#include <boost/graph/adjacency_list.hpp>
14#include <boost/graph/graphviz.hpp>
24 boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
25 boost::property<boost::vertex_name_t, VertexData>,
26 boost::property<boost::edge_name_t, std::string>>;
35 std::string pip_name, boost::shared_ptr<Graph> g_ptr,
38 auto get_fe_name = [](
const auto &fe) {
39 std::ostringstream ss;
40 ss <<
"FE:" << boost::typeindex::type_id_runtime(fe).pretty_name();
44 auto get_name_short = [](
const auto &op) {
45 std::ostringstream ss;
46 ss <<
"OP:" << boost::typeindex::type_id_runtime(op).pretty_name();
50 auto get_name_long = [get_name_short](
const auto &op) {
51 auto ss = get_name_short(op);
52 switch (op.getOpType()) {
54 ss <<
":r:" << op.rowFieldName;
57 ss <<
":c:" << op.colFieldName;
60 ss <<
":r:" << op.rowFieldName <<
":c:" << op.colFieldName;
73 auto vname = get(boost::vertex_name,
g);
74 auto ename = get(boost::edge_name,
g);
78 const boost::ptr_deque<UserDataOperator> &)>
80 const boost::ptr_deque<UserDataOperator> &pip) {
81 auto prev_vertex = root_vertex;
83 for (
auto &op : pip) {
85 auto op_vertex = boost::add_vertex(
g);
86 vname[op_vertex] = {get_name_long(op).str(),
"box",
"solid",
89 auto fe_weak_ptr = op.getSubPipelinePtr();
91 if (
auto fe = fe_weak_ptr.lock()) {
93 auto fe_vertex = boost::add_vertex(
g);
94 vname[fe_vertex] = {get_fe_name(*fe).str(),
"box3d",
"filled",
"lightgrey"};
96 auto last_vertex = add_tree(fe_vertex, fe->getOpPtrVector());
99 auto [e_loop_start, ok1_start] =
100 add_edge(op_vertex, fe_vertex,
g);
101 ename[e_loop_start] =
"go to loop";
102 auto [e_loop_end, ok1_end] = add_edge(last_vertex, op_vertex,
g);
103 ename[e_loop_end] =
"back from loop";
106 auto [e, ok1] = add_edge(prev_vertex, op_vertex,
g);
108 prev_vertex = op_vertex;
114 auto pip_vertex = boost::add_vertex(
g);
115 vname[pip_vertex] = {pip_name,
"box3d",
"filled",
"lightgrey"};
116 auto [e_root_pip, ok] = add_edge(root_vertex, pip_vertex,
g);
117 ename[e_root_pip] =
"pipeline";
119 auto last_vertex = add_tree(pip_vertex, pip);
125 boost::shared_ptr<Graph> g_ptr) {
128 std::ofstream ofs(file_name);
132 auto vdata = get(boost::vertex_name,
g)[
v];
133 out <<
"[label=\"" << vdata.label <<
"\", shape=" << vdata.shape
134 <<
", style=" << vdata.style <<
", color=" << vdata.color <<
"]";
138 auto edge_writer = boost::make_label_writer(get(boost::edge_name,
g));
140 boost::write_graphviz(ofs,
g, vertex_writer, edge_writer);
146 std::string file_name, std::string pip_name,
147 const boost::ptr_deque<UserDataOperator> &pip) {
149 boost::shared_ptr<Graph> g_ptr(
new Graph());
150 auto vname = get(boost::vertex_name, *g_ptr);
151 auto root_vertex = boost::add_vertex(*g_ptr);
152 vname[root_vertex] = {
"Finite Element Pipeline Graph",
"ellipse",
"solid",
162 boost::shared_ptr<Graph> g_ptr) {
163 boost::ptr_deque<UserDataOperator> null_pip;
164 auto vname = get(boost::vertex_name, *g_ptr);
166 auto get_fe_name = [](
const auto &fe) {
167 std::ostringstream ss;
168 ss <<
"FE:" << boost::typeindex::type_id_runtime(fe).pretty_name();
172 auto pre_vertex = boost::add_vertex(*g_ptr);
173 vname[pre_vertex] = {
"Stage PreProcess",
"ellipse",
"solid",
"black"};
174 auto [pre_rhs, ok_pre_rhs] = add_edge(start_vertex, pre_vertex, *g_ptr);
176 auto prev_vertex = pre_vertex;
177 for (
auto &
bit : pre) {
178 auto name =
"BM:" + get_fe_name(
bit.get()).str();
182 auto pro_vertex = boost::add_vertex(*g_ptr);
183 vname[pro_vertex] = {
"Stage Processs",
"ellipse",
"solid",
"black"};
184 auto [pro_rhs, ok_pro_rhs] = add_edge(prev_vertex, pro_vertex, *g_ptr);
186 prev_vertex = pro_vertex;
187 for (
auto &lit : op) {
188 auto name = lit.first +
":" + get_fe_name(*(lit.second)).str();
190 boost::dynamic_pointer_cast<ForcesAndSourcesCore>(lit.second)) {
198 auto post_vertex = boost::add_vertex(*g_ptr);
199 vname[post_vertex] = {
"Stage PostProcesss",
"ellipse",
"solid",
"black"};
200 auto [post_rhs, ok_post_rhs] = add_edge(prev_vertex, post_vertex, *g_ptr);
202 prev_vertex = post_vertex;
203 for (
auto &
bit : post) {
204 auto name =
"BM:" + get_fe_name(
bit.get()).str();
211 std::string file_name) {
213 boost::shared_ptr<Graph> g_ptr(
new Graph());
216 auto vname = get(boost::vertex_name,
g);
217 auto ename = get(boost::edge_name,
g);
219 auto root_vertex = boost::add_vertex(
g);
220 vname[root_vertex] = {
"KSP Graph",
"ellipse",
"solid",
"black"};
222 auto lhs_vertex = boost::add_vertex(
g);
223 vname[lhs_vertex] = {
"Lhs",
"box3d",
"filled",
"lightgrey"};
224 add_edge(root_vertex, lhs_vertex,
g);
228 auto rhs_vertex = boost::add_vertex(
g);
229 vname[rhs_vertex] = {
"Rhs",
"box3d",
"filled",
"lightgrey"};
230 add_edge(root_vertex, rhs_vertex,
g);
240 std::string file_name) {
242 boost::shared_ptr<Graph> g_ptr(
new Graph());
245 auto vname = get(boost::vertex_name,
g);
246 auto ename = get(boost::edge_name,
g);
248 auto root_vertex = boost::add_vertex(
g);
249 vname[root_vertex] = {
"SNES Graph",
"ellipse",
"solid",
"black"};
251 auto lhs_vertex = boost::add_vertex(
g);
252 vname[lhs_vertex] = {
"Lhs",
"box3d",
"filled",
"lightgrey"};
253 add_edge(root_vertex, lhs_vertex,
g);
257 auto rhs_vertex = boost::add_vertex(
g);
258 vname[rhs_vertex] = {
"Rhs",
"box3d",
"filled",
"lightgrey"};
259 add_edge(root_vertex, rhs_vertex,
g);
263 auto load_vertex = boost::add_vertex(
g);
264 vname[load_vertex] = {
"LoadTangent",
"box3d",
"filled",
"lightgrey"};
265 add_edge(root_vertex, load_vertex,
g);
276 std::string file_name) {
278 boost::shared_ptr<Graph> g_ptr(
new Graph());
281 auto vname = get(boost::vertex_name,
g);
282 auto ename = get(boost::edge_name,
g);
284 auto root_vertex = boost::add_vertex(
g);
285 vname[root_vertex] = {
"TS Graph",
"ellipse",
"solid",
"black"};
287 auto ifunction_vertex = boost::add_vertex(
g);
288 vname[ifunction_vertex] = {
"IFunction",
"box3d",
"filled",
"lightgrey"};
289 add_edge(root_vertex, ifunction_vertex,
g);
293 auto rhsfunction_vertex = boost::add_vertex(
g);
294 vname[rhsfunction_vertex] = {
"RHSFunction",
"box3d",
"filled",
"lightgrey"};
295 add_edge(root_vertex, rhsfunction_vertex,
g);
299 auto ijjacobian_vertex = boost::add_vertex(
g);
300 vname[ijjacobian_vertex] = {
"IJacobian",
"box3d",
"filled",
"lightgrey"};
301 add_edge(root_vertex, ijjacobian_vertex,
g);
305 auto rhsjacobian_vertex = boost::add_vertex(
g);
306 vname[rhsjacobian_vertex] = {
"RHSJacobian",
"box3d",
"filled",
"lightgrey"};
307 add_edge(root_vertex, rhsjacobian_vertex,
g);
311 auto monitor_vertex = boost::add_vertex(
g);
312 vname[monitor_vertex] = {
"Monitor",
"box3d",
"filled",
"lightgrey"};
313 add_edge(root_vertex, monitor_vertex,
g);
325 boost::shared_ptr<Graph> g_ptr(
new Graph());
326 auto vname = get(boost::vertex_name, *g_ptr);
327 auto root_vertex = boost::add_vertex(*g_ptr);
328 vname[root_vertex] = {
"Pipeline Manager Graph",
"ellipse",
"solid",
"black"};
333 "DomainLhsPipeline", g_ptr, root_vertex);
336 "BoundaryLhsPipeline", g_ptr, root_vertex);
339 "SkeletonLhsPipeline", g_ptr, root_vertex);
344 "DomainRhsPipeline", g_ptr, root_vertex);
347 "BoundaryRhsPipeline", g_ptr, root_vertex);
351 "SkeletonRhsPipeline", g_ptr, root_vertex);
355 "DomainRhsExplicitPipeline", g_ptr,
359 "BoundaryRhsExplicitPipeline", g_ptr,
363 "SkeletonRhsExplicitPipeline", g_ptr,
369 "MeshsetLhsPipeline", g_ptr, root_vertex);
372 "MeshsetRhsPipeline", g_ptr, root_vertex);
375 "MeshsetRhsExplicitPipeline", g_ptr,
391 : cOre(const_cast<
Core &>(core)) {}
boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, boost::property< boost::vertex_name_t, VertexData >, boost::property< boost::edge_name_t, std::string > > Graph
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
static const char *const FieldSpaceNames[]
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
boost::ptr_deque< UserDataOperator > & getOpBoundaryExplicitRhsPipeline()
Get the Op Boundary Rhs Pipeline object for implicit-explicit G term.
boost::ptr_deque< UserDataOperator > & getOpDomainExplicitRhsPipeline()
Get the Op Domain Rhs Pipeline object for implicit-explicit G term.
boost::ptr_deque< UserDataOperator > & getOpSkeletonExplicitRhsPipeline()
Get the Op Skeleton Rhs Pipeline object for implicit-explicit G term.
boost::ptr_deque< UserDataOperator > & getOpDomainLhsPipeline()
Get the Op Domain Lhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpSkeletonLhsPipeline()
Get the Op Skeleton Lhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpBoundaryLhsPipeline()
Get the Op Boundary Lhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpBoundaryRhsPipeline()
Get the Op Boundary Rhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpSkeletonRhsPipeline()
Get the Op Skeleton Rhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpDomainRhsPipeline()
Get the Op Domain Rhs Pipeline object.
const double v
phase velocity of light in medium (cm/ns)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
static void write_graphviz_impl(std::string file_name, boost::shared_ptr< Graph > g_ptr)
boost::graph_traits< Graph >::vertex_descriptor VertexDescriptor
static VertexDescriptor plot_pipeline_graph_impl(const boost::ptr_deque< UserDataOperator > &pip, std::string pip_name, boost::shared_ptr< Graph > g_ptr, VertexDescriptor root_vertex)
std::deque< BasicMethodPtr > BasicMethodsSequence
std::deque< PairNameFEMethodPtr > FEMethodsSequence
static void add_stages(BasicMethodsSequence &pre, FEMethodsSequence &op, BasicMethodsSequence &post, VertexDescriptor start_vertex, boost::shared_ptr< Graph > g_ptr)
@ OPCOL
operator doWork function is executed on FE columns
@ OPROW
operator doWork function is executed on FE rows
@ OPROWCOL
operator doWork is executed on FE rows &columns
@ OPSPACE
operator do Work is execute on space data
Interface for linear (KSP) solver.
BasicMethodsSequence & getPostProcComputeRhs()
BasicMethodsSequence & getPreProcComputeRhs()
BasicMethodsSequence & getPreProcSetOperators()
FEMethodsSequence & getSetOperators()
FEMethodsSequence & getComputeRhs()
BasicMethodsSequence & getPostProcSetOperators()
static MoFEMErrorCode writeTSGraphGraphviz(TsCtx *ts_ctx, std::string file_name)
TS graph to Graphviz file.
static MoFEMErrorCode writeKSPGraphGraphviz(KspCtx *ksp_ctx, std::string filename)
KSP graph to Graphviz file.
static MoFEMErrorCode writeGraphGraphviz(std::string filename, std::string pip_name, const boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
Pipeline graph to Graphviz file.
static MoFEMErrorCode writePiplineManagerGraphGraphviz(std::string filename, PipelineManager *pip_mng)
Write pipeline manager graph to Graphviz file.
static MoFEMErrorCode writeSNESGraphGraphviz(SnesCtx *snes_ctx, std::string file_name)
SNES graph to Graphviz file.
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Query interface for type-safe casting.
PipelineGraph(const MoFEM::Core &core)
PipelineManager interface.
boost::shared_ptr< FEMethod > & getDomainRhsFE()
Get domain right-hand side finite element.
boost::ptr_deque< UserDataOperator > & getOpMeshsetRhsPipeline()
Get the Op Meshset Rhs Pipeline object.
boost::shared_ptr< FEMethod > & getDomainLhsFE()
Get domain left-hand side finite element.
boost::ptr_deque< UserDataOperator > & getOpMeshsetExplicitRhsPipeline()
Get the Op Meshset Explicit Rhs Pipeline object.
boost::shared_ptr< FEMethod > & getSkeletonRhsFE()
Get skeleton right-hand side finite element.
boost::shared_ptr< FEMethod > & getMeshsetLhsFE()
Get meshset left-hand side finite element.
boost::shared_ptr< FEMethod > & getBoundaryLhsFE()
Get boundary left-hand side finite element.
boost::shared_ptr< FEMethod > & getSkeletonLhsFE()
Get skeleton left-hand side finite element.
boost::shared_ptr< FEMethod > & getMeshsetRhsFE()
Get meshset right-hand side finite element.
boost::shared_ptr< FEMethod > & getDomainExplicitRhsFE()
Get domain explicit right-hand side finite element.
boost::shared_ptr< FEMethod > & getBoundaryRhsFE()
Get boundary right-hand side finite element.
boost::ptr_deque< UserDataOperator > & getOpMeshsetLhsPipeline()
Get the Op Meshset Lhs Pipeline object.
boost::shared_ptr< FEMethod > & getSkeletonExplicitRhsFE()
Get skeleton explicit right-hand side finite element.
boost::shared_ptr< FEMethod > & getBoundaryExplicitRhsFE()
Get boundary explicit right-hand side finite element.
boost::shared_ptr< FEMethod > & getMeshsetExplicitRhsFE()
Get meshset explicit right-hand side finite element.
Interface for nonlinear (SNES) solver.
FEMethodsSequence & getSetOperators()
BasicMethodsSequence & getPreProcLoadTangent()
Get the BasicMethod sequence for preprocessing of FunctionFn.
BasicMethodsSequence & getPreProcSetOperators()
BasicMethodsSequence & getPostProcLoadTangent()
Get the BasicMethod sequence for postprocessing of FunctionFn.
BasicMethodsSequence & getPostProcComputeRhs()
BasicMethodsSequence & getPostProcSetOperators()
BasicMethodsSequence & getPreProcComputeRhs()
FEMethodsSequence & getLoadTangent()
Get the finite element pipeline for FunctionFn, that calculate tangent of function load for arc lengt...
FEMethodsSequence & getComputeRhs()
Interface for Time Stepping (TS) solver.
BasicMethodsSequence & getPostProcessRHSFunction()
Get the postProcess to do RHSFunction object.
BasicMethodsSequence & getPostProcessIJacobian()
Get the postProcess to do IJacobian object.
FEMethodsSequence & getLoopsMonitor()
Get the loops to do Monitor object.
BasicMethodsSequence & getPreProcessMonitor()
Get the preProcess to do Monitor object.
BasicMethodsSequence & getPostProcessRHSJacobian()
Get the postProcess to do RHSJacobian object.
BasicMethodsSequence & getPostProcessIFunction()
Get the postProcess to do IFunction object.
BasicMethodsSequence & getPreProcessRHSFunction()
Get the preProcess to do RHSFunction object.
FEMethodsSequence & getLoopsIFunction()
Get the loops to do IFunction object.
FEMethodsSequence & getLoopsRHSJacobian()
Get the loops to do RHSJacobian object.
BasicMethodsSequence & getPreProcessIFunction()
Get the preProcess to do IFunction object.
FEMethodsSequence & getLoopsRHSFunction()
Get the loops to do RHSFunction object.
FEMethodsSequence & getLoopsIJacobian()
Get the loops to do IJacobian object.
BasicMethodsSequence & getPreProcessRHSJacobian()
Get the preProcess to do RHSJacobian object.
BasicMethodsSequence & getPostProcessMonitor()
Get the postProcess to do Monitor object.
BasicMethodsSequence & getPreProcessIJacobian()
Get the preProcess to do IJacobian object.
base class for all interface classes