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

Accessing dimensions (x, y, z) of cells

Register Blogs Community New Posts Updated Threads Search

Like Tree2Likes
  • 1 Post By olesen
  • 1 Post By olesen

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   April 30, 2021, 07:37
Default Accessing dimensions (x, y, z) of cells
  #1
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Hello everybody,


for a new hybrid turbulence model I want to implement I need the dimensions of each cell to calculate a new delta. I found a way of calculating the dimensions in each direction (x, y, z) in meter. See code attached:


Code:
  const faceList & ff = this->mesh().faces();
  const pointField & pp = this->mesh().points();
  volScalarField deltax = this->y_;
  volScalarField deltay = this->y_;
  volScalarField deltaz = this->y_;

  forAll(this->mesh().C(), celli)
  {
    const cell & cc = this->mesh().cells()[celli];
    labelList pLabels(cc.labels(ff));
    pointField pLocal(pLabels.size(), vector::zero);

    forAll(pLabels, pointi)
    {
      pLocal[pointi] = pp[pLabels[pointi]];
    }

    dimensionedScalar Convert ("Convert", dimensionSet(0, 1, 0, 0, 0, 0, 0), scalar(1));

    deltax = (Foam::max(pLocal & vector(1,0,0)) - Foam::min(pLocal & vector(1,0,0))) * Convert;
    deltay = (Foam::max(pLocal & vector(0,1,0)) - Foam::min(pLocal & vector(0,1,0))) * Convert;
    deltaz = (Foam::max(pLocal & vector(0,0,1)) - Foam::min(pLocal & vector(0,0,1))) * Convert;
  }
I think the code is working fine, at least it is compiling and a few iterations are running but I have to check further.


But my question is:


Is there a more effective way of computing the cell dimensions in x, y and z than using a forAll loop? I have the impression that this is rather time-consuming when using a large mesh.



Many thanks for your help!


Daniel
CFDanielGER is offline   Reply With Quote

Old   May 3, 2021, 02:35
Default
  #2
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
boundBox for the cell points?

BTW in your code example it appears that you are overwriting the entire fields each cell - probably not what you want.

For efficiency, it would make sense to store/access the values as a DimensionedField of vectors and dump all of it into a class as a MeshObject. This would make it demand-driven and you could handle mesh changes seamlessly.
olesen is offline   Reply With Quote

Old   May 3, 2021, 03:12
Default
  #3
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Maybe I show the whole code so it becomes a bit more clear. I should also mention that I am a beginner with OpenFOAM coding and found this code in a other forum post and it seemed that this the thing I need: Cell size (x,y,z)

My whole code for calculating the variable I need with the cell dimensions looks like this. For a non-moving mesh, the dimensions of each cell should only calculated at the beginning since they are not changing in time, but I am not sure yet how to solve this issue. Maybe write another file like the cubeRootVolDelta or the maxDelta. But what changes with each iteration is the vorticity, this should therefore be calculated at each time step.

Code:
template<class BasicTurbulenceModel>
tmp<volScalarField> SAEDES<BasicTurbulenceModel>::deltaOmega
(

) const
{
  volVectorField vorticity = fvc::curl(this->U());
  volScalarField magVorticity = mag(vorticity);
  volVectorField vorticityUnit = vorticity / magVorticity;

  const faceList & ff = this->mesh().faces();
  const pointField & pp = this->mesh().points();
  volScalarField deltax = this->y_;
  volScalarField deltay = this->y_;
  volScalarField deltaz = this->y_;

  forAll(this->mesh().C(), celli)
  {
    const cell & cc = this->mesh().cells()[celli];
    labelList pLabels(cc.labels(ff));
    pointField pLocal(pLabels.size(), vector::zero);

    forAll(pLabels, pointi)
    {
      pLocal[pointi] = pp[pLabels[pointi]];
    }

    dimensionedScalar Convert ("Convert", dimensionSet(0, 1, 0, 0, 0, 0, 0), scalar(1));

    deltax = (Foam::max(pLocal & vector(1,0,0)) - Foam::min(pLocal & vector(1,0,0))) * Convert;
    deltay = (Foam::max(pLocal & vector(0,1,0)) - Foam::min(pLocal & vector(0,1,0))) * Convert;
    deltaz = (Foam::max(pLocal & vector(0,0,1)) - Foam::min(pLocal & vector(0,0,1))) * Convert;

    //Info <<deltax<< endl;
    //Info <<deltay<< endl;
    //Info <<deltaz<< endl;
  }

  return sqrt( sqr(vorticityUnit.component(0)) * deltay * deltaz + sqr(vorticityUnit.component(1)) * deltaz * deltax + sqr(vorticityUnit.component(2)) * deltax * deltay );
}

Quote:
Originally Posted by olesen View Post
boundBox for the cell points?

BTW in your code example it appears that you are overwriting the entire fields each cell - probably not what you want.

For efficiency, it would make sense to store/access the values as a DimensionedField of vectors and dump all of it into a class as a MeshObject. This would make it demand-driven and you could handle mesh changes seamlessly.
Where do you mean the entire fields will be overwritten each cell, sorry if i don't understand yet clearly. And may you please explain or describe further how your idea of storing and accessing the values look like?

Many thanks for your help!

Best regards,
Daniel
CFDanielGER is offline   Reply With Quote

Old   May 3, 2021, 05:32
Default
  #4
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by CFDanielGER View Post
Where do you mean the entire fields will be overwritten each cell, sorry if i don't understand yet clearly. And may you please explain or describe further how your idea of storing and accessing the values look like?

If you examine the closing statements in your loop:
Code:
  forAll(this->mesh().C(), celli)
  {
...
// !!! HERE ! !!!

     deltax = (Foam::max(pLocal & vector(1,0,0)) - Foam::min(pLocal & vector(1,0,0))) * Convert;
    deltay = (Foam::max(pLocal & vector(0,1,0)) - Foam::min(pLocal & vector(0,1,0))) * Convert;
    deltaz = (Foam::max(pLocal & vector(0,0,1)) - Foam::min(pLocal & vector(0,0,1))) * Convert;
  }
You are assigning deltax, deltay etc, which are volume fields with a single value.
After exiting the loop, the entire field will simply have the value of the last cell, which you will not notice if the mesh is uniform.
olesen is offline   Reply With Quote

Old   May 3, 2021, 05:48
Default
  #5
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
You would need to verify, but my first idea was something like this (NOTE: quality not checked!!).

Code:
volScalarField deltax = this->y_;
volScalarField deltay = this->y_;
volScalarField deltaz = this->y_;

... starting here
const polyMesh& pMesh = this->mesh();
const label nCells = pMesh.nCells();


boundBox cellBb;
for (label celli = 0; celli < nCells; ++celli)
{
    const labelList& cPoints = pMesh.cellPoints(celli);
    cellBb.clear();
    cellBb.add(pMesh.points(), cPoints);

   deltax[celli] = (cellBb.max().x() - cellBb.min().x());
   deltay[celli] = (cellBb.max().y() - cellBb.min().y());
   deltaz[celli] = (cellBb.max().z() - cellBb.min().z());
}
CFDanielGER likes this.
olesen is offline   Reply With Quote

Old   May 3, 2021, 07:52
Default
  #6
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Many thanks for your help, now I understand! You are completely right. I just tested your piece of code and it seems to work also it seems much faster, I just have to check if the dimensions are right. I think for this the easiest way is to create IOobjects, what do you think?

But if I now want to calculate the deltaOmega for each cell, I don't have to use a forAll loop, right? I can just calculate like this:

Code:
sqrt( sqr(vorticityUnit.component(0)) * deltay * deltaz + sqr(vorticityUnit.component(1)) * deltaz * deltax + sqr(vorticityUnit.component(2)) * deltax * deltay );
CFDanielGER is offline   Reply With Quote

Old   May 3, 2021, 11:09
Default
  #7
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
It's fine enough the way you now have it.
Since you have complete volfields after the loop, the rest should be OK.

You will Probably want to store deltaxy, deltayz, deltazx instead. Cheap to calculate within the loop, and saves extra multiplications later.

After that can revise how you create your fields. Probably want them with the class scope. For that, autoPtr is the usual container.
CFDanielGER likes this.
olesen is offline   Reply With Quote

Old   May 20, 2022, 07:53
Default
  #8
Member
 
hari charan
Join Date: Sep 2021
Location: India,hyderabad
Posts: 96
Rep Power: 4
saicharan662000@gmail.com is on a distinguished road
Hi Daniel,

what does this->Y in your code mean??
Thanks in advance
saicharan662000@gmail.com is offline   Reply With Quote

Old   May 20, 2022, 09:45
Default
  #9
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Quote:
Originally Posted by saicharan662000@gmail.com View Post
Hi Daniel,

what does this->Y in your code mean??
Thanks in advance

That should be the wall distance if I remember correctly. It was just for initialization.
CFDanielGER is offline   Reply With Quote

Old   May 20, 2022, 10:05
Default
  #10
Member
 
hari charan
Join Date: Sep 2021
Location: India,hyderabad
Posts: 96
Rep Power: 4
saicharan662000@gmail.com is on a distinguished road
I had written a loop similar to yours for finding deltaX and wrote return statement after the loop. But when I use deltaX in return statement it is throwing an error message that deltaX is undefined
saicharan662000@gmail.com is offline   Reply With Quote

Old   May 23, 2022, 02:08
Default
  #11
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Quote:
Originally Posted by saicharan662000@gmail.com View Post
I had written a loop similar to yours for finding deltaX and wrote return statement after the loop. But when I use deltaX in return statement it is throwing an error message that deltaX is undefined

Did you define deltaX before the loop?
CFDanielGER is offline   Reply With Quote

Old   May 23, 2022, 02:12
Default
  #12
Member
 
hari charan
Join Date: Sep 2021
Location: India,hyderabad
Posts: 96
Rep Power: 4
saicharan662000@gmail.com is on a distinguished road
Hi Daniel,
I didn't define it before loop. Because I don't know what I should assign to deltaX as u assigned this->Y. my cose looks like this


Foam::tmp<Foam::volScalarField>
Foam:haseChangeTwoPhaseMixtures::myPhaseChange:: kappaGradT() const
{

const volScalarField limalpha1(min(max((alpha1()), scalar(0)), scalar(1)));
const volVectorField& U = db().lookupObject<volVectorField>("U");
const fvMesh & mesh = U.mesh();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& owner = mesh.owner();
const volVectorField& C = mesh.C();
const volScalarField& T = alpha1().db().lookupObject<volScalarField>("T");
forAll(owner, facei)
{
vector delta = C[neighbour[facei]] - C[owner[facei]];
volScalarField gradAlpha = fvc::grad(limalpha1) & mesh.C();
volScalarField alphaPrim = mag(gradAlpha);
const dimensionedScalar len("len",dimLength,mag(delta));
const dimensionedScalar small("small",dimensionSet(0, 0, 0, 0, 0, 0, 0),1e-5);

}
return
(
(limalpha1*lambda1_+ (1-limalpha1)*lambda2_) * ((T-Tsat_)/(len))*(gradAlpha/max(alphaPrim,small))
);
}
saicharan662000@gmail.com is offline   Reply With Quote

Old   May 23, 2022, 02:24
Default
  #13
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Quote:
Originally Posted by saicharan662000@gmail.com View Post
Hi Daniel,
I didn't define it before loop. Because I don't know what I should assign to deltaX as u assigned this->Y. my cose looks like this


Foam::tmp<Foam::volScalarField>
Foam:haseChangeTwoPhaseMixtures::myPhaseChange:: kappaGradT() const
{

const volScalarField limalpha1(min(max((alpha1()), scalar(0)), scalar(1)));
const volVectorField& U = db().lookupObject<volVectorField>("U");
const fvMesh & mesh = U.mesh();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& owner = mesh.owner();
const volVectorField& C = mesh.C();
const volScalarField& T = alpha1().db().lookupObject<volScalarField>("T");
forAll(owner, facei)
{
vector delta = C[neighbour[facei]] - C[owner[facei]];
volScalarField gradAlpha = fvc::grad(limalpha1) & mesh.C();
volScalarField alphaPrim = mag(gradAlpha);
const dimensionedScalar len("len",dimLength,mag(delta));
const dimensionedScalar small("small",dimensionSet(0, 0, 0, 0, 0, 0, 0),1e-5);

}
return
(
(limalpha1*lambda1_+ (1-limalpha1)*lambda2_) * ((T-Tsat_)/(len))*(gradAlpha/max(alphaPrim,small))
);
}

you could try to define a vector before the loop like:
Code:
vector delta(0,0,0);
CFDanielGER is offline   Reply With Quote

Old   May 23, 2022, 02:32
Default
  #14
Member
 
hari charan
Join Date: Sep 2021
Location: India,hyderabad
Posts: 96
Rep Power: 4
saicharan662000@gmail.com is on a distinguished road
Hi Daniel,
Thanks for your suggestion,I implemented it like this now I have no eroors or warnings,is it correct way??



Foam::tmp<Foam::volScalarField>
Foam:haseChangeTwoPhaseMixtures::myPhaseChange:: kappaGradT() const
{

const volScalarField limalpha1(min(max((alpha1()), scalar(0)), scalar(1)));
const volVectorField& U = db().lookupObject<volVectorField>("U");
const fvMesh & mesh = U.mesh();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& owner = mesh.owner();
const volVectorField& C = mesh.C();
const volScalarField& T = alpha1().db().lookupObject<volScalarField>("T");
vector delta(0,0,0);
const dimensionedScalar len("len",dimLength,0);
forAll(owner, facei)
{
vector delta = C[neighbour[facei]] - C[owner[facei]];
volScalarField gradAlpha = fvc::grad(limalpha1) & mesh.C();
volScalarField alphaPrim = mag(gradAlpha);
const dimensionedScalar len("len",dimLength,mag(delta));
const dimensionedScalar small("small",dimensionSet(0, 0, 0, 0, 0, 0, 0),1e-5);

}
return
(
(limalpha1*lambda1_+ (1-limalpha1)*lambda2_) * ((T-Tsat_)/(len))*(gradAlpha/max(alphaPrim,small))
);
}


is delta in loop getting used? Why I am doubting this is, I have set both delta and len to 0 before the loop ,will the get updated
saicharan662000@gmail.com is offline   Reply With Quote

Old   May 23, 2022, 02:54
Default
  #15
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Quote:
Originally Posted by saicharan662000@gmail.com View Post
Hi Daniel,
Thanks for your suggestion,I implemented it like this now I have no eroors or warnings,is it correct way??



Foam::tmp<Foam::volScalarField>
Foam:haseChangeTwoPhaseMixtures::myPhaseChange:: kappaGradT() const
{

const volScalarField limalpha1(min(max((alpha1()), scalar(0)), scalar(1)));
const volVectorField& U = db().lookupObject<volVectorField>("U");
const fvMesh & mesh = U.mesh();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& owner = mesh.owner();
const volVectorField& C = mesh.C();
const volScalarField& T = alpha1().db().lookupObject<volScalarField>("T");
vector delta(0,0,0);
const dimensionedScalar len("len",dimLength,0);
forAll(owner, facei)
{
vector delta = C[neighbour[facei]] - C[owner[facei]];
volScalarField gradAlpha = fvc::grad(limalpha1) & mesh.C();
volScalarField alphaPrim = mag(gradAlpha);
const dimensionedScalar len("len",dimLength,mag(delta));
const dimensionedScalar small("small",dimensionSet(0, 0, 0, 0, 0, 0, 0),1e-5);

}
return
(
(limalpha1*lambda1_+ (1-limalpha1)*lambda2_) * ((T-Tsat_)/(len))*(gradAlpha/max(alphaPrim,small))
);
}


is delta in loop getting used? Why I am doubting this is, I have set both delta and len to 0 before the loop ,will the get updated

Yes, that should be working. You are just defining delta and len beforehand so that it will be recognized for the loop. During the loop it will then get updated. You could print len or delta during your simulation so you can see if the results are meaningful. I am not sure how to print anymore but there are some posts related to this topic, just google for it.
CFDanielGER is offline   Reply With Quote

Old   May 23, 2022, 03:33
Default
  #16
Member
 
hari charan
Join Date: Sep 2021
Location: India,hyderabad
Posts: 96
Rep Power: 4
saicharan662000@gmail.com is on a distinguished road
Hi daniel,
Thanks for helping me, And I am able to print them and I am getting correct results
saicharan662000@gmail.com is offline   Reply With Quote

Old   May 23, 2022, 05:11
Default
  #17
Member
 
Daniel
Join Date: May 2018
Posts: 43
Rep Power: 8
CFDanielGER is on a distinguished road
Quote:
Originally Posted by saicharan662000@gmail.com View Post
Hi daniel,
Thanks for helping me, And I am able to print them and I am getting correct results
Perfect, no worries!
CFDanielGER is offline   Reply With Quote

Old   May 23, 2022, 05:44
Default
  #18
Member
 
hari charan
Join Date: Sep 2021
Location: India,hyderabad
Posts: 96
Rep Power: 4
saicharan662000@gmail.com is on a distinguished road
Hi Daniel,
Can you look this post and suggest me what's wrong in it.
Multiplication of source term with div(T) is causing error
Thanks in advance
saicharan662000@gmail.com is offline   Reply With Quote

Old   November 21, 2023, 10:26
Default
  #19
New Member
 
Join Date: Aug 2017
Posts: 16
Rep Power: 8
Wang Shang is on a distinguished road
Hi Olesen,

If I want to write it as a post-processing program, is that possible?

Regards.
Wang Shang 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
[ICEM] Problem with prism cells sidharath ANSYS Meshing & Geometry 0 September 1, 2015 07:09
Accessing neighboring cells' cell number Daniel Lattin Siemens 4 October 20, 2006 16:19
physical boundary error!! kris Siemens 2 August 3, 2005 00:32
Accessing neighbouring cells in UDF Hiranya Nath FLUENT 5 March 22, 2002 23:29
Accessing neighboring cells in UDF Christian FLUENT 1 January 18, 2002 22:06


All times are GMT -4. The time now is 11:16.