Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #pragma once
11 :
12 : #include "THMObject.h"
13 : #include "FlowModel.h"
14 : #include "THMProblem.h"
15 : #include "InputParameterWarehouse.h"
16 : #include "LoggingInterface.h"
17 : #include "NamingInterface.h"
18 : #include "ADFunctorInterface.h"
19 :
20 : class THMProblem;
21 : class THMMesh;
22 : class ThermalHydraulicsApp;
23 : class Convergence;
24 :
25 : /**
26 : * Base class for THM components
27 : */
28 : class Component : public THMObject,
29 : public LoggingInterface,
30 : public NamingInterface,
31 : public ADFunctorInterface
32 : {
33 : public:
34 : Component(const InputParameters & parameters);
35 :
36 : /// Component setup status type
37 : enum EComponentSetupStatus
38 : {
39 : CREATED, ///< only created
40 : MESH_PREPARED, ///< mesh set up
41 : INITIALIZED_PRIMARY, ///< mesh set up, called primary init
42 : INITIALIZED_SECONDARY, ///< mesh set up, called both inits
43 : CHECKED ///< mesh set up, called both inits, checked
44 : };
45 :
46 : /// Return a string for the setup status
47 : std::string stringify(EComponentSetupStatus status) const;
48 :
49 : /**
50 : * Get the component name
51 : * @return The name of the component. For composite component, return its parent name
52 : */
53 : const std::string & cname() const;
54 :
55 8225 : Component * parent() { return _parent; }
56 :
57 : /**
58 : * Const reference to mesh, which can be called at any point
59 : *
60 : * Note that overloading mesh() was not possible due to the need to call this
61 : * const version, even when the component is not const.
62 : */
63 1935 : const THMMesh & constMesh() const { return _mesh; }
64 :
65 : /**
66 : * Non-const reference to THM mesh, which can only be called before the end of mesh setup
67 : */
68 : THMMesh & mesh();
69 :
70 : /**
71 : * Gets the THM problem
72 : */
73 : THMProblem & getTHMProblem() const;
74 :
75 : /**
76 : * Test if a parameter exists in the object's input parameters
77 : * @param name The name of the parameter
78 : * @return true if the parameter exists, false otherwise
79 : */
80 : template <typename T>
81 : bool hasParam(const std::string & name) const;
82 :
83 : /**
84 : * Returns a list of names of components that this component depends upon
85 : */
86 : const std::vector<std::string> & getDependencies() const { return _dependencies; }
87 :
88 : /**
89 : * Wrapper function for \c init() that marks the function as being called
90 : */
91 : void executeInit();
92 :
93 : /**
94 : * Wrapper function for \c initSecondary() that marks the function as being called
95 : */
96 : void executeInitSecondary();
97 :
98 : /**
99 : * Wrapper function for \c check() that marks the function as being called
100 : */
101 : void executeCheck() const;
102 :
103 : /**
104 : * Wrapper function for \c setupMesh() that marks the function as being called
105 : */
106 : void executeSetupMesh();
107 :
108 : /**
109 : * Adds relationship managers for the component
110 : */
111 8274 : virtual void addRelationshipManagers(Moose::RelationshipManagerType /*input_rm_type*/) {}
112 :
113 3235 : virtual void addVariables() {}
114 :
115 18 : virtual void addMooseObjects() {}
116 :
117 : /**
118 : * Gets the Component's nonlinear Convergence object if it has one
119 : */
120 : virtual Convergence * getNonlinearConvergence() const;
121 :
122 : /**
123 : * Return a reference to a component via a parameter name
124 : * @tparam T the type of the component we are requesting
125 : * @param name The parameter name that has the component name
126 : */
127 : template <typename T>
128 : const T & getComponent(const std::string & name) const;
129 :
130 : /**
131 : * Return a reference to a component given its name
132 : * @tparam T the type of the component we are requesting
133 : * @param cname The name of the component
134 : */
135 : template <typename T>
136 : const T & getComponentByName(const std::string & cname) const;
137 :
138 : /**
139 : * Check the existence and type of a component via a parameter name
140 : * @tparam T the type of the component we are requesting
141 : * @param name The parameter name that has the component name
142 : * @return true if the component with given name and type exists, otherwise false
143 : */
144 : template <typename T>
145 : bool hasComponent(const std::string & name) const;
146 :
147 : /**
148 : * Check the existence and type of a component given its name
149 : * @tparam T the type of the component we are requesting
150 : * @param cname The name of the component
151 : * @return true if the component with given name and type exists, otherwise false
152 : */
153 : template <typename T>
154 : bool hasComponentByName(const std::string & cname) const;
155 :
156 : /**
157 : * Connects a controllable parameter of the component to a controllable parameter of
158 : * a constituent object.
159 : *
160 : * This version assumes that the component and object have the same control parameter name.
161 : *
162 : * @param[in] obj_params Constituent object input parameters object
163 : * @param[in] obj_name Constituent object name
164 : * @param[in] param Controllable parameter name (same in both component and constituent
165 : * object)
166 : */
167 : void connectObject(const InputParameters & obj_params,
168 : const std::string & obj_name,
169 : const std::string & param) const;
170 : /**
171 : * Connects a controllable parameter of the component to a controllable parameter of
172 : * a constituent object.
173 : *
174 : * This is achieved by creating a "controllable parameter alias".
175 : *
176 : * @param[in] obj_params Constituent object input parameters object
177 : * @param[in] obj_name Constituent object name
178 : * @param[in] comp_param Controllable component parameter
179 : * @param[in] obj_param Constituent object parameter
180 : */
181 : void connectObject(const InputParameters & obj_params,
182 : const std::string & obj_name,
183 : const std::string & comp_param,
184 : const std::string & obj_param) const;
185 :
186 : /**
187 : * Throws an error if the supplied setup status of this component has not been reached
188 : *
189 : * This is useful for getter functions that rely on data initialized after the
190 : * constructor; if an error is not thrown, then uninitialized data could be
191 : * returned from these functions.
192 : *
193 : * @param[in] status Setup status that this component must have reached
194 : */
195 : void checkSetupStatus(const EComponentSetupStatus & status) const;
196 :
197 : /**
198 : * Checks that a component exists
199 : *
200 : * @param[in] comp_name name of the component
201 : */
202 : void checkComponentExistsByName(const std::string & comp_name) const;
203 :
204 : /**
205 : * Checks that the component of a certain type exists, where the name is given by a parameter
206 : *
207 : * @tparam T enforced type of component
208 : * @param[in] param parameter name for component name
209 : */
210 : template <typename T>
211 : void checkComponentOfTypeExists(const std::string & param) const;
212 :
213 : /**
214 : * Checks that the component of a certain type exists
215 : *
216 : * @tparam T enforced type of component
217 : * @param[in] comp_name component name
218 : */
219 : template <typename T>
220 : void checkComponentOfTypeExistsByName(const std::string & comp_name) const;
221 :
222 : /**
223 : * Logs an error
224 : */
225 : template <typename... Args>
226 212 : void logError(Args &&... args) const
227 : {
228 212 : logComponentError(cname(), std::forward<Args>(args)...);
229 212 : }
230 :
231 : /**
232 : * Logs a warning
233 : */
234 : template <typename... Args>
235 38 : void logWarning(Args &&... args) const
236 : {
237 38 : logComponentWarning(cname(), std::forward<Args>(args)...);
238 38 : }
239 :
240 : /**
241 : * Adds a component name to the list of dependencies
242 : *
243 : * @param[in] dependency name of component to add to list of dependencies
244 : */
245 : void addDependency(const std::string & dependency);
246 :
247 : /**
248 : * Gets an enum parameter
249 : *
250 : * This function takes the name of a MooseEnum parameter that is tied to an
251 : * enum defined in THM. If the value is invalid, an error will be logged,
252 : * and a negative integer will be cast into the enum type.
253 : *
254 : * @tparam T enum type
255 : * @param[in] param name of the MooseEnum parameter
256 : * @param[in] log_error If true, log an error if the valid is invalid
257 : */
258 : template <typename T>
259 : T getEnumParam(const std::string & param, bool log_error = true) const;
260 :
261 : /**
262 : * Whether the problem is transient
263 : */
264 7073 : bool problemIsTransient() const { return getTHMProblem().isTransient(); }
265 :
266 : /**
267 : * Gets the node IDs corresponding to this component
268 : */
269 : const std::vector<dof_id_type> & getNodeIDs() const;
270 :
271 : /**
272 : * Gets the element IDs corresponding to this component
273 : */
274 : const std::vector<dof_id_type> & getElementIDs() const;
275 :
276 : /**
277 : * Gets the subdomain names for this component
278 : *
279 : * @return vector of subdomain names for this component
280 : */
281 : virtual const std::vector<SubdomainName> & getSubdomainNames() const;
282 :
283 : /**
284 : * Gets the coordinate system types for this component
285 : *
286 : * @return vector of coordinate system types for this component
287 : */
288 : virtual const std::vector<Moose::CoordinateSystemType> & getCoordSysTypes() const;
289 :
290 : /**
291 : * Runtime check to make sure that a parameter of specified type exists in the component's input
292 : * parameters
293 : *
294 : * This is intended to help developers write code. The idea is to provide a useful message when
295 : * developers make typos, etc. If this check fails, the code execution will be stopped.
296 : *
297 : * @tparam T The type of the parameter to be checked
298 : * @param function_name The name of the function calling this method
299 : * @param param_name The name of the parameter to be checked
300 : */
301 : template <typename T>
302 : void insistParameterExists(const std::string & function_name,
303 : const std::string & param_name) const;
304 :
305 : /**
306 : * Checks that a parameter value is less than a value
307 : *
308 : * @tparam T type of parameter
309 : * @param[in] param parameter name
310 : * @param[in] value_max value which parameter value must be less than
311 : */
312 : template <typename T>
313 : void checkParameterValueLessThan(const std::string & param, const T & value_max) const;
314 :
315 : /**
316 : * Checks that the size of a vector parameter is less than a value
317 : *
318 : * @tparam T type of element in the vector parameter
319 : * @param[in] param parameter name
320 : * @param[in] n_entries value which parameter size must be less than
321 : */
322 : template <typename T>
323 : void checkSizeLessThan(const std::string & param, const unsigned int & n_entries) const;
324 :
325 : /**
326 : * Checks that the size of a vector parameter is greater than a value
327 : *
328 : * @tparam T type of element in the vector parameter
329 : * @param[in] param parameter name
330 : * @param[in] n_entries value which parameter size must be greater than
331 : */
332 : template <typename T>
333 : void checkSizeGreaterThan(const std::string & param, const unsigned int & n_entries) const;
334 :
335 : /**
336 : * Checks that the size of two vector parameters are equal
337 : *
338 : * @tparam T1 type of element in the first vector parameter
339 : * @tparam T2 type of element in the second vector parameter
340 : * @param[in] param1 first parameter name
341 : * @param[in] param2 second parameter name
342 : */
343 : template <typename T1, typename T2>
344 : void checkEqualSize(const std::string & param1, const std::string & param2) const;
345 :
346 : /**
347 : * Checks that the size of a vector parameter equals a value
348 : *
349 : * This version does not supply a description to the value.
350 : *
351 : * @tparam T type of element in the vector parameter
352 : * @param[in] param parameter name
353 : * @param[in] n_entries value which parameter size must be equal to
354 : */
355 : template <typename T>
356 : void checkSizeEqualsValue(const std::string & param, const unsigned int & n_entries) const;
357 :
358 : /**
359 : * Checks that the size of a vector parameter equals a value
360 : *
361 : * This version supplies a description to the value.
362 : *
363 : * @tparam T type of element in the vector parameter
364 : * @param[in] param parameter name
365 : * @param[in] n_entries value which parameter size must be equal to
366 : * @param[in] description description of the value that size must be equal to
367 : */
368 : template <typename T>
369 : void checkSizeEqualsValue(const std::string & param,
370 : const unsigned int & n_entries,
371 : const std::string & description) const;
372 :
373 : /**
374 : * Checks that the size of a vector parameter equals the value of another parameter
375 : *
376 : * @tparam T1 type of element in the vector parameter
377 : * @tparam T2 type of the parameter whose value is compared to size
378 : * @param[in] param1 vector parameter name
379 : * @param[in] param2 name of parameter whose value is compared to size
380 : */
381 : template <typename T1, typename T2>
382 : void checkSizeEqualsParameterValue(const std::string & param1, const std::string & param2) const;
383 :
384 : /**
385 : * Checks that exactly one parameter out of a list is provided
386 : *
387 : * @param[in] params vector of parameter names
388 : * @param[in] need_one_specified Need one of the parameters specified?
389 : */
390 : void checkMutuallyExclusiveParameters(const std::vector<std::string> & params,
391 : bool need_one_specified = true) const;
392 :
393 : protected:
394 : /**
395 : * Initializes the component
396 : *
397 : * The reason this function exists (as opposed to just having everything in
398 : * the constructor) is because some initialization depends on all components
399 : * existing, since many components couple to other components. Therefore,
400 : * when deciding whether code should go into the constructor or this function,
401 : * one should use the following reasoning: if an operation does not require
402 : * the existence of other components, then put that operation in the
403 : * constructor; otherwise, put it in this function.
404 : */
405 761 : virtual void init() {}
406 :
407 : /**
408 : * Perform secondary initialization, which relies on init() being called
409 : * for all components.
410 : */
411 4831 : virtual void initSecondary() {}
412 :
413 : /**
414 : * Check the component integrity
415 : */
416 173 : virtual void check() const {}
417 :
418 : /**
419 : * Performs mesh setup such as creating mesh or naming mesh sets
420 : */
421 1240 : virtual void setupMesh() {}
422 :
423 : /**
424 : * Method to add a relationship manager for the objects being added to the system. Relationship
425 : * managers have to be added relatively early. In many cases before the Action::act() method
426 : * is called.
427 : *
428 : * This method was copied from Action.
429 : *
430 : * @param moose_object_pars The MooseObject to inspect for RelationshipManagers to add
431 : */
432 : void addRelationshipManagersFromParameters(const InputParameters & moose_object_pars);
433 :
434 : Node * addNode(const Point & pt);
435 : Elem * addNodeElement(dof_id_type node);
436 :
437 : /**
438 : * Sets the next subdomain ID, name, and coordinate system
439 : *
440 : * @param[in] subdomain_id subdomain index
441 : * @param[in] subdomain_name name of the new subdomain
442 : * @param[in] coord_system type of coordinate system
443 : */
444 : virtual void
445 : setSubdomainInfo(SubdomainID subdomain_id,
446 : const std::string & subdomain_name,
447 2800 : const Moose::CoordinateSystemType & coord_system = Moose::COORD_XYZ);
448 :
449 : /**
450 : * Adds a functor material to compute the absolute value of the change (step) of some functor
451 : * between nonlinear iterations
452 : *
453 : * @param[in] functor_name Functor for which to compute step
454 : * @param[in] property Name of new step functor material property
455 : * @param[in] functor_is_ad Is the functor for which to compute the step AD?
456 : */
457 : void addNonlinearStepFunctorMaterial(const std::string & functor_name,
458 : const std::string & property,
459 : bool functor_is_ad);
460 :
461 : /**
462 : * Adds a Postprocessor to compute the maximum of a functor over some domain
463 : *
464 : * @param[in] functor_name Functor for which to compute maximum
465 : * @param[in] pp_name Name of new Postprocessor
466 : * @param[in] normalization Factor by which to divide quantity
467 : * @param[in] subdomains Subdomains over which to compute maximum
468 : */
469 : void addMaximumFunctorPostprocessor(const std::string & functor_name,
470 : const std::string & pp_name,
471 : const Real normalization,
472 : const std::vector<SubdomainName> & subdomains);
473 :
474 : /**
475 : * Adds a MultiPostprocessorConvergence for nonlinear convergence for the component
476 : *
477 : * @param[in] postprocessors Postprocessors to compare
478 : * @param[in] descriptions Description of each Postprocessor
479 : * @param[in] tolerances Tolerance for each check
480 : */
481 : void addMultiPostprocessorConvergence(const std::vector<PostprocessorName> & postprocessors,
482 : const std::vector<std::string> & descriptions,
483 : const std::vector<Real> & tolerances);
484 :
485 : /// Nonlinear Convergence name
486 5552 : std::string nonlinearConvergenceName() const { return genName(name(), "nlconv"); }
487 :
488 : /// Pointer to a parent component (used in composed components)
489 : Component * _parent;
490 :
491 : /// THM problem this component is part of
492 : /// TODO: make _sim private (applications need to switch to getters to avoid breaking).
493 : /// Also, rename to "_thm_problem" at that point.
494 : THMProblem & _sim;
495 :
496 : /// The Factory associated with the MooseApp
497 : Factory & _factory;
498 :
499 : const Real & _zero;
500 :
501 : /// The THM mesh
502 : /// TODO: make _mesh private (applications need to switch to getters to avoid breaking)
503 : THMMesh & _mesh;
504 :
505 : /// Node IDs of this component
506 : std::vector<dof_id_type> _node_ids;
507 : /// Element IDs of this component
508 : std::vector<dof_id_type> _elem_ids;
509 :
510 : /// List of subdomain IDs this components owns
511 : std::vector<SubdomainID> _subdomain_ids;
512 : /// List of subdomain names this components owns
513 : std::vector<SubdomainName> _subdomain_names;
514 : /// List of coordinate system for each subdomain
515 : std::vector<Moose::CoordinateSystemType> _coord_sys;
516 :
517 : private:
518 : /**
519 : * Method for adding a single relationship manager
520 : *
521 : * This method was copied from Action.
522 : *
523 : * @param moose_object_pars The parameters of the MooseObject that requested the RM
524 : * @param rm_name The class type of the RM, e.g. ElementSideNeighborLayers
525 : * @param rm_type The RelationshipManagerType, e.g. geometric, algebraic, coupling
526 : * @param rm_input_parameter_func The RM callback function, typically a lambda defined in the
527 : * requesting MooseObject's validParams function
528 : * @param sys_type A RMSystemType that can be used to limit the systems and consequent dof_maps
529 : * that the RM can be attached to
530 : */
531 : void
532 : addRelationshipManager(const InputParameters & moose_object_pars,
533 : std::string rm_name,
534 : Moose::RelationshipManagerType rm_type,
535 : Moose::RelationshipManagerInputParameterCallback rm_input_parameter_func,
536 : Moose::RMSystemType sys_type = Moose::RMSystemType::NONE);
537 :
538 : /// Component setup status
539 : mutable EComponentSetupStatus _component_setup_status;
540 :
541 : /// List of names of components that this component depends upon
542 : std::vector<std::string> _dependencies;
543 :
544 : public:
545 : static InputParameters validParams();
546 : };
547 :
548 : template <typename T>
549 : bool
550 21841 : Component::hasParam(const std::string & name) const
551 : {
552 21841 : return parameters().have_parameter<T>(name);
553 : }
554 :
555 : template <typename T>
556 : const T &
557 430 : Component::getComponent(const std::string & pname) const
558 : {
559 : const std::string & comp_name = getParam<std::string>(pname);
560 430 : return getComponentByName<T>(comp_name);
561 : }
562 :
563 : template <typename T>
564 : const T &
565 : Component::getComponentByName(const std::string & comp_name) const
566 : {
567 15557 : return _sim.getComponentByName<T>(comp_name);
568 : }
569 :
570 : template <typename T>
571 : bool
572 222 : Component::hasComponent(const std::string & pname) const
573 : {
574 : const std::string & comp_name = getParam<std::string>(pname);
575 222 : return hasComponentByName<T>(comp_name);
576 : }
577 :
578 : template <typename T>
579 : bool
580 : Component::hasComponentByName(const std::string & comp_name) const
581 : {
582 26851 : if (_sim.hasComponentOfType<T>(comp_name))
583 : return true;
584 : else
585 : return false;
586 : }
587 :
588 : template <typename T>
589 : T
590 4491 : Component::getEnumParam(const std::string & param, bool log_error) const
591 : {
592 : const MooseEnum & moose_enum = getParam<MooseEnum>(param);
593 4491 : const T value = THM::stringToEnum<T>(moose_enum);
594 4491 : if (log_error && static_cast<int>(value) < 0) // cast necessary for scoped enums
595 : {
596 : // Get the keys from the MooseEnum. Unfortunately, this returns a list of
597 : // *all* keys, including the invalid key that was supplied. Thus, that key
598 : // needs to be manually excluded below.
599 0 : const std::vector<std::string> & keys = moose_enum.getNames();
600 :
601 : // Create the string of keys to go in the error message. The last element of
602 : // keys is skipped because the invalid key should always be last.
603 0 : std::string keys_string = "{";
604 0 : for (unsigned int i = 0; i < keys.size() - 1; ++i)
605 : {
606 0 : if (i != 0)
607 : keys_string += ",";
608 0 : keys_string += "'" + keys[i] + "'";
609 : }
610 : keys_string += "}";
611 :
612 0 : logError("The parameter '" + param + "' was given an invalid value ('" +
613 0 : std::string(moose_enum) + "'). Valid values (case-insensitive) are " + keys_string);
614 0 : }
615 :
616 4491 : return value;
617 : }
618 :
619 : template <typename T>
620 : void
621 21841 : Component::insistParameterExists(const std::string & function_name,
622 : const std::string & param_name) const
623 : {
624 21841 : if (!hasParam<T>(param_name))
625 0 : mooseError(name(),
626 : ": Calling ",
627 : function_name,
628 : " failed, parameter '",
629 : param_name,
630 : "' does not exist or does not have the type you requested. Double check your "
631 : "spelling and/or type of the parameter.");
632 21841 : }
633 :
634 : template <typename T>
635 : void
636 216 : Component::checkComponentOfTypeExists(const std::string & param) const
637 : {
638 432 : insistParameterExists<std::string>(__FUNCTION__, param);
639 :
640 : const std::string & comp_name = getParam<std::string>(param);
641 216 : checkComponentOfTypeExistsByName<T>(comp_name);
642 216 : }
643 :
644 : template <typename T>
645 : void
646 14071 : Component::checkComponentOfTypeExistsByName(const std::string & comp_name) const
647 : {
648 14071 : if (!_sim.hasComponentOfType<T>(comp_name))
649 : {
650 36 : if (_sim.hasComponent(comp_name))
651 36 : logError("The component '", comp_name, "' is not of type '", demangle(typeid(T).name()), "'");
652 : else
653 18 : logError("The component '", comp_name, "' does not exist");
654 : }
655 14071 : }
656 :
657 : template <typename T>
658 : void
659 : Component::checkParameterValueLessThan(const std::string & param, const T & value_max) const
660 : {
661 : insistParameterExists<T>(__FUNCTION__, param);
662 :
663 : const auto & value = getParam<T>(param);
664 : if (value >= value_max)
665 : logError("The value of parameter '", param, "' (", value, ") must be less than ", value_max);
666 : }
667 :
668 : template <typename T>
669 : void
670 : Component::checkSizeLessThan(const std::string & param, const unsigned int & n_entries) const
671 : {
672 : insistParameterExists<std::vector<T>>(__FUNCTION__, param);
673 :
674 : const auto & value = getParam<std::vector<T>>(param);
675 : if (value.size() >= n_entries)
676 : logError("The number of entries in the parameter '",
677 : param,
678 : "' (",
679 : value.size(),
680 : ") must be less than ",
681 : n_entries);
682 : }
683 :
684 : template <typename T>
685 : void
686 3307 : Component::checkSizeGreaterThan(const std::string & param, const unsigned int & n_entries) const
687 : {
688 6614 : insistParameterExists<std::vector<T>>(__FUNCTION__, param);
689 :
690 : const auto & value = getParam<std::vector<T>>(param);
691 3307 : if (value.size() <= n_entries)
692 0 : logError("The number of entries in the parameter '",
693 : param,
694 : "' (",
695 0 : value.size(),
696 : ") must be greater than ",
697 : n_entries);
698 3307 : }
699 :
700 : template <typename T1, typename T2>
701 : void
702 9058 : Component::checkEqualSize(const std::string & param1, const std::string & param2) const
703 : {
704 9058 : insistParameterExists<std::vector<T1>>(__FUNCTION__, param1);
705 18116 : insistParameterExists<std::vector<T2>>(__FUNCTION__, param2);
706 :
707 : const auto & value1 = getParam<std::vector<T1>>(param1);
708 : const auto & value2 = getParam<std::vector<T2>>(param2);
709 9058 : if (value1.size() != value2.size())
710 12 : logError("The number of entries in parameter '",
711 : param1,
712 : "' (",
713 24 : value1.size(),
714 : ") must equal the number of entries of parameter '",
715 : param2,
716 : "' (",
717 12 : value2.size(),
718 : ")");
719 9058 : }
720 :
721 : template <typename T>
722 : void
723 202 : Component::checkSizeEqualsValue(const std::string & param, const unsigned int & n_entries) const
724 : {
725 404 : insistParameterExists<std::vector<T>>(__FUNCTION__, param);
726 :
727 : const auto & param_value = getParam<std::vector<T>>(param);
728 202 : if (param_value.size() != n_entries)
729 0 : logError("The number of entries in parameter '",
730 : param,
731 : "' (",
732 0 : param_value.size(),
733 : ") must be equal to ",
734 : n_entries);
735 202 : }
736 :
737 : template <typename T>
738 : void
739 : Component::checkSizeEqualsValue(const std::string & param,
740 : const unsigned int & n_entries,
741 : const std::string & description) const
742 : {
743 : insistParameterExists<std::vector<T>>(__FUNCTION__, param);
744 :
745 : const auto & param_value = getParam<std::vector<T>>(param);
746 : if (param_value.size() != n_entries)
747 : logError("The number of entries in parameter '",
748 : param,
749 : "' (",
750 : param_value.size(),
751 : ") must be equal to ",
752 : description,
753 : " (",
754 : n_entries,
755 : ")");
756 : }
757 :
758 : template <typename T1, typename T2>
759 : void
760 : Component::checkSizeEqualsParameterValue(const std::string & param1,
761 : const std::string & param2) const
762 : {
763 : insistParameterExists<std::vector<T1>>(__FUNCTION__, param1);
764 : insistParameterExists<T2>(__FUNCTION__, param2);
765 :
766 : const auto & value1 = getParam<std::vector<T1>>(param1);
767 : const auto & value2 = getParam<T2>(param2);
768 : if (value1.size() != value2)
769 : logError("The number of entries in parameter '",
770 : param1,
771 : "' (",
772 : value1.size(),
773 : ") must be equal to the value of parameter '",
774 : param2,
775 : "' (",
776 : value2,
777 : ")");
778 : }
|