/*!
    @brief create a container (array or object) from an initializer list

    Creates a JSON value of type array or object from the passed initializer
    list @a init. In case @a type_deduction is `true` (default), the type of
    the JSON value to be created is deducted from the initializer list @a init
    according to the following rules:

    1. If the list is empty, an empty JSON object value `{}` is created.
    2. If the list consists of pairs whose first element is a string, a JSON
       object value is created where the first elements of the pairs are
       treated as keys and the second elements are as values.
    3. In all other cases, an array is created.

    The rules aim to create the best fit between a C++ initializer list and
    JSON values. The rationale is as follows:

    1. The empty initializer list is written as `{}` which is exactly an empty
       JSON object.
    2. C++ has no way of describing mapped types other than to list a list of
       pairs. As JSON requires that keys must be of type string, rule 2 is the
       weakest constraint one can pose on initializer lists to interpret them
       as an object.
    3. In all other cases, the initializer list could not be interpreted as
       JSON object type, so interpreting it as JSON array type is safe.

    With the rules described above, the following JSON values cannot be
    expressed by an initializer list:

    - the empty array (`[]`): use @ref array(initializer_list_t)
      with an empty initializer list in this case
    - arrays whose elements satisfy rule 2: use @ref
      array(initializer_list_t) with the same initializer list
      in this case

    @note When used without parentheses around an empty initializer list, @ref
    basic_json() is called instead of this function, yielding the JSON null
    value.

    @param[in] init  initializer list with JSON values

    @param[in] type_deduction internal parameter; when set to `true`, the type
    of the JSON value is deducted from the initializer list @a init; when set
    to `false`, the type provided via @a manual_type is forced. This mode is
    used by the functions @ref array(initializer_list_t) and
    @ref object(initializer_list_t).

    @param[in] manual_type internal parameter; when @a type_deduction is set
    to `false`, the created JSON value will use the provided type (only @ref
    value_t::array and @ref value_t::object are valid); when @a type_deduction
    is set to `true`, this parameter has no effect

    @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
    `value_t::object`, but @a init contains an element which is not a pair
    whose first element is a string. In this case, the constructor could not
    create an object. If @a type_deduction would have be `true`, an array
    would have been created. See @ref object(initializer_list_t)
    for an example.

    @complexity Linear in the size of the initializer list @a init.

    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
    changes to any JSON value.

    @liveexample{The example below shows how JSON values are created from
    initializer lists.,basic_json__list_init_t}

    @sa @ref array(initializer_list_t) -- create a JSON array
    value from an initializer list
    @sa @ref object(initializer_list_t) -- create a JSON object
    value from an initializer list

    @since version 1.0.0
    */


/*!
    @brief inserts element

    Inserts element @a val before iterator @a pos.

    @param[in] pos iterator before which the content will be inserted; may be
    the end() iterator
    @param[in] val element to insert
    @return iterator pointing to the inserted @a val.

    @throw type_error.309 if called on JSON values other than arrays;
    example: `"cannot use insert() with string"`
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
    example: `"iterator does not fit current value"`

    @complexity Constant plus linear in the distance between @a pos and end of
    the container.

    @liveexample{The example shows how `insert()` is used.,insert}

    @since version 1.0.0
    */


/*!
    @brief inserts elements

    Inserts @a cnt copies of @a val before iterator @a pos.

    @param[in] pos iterator before which the content will be inserted; may be
    the end() iterator
    @param[in] cnt number of copies of @a val to insert
    @param[in] val element to insert
    @return iterator pointing to the first element inserted, or @a pos if
    `cnt==0`

    @throw type_error.309 if called on JSON values other than arrays; example:
    `"cannot use insert() with string"`
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
    example: `"iterator does not fit current value"`

    @complexity Linear in @a cnt plus linear in the distance between @a pos
    and end of the container.

    @liveexample{The example shows how `insert()` is used.,insert__count}

    @since version 1.0.0
    */


/*!
    @brief inserts elements

    Inserts elements from range `[first, last)` before iterator @a pos.

    @param[in] pos iterator before which the content will be inserted; may be
    the end() iterator
    @param[in] first begin of the range of elements to insert
    @param[in] last end of the range of elements to insert

    @throw type_error.309 if called on JSON values other than arrays; example:
    `"cannot use insert() with string"`
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
    example: `"iterator does not fit current value"`
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
    same JSON value; example: `"iterators do not fit"`
    @throw invalid_iterator.211 if @a first or @a last are iterators into
    container for which insert is called; example: `"passed iterators may not
    belong to container"`

    @return iterator pointing to the first element inserted, or @a pos if
    `first==last`

    @complexity Linear in `std::distance(first, last)` plus linear in the
    distance between @a pos and end of the container.

    @liveexample{The example shows how `insert()` is used.,insert__range}

    @since version 1.0.0
    */


/*!
    @brief inserts elements

    Inserts elements from initializer list @a ilist before iterator @a pos.

    @param[in] pos iterator before which the content will be inserted; may be
    the end() iterator
    @param[in] ilist initializer list to insert the values from

    @throw type_error.309 if called on JSON values other than arrays; example:
    `"cannot use insert() with string"`
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
    example: `"iterator does not fit current value"`

    @return iterator pointing to the first element inserted, or @a pos if
    `ilist` is empty

    @complexity Linear in `ilist.size()` plus linear in the distance between
    @a pos and end of the container.

    @liveexample{The example shows how `insert()` is used.,insert__ilist}

    @since version 1.0.0
    */


// Internal function to calculate the different scalability forms


// Function to return an string for the calculated complexity


// Find the coefficient for the high-order term in the running time, by
// minimizing the sum of squares of relative error.
//   - n          : Vector containing the size of the benchmark tests.
//   - time       : Vector containing the times for the benchmark tests.
//   - complexity : If different than oAuto, the fitting curve will stick to
//                  this one. If it is oAuto, it will be calculated the best
//                  fitting curve.


// Parses 'str' for a 32-bit signed integer.  If successful, writes
// the result to *value and returns true; otherwise leaves *value
// unchanged and returns false.


// Parses 'str' for a double.  If successful, writes the result to *value and
// returns true; otherwise leaves *value unchanged and returns false.


// Returns the name of the environment variable corresponding to the
// given flag.  For example, FlagToEnvVar("foo") will return
// "BENCHMARK_FOO" in the open-source version.


// Reads and returns the Boolean environment variable corresponding to
// the given flag; if it's not set, returns default_value.
//
// The value is considered true iff it's not "0".


// Reads and returns a 32-bit integer stored in the environment
// variable corresponding to the given flag; if it isn't set or
// doesn't represent a valid 32-bit integer, returns default_value.


// Reads and returns the string environment variable corresponding to
// the given flag; if it's not set, returns default_value.


// Parses a string as a command line flag.  The string should have
// the format "--flag=value".  When def_optional is true, the "=value"
// part can be omitted.
//
// Returns the value of the flag, or nullptr if the parsing failed.


// FIXME: This function is a hack so that benchmark.cc can access
// `BenchmarkFamilies`


// Execute one thread of benchmark b for the specified number of iterations.
// Adds the stats collected for the thread into *total.


//////////////////////////////////////////////////////////////////////////////
// parse JSON from file
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
// parse JSON from string
//////////////////////////////////////////////////////////////////////////////


// ldexp -- convert f * 2^e to IEEE single precision


// ldexp -- convert f * 2^e to IEEE double precision


// this is the overload needed for non-copyable types,


// Report the error condition


// CAVEAT: The returned AssertionResult stores a pointer to the argument expr,
//         a temporary DecomposedExpression, which in turn holds references to
//         operands, possibly temporary as well.
//         It should immediately be passed to handleResult; if the expression
//         needs to be reported, its string expansion must be composed before
//         the temporaries are destroyed.


/// constructor for a list of elements


/// clears the contents


/// insert value with hint


/// insert value list


/// remove element at position


/// remove elements in range


/// remove elements with key


/// swaps the contents


// Avoid calling stol as it triggers a bug in clang/glibc build.


// We don't use any library to minimize dependencies.


// Parse disk designators, like "C:\". If Relative == true, also accepts: "C:".
// Returns number of characters considered if successful.


// Parse a file name, like: SomeFile.txt
// Returns number of characters considered if successful.


// Parse a directory ending in separator, like: SomeDir\
// Returns number of characters considered if successful.


// Parse a servername and share, like: SomeServer\SomeShare\
// Returns number of characters considered if successful.


// Parse the given Ref string from the position Offset, to exactly match the given
// string Patt.
// Returns number of characters considered if successful.


// Parse a location, like:
// \\?\UNC\Server\Share\  \\?\C:\  \\Server\Share\  \  C:\  C:
// Returns number of characters considered if successful.


// The rest is added for LibFuzzer


// Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out.


// The control file example:
//
// 3 # The number of inputs
// 1 # The number of inputs in the first corpus, <= the previous number
// file0
// file1
// file2  # One file name per line.
// STARTED 0 123  # FileID, file size
// DONE 0 1 4 6 8  # FileID COV1 COV2 ...
// STARTED 1 456  # If DONE is missing, the input crashed while processing.
// STARTED 2 567
// DONE 2 8 9


// Decides which files need to be merged (add thost to NewFiles).
// Returns the number of new features added.


// Inner process. May crash if the target crashes.


// Outer process. Does not call the target code and thus sohuld not fail.


// Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
// Returns ToSize.


// Inserts part of From[0,ToSize) into To.
// Returns new size of To on success or 0 on failure.


// Copy successful dictionary entries to PersistentAutoDictionary.


// We don't want to create too many trace-based mutations as it is both
// expensive and useless. So after some number of mutations is collected,
// start rejecting some of them. The more there are mutations the more we
// reject.


// This is a reimplementation of Libc's `system()`. On Darwin the Libc
// implementation contains a mutex which prevents it from being used
// concurrently. This implementation **can** be used concurrently. It sets the
// signal handlers when the first thread enters and restores them when the last
// thread finishes execution of the function and ensures this is not racey by
// using a mutex.


// Records data to a maximum coverage tracker. Returns true if additional
// coverage was discovered.


// Returns true if there were more mallocs than frees.


// Crash on a single malloc that exceeds the rss limit.


// Finds minimal number of units in 'Extra' that add coverage to 'Initial'.
// We do it by actually executing the units, sometimes more than once,
// because we may be using different coverage-like signals and the only
// common thing between them is that we can say "this unit found new stuff".


// Tries detecting a memory leak on the particular input that we have just
// executed before calling this function.


// Copied from FuzzerUtil.cpp.


// Based on SetSigaction in FuzzerUtil.cpp


// Write extra stats to the file specified by the user. If none is specified
// this function will never be called.


// Call write_extra_stats before we exit.


// If the user has specified an extra_stats_file through the environment
// variable AFL_DRIVER_EXTRA_STATS_FILENAME, then perform necessary set up
// to write stats to it on exit. If no file is specified, do nothing. Otherwise
// install signal and exit handlers to write to the file when the process exits.
// Then if the file doesn't exist create it and set extra stats to 0. But if it
// does exist then read the initial values of the extra stats from the file
// and check that the file is writable.


// If the user asks us to duplicate stderr, then do it.


// Source code for a simple DSO.


// A modified jenkins_one_at_a_time_hash initialized by non-zero,
// so that simple_hash(0) != 0. See also
// https://en.wikipedia.org/wiki/Jenkins_hash_function


//****************************************************************************
// Deduce whether the input range (or table) is in wavelengths or frequencies.
// Do necessary adjustments accordingly
//****************************************************************************


//*****************************************************************************
// Renormalize the spectrum according to Helium
// abundance and ionization fractions if requested (output_format = 0; default)
// Also add up all components
//*****************************************************************************


//**********************************************
// Convolve the spectrum
//**********************************************


//**************************
// Write the output spectrum
//**************************


//*****************************************************
// Interpolate a single data point on a regular 2D grid
//*****************************************************


//**************************************************
// Check the environment variable
//**************************************************


//*********************************
// Read the van Hoof (2014) table
//*********************************


//**************************************
// Interpolate the van Hoof (2014) table
//**************************************


//*****************************************
// Read the Ercolano & Storey (2006) tables
//*****************************************


//***********************************************************************
// Interpolate the Ercolano+ (2006) table at the user-defined temperature
//***********************************************************************


//********************************************************
// Interpolate the Ercolano+ (2006) table over frequencies
//********************************************************


//**************************************************
// Rydberg formula for the emission line wavelengths
//**************************************************


//****************************
// Read an emission line table
//****************************


//*****************************************
// Calculate the HeI emission line spectrum
//*****************************************


//**********************************************
// Calculate the HI, HeII emission line spectrum
//**********************************************


//*****************************************************************
// Due to the "infinitely small" width of the emission line,
// we must divide the "flux" by the width of the frequency interval
// to have the line in the same units as the continuum
//*****************************************************************


//**************************************************************************
// Transition probability for hydrogenic ions
// (fit from Nussbaumer & Schmutz (1984)
//**************************************************************************


//************************************************
// Read the Hummer & Storey (1987) 2s coefficients
//************************************************


//***********************************
// Calculate the two-photon continuum
//***********************************


//**********************************************************************
// Effective recombination coefficient to HeI 1-2S (Ilmas & Nugis, 1982)
//**********************************************************************


//************************************************
// Calculate the collision rate coefficients
// following Pengelly (1964, paper II)
//************************************************


//*************************************************************************
// Iterating using fixed electron density
// Modified approach as fixed ne does not require iteration
//*************************************************************************


//*************************************************************************
// Iterating using fixed mass density (as in Rouse 1962)
//*************************************************************************


/// Convert and add mesh nodes to the geo_objects. A new name of the geo object
/// is returned.


/// Lookup-table for returning the third node of bottom or top triangle given
/// the other two.


/// Subdivides a nonplanar quad into two triangles.


/// Subdivides a prism with nonplanar quad faces into two tets.


/// Subdivides a Hex with nonplanar faces into tets.


/// Subdivides a pyramid with a nonplanar base into two tets.


/// Creates a line element from the first two unique nodes found in the element
/// (element *should* have exactly two unique nodes!)


/// Creates a triangle element from the first three unique nodes found in the
/// element (element *should* have exactly three unique nodes!)


/// Creates a quad or a tet, depending if the four nodes being coplanar or not
/// (element *should* have exactly four unique nodes!)


/// Reduces a pyramid element by removing collapsed nodes and constructing a new
/// elements from the remaining nodes.


/// Reduces a prism element by removing collapsed nodes and constructing one or
/// two new elements from the remaining nodes.
/// @return The number of newly created elements


/// Lookup-table for returning four nodes connected to the two nodes (id1, id2)
/// forming an edge in a Hex.


/// Lookup-table for returning the diametral node id of the given node id in a
/// Hex.


/// When a hex is subdivided into two prisms, this returns the nodes of the hex
/// edge that will serve as the back of one of the prisms.


// In an element with 5 unique nodes, return the node that will be the top of
// the resulting pyramid.


/// Subdivides an element if it has a face that is not coplanar
/// @param element the element that will be subdivided
/// @param nodes vector containing the nodes the elements originated by the
/// subdivision are based on
/// @param elements vector of MeshLib::Elements; the elements originated by the
/// subdivision will be inserted into elements
/// @return the number of elements originated by the subdivision


// Revises an element by removing collapsed nodes, using the nodes vector from
// the result mesh.


/// Copies all scalar arrays according to the restructured Node- and
/// Element-vectors after the mesh revision process (i.e. collapsed nodes, split
/// elements, etc.)


// check whether dynamic_cast of cell data is possible the type of cell data to
// map them on voxelgrid


// end namespace MeshGenerator


// returns the AABB of all mesh nodes of layers read so far


// creates a voxel grid of the AABB of all layers


// casts vote if the given nodes belongs to lower layer, upper layer or no layer
// at all


// Removes all elements from mesh that have not been marked as being located
// between two layers. If all elements remain unmarked, a nullptr is returned.


// Creates a VoxelGrid after extending the AABB for each layer.


// tests if a plane and an AABB are intersecting
// (based on Christer Ericson "Real Time Collision Detection" 5.2.3)


// tests if a triangle and an AABB are intersecting
// (based on Christer Ericson "Real Time Collision Detection" 5.2.9)


/// Return a new quadratic element corresponding to the linear element's type.


// Note: the function is used for parsing
// 1. base1 for the case of an implicit base0.
// 2. or base2.


/**
 * Check if a vector of node IDs includes all nodes of a given element
 * \param vec_node_ids         a vector of Node IDs
 * \param edge                 Edge object whose node IDs are checked
 * \param edge_node_distances  a vector of distances of the edge nodes from the
 * beginning of the given node ID vector
 * \return true if all element nodes are included in the vector
 */


/**
 * Modify node ordering of an edge so that its first node is closer to the
 * beginning of a polyline than others
 * \param edge                           Element object
 * \param ply                            Polyline object
 * \param edge_node_distances_along_ply  A vector of current edge node
 * distances along poly
 * \param node_ids_on_poly               A vector of node IDs along the polyine
 * \return A pointer to the new modified edge object. A pointer to the original
 * edge is returned if the modification is unnecessary.
 */


/// Find all elements which consist of all of the given node ids.
/// \note It is recommended to include only base nodes of elements into the
/// search \c node_ids.


/// Find the 2d-element within the \c elements that contains the given point \c
/// p.
///
/// The algorithm projects every element of the elements vector and the point
/// \c p orthogonal to the \f$x\f$-\f$y\f$ plane. In the \f$x\f$-\f$y\f$ plane
/// it is checked if the projected point is in the projected element.


// On windows this command line option is not present.


/// To use this module import dependencies first:
///   import ogs.mesh as mesh
///   import ogs.simulator as sim
///
/// See also
/// https://github.com/pybind/pybind11/issues/1391#issuecomment-912642979


// Convert NumPy array to Point3d if not None. This function is there to avoid
// pulling the MeshLib::Point3d object into python, but use std::array (which
// has all automatic conversions in pybind11).


// Convert SpatialPositon to python array if coordinates are set. This function
// is there to avoid pulling the MeshLib::Point3d object into python, but use
// python arrays.


/// python module name is OpenGeoSys


/**
 * \brief Reverses order of nodes. In particular, this fixes issues between OGS5
 * and OGS6 meshes.
 *
 * \param elements  Mesh elements whose nodes should be reordered
 * \param forced    If true, nodes are reordered for all
 * elements, if false it is first checked if the node order is correct according
 * to OGS6 element definitions.
 */


/// Fixes inconsistencies between VTK's and OGS' node order for prism elements.
/// In particular, this fixes issues between OGS6 meshes with and without
/// InSitu-Lib


/// Orders the base nodes of each elements before its non-linear nodes.


/// creates a vector of sampling points based on the specified resolution


/// creates a polyline to be mapped on a mesh layer


/// creates a mapped line for each of the mesh layers


/// Merges all layer geometries into one. Each layer is specified by one
/// polygon. This will ensure that GMSH deals with the subsequent assignment of
/// material groups automatically.


/// rotates the merged geometry into the XY-plane


/// This encapsulates a workaround:
/// For unknown reasons, the GML->GEO converter will not work correctly when
/// inputting the merged geometry directly. However, if the geometry is saved to
/// a file and immediately loaded again, everything works fine.


/// converts geometry into GMSH format and creates mesh


/// inverse rotation of the mesh, back into original position


/// removes line elements from mesh such that only triangles remain


/// Prerequisite: the ghost elements has to be found
/// Finds ghost nodes and non-linear element ghost nodes by walking over
/// ghost elements.


/// Partition existing properties and add vtkGhostType cell data array property.


// determine and append ghost nodes to partition.nodes in the following order
// [base nodes, higher order nodes, base ghost nodes, higher order ghost
// nodes]


/// Write the configuration data of the partition data in binary files.
/// \return a pair of vectors for:
///  1. The number of all non-ghost element integer variables for each
///     partition.
///  2. The number of all ghost element integer variables for each partition.


/// Generates a mapping of given node ids to a new local (renumbered) node ids.


/// Write the element integer variables of all partitions into binary files.
/// \param file_name_base       The prefix of the file name.
/// \param partitions           Partitions vector.
/// \param regular_element_offsets The numbers of all non-ghost element
///                             integer variables of each partitions.
/// \param ghost_element_offsets  The numbers of all ghost element


/// Write the nodes of all partitions into a binary file.
/// \param file_name_base The prefix of the file name.
/// \param partitions the list of partitions
/// \param global_node_ids global numbering of nodes


/// Trims a substring containing a variable-name


/// Tests if the number of read values equals the number of expected values


/// Tests if the number of read values equals the number of expected values and
/// closes the stream


/// Resets all data structures after a new "Variables"-description is found


/// Writes one section/zone into a separate TecPlot file


/// Writes one section/zone into a separate OGS-mesh


/// If a geometry-section is encountered, it is currently ignored


/// Splits a TecPlot file containing multiple sections/zones into separate files


/// Converts a TecPlot file into one or more OGS-meshes (one mesh per
/// section/zone)


/// Create 3d Station objects


//----------------------------------------------------------------------------
// Display text in the window, and translate the \n to \r\n.
//


// Instructions if the OK-Button has been pressed.


// set up x-axis/lat


// set up y-axis/lon


// set up time


// set up additional dimension


/**
 * Returns the model index of an item in the tree.
 * \param row The row where the item is located
 * \param column The column where the item is located
 * \param parent The parent of the item
 * \return The model index of the item
 */


/**
 * Returns the Station-Object of the ModelTreeItem with the given index and the
 * name of the list this station belongs to. \param index Index of the requested
 * item \param listName Here, the method will put the name of the list this
 * station belongs to. \return The station object associated with the tree item
 */


/**
 * Inserts a subtree under _rootItem.
 * \param listName Name of the new subtree. If no name is given a default name
 * is assigned. \param stations The list with stations to be added as children
 * of that subtree
 */


/**
 * Removes the TreeItem with the given Index including all its children
 */


/**
 * Removes the TreeItem with the given name including all its children
 */


/*
void ProcessView::editCondition()
{
    CondItem* item =
dynamic_cast<CondItem*>(static_cast<ProcessModel*>(this->model())->getItem(this->selectionModel()->currentIndex()));

    if (item)
    {
        FEMConditionSetupDialog dlg(*(item->getItem()));
        connect(&dlg, SIGNAL(createFEMCondition(std::vector<FEMCondition*>)),
this, SLOT(replaceCondition(std::vector<FEMCondition*>))); dlg.exec();
    }
}

void ProcessView::replaceCondition(std::vector<FEMCondition*> conditions)
{
    static_cast<ProcessModel*>(this->model())->replaceCondition(this->selectionModel()->currentIndex(),
conditions[0]); this->reset();
}

void ProcessView::saveConditions()
{
    emit saveConditionsRequested();
}
*/


/// Instructions if the OK-Button has been pressed.


/*
   int DiagramList::readList(char* path)
   {
    int date;
    double xVal, yVal;
    QString line;
    QStringList fields;

    QFile file(path);
    QTextStream in( &file );

    if (!file.open(QIODevice::ReadOnly))
    {
        return 0;
    }

    while (!in.atEnd()) {
        line = in.readLine();
        fields = line.split('\t');
        if (fields.size() >= 2) {
            xVal = fields.takeFirst().toDouble();
            yVal = fields.takeFirst().toDouble();
            xCoords.push_back(xVal);
            yCoords.push_back(yVal);
        }
        else return 0;
    }

    file.close();
    update();

    return 1;
   }*/


/**
 * Creates a grid using a QRectF object and a default pen and no ticks.
 * \param rect A rectangle specifying the size of the grid.
 * \param xCells The number of grid cells in x-direction.
 * \param yCells The number of grid cells in y-direction.
 * \param parent The parent QGraphicsItem.
 */


/**
 * Creates a grid by specifying its bounding rectangle using a default pen and
 * no ticks. \param x X-coordinate for the lower left corner of the bounding
 * rectangle for the grid. \param y Y-coordinate for the lower left corner of
 * the bounding rectangle for the grid. \param width Width of the bounding
 * rectangle. \param height Height of the bounding rectangle. \param xCells The
 * number of grid cells in x-direction. \param yCells The number of grid cells
 * in y-direction. \param parent The parent QGraphicsItem.
 */


/**
 * Creates a grid using a QRectF object and a default pen and no ticks.
 * \param rect A rectangle specifying the size of the grid.
 * \param xCells The number of grid cells in x-direction.
 * \param yCells The number of grid cells in y-direction.
 * \param ticks Specifies if ticks are displayed for the grid.
 * \param pen The pen for drawing the grid.
 * \param parent The parent QGraphicsItem.
 */


/**
 * Creates a grid by specifying its bounding rectangle using a default pen and
 * no ticks. \param x X-coordinate for the lower left corner of the bounding
 * rectangle for the grid. \param y Y-coordinate for the lower left corner of
 * the bounding rectangle for the grid. \param width Width of the bounding
 * rectangle. \param height Height of the bounding rectangle. \param xCells The
 * number of grid cells in x-direction. \param yCells The number of grid cells
 * in y-direction. \param ticks Specifies if ticks are displayed for the grid.
 * \param pen The pen for drawing the grid.
 * \param parent The parent QGraphicsItem.
 */


/// Defines the default pens.


/// Paints the grid.


/**
 * Initialises the view.
 */


/**
 * Updates the view automatically when a new list is added or when
 * the window containing the view is resized or changes its state.
 * Basically, the methods makes sure that everything keeps looking
 * as it is supposed to.
 */


/**
 * Creates a new scene. Since no data points are given some default
 * values are used for constructing all the necessary objects.
 */


/**
 * Creates a new scene.
 * \param list includes all necessary information of the graph to display.
 * \param parent The parent QObject.
 */


/// Adds an arrow object to the diagram which might be used as a coordinate
/// axis, etc.


/// Adds a caption for a graph beneath the actual diagram.


/// Adds a graph to the scene, including all data points and meta-information.


/// Adds a grid-object to the scene


/// Adds a non-scalable text object to the scene


/// Resizes a given axis to "nice" dimensions and calculates an adequate number
/// of ticks to be placed on it


/// Calculates scaling factors to set coordinate system and graphs to default
/// window size


/// Destroys the grid object (coordinate system) when a new graph is added.


/// Adjusts the underlying grid based on the graphs that are displayed in the
/// diagram


/// Plots the graph.


/// Returns the y-value at which the x-axis should cross the y-axis.
/// This value is zero if minYValue<0<maxYValue and minYValue otherwise.


/// Returns the x-value at which the y-axis should cross the x-axis.
/// This value is zero if minXValue<0<maxXValue and minXValue otherwise.


/// Initialises the coordinate axes, adds labels and/or units to the axes,
/// calculates axes-lengths, offsets, etc.


/// Updates the (unscaled) boundaries of the visible coordinate system when a
/// new list is added (boundaries are rescaled in the constructGrid-method


/**
 * Updates the scene at the start and every time new data points
 * are added. Specifically, objects on the scene are assigned
 * their position in the new coordinate system and are resized
 * if necessary.
 */


/**
 * Creates an arrow as a QGraphicItem.
 * \param l Length of the arrow
 * \param a Orientation of the arrow
 * \param hl Length of the arrow head
 * \param hw Width of the arrow head
 * \param pen The pen for drawing the arrow
 * \param parent The parent QGraphicsItem.
 */


/**
 * Creates an arrow as a QGraphicItem. Length and width of the arrow head are
 * given by default values. \param l Length of the arrow \param a Orientation of
 * the arrow \param pen The pen for drawing the arrow \param parent The parent
 * QGraphicsItem.
 */


/// The bounding box of the arrow


/**
 * Overloaded paint-method from QGraphicsItem.
 * Basically it draws a line with an arrowhead consisting of two short lines at
 * the end
 */


/**
 * Returns the child that corresponds to the specified row number
 * in the item's list of child items
 * Returns nullptr if that child does not exist.
 */


/**
 * Returns the item's location within its parent's list of items.
 */


/**
 * Sets the data at a given column.
 */


/**
 * Removes a number of children of the TreeItem starting from the given
 * position.
 */


/**
 * A model for the QTreeView implementing the tree as a double-linked list.
 */


/**
 * Returns the index of a TreeItem given its parent and position.
 * It is first checked if the model index is valid. If it is not, it is assumed
 * that a top-level item is being referred to; otherwise, the data pointer from
 * the model index is obtained with its internalPointer() function and is used
 * to reference a TreeItem object \param row Row of the tree object \param
 * column Column of the tree object \param parent Index of the parent object
 */


/**
 * Returns the model index of a TreeItem based on its index.
 */


/**
 * Returns the number of child items for the TreeItem that corresponds to a
 * given model index, or the number of top-level items if an invalid index is
 * specified.
 */


/**
 * Determines how many columns are present for a given model index.
 */


/**
 * Since each item manages its own columns, the column number is used to
 * retrieve the data with the TreeItem::data() function
 */


/**
 * Returns the Item characterized by the given index.
 */


/**
 * Removes item from the model.
 */


/**
 * Test method for creating a tree model
 */


/// Constructor using a QGraphicsTextItem.


/// Constructor using a QString.


/// Paints the text item.


/// Returns the bounding rectangle of the text item.


/** reads the points inclusive their names from input stream in
 * using the OGS-4 file format */


/** reads points from a vector */


/** read a single Polyline from stream in into the ply_vec-vector */


/** read a single Surface */


/**************************************************************************
   GEOLib-Method:
   Task: Surface read function
   Programming:
   03/2004 OK Implementation
   05/2004 CC Modification
   01/2010 TF changed signature of function, big modifications
**************************************************************************/


/// A GoCAD file may contain multiple datasets with the same name. To avoid
/// conflicts when writing meshes, a unique id is appended to the mesh name if
/// another dataset with the same name exists.


/// Parses current section until END-tag is reached


/// Checks if current line is a designated keyword for a GoCAD data set


/// Checks if a GoCAD data set begins at the current stream position.


/// Parses the HEADER section (everything except the name is ignored right now)


/// Reads PROPERTY_CLASS_HEADER sections of the file.
/// All this information is currently ignored.


/// Checks if the current line starts with one of the allowed keywords


/// Parses information of node properties.
/// Only property names and array sizes are currently used.


/// parse Atom Region Indicator section for current TFACE
/// (currently the information in this section is ignored)


/// Parses the node data for the current mesh


/// Parses the segments of the current line


/// Parses line information (nodes, segments, properties)


/// Parses the element data for the current mesh


/// Parses the surface information (nodes, triangles, properties)


/// Reads one mesh contained in the file (there may be more than one!)


/**
 * \param line input/output
 * \param in input stream containing the face set
 */


// Reads given number of bits (rounded up to next byte) into a bitset.
// Used for reading region information which can be represented by some
// number of bits.


/// Managing data associated with a boundary condition


/// Test if the given string is convertible to a valid double value, not a NaN.


/// Wraps a string into double ticks.


/// Tries to find a vtkdiff executable by testing 'path/vtkdiff --version' calls
/// for various paths.


////////////////////////
// The Borehole class //
////////////////////////


/// Reads a double replacing comma by point.


/// Reads the header of a Esri asc-file.
/// If the return value is empty, reading was not successful.


/// Reads the header of a Surfer grd-file with minimum and maximum values.
/// If the return value is empty, reading was not successful.


/// Checks if all raster files actually exist


/// Returns a line segment represented by its begin and end points.


/// Returns a ball represented by its center and its radius.


//! Dumps a \c std::vector<double> as a Python script snippet.


/// initialize output, convergence criterion, etc.


/// Thermal resistances due to grout-soil exchange.
///
/// Check if constraints regarding negative thermal resistances are violated
/// apply correction procedure.
/// Section (1.5.5) in FEFLOW White Papers Vol V.


/// Nu is the Nusselt number.


// Nu is the Nusselt number.


/// Returns a vector of active element ids with corresponding local assemblers.


// this is almost a copy of the implementation in the GroundwaterFlow


/// Computes the d.o.f. tables for the given \c output_mesh.
///
/// These are the passed \c bulk_mesh_dof_tables for output of the entire
/// simulation domain of the given \c process. In the case of submesh output
/// d.o.f. tables for the submesh will be computed.
///
/// \return A pair of (vector of d.o.f. table pointers, vector of d.o.f. table
/// storage), where the latter is populated in the case of submesh output only.
///
/// Each element in the returned vectors corresponds to a specific \c process_id
/// of the \c process.


/// Copies the ogs_version string containing the release number and the git
/// hash.


/**
 * Adds data for the given \c process_variables to the given \c mesh, if they
 * occur in \c output_variables.
 *
 * \param mesh the mesh the data is added to.
 * \param x the global solution vector providing the data.
 * \param process_variables the primary variables comprising \c x.
 * \param output_variables the names of variables that can be added to the
 *        \c mesh.
 * \param dof_table the d.o.f. table related to the passed \c mesh and
 *        solution vector \c x.
 * \param bulk_mesh_dof_table the d.o.f. table related to the entire simulation
 *        domain and the passed solution vector \c x.
 *
 * \note Usually \c mesh and the full simulation domain are the same. But if
 *       output should be written to a sub mesh, they will differ. In that case,
 *       also the two d.o.f. tables will be different from each other.
 *
 * \note The \c dof_table must correspond to the \c mesh, to the solution
 *       vector \c x and to the \c process_variables. I.e., if there are, e.g.,
 *       two primary variables in \c x, there must also be two variables in the
 *       \c dof_table and two entries in \c process_variables and so on.
 *
 * \note The \c dof_table must correspond to the \c bulk_mesh_dof_table,
 *       i.e., the former must have been derived from the latter. In particular,
 *       both must have the same number of variables and components.
 *
 * \return The names of all variables that have been written to the \c mesh.
 */


//! Converts a vtkXMLWriter's data mode string to an int. See
/// OutputVTKFormat::data_mode.


// update new values and corresponding indices.


/// Collects the degrees of freedom of the passed element from the passed global
/// vector into a vector.
///
/// \note \c num_nodes can be set "arbitrarily", e.g., to only collect d.o.f. on
/// the base nodes of the passed mesh element.


// Applies a patch file to the prj content in prj_stream.


// Will set prj_file to the actual .prj file and returns the final prj file
// content in prj_stream.


// A = a*A


/// printout this matrix for debugging


/// Forwards the respective method from MeshComponentMap.


/// Computes the index in a local (for DDC) vector for a given location and
/// component; forwarded from MeshComponentMap.


// end of USE_PETSC


/// Returns sum of the newly added time increments.


/// Create a IterationNumberBasedTimeStepping time stepper from the given
/// configuration.


/// The function returns a set of process names and the maximum iteration number
/// of a sub-coupling or nothing.


// end of ifdef USE_PETSC


/// rotate points to local coordinates


// similar to the above only with regular higher order nodes


/// Adds the integration point data and creates meta data for it.
///
/// Returns meta data for the written integration point data.


/// Adds integration point meta data as char mesh property encoded in JSON
/// format, which is then stored as VTK's field data.


/**
 * \brief Assumes a dataset is already opened by createDatasetFunction
 * \details Defines what (nodes_data, data_type) will be written how (data
 * subsections: data_dims, offset_dims, max_dims, chunk_dims, time) where
 * (dataset and dataset_name)
 */


/**
 * \brief Write vector with time values into open hdf file
 * \details In contrast to all other hdf write methods writing is only performed
 * by one process (is_file_manager_true). file handle is to an already opened
 * file
 */


// Transforms MeshItemType into string


// Transforms MeshPropertyDataType into string
// constexpr with literal type std::string not yet supported


// Returns MeshPropertyDataType-to-Size (in bytes) lookup-table


// Collects all known data and return a function that takes all unknown data
// known: XdmfData of mesh to be written, unknown: timesteps


// reflect point p on the point c in x-y plane


// This test creates an AABB containing a single point.
// This point is moved in every space direction to the next possible double
// value. It is checked that the AABB contains the point iff it has not been
// moved.


// Test the intersection of intersecting line segments. Line segments are chords
// of the same circle that both contains the center of the circle. As a
// consequence the center of the circle is the intersection point.


// Test the intersection of non-intersecting line segments. Line segments are
// chords of non-intersecting circles.


// Test the intersection of non-intersecting, parallel line segments. The second
// line segment is created by translating the first line segment.


// Test the intersection of parallel, interfering line segments.


// Generates n new points according to given random number distribution,
// which is uniform distribution in [-1, 1]^3.


// Testing empty input vector.


// Testing input vector with single point.


// Testing input vector with two different points.


// Testing input vector with two equal points.


// Testing random input points.


/// Reading 3D points


/// Dealing with unconvertable data types


/// Dealing with not existing columns


/// Dealing with missing values


/// Reading 2D points


/// Dealing with non-sequential column order


/// Getting single columns


/// Dealing with non-existing column


/// Dealing with wrong data type


// TetGen mesh with material array


// TetGen mesh without additional information


//
// Self-test of Kelvin to tensor and back conversion, which should be identity
// up to numerical errors.
//


//
// Determinants of a Kelvin vector and corresponding Eigen::Matrix are equal.
//


//
// Inverse of a Kelvin vector and corresponding Eigen::Matrix are equal.
//


//
// Self-test of LiftVectorToKelvin and back conversion, which should be identity
// up to numerical errors.
//


//
// Tests of deviatoric and spherical projection tensors.
//


// Make sure ranges and Eigen matrices and vectors can be handled in the same
// compilation unit.


/**
 * This test case checks if the internal Eigen::SparseMatrix compressed storage
 * format is a conventional CSR matrix. Currently this is the case, but it is
 * not guaranteed for all time.
 *
 * Cf. section "Sparse matrix format" on page
 * http://eigen.tuxfamily.org/dox/group__TutorialSparse.html
 */


//
// Identities of a vectorized tensors correspond to Eigen matrix identities.
//


// Test a simple cubic equation: x^3 - 6x^2 + 11x - 6 = 0
// This equation has known roots: x = 1, 2, 3


// Test a cubic equation with one real root: x^3 - 3x^2 + 3x - 1 = 0
// This equation has a triple root at x = 1


// Test a cubic equation with one real root: x^3 + 7x^2 - 12x - 30 = 0
// This equation has two negative and one positive reel at x = 2.515


// Test a cubic equation with one real root and complex roots
// x^3 - x + 1 = 0 has one real root and two complex roots


// Helper function to perform the root finding test on a given set of roots


// Test with predefined root sets


// Test with randomly generated root sets


// test for operator<


// Up to the polynomial order returned by this function the numerical
// integration should be exact in the base case test.


// Up to the polynomial order returned by this function the numerical
// integration should be exact in the separable polynomial test.


// Up to the polynomial order returned by this function the numerical
// integration should be exact in the nonseparable polynomial test.


// In the following test, the expected results are calculated by using OGS5.


// Test for trivial case of zero latent heat at the critical temperature


// Test for an arbitrary set of values at the critical temperature


// Test for an arbitrary set of values far below the critical temperature


// Test for an arbitrary set of values far above the critical temperature


// Consistency check that the MFront model really detects errors


// This test verifies the correct conversion routines from enum to string and
// back. Errors in this conversions can occur easily when the corresponding
// string vectors and the property enum is not lined up correctly.


/// This method creates an XML-snippet of a single property.


/// This method creates an XML-snippet of a property section.


/// This method creates an XML-snippet of a single component.


/// This method creates an XML-snippet of the phase components.


/// This method creates an XML-snippet of a single material phase.


/// This method creates an XML-snippet of the material phases.


/// This method creates the entire XML-tree structure from the string- based
/// medium specification object. I know, indentation is not necessary for this,
/// but my OCD kicked in...


// This test represents an invariant test. First, several phases, components,
// and properties are generated (more or less randomly).
// Then, an XML-tree is generated from those information. The XML tree is then
// parsed into a configTree, from which an MPL::MaterialObject is generated.
// Last step compares the names (as well as the topology) of the Material object
// with the specified parameters.


/* Keep for debugging
TEST(MaterialPropertyLib, TemperatureDependentFraction_values_out)
{
    // arbitrary values for space and time
    ParameterLib::SpatialPosition const pos;
    double const time = std::numeric_limits<double>::quiet_NaN();
    double const dt = std::numeric_limits<double>::quiet_NaN();

    MPL::VariableArray vars;
    ParameterSet water_ice;

    double T_c = water_ice.T_c;
    double T_s = T_c-10;
    double T_e = T_c+10;
    size_t n_T = 400;
    double dT = (T_e - T_s) / n_T;

    auto const medium = createMyMedium();
    auto const& fraction =
        medium->property(MaterialPropertyLib::PropertyType::volume_fraction);

    std::vector<double> temperatures(n_T+1);
    std::generate(temperatures.begin(), temperatures.end(),
                  [T = T_s - dT, dT]() mutable { return T += dT; });

    std::ofstream fout("/home/cbs/data_frozen_fraction.txt");
    fout << "T" << '\t' << "f" << '\t' << "f,T" << '\t' << "f,TT" << '\n';
    for (double T : temperatures)
    {
        vars.temperature = T;

        auto const f = std::get<double>(fraction.value(vars, pos, time, dt));
        auto const fT = std::get<double>(
            fraction.dValue(vars, MPL::Variable::temperature, pos, time, dt));
        auto const fTT = std::get<double>(
            fraction.d2Value(vars, MPL::Variable::temperature,
                             MPL::Variable::temperature, pos, time, dt));
        if (!fout)
        {
            std::cout << T - T_c << '\t' << f << '\t' << fT << '\t' << fTT
                      << '\n';
        }
        else
        {
            fout << T-T_c << '\t' << f << '\t' << fT << '\t' << fTT << '\n';
        }
    }
    fout.close();
}
*/


// For zero radius only the starting element is always returned.


// Find all elements connected through all nodes of the element


// Find nodes in radius of a given node.


// Find nodes in radius of all nodes of a given element.


// Brute force search for checking the actual algorithm.


// For a small radius only the element and its neighbors (through all nodes) are
// expected.


// For radii large enough to cover all of the mesh all of the elements are
// expected to be found.


// Random test (element_id and radius > 0); comparison with brute-force search
// algorithm.


// A node is connected to four elements inside the mesh, two on the boundary,
// and one in the corner.


// validates mesh. for line meshes, node order tests will fail because vertical
// elements are created during the extrusion. Therefore node order tests are
// switched off for line meshes.


// Special case: quad9


// Appends the coordinates of a MathLib::Point3d to a 3 x #nodes matrix of node
// coordinates.


// Computes the dimension of a flat, i.e., not curved, face from n points on
// that face given as a d_S x n matrix, where d_S is the space dimension.


// This test checks consistency between the face-to-bulk natural coordinates
// mapping and the natural coordinates used in FEM shape functions.
//
// We iterate over all nodes of all faces of a bulk element and check that these
// nodes are mapped to nodes of the bulk element. I.e., this test checks if the
// face nodes are mapped to some nodes of the bulk element; it does not check if
// the face nodes are mapped to the right bulk nodes.


// This test is very similar to CheckFaceNodesAreMappedToBulkElementNodes above.
//
// It checks a subset of the test above and extends it with a check that points
// that are not corners of the face are mapped to a bulk point lying on the
// surface of the bulk element.


// This test is much stricter than the tests before. It does not only check if
// the face to bulk mapping under test maps face nodes to some bulk element
// nodes, but also if they are mapped to the right bulk element nodes. However,
// this test involves shape function interpolation, i.e., needs a larger
// machinery. Therefore, the other tests are still justified.


// Same for points that are anywhere on the face, not only (corner) nodes of the
// face.


// nodes on x axis


// nodes on y axis


// nodes on z axis


// nodes on x-y plane


// nodes on y-z plane


// nodes on x-z plane


// nodes in 3D space


// 2.5D case: inclined


// keep this function for debugging


// Returns the (inverse) permutation vector of b_nodes to a_nodes, or an error
// message.


// Two elements are equal if their corresponding node coordinates are equal up
// to a (shift) permutation.
// Returns a string in case of error containing a descriptive message.


// Returns a vector filled with numbers [0, size) randomly permuted.


// Test the inverse permutation for being the inverse: p^-1(p(.)) = Id.
// In case of failure an error message is returned.


// Create new nodes in permuted order with new ids.


// Tests the nodes of two meshes and returns a string in case of error with
// message, otherwise a permutation vector as in compareNodes().


// Helper functions to access elements and nodes.


// This is identical to the above
// MeshLibBoundaryElementSearchInSimpleHexMesh.SurfaceSearch test but
// creates a quadratic mesh from the original hex mesh.


// Creates a PropertyVector<double> and maps it into a vtkDataArray-equivalent


// Creates a PropertyVector<int> and maps it into a vtkDataArray-equivalent


// Creates a PropertyVector<unsigned> and maps it into a vtkDataArray-equivalent


/**
  The function calculates increment of net stress vector, of state variable vector and new Sr.

  @param signet[9] - (input): total stress: old value. This is not to be updated, increment of stress is in dsignet[9].
  @param suction - (input): suction: old value. This is not to be updated.
  @param Temper - (input): temperature: old value. This is not to be updated.
  @param qstatev[] - (input): state variable vector: old values. This is only to be updated if flag==0, otherwise only their increment is produced in dqstatev[].
  @param deps[9] - (input): increment of total strain
  @param dsuction - (input): increment of pore air pressure
  @param dTemper - (input): increment of temperature
  @param dsignet[9] - (output): increment of net stress
  @param Sr - (output): new degree of saturation
  @param dqstatev[] - (output): increment of state variables
  @param kinc       - (input):

  @return The function does not return anything.

  Created by D. Masin 13.7.2015
*/


/**
  The function calculates state variable increment vector dqstatev[]. The old values of qstatev[0] (void ratio) and qstatev[6] (a_scan) must be provided by the FEM (even for the initialisation stage). The order of state variables is as follows:
  [0]e (required on input)
  [1]suction
  [2]Sr
  [3]T
  [4]em
  [5]eM
  [6]SrM
  [7]a_scan (required on input)
  [8]re
  [9] swelling indicator ???

  @param signet[9] - (input): total stress: old value. This is not to be updated, increment of stress is in dsignet[9].
  @param suction - (input): suction: old value. This is not to be updated.
  @param Temper - (input): temperature: old value. This is not to be updated.
  @param qstatev[] - (input): state variable vector: old values. This is only to be updated if flag==0, otherwise only their increment is produced in dqstatev[].
  @param deps[9] - (input): increment of total strain
  @param dsuction - (input): increment of pore air pressure
  @param dTemper - (input): increment of temperature
  @param dsignet[9] - (output): increment of total stress
  @param Sr - (output): new degree of saturation
  @param dqstatev[] - (output): increment of state variables
  @param flag -
  @param fu -

  @return The function does not return anything.

  Created by D. Masin 13.7.2015
*/


/**
  The function calculates the macrostructural effective stress.

  @param sig[9] - (input): net stress.
  @param suction - (input): pore air pressure.
  @param SrM - (input): degree of saturation of macrostructure.
  @param tensor_unsat[9] - (output): effective stress of macrostructure
  @param scalar_unsat - (output): suction

  @return The function does not return anything.

  Created by D. Masin 13.7.2015
*/


/**
  The function calculates the microstructural strain.

  @param signet[9] - (input): total stress.
  @param suction - (input): suction
  @param Temper - (input): temperature.
  @param dsuction - (input): increment of matric suction
  @param dTemper - (input): increment of temperature
  @param dsignet[9] - (input!!!): increment of total stress
  @param depm[9] - (output): microstructural strain

  @return The function does not return anything.

  Created by D. Masin 13.7.2015
*/


/**
  The function calculates current position and slope of normal compression line Nuse and lambda_use, and also the derivatives (dpe/ds)/pe and (dpe/dT)/pe

  @param Nuse - (output): Nuse
  @param lambda_use - (output): lambda_use
  @param dpeds_divpe - (output): (dpe/ds)/pe
  @param dpedT_divpe - (output): (dpe/dT)/pe
  @param signet[9] - (input): total stress.
  @param suction - (input): suction.
  @param Temper - (input): temperature.
  @param qstatev[] - (input): state variable vector.

  @return The function does not return anything.

  Created by D. Masin 13.7.2015
*/


/**
  The function calculates tangent operators hypo_L, hypo_N, H_unsat and HT_unsat of the model for macrostructure

  @param signet[9] - (input): total stress.
  @param suction - (input): suction.
  @param Temper - (input): temperature.
  @param qstatev[] - (input): state variable vector.
  @param hypo_L[3][3][3][3] - (output): tangent operator hypo_L
  @param hypo_N[3][3] - (output): tangent operator hypo_N
  @param H_unsat[3][3] - (output): tangent operator H_unsat
  @param HT_unsat[3][3] - (output): tangent operator HT_unsat

  @return The function does not return anything.

  Created by D. Masin 13.7.2015
*/


//Functions for abaqus-full convention conversion


//Functions for mathematical operations


//@GS Functions adapted from SIFEL
/**
  The function integrates ODEs by adaptive forward Euler rule.

  @param strain_gen[ngstrain] - (input): controlled variables [eps11, eps22, eps33, gamma12, gamma13, gamma23, s, T]^T
  @param stress_gen[c_ngstress] - (input): implied variables, will not be updated [signet11, signet22, signet33, signet12, signet13, signet23, Sr]^T. "signet" is net stress, that is total stress minus krondelta x ua.
  @param qstatev[c_nstatev] - (input): state variable vector, will be updated only for flag==0.
  @param dstrain_gen[ngstrain] - (input): increment of controlled variables [deps11, deps22, deps33, dgamma12, dgamma13, dgamma23, ds, dT]^T
  @param dtime - (input): increment of time
  @param parms[c_nparms] - array of model parameters (input)
  @param rkf_statev[nrkf_statev] - (input): array of state variables from SIFEL for Runge-Kutta
  @param rkf_parms[nrkf_parms] - (input): array of parameters from SIFEL for Runge-Kutta

  @retval 0 - on success
  @retval 1 - in the case of substepping failure => global step length must be decreased

  Created by Tomas Koudelka, 6.10.2015; modified by G. Scaringi, January 2019 //@GS
*/


//Forward Euler with fixed number of substeps


/**
  The function integrates ODEs by the kind of Runge-Kutta-Fehlberg 23 method.

  @param strain_gen[ngstrain] - (input): controlled variables [eps11, eps22, eps33, gamma12, gamma13, gamma23, s, T]^T
  @param stress_gen[max_ngstress] - (input): implied variables, will not be updated [signet11, signet22, signet33, signet12, signet13, signet23, Sr]^T. "signet" is net stress, that is total stress minus krondelta x ua.
  @param qstatev[max_nstatev] - (input): state variable vector, will be updated only for flag==0.
  @param dstrain_gen[ngstrain] - (input): increment of controlled variables [deps11, deps22, deps33, dgamma12, dgamma13, dgamma23, ds, dT]^T
  @param dtime - (input): increment of time
  @param parms[c_nparms] - array of model parameters (input)
  @param rkf_statev[nrkf_statev] - (input): array of state variables from SIFEL for Runge-Kutta
  @param rkf_parms[nrkf_parms] - (input): array of parameters from SIFEL for Runge-Kutta

  @retval 0 - on success
  @retval 1 - in the case of substepping failure => global step length must be decreased

  Created by Tomas Koudelka, 6.10.2015; modified by G. Scaringi, January 2019 //@GS
*/


/**
  The function integrates ODEs by the kind of Runge-Kutta-Fehlberg 23 method proposed by
  Bogacki & Shampine.

  @param strain_gen[ngstrain] - (input): controlled variables [eps11, eps22, eps33, gamma12, gamma13, gamma23, s, T]^T
  @param stress_gen[max_ngstress] - (input): implied variables, will not be updated [signet11, signet22, signet33, signet12, signet13, signet23, Sr]^T. "signet" is net stress, that is total stress minus krondelta x ua.
  @param qstatev[max_nstatev] - (input): state variable vector, will be updated only for flag==0.
  @param dstrain_gen[ngstrain] - (input): increment of controlled variables [deps11, deps22, deps33, dgamma12, dgamma13, dgamma23, ds, dT]^T
  @param dtime - (input): increment of time
  @param parms[c_nparms] - array of model parameters (input)
  @param rkf_statev[nrkf_statev] - (input): array of state variables from SIFEL for Runge-Kutta
  @param rkf_parms[nrkf_parms] - (input): array of parameters from SIFEL for Runge-Kutta

  @retval 0 - on success
  @retval 1 - in the case of substepping failure => global step length must be decreased

  Created by Tomas Koudelka, 6.10.2015; modified by G. Scaringi, January 2019 //@GS
*/


/**
  The function integrates ODEs by the kind of Runge-Kutta-Fehlberg 34 method.

  @param strain_gen[ngstrain] - (input): controlled variables [eps11, eps22, eps33, gamma12, gamma13, gamma23, s, T]^T
  @param stress_gen[max_ngstress] - (input): implied variables, will not be updated [signet11, signet22, signet33, signet12, signet13, signet23, Sr]^T. "signet" is net stress, that is total stress minus krondelta x ua.
  @param qstatev[max_nstatev] - (input): state variable vector, will be updated only for flag==0.
  @param dstrain_gen[ngstrain] - (input): increment of controlled variables [deps11, deps22, deps33, dgamma12, dgamma13, dgamma23, ds, dT]^T
  @param dtime - (input): increment of time
  @param parms[c_nparms] - array of model parameters (input)
  @param rkf_statev[nrkf_statev] - (input): array of state variables from SIFEL for Runge-Kutta
  @param rkf_parms[nrkf_parms] - (input): array of parameters from SIFEL for Runge-Kutta

  @retval 0 - on success
  @retval 1 - in the case of substepping failure => global step length must be decreased

  Created by Tomas Koudelka, 6.10.2015; modified by G. Scaringi, January 2019 //@GS
*/


/**
  The function integrates ODEs by the kind of Runge-Kutta-Fehlberg 45 method.

  @param strain_gen[ngstrain] - (input): controlled variables [eps11, eps22, eps33, gamma12, gamma13, gamma23, s, T]^T
  @param stress_gen[max_ngstress] - (input): implied variables, will not be updated [signet11, signet22, signet33, signet12, signet13, signet23, Sr]^T. "signet" is net stress, that is total stress minus krondelta x ua.
  @param qstatev[max_nstatev] - (input): state variable vector, will be updated only for flag==0.
  @param dstrain_gen[ngstrain] - (input): increment of controlled variables [deps11, deps22, deps33, dgamma12, dgamma13, dgamma23, ds, dT]^T
  @param dtime - (input): increment of time
  @param parms[c_nparms] - array of model parameters (input)
  @param rkf_statev[nrkf_statev] - (input): array of state variables from SIFEL for Runge-Kutta
  @param rkf_parms[nrkf_parms] - (input): array of parameters from SIFEL for Runge-Kutta

  @retval 0 - on success
  @retval 1 - in the case of substepping failure => global step length must be decreased

  Created by Tomas Koudelka, 6.10.2015; modified by G. Scaringi, January 2019 //@GS
*/


//@GS more routines
/**
  The function reduces step length in Runge-Kutta-Fehlberg methods according to given
  coefficient and minimum step length.

  @param rc   - reduction coefficient of step length (input)
  @param h    - actual/modified step length (input/output)
  @param hmin - minimum step length (input)

  @retval 0 - On sucessfull step reduction.
  @retval 1 - The minimum step length has been attained and the step cannot be reduced further.

  Created by Tomas Koudelka, 24.5.2016; modified by G. Scaringi, January 2019 //@GS
*/


//! Fills a vector with values whose absolute value is between \c abs_min and
//! \c abs_max.


// Computes reference data and initializes the internal (integration point)
// data of the passed \c loc_asm.


// Same test as above, but with constant gas density


// Note: the two meshes are the same except the values of double type field
// data.


// For all elements all nodes have a constant value.


// Test: basis_vector_2 must not be presented in  the 2D coordinate system


// Quicksort result is sorted.


// Permutations of non-empty, sorted, unique vector remain untouched.


// Permutations of non-empty, reverse sorted, unique vector is also reversed.


// String literals are somewhat special for template classes


// only scalar arguments


// also vectorial arguments


// Assert that we don't forget any integration method in this test suite.


// Assert that the integration method registry contains all integration orders
// of the underlying integration methods.


// TypeParam is the type of the ShapeFunction.
// Access private members via this pointer or TestFixture:: for types


// unit test related to ThermoRichardsMechanics/LiakopoulosHM/liakopoulos.prj


// unit test related to
// ogs-ThermoMechanics_CreepBGRa_Verification_m2_3Dload_m2_3Dload


// extracted from Sandwich-0c-Aqeel-R5DeCoT68


// For most element types the element's natural coordinates coincide with the
// real coordinates in the reference element. I.e., when interpolating the node
// coordinates of the reference element to a point inside the element given by
// its natural coordinates r, s, t the following holds:
//
// (r, s, t) == N(r, s, t) * [coords of reference element's nodes],
//
// where N is a combination of shape matrices used for interpolation.
//
// One notable exception are pyramids.
//
// This unit test checks the property described above for r, s, t being the
// coordinates of the nodes of the reference element.
//


// For most element types the element's natural coordinates coincide with the
// real coordinates in the reference element. I.e., when interpolating the node
// coordinates of the reference element to a point inside the element given by
// its natural coordinates r, s, t the following holds:
//
// (r, s, t) == N(r, s, t) * [coords of reference element's nodes],
//
// where N is a combination of shape matrices used for interpolation.
//
// One notable exception are pyramids.
//
// This unit test checks the property described above for r, s, t being the
// coordinates some points inside the reference element.
//


// Returns global index of a node location and a component.


/// Prints info about MFront variables.


/// Prints info about MFront parameters.


// Very similar to above readMaterialProperties but does not generalize because
// of config specific strings for ogs_file_param and return type.


/// Regularized van Genuchten capillary pressure-saturation Model


///  van Genuchten capillary pressure-saturation Model


/// derivative dPCdS based on regularized van Genuchten capillary
/// pressure-saturation Model


/// derivative dPCdS based on standard van Genuchten capillary
/// pressure-saturation Model


/**
    \param config ConfigTree object which contains the input data
                  including `<type>BrooksCorey</type>`
                  and it has a tag of `<capillary_pressure>`
*/


/**
    \param config ConfigTree object which contains the input data
                  including `<type>vanGenuchten</type>`
                  and it has a tag of `<capillary_pressure>`
*/


/**
    \param config ConfigTree object which contains the input data
                  including `<type>WettingPhaseVanGenuchten</type>`
                  and it has a tag of `<relative_permeability>`
*/


/**
    \param config ConfigTree object which contains the input data
                  including `<type>NonWettingPhaseVanGenuchten</type>`
                  and it has a tag of `<relative_permeability>`
*/


/**
    \param config ConfigTree object which contains the input data
                  including `<type>WettingPhaseBrooksCoreyOilGas</type>`
                  and it has a tag of `<relative_permeability>`
*/


/**
    \param config ConfigTree object which contains the input data
                  including `<type>NonWettingPhaseBrooksCoreyOilGas</type>`
                  and it has a tag of `<relative_permeability>`
*/


/// The default implementation of this method only returns the
/// property value derivative without altering it.


/// Default implementation: 2nd derivative of any constant property is zero.


///< reference pressure in Pa.


//! Gets previous attribute, optionally matching attribute name.
//! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
//! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
//! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
//! \return Pointer to found attribute, or 0 if not found.


//! Gets last child node, optionally matching node name.
//! Behaviour is undefined if node has no children.
//! Use first_node() to test if node has children.
//! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
//! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
//! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
//! \return Pointer to found child, or 0 if not found.


//! Gets previous sibling node, optionally matching node name.
//! Behaviour is undefined if node has no parent.
//! Use parent() to test if node has a parent.
//! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
//! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
//! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
//! \return Pointer to found sibling, or 0 if not found.


//! Appends a new child node.
//! The appended child becomes the last child.
//! \param child Node to append.


//! Inserts a new child node at specified place inside the node.
//! All children after and including the specified node are moved one position back.
//! \param where Place where to insert the child, or 0 to insert at the back.
//! \param child Node to insert.


//! Removes first child node.
//! If node has no children, behaviour is undefined.
//! Use first_node() to test if node has children.


//! Removes last child of the node.
//! If node has no children, behaviour is undefined.
//! Use first_node() to test if node has children.


//! Inserts a new attribute at specified place inside the node.
//! All attributes after and including the specified attribute are moved one position back.
//! \param where Place where to insert the attribute, or 0 to insert at the back.
//! \param attribute Attribute to insert.


//! Removes first attribute of the node.
//! If node has no attributes, behaviour is undefined.
//! Use first_attribute() to test if node has attributes.


//! Removes last attribute of the node.
//! If node has no attributes, behaviour is undefined.
//! Use first_attribute() to test if node has attributes.


/* perform the butterfly for one stage of a mixed radix FFT */


// end of anonymous namespace


//   return 0;
// }


// anonymous namespace to avoid linker error (multiple definitions
// of function with identical names and parameters)


/*
  To keep track of the n best potential target sequences, we store
  them in a min heap. The root element corresponds to the least good
  target, while the best elements are found at the leaf nodes. This
  makes it simple to decide whether a new target should be included or
  not, because it just needs to be compared to the root note.  The
  list will be fully sorted before use when we want to find the best
  element and then the second best and so on.
*/


// refactoring: make generic function (extract to utils/file_open_write.cpp)


// refactoring: factorize all versions of this function, extract to new header


// refactoring C++17 [[nodiscard]]


// auto trim_deck(std::vector<struct sortinfo_size_s> & deck)
//     -> std::vector<struct sortinfo_size_s> {
//   // assume deck is sorted by decreasing abundance
//   // - opt_minsize = 0 by default
//   // - opt_maxsize = LONG_MAX by default
//   // - size is unsigned int
//   auto begin = std::upper_bound(deck.begin(), deck.end(), opt_maxsize,
//                                 [](int64_t maxsize, struct sortinfo_size_s & seq) -> bool {
//                                   return seq.size > maxsize;
//                                 });
//   auto end = std::lower_bound(deck.begin(), deck.end(), opt_minsize,
//                               [](int64_t minsize, struct sortinfo_size_s & seq) -> bool {
//                                 return seq.size <= minsize;
//                               });
//   return std::vector<struct sortinfo_size_s>{begin, end};
// }


// refactoring: extract as a template


// refactoring:
// - create vector (no branch)
// - stable_sort vector (by increasing size, then label)
// - find lower_bound(comp(opt_minsize)),
// - deck.resize()
// - find upper_bound(comp(opt_maxsize)),
// - std::vector<S> subdeck = {deck.begin() + upper_bound, deck.end()};  // view?
// - opt_minsize = 0 by default
// - opt_maxsize = LONG_MAX by default
// - top_n = LONG_MAX by default
// - mediane, etc...
// - std::min(subdeck.size(), topn);


/* per thread data */


// 3 attributes: size, ee, length


// refactoring: enum struct status {};
/*
  new chimeric status:
  0: no parents, non-chimeric
  1: score < 0 (no alignment), non-chimeric
  2: score < minh, non-chimeric
  3: score >= minh, suspicious -> not available with uchime2_denovo and uchime3_denovo
  4: score >= minh && (divdiff >= opt_mindiv) && ..., chimeric
*/


// A 32-bit to 32-bit integer hash copied from Murmur3.


// This probably works well for 16-byte strings as well, but it may be overkill
// in that case.


// Return a 16-byte hash for 48 bytes.  Quick and dirty.
// Callers do best to use "random-looking" values for a and b.


// Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.


// Return an 8-byte hash for 33 to 64 bytes.


// A subroutine for CityHash128().  Returns a decent 128-bit hash for strings
// of any length representable in signed long.  Based on City and Murmur.


// Requires len < 240.


// refactoring: create reverse_complement.hpp, progressive migration
// write overloads for span?
// assert(destination.size() > source.size());
// std::reverse_copy(source.begin(), source.end(), destination.begin());
// auto complement = [](char nucleotide) -> char { ... };
// std::transform(destination.begin(), destination.end(), destination.begin(), complement)
// destination[length] = '\0';


// refactoring: turn into template, remove conditional


// refactoring: C++14 tests
// static_assert(compute_index_padding(0) == 0U, "error: wrong padding value (expect 0)");
// static_assert(compute_index_padding(7) == 1U, "error: wrong padding value (expect 1)");
// static_assert(compute_index_padding(8) == 0U, "error: wrong padding value (expect 0)");
// static_assert(compute_index_padding(9) == 7U, "error: wrong padding value (expect 7)");
// static_assert(compute_index_padding(87) == 1U, "error: wrong padding value (expect 1)");
// static_assert(compute_index_padding(88) == 0U, "error: wrong padding value (expect 0)");
// static_assert(compute_index_padding(89) == 7U, "error: wrong padding value (expect 7)");
// static_assert(compute_index_padding(111) == 1U, "error: wrong padding value (expect 1)");
// static_assert(compute_index_padding(112) == 0U, "error: wrong padding value (expect 0)");
// static_assert(compute_index_padding(113) == 7U, "error: wrong padding value (expect 7)");
// static_assert(compute_index_padding(std::numeric_limits<uint32_t>::max()) == 1U, "error: wrong padding value (expect 1)");


// very similar to header_find_attribute() in attributes.cc


///////////////////////////////
///We do some tests pre run///
/////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////
//		This function reads a bunch of transfer files in transfer_files/ and saves them ///
//////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// These functions run Boltzmann over the redshift list zlist_transfer and saves transfer functions.  ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////
////    we RUN Boltzmann code to get the transfer functions between z=zi and z=0.	////
////////////////////////////////////////////////////////////////////////////////////////


//for progressbar:
//PBWIDTH and PBSTR defined in .h


////////////////////////////////////////////////////////////////////////
//unused, although they are useful for checks://


//now collapse functions:


/* "cows/_skeletonize_3d_cy.pyx":146
 * @cython.boundscheck(False)
 * @cython.wraparound(False)
 * cdef void find_simple_point_candidates(pixel_type[:, :, ::1] img,             # <<<<<<<<<<<<<<
 *                                        int curr_border,
 *                                        vector[coordinate] & simple_border_points) nogil:
 */


/* "cows/_skeletonize_3d_cy.pyx":215
 * @cython.boundscheck(False)
 * @cython.wraparound(False)
 * cdef void get_neighborhood(pixel_type[:, :, ::1] img,             # <<<<<<<<<<<<<<
 *                            npy_intp p, npy_intp r, npy_intp c,
 *                            pixel_type neighborhood[]) nogil:
 */


/* "cows/_skeletonize_3d_cy.pyx":290
 * @cython.boundscheck(False)
 * @cython.wraparound(False)
 * cdef bint is_Euler_invariant(pixel_type neighbors[],             # <<<<<<<<<<<<<<
 *                              int[::1] lut) nogil:
 *     """Check if a point is Euler invariant.
 */


/* "cows/_skeletonize_3d_cy.pyx":522
 *
 *
 * cdef bint is_simple_point(pixel_type neighbors[]) nogil:             # <<<<<<<<<<<<<<
 *     """Check is a point is a Simple Point.
 *
 */


/* "cows/_skeletonize_3d_cy.pyx":582
 * @cython.boundscheck(False)
 * @cython.wraparound(False)
 * cdef void octree_labeling(int octant, int label, pixel_type cube[]) nogil:             # <<<<<<<<<<<<<<
 *     """This is a recursive method that calculates the number of connected
 *     components in the 3D neighborhood after the center pixel would
 */


/* "View.MemoryView":298
 *
 * @cname('__pyx_align_pointer')
 * cdef void *align_pointer(void *memory, size_t alignment) nogil:             # <<<<<<<<<<<<<<
 *     "Align pointer memory on a given boundary"
 *     cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
 */


/* "View.MemoryView":807
 *
 * @cname('__pyx_memoryview_slice_memviewslice')
 * cdef int slice_memviewslice(             # <<<<<<<<<<<<<<
 *         __Pyx_memviewslice *dst,
 *         Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
 */


/* "View.MemoryView":943
 *
 * @cname('__pyx_memslice_transpose')
 * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:             # <<<<<<<<<<<<<<
 *     cdef int ndim = memslice.memview.view.ndim
 *
 */


/* "View.MemoryView":1116
 *
 * @cname('__pyx_get_best_slice_order')
 * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil:             # <<<<<<<<<<<<<<
 *     """
 *     Figure out the best memory access order for a given slice.
 */


/* "View.MemoryView":1187
 *
 * @cname('__pyx_fill_contig_strides_array')
 * cdef Py_ssize_t fill_contig_strides_array(             # <<<<<<<<<<<<<<
 *                 Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
 *                 int ndim, char order) nogil:
 */


/* "View.MemoryView":1208
 *
 * @cname('__pyx_memoryview_copy_data_to_temp')
 * cdef void *copy_data_to_temp(__Pyx_memviewslice *src,             # <<<<<<<<<<<<<<
 *                              __Pyx_memviewslice *tmpslice,
 *                              char order,
 */


/* "View.MemoryView":1362
 *
 * @cname('__pyx_memoryview_refcount_copying')
 * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object,             # <<<<<<<<<<<<<<
 *                            int ndim, bint inc) nogil:
 *
 */


/* "View.MemoryView":1371
 *
 * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
 * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape,             # <<<<<<<<<<<<<<
 *                                              Py_ssize_t *strides, int ndim,
 *                                              bint inc) with gil:
 */


/*! @brief Used by the TrickHLA extension to determine if the object data changed.
    *  @return True if object data has changed. */


/*! @brief Convert value to a time on the timeline with the minimum time resolution.
    *  @return Returns the time in seconds on the timeline with the minimum resolution.
    *  @param value The time value to convert. */


/*! @brief C (char *) string to C++ wide string conversion routine.
    *  @param output The output wide string.
    *  @param input  The input C string. */


/*! @brief C++ string to C++ wide string conversion routine.
    *  @param output The output wide string.
    *  @param input  The input C++ string. */


/*! @brief C++ wide string to C++ string conversion routine.
    *  @param output The output C++ string.
    *  @param input  The input wide string. */


/*! @brief C++ string to C (char *) string conversion routine with the
    * string being placed into Trick memory space.
    *  @details Make sure to use ip_free() to free the memory otherwise you
    *  could end up with a memory leak.
    *  @return C string.
    *  @param input The input string. */


/*! @brief C++ wide string to C (char *) string conversion routine with the
    * string being placed into Trick memory space.
    *  @details Make sure to use ip_free() to free the memory otherwise you
    *  could end up with a memory leak.
    *  @return C string.
    *  @param input The input wide string. */


/*! @brief HLA RTI User Data to printable C++ string conversion routine.
    *  @param output The output C++ string with only printable characters.
    *  @param data   User supplied tag */


/*! @brief HLA RTI User Data to C++ string conversion routine.
    *  @param output The output C++ string.
    *  @param data   User supplied tag */


/*! @brief Convert a federate handle to a C string representation.
    *  @param output The output C++ string.
    *  @param handle Federate handle. */


/*! @brief Convert an interaction class handle to a C string representation.
    *  @param output The output C++ string.
    *  @param handle Class handle. */


/*! @brief Convert an interaction class handle to a C string representation.
    *  @param output The output C++ string.
    *  @param handle Parameter Handle. */


/*! @brief Convert an object instance handle to a C string representation.
    *  @param output The output C++ string.
    *  @param handle Instance handle. */


/*! @brief Convert an object class handle to a C string representation.
    *  @param output The output C++ string.
    *  @param handle Class handle. */


/*! @brief Convert an attribute handle to a C string representation.
    *  @param output The output C++ string.
    *  @param handle Attribute handle. */


/*! @brief Trim any leading or trailing whitespace from the string.
    *  @param s The string to trim. */


/*! @brief Trim any leading or trailing whitespace from the wstring.
    *  @param s The wstring to trim. */


/*! @brief Tokenize a given string for the specified delimiter characters.
    *  @param str        The input string.
    *  @param tokens     Tokens of the string.
    *  @param delimiters Delimiter characters for tokenizing the string. */


/*! @brief Tokenize a given wstring for the specified delimiter characters.
    *  @param str        The input string.
    *  @param tokens     Tokens of the string.
    *  @param delimiters Delimiter characters for tokenizing the string. */


/*! @brief Calculate the number of attribute items associated with this parameter.
    *  @return The number of attribute items associated with this parameter. */


/*! @brief Default constructor for the TrickHLA KnownFederate class. */


/*! @brief Mark the attribute is locally owned flag. */


/*! @brief Mark the attribute is NOT locally owned flag. */


/*! @brief Determine is the data cycle is ready for sending data.
    *  @return True if the data cycle is ready for a send, false otherwise.*/


/*! @brief Calculate the number of items in the attribute.
    *  @return Number of items in the attribute. */


/*! @brief Clear the Trick allocated memory for the FOM name. */


/*! @brief Reset both the push and pull buffer positions. */


/*! @brief Query if time advance has been granted.
    *  @return True if time advance has been granted; False otherwise. */


/*! @brief Query if time management is enabled.
    *  @return True if time management is enabled; False otherwise. */


/*! @brief On receive boundary if the main thread simulation-time is an integer
    * multiple of a valid thread cycle-time.
    * Note: This is thread safe because this function is only local to this class
    * and it is called from a locked mutex critical section. */


/*! @brief On send boundary if the main thread simulation-time is an integer
    * multiple of a valid thread cycle-time for the send frame.
    * Note: This is thread safe because this function is only local to this class
    * and it is called from a locked mutex critical section. */


/*! @brief True if the specified thread ID is for an enabled Trick child thread association. */


/*! @brief Reset the manager as initialized. */


/*! @brief Compensate the state data from the data time to the current scenario time.
    *  @param t_begin Scenario time at the start of the compensation step.
    *  @param t_end   Scenario time at the end of the compensation step. */


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this CabinAtmo Configuration Data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this CabinAtmo.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Initializes this CabinAtmo model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Does some valid range checks on the configuration data, outputs error messages.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] dt (s) Timestep of integration.
///
/// @details  This is the main model step.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This is the local model update, propagates the volume states forward by one
///           integration time step.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Updates the IMV fan model, which we model as a pressure source in the SOE from which
///           flow results in the SOE solution.  The fan source pressure is modeled as a line
///           its dead-head (stall) pressure at zero flow, to a maximum flow at zero pressure.  The
///           default configuration should match the dead-head and nominal flow points for a typical
///           ISS fan, but the maximum flow rate will be unrealistically high because of this linear
///           fan curve simplification.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This builds the system of equations for the model.  The system is [A]{x} = {b}, where
///           [A] is the admittance matrix, {x} is the new pressures to be solved for, and {b} is
///           the source vector.  Each of the 3 model volumes has a row in the system.  The units of
///           this system is flow rate (mol/s) = {b} = A (mol/s/Pa) * P (Pa).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Computes the inverse of the admittance matrix.  The admittance matrix is 3x3,
///           symmetric, positive-definite.  The determinant is always non-zero because A[0][0]
///           is always non-zero (from non-zero cabin volume).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[out] x (Pa)    The computed pressures of the solution.
/// @param[in]  b (mol/s) The source vector.
///
/// @details  Computes {x} = [A]^-1 * {b}, which is the solution of the SOE, with volume pressures
///           propagated to the next time step as the integral of flows to/from the volume's
///           capacitance.  The pressure and source vectors are arguments, rather than being
///           operated on directly, so this function can compute alternate solutions for {x} such as
///           for modified {b} used to compute capacitances, etc.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Computes the flows between the volumes corresponding to the latest pressure solution.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Transports flow between the volumes and the Fluid Distributed Interfaces.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Updates the volume pressures to match the final mole quantity and temperature after
///           transport.  These can differ from the solution of the SOE when the volume temperature
///           has changed due to mixing of inflows, because the SOE solution is based on the last-
///           pass temperature.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Computes the effective capacitance of the Fluid Distributed Interface volumes.  This
///           uses the 'mock solution' approach recommended by the interface documentation, where we
///           compute what the volume pressures would be if we added an extra mole of air to it, by
///           re-solving the SOE with a modified source vector that adds the extra mole.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Updates the total moles and energy within the volumes that this model owns.  This can
///           be used to check for conservation of mass & energy.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] level   (--) Severity level of the message.
/// @param[in] message (--) Detailed message string.
///
/// @details  Constructs this notification message with the given values.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that  (--)  Object to be copied.
///
/// @details  Notification message copy constructor.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Distributed 2-Way Bus Base interface data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] inDataPtr  (--) Pointer to the interface incoming data object.
/// @param[in] outDataPtr (--) Pointer to the interface outgoing data object.
///
/// @details  Default constructs this Distributed 2-Way Bus Base Interface.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] isPairMaster (--) True if this is the master side of the interface, for tie-breaking.
///
/// @details  Initializes this Distributed 2-Way Bus Base Interface.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Update frame counters and loop latency measurement.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[out] notification (--) Reference to the caller's message object to copy the message into.
///
/// @returns  unsigned int (--) Number of notifications remaining in the queue.
///
/// @details  Set the caller's supplied notification object equal to the tail of the queue and pops
///           that message off of the queue, reducing the queue size by one.  If the queue size is
///           already zero, then returns an empty message.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this distributed fluid mixture data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default destructs this distributed fluid mixture data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] nBulk   (--) Number of bulk fluid constituents.
/// @param[in] nTc     (--) Number of trace compounds.
/// @param[in] name    (--) Not used.
///
/// @details  Allocates arrays for bulk fluid and trace compounds mole fractions.  This function is
///           virtual and the name argument exists to support derived types needing to allocate the
///           mixture arrays using a specific sim memory manager.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] fractions (--) Array of bulk fluid mole fraction values to read from.
/// @param[in] size      (--) Size of the given fractions array.
///
/// @details  Sets this object's bulk fluid mole fractions equal to the given values.  The given
///           array can be larger or smaller than our internal array.  If our array is larger, then
///           the remaining values in the our array are filled with zeroes.
////////////////////////////////////////////////////////////////////////////////////////////////////