Skip to content

Saving and Loading Fields at each timestep

OpenLB – Open Source Lattice Boltzmann Code Forums on OpenLB General Topics Saving and Loading Fields at each timestep

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #6802
    ramirofreile
    Participant

    Hello OpenLB community,

    I am running a turbulent LES case. To develop the turbulence, I am using periodic boundary conditions.

    For my final application, periodic boundary conditions will not be appropriate, I will need inlet conditions instead.

    Therefore, I thought about the possibility of saving the velocity fields at each lattice time at the inlet and then, for my real application, load the exported velocity fields and impose them as boundary conditions at different timesteps.

    Is this capability currently in the code? If not, I would appreciate some guidance on how to approach it.

    Thank you!

    Ramiro Freile

    #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);
      }
    
    };
    

Viewing 2 posts - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.