Islands - nasa/gunns GitHub Wiki

{{>toc}}

Islands

What are islands?

What we call “islands” are also called “partitions”, “blocks” or “sub-matrices” in linear algebra. These are groups of rows (nodes) in the [A] matrix that are independent of the rest of the matrix. This means a set of nodes that are directly or indirectly connected to each other through conductive paths and have no conductive paths to the other network nodes. In the example network shown below, nodes 0 & 1 would belong to the same island, and node 2 would be by itself in its own island.

Note that although the Source link connects nodes 1 & 2, it is not a conductive path so it doesn’t join them in the same island. Nodes 0 and 1 are in the same island because they are connected by the conductance G. This is easy to see in the [A] matrix because all conductances between nodes show up in the off-diagonals of those row/columns (shown above in red).

Islands can run faster

The main reason to use islands is because they can vastly reduce the amount of CPU needed to solve the network, so it can run faster. Because each island is its own sub-matrix in [A], the Cholesky decomposition of [A] as a whole is identical to the sum of the individually decomposed sub-matrices. And, since the decomposition is a number of nodes roughly n^2.7 problem, smaller matrices decompose much faster than larger matrices. A network with n number of nodes is about 3 times slower than 2 networks of size n/2:

o = 2.7
n^o / ( (n/2)^o + (n/2)^o ) = n^o / ( 2^(1-o) * n^o ) = 3.24

Some networks can get an even larger improvement if they have more than 2 islands and the largest island is small compared to the overall network size. For instance, the Primary EPS network in TS-21’s ISS simulation is approximately 435 nodes, with 8 islands of about 30 nodes each, leaving the largest remaining island at about 195 nodes. When they started using islands, they saw an approximately 10-fold speed increase in their network because:

435^o / (195^o + 8*(30)^o) = 8.3

Predicting the speed increase

When predicting how much faster a network will run with islands, we can usually neglect all but the largest island in the network, and compare that to the total network size:

speed increase factor = (total network size / largest island size)^2.7

So in the above example, (435/195)^o = 8.7, and this is a good enough approximation for determining whether or not to use islands in your network.

When to use islands

There is a CPU cost to finding the islands before they can be decomposed separately. This cost depends on the sparsity of the matrix, but in our aspects, which are always very sparse, it comes out to about a 5-10% increased CPU cost on average. We can easily recover that cost with a (largest island / total size) ratio of only 0.95, so we recommend using islands whenever the largest island is 95% the total network size or less.

> Use islands whenever the largest resulting island is 95% of the total network size or less.

Conveniently, the solver tells you what the largest island size is whenever it is in an island-finding mode. See the island metrics below.

Solver Island Mode

The solver has an island mode setting that determines how to use islands. The settings currently are:

  • OFF: This is the default mode. Islands are not found or used in the solver. Certain links and spotters that depend on islands being found by the solver do not work in this mode.
  • FIND: Islands are determined & output to nodes but not used in solver. As discussed above, this incurs a 5-10% increase in CPU load for the network.
  • SOLVE: Islands are decomposed separately by building new island admittance matrices. This solves faster than SOLVE_2 so it is the preferred mode.
  • SOLVE_2: Islands are decomposed separately within the main admittance matrix.

Setting the Island Mode

The island mode of all networks defaults to OFF when a load comes up. To use a different mode, call the solver’s setIslandMode(const Gunns::IslandMode) with the desired mode value, enumerated above. This can be called from the Trick input file. For example, this sets an island mode to SOLVE:


    eclss.fluid.netSolver.setIslandMode(trick.Gunns.SOLVE)

You can change the island mode at any time.

Finding the Islands

The conductive topography of a network can change every pass, so it is necessary for the solver to re-find the islands every pass because if we try to decompose [A] with a stale island set, some conductances can get lost and their effects not seen in the solution.

When the solver is in an island-finding mode (FIND, SOLVE, SOLVE_2), the solver re-finds the islands during each minor step iteration after it has built but before it decomposes [A]. The islands are found by looping over [A] and looking for non-zero values in the off-diagonals. Since off-diagonals only correspond to the conductance effect, and islands are determined only by conductive paths, they can be completely determined by tracking the off-diagaonals in [A]. The row/column coordinates of the off-diagonal define the two nodes that are in the same island, and the node numbers are collected in an island vector. During the whole process, islands are merged if they are found to be joined between any two of their nodes by an off-diagonal.

Island Metrics

When the solver is in an island-finding mode, it re-finds the islands every major step and stores a couple of related parameters in these class attributes:

  • mIslandCount: the number of distinctly separate islands. There is always at least one island (consisting of the entire network, so this value will be >= 1 when islands are being found.
  • mIslandMaxSize: the number of nodes in the largest island. This is useful for predicting how much faster the network will run (see above).

The island analyzer spotters

You can use these spotter classes to get more information about the islands. There is one such spotter class in gunns/core for basic & fluid networks. The spotter allows you to attach it to a node by setting its mAttachedNode term. It then finds things out about the island that node is in that might be useful: the number of nodes in the island, which nodes are in it, which nodes have the highest & lowest potential, etc. We recommend always including at least one such spotter of the appropriate basic/fluid type in your network.

Note that these spotters only work if the network is in an island-finding mode.

Here is a list of the island attributes that the GunnsBasicIslandAnalyzer spotter class finds for basic networks:


        int            mIslandSize;      /**< (--)                     Number of nodes in the attached island     */
        bool*          mIslandNodes;     /**< (--) trick_chkpnt_io(**) Flags for nodes present in the island      */
        double         mIslandNetFlux;   /**< (--)                     Sum of net flux in all nodes in the island */
        double         mHiPotential;     /**< (--)                     Highest node potential in the island       */
        int            mHiPotentialNode; /**< (--)                     Island node with the highest potential     */
        double         mLoPotential;     /**< (--)                     Lowest node potential in the island        */
        int            mLoPotentialNode; /**< (--)                     Island node with the lowest potential      */

Here is the list of attributes that the GunnsFluidIslandAnalyzer spotter class finds for fluid networks:


        int            mIslandSize;            /**< (--)                     Number of nodes in the attached island                 */
        bool*          mIslandNodes;           /**< (--) trick_chkpnt_io(**) Flags for nodes present in the island                  */
        double         mIslandVolume;          /**< (m3)                     Total fluid volume of all nodes in the island          */
        double         mIslandMass;            /**< (kg)                     Total fluid mass in all nodes in the island            */
        double*        mIslandConstituentMass; /**< (kg) trick_chkpnt_io(**) Total constituent mass in all nodes in the island      */
        double         mIslandEnergy;          /**< (J)                      Total fluid enthalpy * mass in all nodes in the island */
        double         mHiPressure;            /**< (kPa)                    Highest node pressure in the island                    */
        int            mHiPressureNode;        /**< (--)                     Island node with the highest pressure                  */
        double         mLoPressure;            /**< (kPa)                    Lowest node pressure in the island                     */
        int            mLoPressureNode;        /**< (--)                     Island node with the lowest pressure                   */
        double         mHiTemperature;         /**< (K)                      Highest node temperature in the island                 */
        int            mHiTemperatureNode;     /**< (--)                     Island node with the highest temperature               */
        double         mLoTemperature;         /**< (K)                      Lowest node temperature in the island                  */
        int            mLoTemperatureNode;     /**< (--)                     Island node with the lowest temperature                */
        double*        mHiMoleFraction;        /**< (--) trick_chkpnt_io(**) Highest constituent mole fraction in the island        */
        int*           mHiMoleFractionNode;    /**< (--) trick_chkpnt_io(**) Island node with the highest constituent mole fraction */
        double*        mLoMoleFraction;        /**< (--) trick_chkpnt_io(**) Lowest constituent mole fraction in the island         */
        int*           mLoMoleFractionNode;    /**< (--) trick_chkpnt_io(**) Island node with the lowest constituent mole fraction  */
⚠️ **GitHub.com Fallback** ⚠️