Skip to content

JPEG output of time-averaged fonctor

OpenLB – Open Source Lattice Boltzmann Code Forums on OpenLB General Topics JPEG output of time-averaged fonctor

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #6521
    Mathis
    Participant

    Dear all,

    I would like to use the ability of OpenLB to extract JPEG data from slices in the computational domain during a simulation. I know how to do this for “regular” fonctors like SuperLatticePhysVelocity3D for example, by using the following lines of code after the prepareLattice stage:

    SuperLatticePhysVelocity3D<T, DESCRIPTOR> velocity( sLattice, converter );
    SuperEuklidNorm3D<T, DESCRIPTOR> normVel( velocity );
    BlockReduction3D2D<T> planeReduction(
    normVel,
    Hyperplane3D<T>().centeredIn(cuboidGeometry.getMotherCuboid()).normalTo({0,-1,0}),
    0,
    BlockDataSyncMode::ReduceOnly
    );

    and then using the following lines in the getResults routine:

    if ( iT%vtkIter==0 ) {
    planeReduction.update();
    // write output as JPEG
    heatmap::write(planeReduction, iT);
    }

    (the above lines of code are inspired of the example case bstep3d.cpp)

    My question is : how do you apply this procedure to a time-avergaed fonctor ? like one for the averaged velocity field magnitude for instance, which could be constructed as

    SuperLatticePhysVelocity3D<T, DESCRIPTOR> sVel( sLattice, converter );
    SuperLatticeTimeAveragedF3D<T> sAveragedVel( sVel );

    For information, simply plugging sAveragedVel in SuperEuklidNorm3D does not work.

    Thank you for your help !

    #6523
    Mathis
    Participant

    POST SCRIPTUM : working on version 1.4

    #6542
    stephan
    Moderator

    Dear Mathis,

    thank you for your comment.

    Please note that the SuperLatticeTimeAveragedF3D functor returns more than 3 dimensions.
    The exact specification is given for example here:
    https://www.openlb.net/DoxyGen/html/d5/dc4/superLatticeTimeAveraged3D_8h_source.html

    Hence, if you extract the corresponding entries to another vector on SuperLattice level, you are able to continue as suggested (using the latter as an input for SuperEuklidNorm3D).

    BR
    Stephan

    #6547
    Mathis
    Participant

    Dear Stephan,

    Thank you for your answer.
    So I managed to extract components from the instance of SuperLatticeTimeAveragedF3D using the method SuperExtractComponentF3D, which extracts one component at a time. By doing this for each component of the velocity (three in 3D), I managed to generate three distinct outputs for each time-averaged velocity component with the following lines of code before the time loop in the main() function :

    // definition of turbulent statistics objects
    SuperLatticePhysVelocity3D<T, DESCRIPTOR> sVel( sLattice, converter );
    SuperLatticeTimeAveragedF3D<T> sAveragedVel( sVel );
    SuperExtractComponentF3D<T,T> uAvgVel( sAveragedVel, 0);
    SuperExtractComponentF3D<T,T> vAvgVel( sAveragedVel, 1);
    SuperExtractComponentF3D<T,T> wAvgVel( sAveragedVel, 2);
    uAvgVel.getName() = “physVelU”;
    vAvgVel.getName() = “physVelV”;
    wAvgVel.getName() = “physVelW”;
    // x vel component
    BlockReduction3D2D<T> planeReduction_u(uAvgVel, Hyperplane3D<T>().originAt({0,0,3.5}).normalTo({0,0,1}), 0, BlockDataSyncMode::ReduceOnly);
    // y vel component
    BlockReduction3D2D<T> planeReduction_v(vAvgVel, Hyperplane3D<T>().originAt({0,0,3.5}).normalTo({0,0,1}), 0, BlockDataSyncMode::ReduceOnly);
    // z vel component
    BlockReduction3D2D<T> planeReduction_w(wAvgVel, Hyperplane3D<T>().originAt({0,0,3.5}).normalTo({0,0,1}), 0, BlockDataSyncMode::ReduceOnly);

    along with the update lines on the function getResults :

    // Writes the ppm files
    if ( iT%vtkIter==0 ) {
    planeReduction_u.update();
    planeReduction_v.update();
    planeReduction_w.update();
    // write output as JPEG
    heatmap::write(planeReduction_u, iT);
    heatmap::write(planeReduction_v, iT);
    heatmap::write(planeReduction_w, iT);
    }

    In the end I did not use the SuperEukildNorm3D because if I input uAvgVel for instance, it outputs a segmentation error (there is no need to apply a norm to each component separately anyway, but I mention this segFault for your information)

    A more optimal way to proceed would be to find a way to directly create a SuperLatticeF3D functor (with dimension 3) from the SuperLatticeTimeAveragedF3D (which has dimension 6, with 3 time-avg vel components + 3 RMS values) with the components of interest, and to give it to SupeEuklidNorm3D, but I did not find any way to do so.

    If you have any clue, feel free to let me know, I would be interested to use it, although the solution I described above appears to meet my original goal.

    Thank you very much
    Best regards

    Mathis

    #6563
    jjessberger
    Participant

    Dear Mathis,

    Typically, such segfaults arise if the dimensions of the functors and the output arrays do not fit. For instance, SuperEuklidNorm3D expects to get a 3D functor and will probably segfault if a 1D functor is passed.

    You could copy and modify the SuperExtractComponentF3D, s.t. it extracts several components. A most simple version of the operator() method to extract the first n components would then look like

    template <typename T, typename W>
    bool SuperExtractComponentVariantF3D<T,W>::operator()(W output[], const int input[])
    {
    std::vector<T> outTmp(_f->getTargetDim(), T{});
    _f(outTmp.data(), input);
    for (unsigned i=0; i<n; ++i) {
    output[i] = outTmp[i];
    }
    return true;
    }

    Kind regards
    Julius

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