Known limitations
=================

Behaviour that is known to be incomplete, untested or surprising. Check this
list before relying on a feature in production, and update it when you fix or
discover something.

Features with restrictions
--------------------------

Load balancing
   ``doLoadBalance()``/``doRestructure()`` need the ParMETIS build
   (``hemocell_parmetis``), which currently does not compile: the
   per-block timers it reads were dropped from the Palabos patch. Without
   ParMETIS, ``doRestructure()`` only prints a warning. It is not supported
   together with a pre-inlet or the CEPAC field, and has not been tested since
   its fixes.

Lees-Edwards boundary condition
   Only correct when the blocks on both sides of the shearing (z) boundary are
   on the same rank: the shear offset is applied only to particles copied
   locally, and the population buffers are per rank.

Pre-inlet
   Only the ``Xpos`` direction has been tested. The pre-inlet needs at least two
   ranks.

Solidification
   Binding sites near block boundaries and regions that already overlap cells
   when marked as binding sites have shown problems on several ranks (see
   ``TODO.md``).

Interior viscosity
   Compiled only into ``hemocell_interior_viscosity``; not covered by the test
   suite.

``cases/``
   Research cases, some experimental or incompletely validated. Validate before
   treating them as reference behaviour.

Numerical and modelling notes
-----------------------------

Repulsion
   The force is ``k * r_c / d`` along the line between two vertices of
   different cells (or a vertex and a wall node) for ``d < r_c``; ``k`` is
   given in pN and ``r_c`` in micrometres. The repulsion force per vertex is
   capped at ``FORCE_LIMIT``, separately from the membrane force, so the total
   force of a vertex can reach twice the limit. The neighbour search covers
   adjacent lattice nodes only, so cutoffs above one lattice spacing are only
   partially effective (a warning is printed). The shipped configurations use
   ``kRep = 5`` pN, a low value chosen to have an effect, not a validated one.
   Particle and wall repulsion must use the same update interval.

Bending torque
   The bending force of a vertex acts along its patch normal and is balanced by
   equal shares on its neighbours: the net force of every model is zero, but
   the bending term is not torque-free. For a mildly deformed cell the net
   torque of all membrane forces is 1.5e-5 to 3e-5 of the sum of
   ``|r| |F|`` (``tests/integration/test_mechanics.cpp``); it can spin cells
   slightly.

Force cap
   ``FORCE_LIMIT`` (default 50 pN per vertex) caps the membrane force spread to
   the fluid; a quarter of it caps the membrane-viscosity force per edge. Capping
   keeps runs stable but changes the physics when it is active (a warning is
   printed at start-up).

Cells across a periodic boundary at load
   By default, a cell of a ``.pos`` file whose surface crosses a periodic
   boundary is not placed; the log counts such cells. With
   ``setPlaceCellsAcrossPeriodicBoundaries(true)`` they are placed as periodic
   images, which is correct only for ``.pos`` files packed periodically for
   this domain: the shipped ``.pos`` files were packed for other box sizes (the
   pipeflow test file for 67 um in x, its domain is 51.5 um), and their cells at
   opposite ends would overlap.

Broken cells
   A cell that loses a vertex (it enters a wall node or leaves the domain, or
   its force is not finite) is deleted as a whole at the next particle update
   and not re-inserted; ``<verbose><cellsDeletedInfo>`` prints each deletion.

Time-scale separation
   Output shows the total force from the last material update but evaluates
   force components for the current shape; with separations > 1 the components
   need not add up to the total.

Initial placement
   ``setInitialMinimumDistanceFromSolid()`` rejects vertices within
   ``floor(d / dx)`` lattice nodes of a wall; distances below one lattice
   spacing have no effect. A cell is dropped as a whole when one of its
   vertices is rejected, lies outside the domain or across a periodic boundary
   (images are not placed); ``loadParticles()`` logs how many cells of each
   type were placed. A missing ``<name>.pos`` file is a fatal error; a file
   containing ``0`` means no cells of that type.

Software constraints
--------------------

* One ``HemoCell`` object at a time per process (process-wide state, reset
  when the object is destroyed).
* Library code is C++11; the test runner is C++17.
* Output is written as one HDF5 file per atomic block and output step; very
  large runs produce many small files. Most datasets are single precision.
* Restarts need the same case code and cell types; the number of ranks may
  change.
