Reading a list from parameter file

124 views
Skip to first unread message

Paras Kumar

unread,
Apr 15, 2021, 11:23:36 AM4/15/21
to deal.II User Group
Dear All,

I am trying to read a list of integers from the parameter file using the dealii::Patterns::List class.
However, I get a runtime error which can be reproduced using the attached MWE.

I also tried the approach described (for tensor) in https://groups.google.com/g/dealii/c/TvtcOnxeVjw/m/9uaSAh-kAwAJ but it doesn't seem to work for the current case.

It would be great help if someone could help me understand where I go wrong?

Thanks in advance and best regards,
Paras



mwe-patterns-list.cc

Wolfgang Bangerth

unread,
Apr 16, 2021, 5:53:31 PM4/16/21
to dea...@googlegroups.com

Paras,

> I am trying to read a list of integers from the parameter file using the
> dealii::Patterns::List class.
> However, I get a runtime error which can be reproduced using the attached MWE.
>
> I also tried the approach described (for tensor) in
> https://groups.google.com/g/dealii/c/TvtcOnxeVjw/m/9uaSAh-kAwAJ but it doesn't
> seem to work for the current case.
>
> It would be great help if someone could help me understand where I go wrong?

First: Excellent job coming up with a self-contained minimal example!

The problem is that in this line:

nIters =
dealii::Patterns::Tools::Convert<decltype(nIters)>::to_value(nMaxItersString);

The to_value() function creates its own pattern based on the type of the
argument nMaxItersString. This pattern uses "," as the separator, but you want
"|". You can fix this by providing an explicit pattern:

nIters =
dealii::Patterns::Tools::Convert<decltype(nIters)>::to_value(nMaxItersString,dealii::Patterns::List(dealii::Patterns::Integer(1),
2, 8, "|"));

Best
W.

--
------------------------------------------------------------------------
Wolfgang Bangerth email: bang...@colostate.edu
www: http://www.math.colostate.edu/~bangerth/

Paras Kumar

unread,
Apr 19, 2021, 6:20:13 AM4/19/21
to dea...@googlegroups.com
Dear Wolfgang,

Thank you so much for the suggestion. Just to avoid confusion for future readers, the to_value() function needs a unique_ptr, and hence the aforementioned line needs to be replaced by the following lines:

std::unique_ptr<dealii::Patterns::PatternBase> nItersListPattern(new dealii::Patterns::List(dealii::Patterns::Integer(1), 2, 8, "|"));
nIters = dealii::Patterns::Tools::Convert<decltype(nIters)>::to_value(nMaxItersString,  nItersListPattern);

Best regards,
Paras

--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see https://groups.google.com/d/forum/dealii?hl=en
---
You received this message because you are subscribed to the Google Groups "deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dealii+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dealii/98664411-dca8-ba63-dcf3-cbdd1d0489d4%40colostate.edu.

Wolfgang Bangerth

unread,
Apr 19, 2021, 11:38:31 AM4/19/21
to dea...@googlegroups.com
On 4/19/21 4:19 AM, Paras Kumar wrote:
>
> std::unique_ptr<dealii::Patterns::PatternBase> nItersListPattern(new
> dealii::Patterns::List(dealii::Patterns::Integer(1), 2, 8, "|"));
> nIters =
> dealii::Patterns::Tools::Convert<decltype(nIters)>::to_value(nMaxItersString,
>  nItersListPattern);

I suspect you need to write this last line as
dealii::Patterns::Tools::Convert<decltype(nIters)>::to_value(nMaxItersString,
std::move(nItersListPattern));

but the idea seems right. I was using the latest development sources in which
the argument has been changed from a unique-ptr to just a regular object.

Paras Kumar

unread,
May 8, 2025, 11:40:11 AM5/8/25
to deal.II User Group
Dear All,

Here is a kind of follow-up to the above question.

I now to try to read a list of strings and each of the values in the list must to be converted to an enum class type.

But I get the following compile time error when I try to compile below code snippet

"
: error: use of deleted function ‘static T dealii::Patterns::Tools::Convert<T, Enable>::to_value(const std::string&, const dealii::Patterns::PatternBase&) [with T = NonlinearSolverType; Enable = void; std::string = std::__cxx11::basic_string<char>]’
 1829 |                    Convert<typename T::value_type>::to_value(str, *base_p));
"

I also tried playing around with the second template option "A" of the dealii::Patterns::Tools::Convert<T,A>() function but it did not help. I am not sure if this function is not yet instantiated to work for T = decltype(nonlinearSolverTypes_)? or am I make syntactical mistake in calling the function?

 enum class NonlinearSolverType
 {
      NEWTON_STANDARD,      
      NEWTON_MODIFIED
  };
using NonlinearSolverListType = std::vector<NonlinearSolverType>;
dealii::Patterns::List nonlinearSolverListPattern(
  dealii::Patterns::MultipleSelection(
    "NEWTON_STANDARD|NEWTON_MODIFIED"),
  nMinListElems,
  nMaxListElems,
  "|");
const std::string nonlinearSolverTypesString =  parameterHandler.get("Nonlinear solver types");
blockNonlinearSolverParameters_.nonlinearSolverTypes_ =  dealii::Patterns::Tools::Convert<NonlinearSolverListType, typename std::enable_if<dealii::Patterns::Tools::is_list_compatible<NonlinearSolverListType>::value>::type>::to_value(nonlinearSolverTypesString, std::move(nonlinearSolverListPattern));

Some suggestions on resolving this issue will be really helpful.

Best regards,
Paras Kumar

Luca Heltai

unread,
May 8, 2025, 11:53:37 AM5/8/25
to dea...@googlegroups.com, deal.II User Group
This is supported by default on deal.II master if you compile with magic enum support. 

It will allow you to parse directly the enum. 

You can simply copy and paste the relevant code in patterns.h to your header if you have an older deal.II. 

Luca

Il giorno 8 mag 2025, alle ore 17:40, Paras Kumar <parasku...@gmail.com> ha scritto:


--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see https://groups.google.com/d/forum/dealii?hl=en
---
You received this message because you are subscribed to the Google Groups "deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dealii+un...@googlegroups.com.

Paras Kumar

unread,
May 9, 2025, 4:20:50 AM5/9/25
to deal.II User Group
Hi Luca,

Thank you for the quick response.

One (may be off-topic) short follow-up. How can I turn on the DEAL_II_WITH_MAGIC_ENUM option on using spack. I could not find any relevant option in the spack/dealii-9.4.0/var/spack/repos/builtin/packages/dealii/package.py file.

Best regards,
Paras

Luca Heltai

unread,
May 9, 2025, 11:49:14 AM5/9/25
to Deal.II Users
It was added after 9.6.0. It is not there on spack yet.

You don’t really need to recompile the library. You need one include file (magic_enum.hpp from https://github.com/Neargye/magic_enum) in your include path, and to copy this to one of your headers:


#include <magic_enum.hpp>

namespace dealii {
namespace Patterns {
namespace Tools {

template <class T>
struct Convert<T, typename std::enable_if<std::is_enum<T>::value>::type>
{
static std::unique_ptr<Patterns::PatternBase>
to_pattern()
{
const auto n = magic_enum::enum_names<T>();
std::vector<std::string> names = {n.begin(), n.end()};
const auto selection =
Patterns::Tools::Convert<decltype(names)>::to_string(
names,
Patterns::List(
Patterns::Anything(), names.size(), names.size(), "|"));
// Allow parsing a list of enums, and make bitwise or between them
return Patterns::List(Patterns::Selection(selection),
0,
names.size(),
"|")
.clone();
}

static std::string
to_string(const T &value,
const Patterns::PatternBase &p = *Convert<T>::to_pattern())
{
const auto values = magic_enum::enum_values<T>();
std::vector<std::string> names;
for (const auto &v : values)
if (magic_enum::bitwise_operators::operator&(value, v) == v)
names.push_back(std::string(magic_enum::enum_name(v)));
return Patterns::Tools::Convert<decltype(names)>::to_string(names, p);
}

static T
to_value(const std::string &s,
const dealii::Patterns::PatternBase &p = *to_pattern())
{
// Make sure we have a valid enum value, or empty value
AssertThrow(p.match(s), ExcNoMatch(s, p.description()));
T value = T();
std::vector<std::string> value_names;
value_names =
Patterns::Tools::Convert<decltype(value_names)>::to_value(s, p);
for (const auto &name : value_names)
{
auto v = magic_enum::enum_cast<T>(name);
if (v.has_value())
value =
magic_enum::bitwise_operators::operator|(value, v.value());
}
return value;
}
};
> To view this discussion visit https://groups.google.com/d/msgid/dealii/1fd93eda-8535-4709-bc8d-fafcf97ef1b5n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages