Program Listing for File network.h

↰ Return to documentation for file (include/immersx/vascularization/network.h)

// Copyright (C) 2026 by Luca Heltai
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef immersx_vascularization_network_h
#define immersx_vascularization_network_h

#include <deal.II/base/point.h>
#include <deal.II/base/types.h>

#include <array>
#include <cstdint>
#include <limits>
#include <map>
#include <string>
#include <vector>

namespace ImmersX::Vascularization
{
  using Id                       = std::uint64_t;
  inline constexpr Id invalid_id = std::numeric_limits<Id>::max();

  enum class System : unsigned int
  {
    arterial,
    venous,
    portal
  };

  enum class Provenance : unsigned int
  {
    imported,
    generated
  };

  enum class Port : unsigned int
  {
    none,
    arterial_inlet,
    venous_outlet,
    arterial_outlet,
    portal_inlet,
    portal_outlet
  };

  struct Node
  {
    dealii::Point<3>            position;
    dealii::types::subdomain_id owner      = 0;
    Port                        port       = Port::none;
    Provenance                  provenance = Provenance::imported;
    dealii::Point<3> inward_port_normal{};
  };

  struct Vessel
  {
    std::array<Id, 2>     nodes{{invalid_id, invalid_id}};
    std::array<double, 2> radii{{0., 0.}};
    double                viscosity  = std::numeric_limits<double>::quiet_NaN();
    System                system     = System::arterial;
    Provenance            provenance = Provenance::imported;
    dealii::types::subdomain_id owner = 0;
    std::map<std::string, double> physical_properties;
  };

  struct Terminal
  {
    Id                          node      = invalid_id;
    Id                          territory = invalid_id;
    System                      system    = System::arterial;
    dealii::types::subdomain_id owner     = 0;
    double demand = 1.;
  };

  struct TerminalPair
  {
    Id     territory  = invalid_id;
    Id     arterial   = invalid_id;
    Id     venous     = invalid_id;
    double resistance = 0.;
  };

  struct TerminalTriplet
  {
    Id territory = invalid_id, arterial = invalid_id, portal = invalid_id,
       venous = invalid_id;
    std::array<double, 3> resistances{{0., 0., 0.}};
  };

  struct NetworkData
  {
    std::map<Id, Node>     nodes;
    std::map<Id, Vessel>   vessels;
    std::map<Id, Terminal> terminals;
  };

  struct ValidationIssue
  {
    std::string entity;
    Id          id = invalid_id;
    std::string message;
  };

  struct ValidationReport
  {
    std::vector<ValidationIssue> issues;

    bool
    valid() const;
  };

  ValidationReport
  validate_data(const NetworkData &network, unsigned int communicator_size);

  ValidationReport
  validate_terminal_pairs(const NetworkData               &network,
                          const std::vector<TerminalPair> &pairs);

  double
  length(const NetworkData &network, Id vessel);

  double
  volume(const NetworkData &network,
         Id                 vessel,
         double             begin = 0.,
         double             end   = 1.);

  double
  resistance(const NetworkData &network,
             Id                 vessel,
             double             begin = 0.,
             double             end   = 1.);

  double
  murray_radius(const std::vector<double> &children, double gamma);

  struct VesselCell
  {
    Id     vessel = invalid_id;
    double begin  = 0.;
    double end    = 1.;
  };

  std::vector<VesselCell>
  subdivide(const NetworkData         &network,
            Id                         vessel,
            const std::vector<double> &coordinates);
} // namespace ImmersX::Vascularization

#endif