Skip to content

Reply To: Saving and Loading Fields at each timestep

#6833
Adrian
Keymaster

While there is no ready made switch to do exactly this, OpenLB certainly provides the necessary tools. I would suggest to roughly proceed as follows:

1. Declare a new field for storing the velocity data for serialization (e.g. struct INLET_VELOCITY : public descriptors::FIELD_BASE<0,1> { }; for a D-dimensional field at each lattice node)
2. Implement a post processor for computing the velocity and storing it in the new field (see example at the end)
3. Add the post processor to the inlet cells via an indicator (i.e. sLattice.addPostProcessor(indicatorF, meta::id<StoreInletVelocity>{});)
4. Serialize the field to file using blockLattice.getField<StoreInletVelocity::U>().save("inletVelocity.field")
5. Load the field from file using blockLattice.getField().load(“inletVelocity.field”)`

Ideally you can load it back to the specific field used by the inlet condition to store its velocity values. E.g. in case of local/interpolated velocity boundaries this is momenta::FixedVelocityMomentumGeneric::VELOCITY.

Alternatively the same can be achieved by:

1. Computing the velocity at the inlet cells using the SuperLatticeVelocity3D functor
2. Writing them to disk using standard C++
3. Loading them from disk and applying them to the inlet cells using Cell::setField.

I hope that one of the two options is enough to get you started.

—–


class StoreInletVelocity  {
public:
  static constexpr OperatorScope scope = OperatorScope::PerCell;

  struct U : public descriptors::FIELD_BASE<0,1> { };

  int getPriority() const {
    // Ensure that the post processor is executed after any boundary processing
    // Alternatively it may be nicer to add it to a custom stage and call it only when necessary in the main loop 
    return std::numeric_limits<int>::max();
  }

  template <typename CELL>
  void apply(CELL& cell) any_platform {
    using V = typename CELL::value_t;
    using DESCRIPTOR = typename CELL::descriptor_t;
    V u[DESCRIPTOR::d] { };
    cell.computeU(u);
    cell.template setField<U>(u);
  }

};