Flow123d  jenkins-Flow123d-linux-release-multijob-282
input.h
Go to the documentation of this file.
1 /**
2  * @defgroup input Input Classes
3  *
4  * \section classes Overview of data input classes
5  * We assume that the input data of the program can be represented by a tree.
6  * The leave nodes of the tree contain actual data and has one of the 'scalar' types
7  * represented by the classes in Input::Type namespace : Bool, Integer, Double, String,
8  * and FileName. The branching nodes of the input tree
9  * can be either of type Array or type Record (or AbstractRecord).
10  * Classes derived from \p Input::Type::TypeBase only describes structure of the input tree
11  * which is independent of actual format of the input data.
12  *
13  * Instances of the classes from
14  * the Input::Type namespace form a \e declaration-tree that is later used
15  * by a reader of the particular file format (currently we support only JSON through
16  * the Input::JSONToStorage reader) to interpret the input data, check its structure, possibly use default values
17  * and put the raw data into an intermediate \e storage-tree formed be Input:Storage classes.
18  *
19  * Finally,
20  * the data are accessible through accessors Input::Record, Input::Array, and Input::AbstractRecord.
21  * These accessors holds pointers into declaration tree as well as into the data storage tree
22  * and provides unified access to the data.
23  *
24  * Furthermore, the \e declaration-tree can output itself provided a basic documentation of the
25  * input data structure, that is consistent with the actual state.
26  *
27  * Here is simple scheme of information exchange between classes:
28  *
29  * @dot
30  digraph G
31 {
32  graph[rankdir="LR",bgcolor="transparent"];
33 
34  edge [fontname="FreeSans",fontsize=15,labelfontname="FreeSans",labelfontsize=10];
35  node [fontname="FreeSans",fontsize=15,
36  shape=record,height=0.2,width=0.4,
37  color="black", fillcolor="white", style="filled"];
38 
39  DeclarationTree [label="Declaration tree\n(Input::Type...)",URL="\ref input_types"];
40  InputFile [label="Input file\n(JSON, XML, HDF5)"];
41  Reader [label="Particular reader\n(Input::JSONToStorage)",URL="\ref JSONToStorage"];
42  Storage [label="Data storage tree\n(Input::StorageBase...)",URL="\ref StorageBase"];
43  Accessors [label="Data accessors\n(Input::Record, Input::Array, ...)",URL="\ref input_accessors"];
44  Doc [label="Input documentation"];
45  DataUsage [label="Data usage"];
46 
47  {rank=same; InputFile Reader Storage Accessors DataUsage}
48  {rank=same; DeclarationTree Doc }
49 
50  DeclarationTree -> Reader [color="black",fontsize=10,style="solid",fontname="FreeSans"];
51  DeclarationTree -> Accessors [color="black",fontsize=10,style="solid",fontname="FreeSans"];
52  DeclarationTree -> Doc [color="black",fontsize=10,style="solid",fontname="FreeSans"];
53  InputFile -> Reader [color="black",fontsize=10,style="solid",fontname="FreeSans"];
54  Reader -> Storage [color="black",fontsize=10,style="solid",fontname="FreeSans"];
55  Storage -> Accessors [color="black",fontsize=10,style="solid",fontname="FreeSans"];
56  Accessors -> DataUsage [color="black",fontsize=10,style="solid",fontname="FreeSans"];
57 }
58  * @enddot
59  *
60  * \section practical_usage Practical usage
61  *
62  * In order to use input interface you have to create \e declaration-tree, namely Selection, Record, and AbstractRecord types
63  * has to be declared by specification of its keys. We suggest to have a static method that returns Input::Type::Record
64  * for ever class which is initialized from input interface. Example of usage follows:
65  *
66  @code
67  class Mesh {
68  static Input::Type::Record get_input_type() {
69  using namespace Input::Type;
70  static Record rec("Mesh", "Full description of computational mesh.");
71 
72  if ( ! rec.is_finished() ) {
73  rec.declare_key("mesh_name", String(), Default::optional(),"Optional name of the mesh");
74  rec.declare_key("mesh_file", FileName::input(), Default("mesh.msh"), "Principial mesh input file");
75  rec.declare_key("materials_to_remove", Array(Integer()), "Removes elements with material ID that appears in this list.");
76 
77  // here we refer to declaration of Input::Type::Record of another class Boundary
78  rec.declare_key("boundary",Boundary::get_input_type(), "Boundary description");
79  rec.finish()
80  }
81  return rec; // copies of complex types are bare pointers to the same declaration data
82  }
83 
84  Mesh( Input::Record input)
85  : name( input.val<string>("mesh_name") )
86  {
87  string fname = input.val<FilePath>("mesh_file");
88  boundary = new Boundary( input.val<Input::Record>("boundary") );
89  std::vector<int> ids_to_remove;
90  input.val<Input::Array>("materials_to_remove").copy_to( ids_to_remove );
91  }
92  }
93  @endcode
94  *
95  * The accessor for the root Input::Record is provided by the reader class ( JSONToStorage.get_root_interface<>() )
96  *
97  */