CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

Extract data in volVectorField to a primitive C or C++ data type

Register Blogs Community New Posts Updated Threads Search

Like Tree1Likes
  • 1 Post By mkiewat

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   February 12, 2016, 08:45
Default Extract data in volVectorField to a primitive C or C++ data type
  #1
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
Consider a volVectorField like U. How can I extract the data inside the object to a primitive C or C++ data type?

I want the data in memory but not in a OpenFOAM-specific object. Basically what I want is just a std::vector (or even better: a C array) containing the values in e.g. 0/U.

My goal is to write a function which computes vorticity and returns just a C pointer to the first value in memory.
cfbaptista is offline   Reply With Quote

Old   February 12, 2016, 10:17
Default
  #2
Senior Member
 
dkxls's Avatar
 
Armin
Join Date: Feb 2011
Location: Helsinki, Finland
Posts: 156
Rep Power: 19
dkxls will become famous soon enough
I would recommend you to take a look at OpenFOAM's container classes as they build the underlying data structure for the fields (e.g. volVectorField or volScalarField). Specifically have a look at the List [1] and UList [2] classes.

Now, assuming f is of type volScalarField, you would get access to the internal field (i.e. without the boundaries) like this:
Code:
    const scalarField& fCellValues = f.internalField();
To get access to the C data structure something like this should do the trick:
Code:
    const double* data = fCellValues.cdata();
Now, for vector fields that might be a bit different, since I cannot recall how they are stored exactly (e.g. if the data arrays are contiguous). But maybe somebody else can comment on that.

Hope that helped!

-Armin

[1] https://github.com/OpenFOAM/OpenFOAM...ts/List/List.H
[2] https://github.com/OpenFOAM/OpenFOAM.../UList/UList.H
dkxls is offline   Reply With Quote

Old   February 12, 2016, 10:49
Default
  #3
New Member
 
Marco
Join Date: Nov 2014
Location: Germany
Posts: 14
Rep Power: 12
mkiewat is on a distinguished road
I'm dealing with a similar problem. I managed to extract the entire field to std namespace vectors using the object registry to get the components of the vectorfield (u_,v_,w_), then I copy them cell by cell (which is probably not a good idea at all) into the std vector structure (u,v,w).
Code:
const volScalarField u_(obr().objectRegistry::lookupObject<volVectorField>("U").component(vector::X));
const volScalarField v_(obr().objectRegistry::lookupObject<volVectorField>("U").component(vector::Y));
const volScalarField w_(obr().objectRegistry::lookupObject<volVectorField>("U").component(vector::Z));
    
const int nCells(v_.size());
    
std::vector<double> u(nCells,0);
std::vector<double> v(nCells,0);
std::vector<double> w(nCells,0);
    
forAll(u_, cellI)
{
        u[cellI]=u_[cellI];
        v[cellI]=v_[cellI];
        w[cellI]=w_[cellI];
}
My current problem is, that I want to extract only a certain sub-volume of cells to such a data structure. For this I copied the cellSource functionObject and started to look for the right location to implement that data extraction and transfer. I figured, the function Foam::fieldValues::cellSource::writeValues(const word& fieldName) from cellSourceTemplates.C might be a good place, since the sub-volume field data is already available by the variable "values". The problem: how do I extract the respective velocity components (or pressure values) from this structure? The values variable can contain: <scalar> <vector> <sphericalTensor> <symmTensor> <tensor>. Depending on the function call "writeValues" the type of values is different. I would like to extract the numbers stored in "values". At the end I want to transfer a p-vector and vectors for each velocity component. Any help is appreciated.

Here is the function that I want to edit and use:
Code:
template<class Type>
bool Foam::fieldValues::cellToMat::writeValues(const word& fieldName)
{
    const bool ok = validField<Type>(fieldName);

    if (ok)
    {
        Field<Type> values(setFieldValues<Type>(fieldName));
        scalarField V(filterField(mesh().V()));
        scalarField weightField(values.size(), 1.0);

        if (weightFieldName_ != "none")
        {
            weightField = setFieldValues<scalar>(weightFieldName_, true);
        }

        // Combine onto master
        combineFields(values);
        combineFields(V);
        combineFields(weightField);

        // apply weight field
        values *= weightField;

        if (Pstream::master())
        {
            Type result = processValues(values, V, weightField);

            // add to result dictionary, over-writing any previous entry
            resultDict_.add(fieldName, result, true);

            if (valueOutput_)
            {
                IOField<Type>
                (
                    IOobject
                    (
                        fieldName + "_" + sourceTypeNames_[source_] + "-"
                            + sourceName_,
                        obr_.time().timeName(),
                        obr_,
                        IOobject::NO_READ,
                        IOobject::NO_WRITE
                    ),
                    values
                ).write();
            }

            file()<< tab << result;

            Info(log_)<< "    " << operationTypeNames_[operation_]
                << "(" << sourceName_ << ") for " << fieldName
                <<  " = " << result << endl;
            
            //----- moving field to MATLAB starts here --------//
            // available variables:
            // - sourceName_ = "sampleBox" -> cellZone name
            // - fieldName   = "U" -> name of the currently processed field 
            // - operationTypeNames_[operation_] = "none" -> operation to be applied to the field 
            //                                     (can be:"none","sum","average","weightedAverage"
            //                                             "volAverage","volIntegrate","min","max","CoV")
            // - result      = (0 0 0) -> result from operation
            // - obr_.time().timeName() = "100.01"
            Info << nl << "Transferring " << fieldName
                       << " to MATLAB at t= " << obr_.time().timeName() << endl;

            if(fieldName == "U")
            {
                //const scalarField& test(values.component(vector::X));
                const volScalarField u_(values.component(vector::X));
                //Info << nl << "!!!!now U!!! " << values[0].component(vector::X) << endl;
                //int* temp = values[0];
                
                //ptr->DoSomething(); // Use the object in some way.
            }
            else if(fieldName == "p")
            {
                Info << nl << "!!!!now p!!!" << values[0] << endl;
            }
//const DimensionedField<Type,volMesh>& iField = this->dimensionedInternalField();
//const Field<Type>& iField = this->internalField();
// if (!iField.name().compare("U"))
// {
//   Info << nl << "SUCCESS "  << endl;
// }

            
        }
    }

    return ok;
}
atulkjoy likes this.
mkiewat is offline   Reply With Quote

Old   February 12, 2016, 10:54
Default
  #4
New Member
 
Marco
Join Date: Nov 2014
Location: Germany
Posts: 14
Rep Power: 12
mkiewat is on a distinguished road
..........
mkiewat is offline   Reply With Quote

Old   February 15, 2016, 07:02
Default
  #5
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
Thanks dkxls!

From what I gathered is that in a volVectorField all the components are stored in a separate Foam::Vector. You can then do something like:

Code:
const Foam::Vector<double>& u = U.internalField()[0];
const Foam::Vector<double>& v = U.internalField()[1];
const Foam::Vector<double>& w = U.internalField()[2];
But I need all the components in a single contiguous array. Although not efficient, I am now copying the values into a C-style array:

NOTE: i is the cell index and j is the component index

Code:
vorticity = fvc::curl(U);

int index = 0;

// Copy vorticity components stored in volVectorField object to C-style array
forAll( vorticity.internalField(), i )
{
    for ( int j = 0; j < mesh.nGeometricD(); j++ )
    {
        eulerianVorticity[index] = vorticity.internalField()[i][j];
        index++;
    }
}

// Check if size of input array exactly matches number of copied values
if ( index+1 != nbValues )
{
    if ( index+1 > nbValues )
    {
        Info<< "ERROR: Size of input array for vorticity is too small\n" << endl;
    }
    else if ( index+1 < nbValues )
    {
        Info<< "ERROR: Size of input array for vorticity is too large\n" << endl;
    }
    Info<< "ERROR: Expected size: " << nbValues << ", received size: " << index+1 << "\n" << endl;
}
If there is a more efficient or succinct way of doing this please let me know!
cfbaptista is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
CFD by anderson, chp 10.... supersonic flow over flat plate varunjain89 Main CFD Forum 18 May 11, 2018 08:31
Boundary Conditions MtnRunBeachBum OpenFOAM Pre-Processing 1 April 30, 2015 17:33
Divergent temperature in chtMultiRegion(Simple)Foam akrasemann OpenFOAM Running, Solving & CFD 13 March 24, 2014 03:54
[General] 2 datas on one plot Akuji ParaView 46 December 1, 2013 15:06
[Commercial meshers] fluentMeshToFoam multidomain mesh conversion problem Attesz OpenFOAM Meshing & Mesh Conversion 12 May 2, 2013 11:52


All times are GMT -4. The time now is 18:46.