--- /dev/null
+New: Created two new methods ParameterAcceptor::enter_subsection() and
+ParameterAcceptor::leave_subsection() that allow more intricated parameter
+paths within ParameterAcceptor classes.
+<br>
+(Luca Heltai, 2021/01/12)
*/
static ParameterHandler prm;
+ /**
+ * Add the given @p subsection to the global path stored in this class.
+ *
+ * This function changes the behaviour of enter_my_subsection(), by
+ * appending a new subsection to the path stored in this class.
+ *
+ * This method can be used to split the parameters of this class into
+ * subsections, while still maintaining the general behaviour of this
+ * class.
+ *
+ * An example usage is given by the following snippet:
+ * @code
+ * class MyClass : public ParameterAcceptor
+ * {
+ * MyClass()
+ * : ParameterAcceptor("Main section")
+ * {
+ * add_parameter("A param", member_var);
+ * enter_subsection("New section");
+ * add_parameter("Another param", another_member_var);
+ * leave_subsection();
+ * }
+ *
+ * private:
+ * std::vector<unsigned int> member_var = {1,2};
+ * std::map<types::boundary_id, std::string> another_member_var;
+ * ...
+ * };
+ *
+ * int main()
+ * {
+ * // ParameterAcceptor::initialize()
+ * MyClass class;
+ *
+ * // With this call, all derived classes will have their
+ * // parameters initialized
+ * ParameterAcceptor::initialize("file.prm");
+ * }
+ * @endcode
+ *
+ * which will produce a parameter file organized as
+ *
+ * @code
+ * subsection Main section
+ * set A param = 1, 2
+ * subsection New section
+ * set Another param =
+ * end
+ * end
+ * @endcode
+ */
+ void
+ enter_subsection(const std::string &subsection);
+
+ /**
+ * Leave the subsection that was entered by calling the enter_subsection()
+ * function.
+ */
+ void
+ leave_subsection();
+
/**
* Make sure we enter the right subsection of the given parameter.
*/
protected:
/** The subsection name for this class. */
const std::string section_name;
+
+ /** The subsubsections that are currently active. */
+ std::vector<std::string> subsections;
};
}
+
ParameterAcceptor::~ParameterAcceptor()
{
class_list[acceptor_id] = nullptr;
}
+
+
std::string
ParameterAcceptor::get_section_name() const
{
}
+
void
ParameterAcceptor::initialize(
const std::string & filename,
parse_all_parameters(prm);
}
+
+
void
ParameterAcceptor::clear()
{
}
}
+
+
void
ParameterAcceptor::declare_all_parameters(ParameterHandler &prm)
{
}
+
std::vector<std::string>
ParameterAcceptor::get_section_path() const
{
break;
}
}
+ // Finally, insert the remaining subsections
+ sections.insert(sections.end(), subsections.begin(), subsections.end());
return sections;
}
+
+
+void
+ParameterAcceptor::enter_subsection(const std::string &subsection)
+{
+ AssertThrow(subsection.find(sep) == std::string::npos,
+ ExcMessage(
+ "A subsection name cannot contain the special character '/'"));
+ // First the easy case.
+ if (subsection == "")
+ return;
+ subsections.push_back(subsection);
+}
+
+
+
+void
+ParameterAcceptor::leave_subsection()
+{
+ AssertThrow(subsections.size() > 0,
+ ExcMessage("There is no subsection to leave here."));
+ subsections.pop_back();
+}
+
+
+
void
ParameterAcceptor::enter_my_subsection(
ParameterHandler &prm = ParameterAcceptor::prm)
}
}
+
+
void
ParameterAcceptor::leave_my_subsection(
ParameterHandler &prm = ParameterAcceptor::prm)
}
}
-
-
DEAL_II_NAMESPACE_CLOSE
--- /dev/null
+//-----------------------------------------------------------
+//
+// Copyright (C) 2017 - 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+//-----------------------------------------------------------
+
+
+// Test subsectioning within parameter acceptor itself
+
+#include <deal.II/base/parameter_acceptor.h>
+#include <deal.II/base/path_search.h>
+
+#include "../tests.h"
+
+class Test : public ParameterAcceptor
+{
+public:
+ Test(const std::string &sec_name = "First Class",
+ const std::string &par_name = "Parameter name",
+ const std::string &par_value = "Parameter value",
+ const std::string &subsection_name = "")
+ : ParameterAcceptor(sec_name)
+ , par_name(par_name)
+ , par_value(par_value)
+ {
+ if (subsection_name != "")
+ enter_subsection(subsection_name);
+ add_parameter(par_name, this->par_value);
+ if (subsection_name != "")
+ leave_subsection();
+
+ deallog << "Section Name : " << sec_name << std::endl;
+ deallog << "N sections : " << get_section_path().size() << std::endl;
+ deallog << "Sections : ";
+ for (auto s : get_section_path())
+ deallog << "\"" << s << "\" ";
+ deallog << std::endl << std::endl;
+ };
+
+private:
+ std::string par_name;
+ std::string par_value;
+ std::string subsection_name;
+};
+
+int
+main()
+{
+ initlog();
+ auto &prm = ParameterAcceptor::prm;
+
+ // Relative, no subsections
+ Test a("Class A", "Parameter A", "a");
+
+ // Relative, with subsection
+ Test c("Class B", "Parameter C", "c", "Subsection B");
+
+ // Explicit, with absolute path
+ Test d1("/Class D/Class D1", "Parameter D1", "d");
+
+ // Relative to previous, with trailing
+ Test d2("Class D2/", "Parameter D2", "d");
+
+ // Relative to previous
+ Test d3("Class D2D3", "Parameter D2D3", "e");
+
+ // Relative to previous, with subsection
+ Test d4("Class D2D3", "Parameter D2D3", "e", "Subsection D2D3");
+
+ ParameterAcceptor::declare_all_parameters();
+ prm.log_parameters(deallog);
+}
--- /dev/null
+
+DEAL::Section Name : Class A
+DEAL::N sections : 1
+DEAL::Sections : "Class A"
+DEAL::
+DEAL::Section Name : Class B
+DEAL::N sections : 1
+DEAL::Sections : "Class B"
+DEAL::
+DEAL::Section Name : /Class D/Class D1
+DEAL::N sections : 2
+DEAL::Sections : "Class D" "Class D1"
+DEAL::
+DEAL::Section Name : Class D2/
+DEAL::N sections : 2
+DEAL::Sections : "Class D" "Class D2"
+DEAL::
+DEAL::Section Name : Class D2D3
+DEAL::N sections : 3
+DEAL::Sections : "Class D" "Class D2" "Class D2D3"
+DEAL::
+DEAL::Section Name : Class D2D3
+DEAL::N sections : 3
+DEAL::Sections : "Class D" "Class D2" "Class D2D3"
+DEAL::
+DEAL:parameters:Class A::Parameter A: a
+DEAL:parameters:Class B:Subsection B::Parameter C: c
+DEAL:parameters:Class D:Class D1::Parameter D1: d
+DEAL:parameters:Class D:Class D2::Parameter D2: d
+DEAL:parameters:Class D:Class D2:Class D2D3::Parameter D2D3: e
+DEAL:parameters:Class D:Class D2:Class D2D3:Subsection D2D3::Parameter D2D3: e