• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Open-Sn / opensn / 18300593117

06 Oct 2025 10:47PM UTC coverage: 74.862% (-0.2%) from 75.031%
18300593117

push

github

web-flow
Merge pull request #759 from wdhawkins/performance

Sweep performance optimizations

294 of 302 new or added lines in 15 files covered. (97.35%)

334 existing lines in 80 files now uncovered.

17788 of 23761 relevant lines covered (74.86%)

61852783.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.2
/framework/parameters/input_parameters.cc
1
// SPDX-FileCopyrightText: 2024 The OpenSn Authors <https://open-sn.github.io/opensn/>
2
// SPDX-License-Identifier: MIT
3

4
#include "framework/parameters/input_parameters.h"
5
#include "framework/runtime.h"
6
#include "framework/logging/log.h"
7
#include <sstream>
8
#include <algorithm>
9
#include <utility>
10

11
namespace opensn
12
{
13

14
namespace
15
{
16

17
std::string
18
InputErrorStr(const std::string& error_scope,
4✔
19
              const std::string& object_type,
20
              const std::string& err_msg)
21
{
22
  return (error_scope.empty() ? "" : error_scope + "\n") + "Input error: " + object_type + "\n" +
8✔
23
         err_msg;
8✔
24
}
25

26
std::string
27
ParamNotPresentErrorStr(const std::string& function_name, const std::string& param_name)
×
28
{
29
  return std::string(__PRETTY_FUNCTION__) + ": Parameter \"" + param_name +
×
30
         "\" not present in list of parameters.";
×
31
}
32

33
} // namespace
34

35
const std::vector<std::string> InputParameters::system_ignored_param_names_ = {"obj_type"};
36

37
InputParameters&
38
InputParameters::operator+=(InputParameters other)
×
39
{
40
  for (const auto& param : other)
×
41
    AddParameter(param);
×
42

43
  // Copy maps
44
  {
45
    auto& other_map = other.parameter_class_tags_;
×
46
    auto& this_map = parameter_class_tags_;
×
47
    for (const auto& [param_name, tag] : other_map)
×
48
    {
49
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
50
      this_map[param_name] = tag;
×
51
    }
52
  }
53
  {
54
    auto& other_map = other.parameter_doc_string_;
×
55
    auto& this_map = parameter_doc_string_;
×
56
    for (const auto& [param_name, tag] : other_map)
×
57
    {
58
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
59
      this_map[param_name] = tag;
×
60
    }
61
  }
62
  {
63
    auto& other_map = other.deprecation_warning_tags_;
×
64
    auto& this_map = deprecation_warning_tags_;
×
65
    for (const auto& [param_name, tag] : other_map)
×
66
    {
67
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
68
      this_map[param_name] = tag;
×
69
    }
70
  }
71
  {
72
    auto& other_map = other.deprecation_error_tags_;
×
73
    auto& this_map = deprecation_error_tags_;
×
74
    for (const auto& [param_name, tag] : other_map)
×
75
    {
76
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
77
      this_map[param_name] = tag;
×
78
    }
79
  }
80
  {
81
    auto& other_map = other.renamed_error_tags_;
×
82
    auto& this_map = renamed_error_tags_;
×
83
    for (const auto& [param_name, tag] : other_map)
×
84
    {
85
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
86
      this_map[param_name] = tag;
×
87
    }
88
  }
89
  {
90
    auto& other_map = other.type_mismatch_allowed_tags_;
×
91
    auto& this_map = type_mismatch_allowed_tags_;
×
92
    for (const auto& [param_name, tag] : other_map)
×
93
    {
94
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
95
      this_map[param_name] = tag;
×
96
    }
97
  }
98
  {
99
    auto& other_map = other.parameter_link_;
×
100
    auto& this_map = parameter_link_;
×
101
    for (const auto& [param_name, tag] : other_map)
×
102
    {
103
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
104
      this_map[param_name] = tag;
×
105
    }
106
  }
107
  {
108
    auto& other_map = other.constraint_tags_;
×
109
    auto& this_map = constraint_tags_;
×
110
    for (auto& [param_name, tag] : other_map)
×
111
    {
112
      OpenSnLogicalErrorIf(this_map.count(param_name) != 0, "Duplicate tags detected.");
×
113
      this_map[param_name] = std::move(tag);
×
114
    }
115
  }
116

117
  return *this;
×
118
}
119

120
void
121
InputParameters::SetObjectType(const std::string& obj_type)
2,686✔
122
{
123
  class_name_ = obj_type;
2,686✔
124
}
2,686✔
125

126
std::string
127
InputParameters::GetObjectType() const
4✔
128
{
129
  return class_name_;
4✔
130
}
131

132
void
133
InputParameters::LinkParameterToBlock(const std::string& param_name, const std::string& block_name)
1,135✔
134
{
135
  OpenSnInvalidArgumentIf(not this->Has(param_name),
1,135✔
136
                          "Parameter \"" + param_name + "\" not present in block");
137
  parameter_link_[param_name] = block_name;
1,135✔
138
}
1,135✔
139

140
std::string
141
InputParameters::GetParameterDocumentationLink(const std::string& param_name) const
×
142
{
143
  if (parameter_link_.count(param_name) > 0)
×
144
    return parameter_link_.at(param_name);
×
145
  return {};
×
146
}
147

148
std::string
149
InputParameters::GetParameterDocString(const std::string& param_name)
3✔
150
{
151
  OpenSnInvalidArgumentIf(parameter_doc_string_.count(param_name) == 0,
3✔
152
                          "Invalid parameter \"" + param_name + "\".");
153
  return parameter_doc_string_.at(param_name);
3✔
154
}
155

156
bool
157
InputParameters::IsParameterIgnored(const std::string& param_name)
64,098✔
158
{
159
  bool ignored = false;
64,098✔
160

161
  {
162
    const auto& list = system_ignored_param_names_;
64,098✔
163
    if (std::find(list.begin(), list.end(), param_name) != list.end())
64,098✔
164
      ignored = true;
×
165
  }
166

167
  return ignored;
64,098✔
168
}
169

170
void
171
InputParameters::AddOptionalParameterBlock(const std::string& name,
379✔
172
                                           const ParameterBlock& block,
173
                                           const std::string& doc_string)
174
{
175
  auto new_block = block;
379✔
176
  new_block.SetBlockName(name);
379✔
177
  AddParameter(new_block);
379✔
178
  parameter_class_tags_[name] = InputParameterTag::OPTIONAL;
379✔
179
  parameter_doc_string_[name] = doc_string;
379✔
180
}
379✔
181

182
void
183
InputParameters::AddOptionalParameterArray(const std::string& name,
435✔
184
                                           const std::vector<ParameterBlock>& array,
185
                                           const std::string& doc_string)
186
{
187
  ParameterBlock new_block(name);
435✔
188
  new_block.ChangeToArray();
435✔
189
  for (const auto& block : array)
435✔
190
    new_block.AddParameter(block);
×
191

192
  AddParameter(new_block);
435✔
193
  parameter_class_tags_[name] = InputParameterTag::OPTIONAL;
435✔
194
  parameter_doc_string_[name] = doc_string;
435✔
195
}
435✔
196

197
void
198
InputParameters::AddRequiredParameterBlock(const std::string& name, const std::string& doc_string)
56✔
199
{
200
  ParameterBlock new_block(name);
56✔
201
  AddParameter(new_block);
56✔
202
  parameter_class_tags_[name] = InputParameterTag::REQUIRED;
56✔
203
  parameter_doc_string_[name] = doc_string;
56✔
204
}
56✔
205

206
void
207
InputParameters::AddRequiredParameterArray(const std::string& name, const std::string& doc_string)
1,824✔
208
{
209
  ParameterBlock new_block(name);
1,824✔
210
  new_block.ChangeToArray();
1,824✔
211
  AddParameter(new_block);
1,824✔
212
  parameter_class_tags_[name] = InputParameterTag::REQUIRED;
1,824✔
213
  parameter_doc_string_[name] = doc_string;
1,824✔
214
}
1,824✔
215

216
void
217
InputParameters::AssignParameters(const ParameterBlock& params)
4,587✔
218
{
219
  param_block_at_assignment_ = params;
4,587✔
220
  std::stringstream err_stream;
4,587✔
221

222
  if (log.GetVerbosity() >= 2)
4,587✔
223
    log.Log0Verbose2() << "Number of parameters " << params.GetNumParameters();
×
224

225
  // Check required parameters
226
  // Loops over all input-parameters that have been
227
  // classed as being required. Input-parameters that
228
  // have any form of deprecation is ignored.
229
  for (const auto& [param_index, tag] : parameter_class_tags_)
38,405✔
230
  {
231
    if (tag != InputParameterTag::REQUIRED)
33,818✔
232
      continue;
28,364✔
233

234
    const auto& req_param = GetParam(param_index);
5,454✔
235
    const auto& req_param_name = req_param.GetName();
5,454✔
236

237
    if (deprecation_warning_tags_.count(req_param_name) > 0 or
5,454✔
238
        deprecation_error_tags_.count(req_param_name) > 0 or
10,908✔
239
        renamed_error_tags_.count(req_param_name) > 0)
5,454✔
240
      continue;
×
241

242
    if (not params.Has(req_param_name))
5,454✔
243
      err_stream << "Required param \"" << req_param_name
244
                 << "\" not supplied.\ndoc-string: " << GetParameterDocString(req_param_name)
1✔
245
                 << "\nEnsure the parameter given is supplied or not nil";
1✔
246
  }
5,454✔
247

248
  if (not err_stream.str().empty())
4,587✔
249
    throw std::invalid_argument(
250
      InputErrorStr(GetErrorOriginScope(), GetObjectType(), err_stream.str()));
1✔
251

252
  // Check unused parameters
253
  // Loops over all candidate-parameters and
254
  // checks whether they have an assignable
255
  // input-parameter or if they have been renamed.
256
  {
257
    for (const auto& param : params.GetParameters())
20,612✔
258
    {
259
      const auto& param_name = param.GetName();
16,026✔
260
      if (IsParameterIgnored(param_name))
16,026✔
261
        continue;
×
262
      if (not this->Has(param_name))
16,026✔
263
        err_stream << "Invalid param \"" << param_name << "\" supplied.\n";
2✔
264
      else if (renamed_error_tags_.count(param_name) > 0)
16,024✔
265
      {
266
        err_stream << "Invalid param \"" << param_name << "\" supplied. ";
×
267
        err_stream << "The parameter has been renamed. ";
×
UNCOV
268
        err_stream << renamed_error_tags_.at(param_name);
×
269
      }
270
    }
16,026✔
271

272
    if (not err_stream.str().empty())
4,586✔
273
      throw std::invalid_argument(
274
        InputErrorStr(GetErrorOriginScope(), GetObjectType(), err_stream.str()));
1✔
275
  }
276

277
  // Check deprecation warnings
278
  // Loops over all candidate-parameters and
279
  // checks whether they have deprecation warnings.
280
  {
281
    const auto& dep_warns = deprecation_warning_tags_;
4,585✔
282
    for (const auto& param : params.GetParameters())
20,609✔
283
    {
284
      const auto& param_name = param.GetName();
16,024✔
285

286
      if (IsParameterIgnored(param_name))
16,024✔
287
        continue;
×
288

289
      if (this->Has(param_name) and (dep_warns.count(param_name) > 0))
16,024✔
290
        log.Log0Warning() << "Parameter \"" << param_name << "\" has been deprecated "
×
291
                          << "and will be removed soon.\n"
×
292
                          << dep_warns.at(param_name);
×
293
    }
16,024✔
294
  }
295

296
  // Check deprecation errors
297
  // Loops over all candidate-parameters and
298
  // checks whether they have deprecation errors.
299
  {
300
    const auto& dep_errs = deprecation_error_tags_;
4,585✔
301
    for (const auto& param : params.GetParameters())
20,609✔
302
    {
303
      const auto& param_name = param.GetName();
16,024✔
304

305
      if (IsParameterIgnored(param_name))
16,024✔
306
        continue;
×
307

308
      if (this->Has(param_name) and (dep_errs.count(param_name) > 0))
16,024✔
309
      {
310
        std::ostringstream oss;
×
311
        oss << "Parameter \"" << param_name << "\" has been deprecated.\n"
312
            << dep_errs.at(param_name);
×
313
        throw std::runtime_error(oss.str());
×
314
      }
×
315
    }
16,024✔
316
  }
317

318
  // Now attempt to assign values
319
  for (const auto& param : params.GetParameters())
20,609✔
320
  {
321
    const auto& param_name = param.GetName();
16,024✔
322

323
    if (IsParameterIgnored(param_name))
16,024✔
324
      continue;
×
325

326
    auto& input_param = GetParam(param_name);
16,024✔
327

328
    // Check types match
329
    if (param.GetType() != input_param.GetType())
16,024✔
330
    {
331
      if (type_mismatch_allowed_tags_.count(param_name) == 0)
2✔
332
      {
333
        err_stream << "Invalid parameter type \"" << ParameterBlockTypeName(param.GetType())
2✔
334
                   << "\" for parameter \"" << param_name << "\". Expecting type \""
335
                   << ParameterBlockTypeName(input_param.GetType()) << "\".\n"
4✔
336
                   << "doc-string: " << GetParameterDocString(param_name);
6✔
337
        continue;
2✔
338
      } // if not mismatch allowed
339
    } // if type mismatch
340

341
    // Check constraint
342
    if (constraint_tags_.count(input_param.GetName()) != 0)
16,022✔
343
    {
344
      const auto& constraint = constraint_tags_.at(input_param.GetName());
3,452✔
345
      if (not constraint->IsAllowable(param.GetValue()))
3,452✔
346
      {
347
        err_stream << constraint->OutOfRangeString(input_param.GetName(), param.GetValue());
×
348
        err_stream << "\n";
×
349
        continue;
×
350
      }
351
    } // if constraint
352

353
    if (log.GetVerbosity() >= 2)
16,022✔
354
      log.Log0Verbose2() << "Setting parameter " << param_name;
×
355
    input_param = param;
16,022✔
356
    parameter_valid_[param_name] = true;
16,022✔
357
  } // for input params
16,024✔
358

359
  if (not err_stream.str().empty())
4,585✔
360
    throw std::invalid_argument(
361
      InputErrorStr(GetErrorOriginScope(), GetObjectType(), err_stream.str()));
2✔
362
}
4,587✔
363

364
void
365
InputParameters::MarkParameterDeprecatedWarning(const std::string& param_name,
×
366
                                                const std::string& deprecation_message)
367
{
368
  if (Has(param_name))
×
369
    deprecation_warning_tags_[param_name] = deprecation_message;
×
370
  else
371
    throw std::logic_error(ParamNotPresentErrorStr(__PRETTY_FUNCTION__, param_name));
×
372
}
×
373

374
void
375
InputParameters::MarkParameterDeprecatedError(const std::string& param_name,
×
376
                                              const std::string& deprecation_message)
377
{
378
  if (Has(param_name))
×
379
    deprecation_error_tags_[param_name] = deprecation_message;
×
380
  else
381
    throw std::logic_error(ParamNotPresentErrorStr(__PRETTY_FUNCTION__, param_name));
×
382
}
×
383

384
void
385
InputParameters::MarkParameterRenamed(const std::string& param_name,
×
386
                                      const std::string& renaming_description)
387
{
388
  if (Has(param_name))
×
389
    renamed_error_tags_[param_name] = renaming_description;
×
390
  else
391
    throw std::logic_error(ParamNotPresentErrorStr(__PRETTY_FUNCTION__, param_name));
×
392
}
×
393

394
void
395
InputParameters::ConstrainParameterRange(const std::string& param_name,
5,081✔
396
                                         std::shared_ptr<AllowableRange> allowable_range)
397
{
398
  if (Has(param_name))
5,081✔
399
  {
400
    const auto& param_type = GetParam(param_name).GetType();
5,081✔
401
    OpenSnInvalidArgumentIf(
5,081✔
402
      param_type == ParameterBlockType::BLOCK or param_type == ParameterBlockType::ARRAY,
403
      std::string("Parameter \"") + param_name + "\" is of type " +
404
        ParameterBlockTypeName(param_type) + " to which constraints cannot be applied");
405
    constraint_tags_[param_name] = allowable_range;
5,081✔
406
  }
407
  else
408
    throw std::logic_error(ParamNotPresentErrorStr(__PRETTY_FUNCTION__, param_name));
×
409
}
5,081✔
410

411
void
412
InputParameters::SetParameterTypeMismatchAllowed(const std::string& param_name)
×
413
{
414
  OpenSnInvalidArgumentIf(not Has(param_name), "Parameter \"" + param_name + "\" not present.");
×
415
  type_mismatch_allowed_tags_[param_name] = true;
×
416
}
×
417

418
void
419
InputParameters::DumpParameters() const
×
420
{
421
  log.Log() << "CLASS_NAME " << class_name_;
×
422

423
  log.Log() << "DESCRIPTION_BEGIN";
×
424
  std::cout << GetGeneralDescription() << "\n";
×
425
  log.Log() << "DESCRIPTION_END\n";
×
426

427
  log.Log() << "DOC_GROUP " << doc_group_;
×
428
  const std::string sp2 = "  ";
×
429
  const std::string sp4 = "    ";
×
430
  const auto params = GetParameters();
×
431
  for (const auto& param : params)
×
432
  {
433
    const auto& param_name = param.GetName();
×
434
    log.Log() << sp2 << "PARAM_BEGIN " << param_name;
×
435

436
    const auto type = param.GetType();
×
437

438
    log.Log() << sp4 << "TYPE " << ParameterBlockTypeName(type);
×
439

440
    if (parameter_class_tags_.at(param_name) == InputParameterTag::OPTIONAL)
×
441
    {
442
      log.Log() << sp4 << "TAG OPTIONAL";
×
443
      if (type != ParameterBlockType::BLOCK and type != ParameterBlockType::ARRAY)
×
444
        log.Log() << sp4 << "DEFAULT_VALUE " << param.GetValue().PrintStr();
×
445
      else if (type == ParameterBlockType::ARRAY)
×
446
      {
447
        std::stringstream outstr;
×
448
        outstr << sp4 << "DEFAULT_VALUE ";
×
449
        for (size_t k = 0; k < param.GetNumParameters(); ++k)
×
450
        {
451
          const auto& sub_param = param.GetParam(k);
×
452
          outstr << sub_param.GetValue().PrintStr() << ", ";
×
453
        }
454
        log.Log() << outstr.str();
×
455
      }
×
456
    }
457
    else
458
      log.Log() << sp4 << "TAG REQUIRED";
×
459

460
    if (constraint_tags_.count(param_name) != 0)
×
461
      log.Log() << sp4 << "CONSTRAINTS " << constraint_tags_.at(param_name)->PrintRange();
×
462

463
    if (parameter_doc_string_.count(param_name) != 0)
×
464
    {
465
      log.Log() << sp4 << "DOC_STRING_BEGIN";
×
466
      std::cout << parameter_doc_string_.at(param_name) << "\n";
×
467
      log.Log() << sp4 << "DOC_STRING_END";
×
468
    }
469

470
    const auto& linkage = GetParameterDocumentationLink(param_name);
×
471
    if (not linkage.empty())
×
472
    {
473
      log.Log() << sp4 << "LINKS " << linkage;
×
474
    }
475

476
    log.Log() << sp2 << "PARAM_END";
×
477
  }
×
478
}
×
479

480
bool
481
InputParameters::IsParameterValid(const std::string& param_name) const
1,335✔
482
{
483
  auto it = parameter_valid_.find(param_name);
1,335✔
484
  if (it != parameter_valid_.end())
1,335✔
485
    return it->second;
782✔
486
  else
487
    return false;
553✔
488
}
489

490
} // namespace opensn
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc