CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   use of pointers in openfoam (https://www.cfd-online.com/Forums/openfoam-programming-development/231213-use-pointers-openfoam.html)

kcengiz October 27, 2020 03:48

use of pointers in openfoam
 
Hi all,
Because I am new to C++ programming and the OpenFOAM templates and tools, I have a rather simple question. I need to collect extra data for postprocessing (via fieldAverage) in every time step.



Code:

        //Calculate gradU and distribute to scalar Fields
        gradU = fvc::grad(U);

        gradux = gradU.component(tensor::XX);
        graduy = gradU.component(tensor::XY);
        graduz = gradU.component(tensor::XZ);
 
        gradvx = gradU.component(tensor::YX);
        gradvy = gradU.component(tensor::YY);
        gradvz = gradU.component(tensor::YZ);
 
        gradwx = gradU.component(tensor::ZX);
        gradwy = gradU.component(tensor::ZY);
        gradwz = gradU.component(tensor::ZZ);

This works fine, but is also stupid because there is a copying operation at each time step (as well as waste of memory). gradux etc are declared as scalar fields,


Code:

    volScalarField gradux
      (
        IOobject
        (
            "gradux",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh, dimensionedScalar("gradux", dimensionSet(0,0,-1,0,0,0,0), 0.0)
      );

etc., because fieldAverage function object cannot work with tensors. Is there an easy way to use pointers instead?


Thanks for the help!

olesen October 29, 2020 16:30

Quote:

Originally Posted by kcengiz (Post 786070)
Code:

        //Calculate gradU and distribute to scalar Fields
        gradU = fvc::grad(U);

        gradux = gradU.component(tensor::XX);
        graduy = gradU.component(tensor::XY);
        graduz = gradU.component(tensor::XZ);
 
        gradvx = gradU.component(tensor::YX);
        gradvy = gradU.component(tensor::YY);
        gradvz = gradU.component(tensor::YZ);
 
        gradwx = gradU.component(tensor::ZX);
        gradwy = gradU.component(tensor::ZY);
        gradwz = gradU.component(tensor::ZZ);

This works fine, but is also stupid because there is a copying operation at each time step (as well as waste of memory). gradux etc are declared as scalar fields,

This probably reflects my first impressions as well, however you have to dig deeper into what is really happening. Without saying "read the docs" in a bad sense, you really do need to read the docs to see how wasteful /non-wasteful it is (needs a bit of digging). The component() method returns a 'tmp', which masks a useful reference or allocated pointer duality. In the case of component(), a pointer to a field is allocated. However, in the next step the assignment of this tmp field to a field results in a transfer of its content to the field and deletion of the pointer. The addressed range of the field is transferred without copying.

Later, when you want to use any of these fields as a volField, they should be wrapped with a std::move() to get move semantics on construction. Of course you need to do that yourself, the compiler and class definitions won't do it for you.


All times are GMT -4. The time now is 07:20.