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

How to assign value to a single cell?

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree4Likes
  • 1 Post By Zeppo
  • 2 Post By Zeppo
  • 1 Post By Zeppo

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   January 6, 2017, 13:45
Default How to assign value to a single cell?
  #1
Member
 
Oleg Sutyrin
Join Date: Feb 2016
Location: Russia
Posts: 41
Rep Power: 10
OlegSutyrin is on a distinguished road
Hi!
I'm developing custom solver based on rhoCentralFoam. There I have three main fields initialized as follows:
Code:
volScalarField& p = thermo.p();
const volScalarField& T = thermo.T(); 
volVectorField U
(
    IOobject
    (
        "U",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh
);
Later, I create some scalars:
Code:
      
scalar tmpT, tmpP, tmpUx, tmpUy, tmpUz;
and read them from some file.
Now I need to assign them them to cell subset, something like this:
Code:
forAll (selectedCellSet, celli)
{
  T[celli] = tmpT;  
  p[celli] = tmpP;  
  U[celli] = Vector(tmpUx, tmpUy, tmpUz);
}
This code generates various error messages, including 'cannot convert' statements and 'assignment of read-only location' (for T). What would be the correct way to assign them?
OlegSutyrin is offline   Reply With Quote

Old   January 6, 2017, 16:51
Default
  #2
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Code:
const volScalarField& T = thermo.T();
==>
Code:
volScalarField& T = thermo.T();
OlegSutyrin likes this.
Zeppo is offline   Reply With Quote

Old   January 6, 2017, 16:57
Default
  #3
Member
 
Oleg Sutyrin
Join Date: Feb 2016
Location: Russia
Posts: 41
Rep Power: 10
OlegSutyrin is on a distinguished road
Thanks, Zeppo! That solved the problem with 'assignment of read-only location'.

The main question still stands: how to assign scalar value to T[celli]? Maybe somehow through dimensionedScalar / dimensionedVector construction?
OlegSutyrin is offline   Reply With Quote

Old   January 6, 2017, 17:44
Default
  #4
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Code:
volScalarField& T = thermo.T();
T.internalField() = tmpT; // for OF 3.0
//T.primitiveFieldRef() = tmpT; // for OF 4.0
Zeppo is offline   Reply With Quote

Old   January 7, 2017, 02:59
Default
  #5
Member
 
Oleg Sutyrin
Join Date: Feb 2016
Location: Russia
Posts: 41
Rep Power: 10
OlegSutyrin is on a distinguished road
Quote:
Originally Posted by Zeppo View Post
Code:
T.internalField() = tmpT; // for OF 3.0
Wouldn't it set the entire field to tmpT instead of only T[celli]?
And what is the correct syntax for U[celli], which is vector?
OlegSutyrin is offline   Reply With Quote

Old   January 7, 2017, 04:58
Default
  #6
Member
 
Oleg Sutyrin
Join Date: Feb 2016
Location: Russia
Posts: 41
Rep Power: 10
OlegSutyrin is on a distinguished road
In addition to previous post:
Quote:
Originally Posted by Zeppo View Post
Code:
const volScalarField& T = thermo.T();
==>
Code:
volScalarField& T = thermo.T();
It turned out that this doesn't work:
Code:
createFields.H:11:29: error: binding ‘const volScalarField 
{aka const Foam::GeometricField<double, Foam::fvPatchField,
 Foam::volMesh>}’ to  reference of type ‘Foam::volScalarField& {aka
 Foam::GeometricField<double, Foam::fvPatchField, 
Foam::volMesh>&}’ discards qualifiers
OlegSutyrin is offline   Reply With Quote

Old   January 7, 2017, 05:36
Default
  #7
Member
 
Join Date: Mar 2014
Posts: 39
Rep Power: 12
Traction is on a distinguished road
Hey,

did you try it with a copy-process ?
Code:
volScalarField T = thermo.T();
T.internalField()[celli] = value;
Depending on the structure of thermo.T() you should be able to assign a scalar or a dimensionedScalar. That´s the clean solution.
Otherwise you can try to assign a non dimensioned scalar with:
Code:
T.internalField()[celli].value() = value;
That´s the dirty one

You will need a volVectorField to assign a vector or a dimensionedVector to it. In addition you can assign single vector components by the functions vector.x() or vector.y() or vector.z().

Please note that this can vary depending on the OF versions you use.
Traction is offline   Reply With Quote

Old   January 7, 2017, 08:02
Default
  #8
Member
 
Oleg Sutyrin
Join Date: Feb 2016
Location: Russia
Posts: 41
Rep Power: 10
OlegSutyrin is on a distinguished road
Thanks, Traction!
The first way compiles OK in foam-extend 3.2 (which is based on OF 3, I believe). It generates some weird patchy field value assignments, which is probably have no relation to this thread (some errors in cell indexes, probably).

For now I'm abandoning this approach in favor of re-using some part of setFields code, which is much simpler. I've posted some problems I have with it in another thread: Re-read basicPsiThermo from temperature file.
OlegSutyrin is offline   Reply With Quote

Old   January 7, 2017, 08:59
Default
  #9
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Quote:
Originally Posted by OlegSutyrin View Post
In addition to previous post:
Code:
volScalarField& T = thermo.T();
It turned out that this doesn't work:
Code:
createFields.H:11:29: error: binding ‘const volScalarField 
{aka const Foam::GeometricField<double, Foam::fvPatchField,
 Foam::volMesh>}’ to  reference of type ‘Foam::volScalarField& {aka
 Foam::GeometricField<double, Foam::fvPatchField, 
Foam::volMesh>&}’ discards qualifiers
The reason for the code being not compiled might be that the thermo was declared as a const reference like
Code:
autoPtr<rhoThermo> thermoPtr = new rhoThermo(vfMesh);
const rhoThermo& thermo = thermoPtr();
If so, then
Code:
volScalarField& T = thermo.T();
won't work.

Quote:
Originally Posted by OlegSutyrin View Post
Code:
T.internalField() = tmpT; // for OF 3.0
Wouldn't it set the entire field to tmpT instead of only T[celli]?
And what is the correct syntax for U[celli], which is vector?
Code:
T.internalField() = tmpT ;
sets every cell's value to be tmpT

Quote:
Originally Posted by OlegSutyrin View Post
And what is the correct syntax for U[celli], which is vector?
Code:
U[celli] = vector(Ux, Uy, Uz);
Quote:
Originally Posted by Traction View Post
Hey,
did you try it with a copy-process ?
Code:
volScalarField T = thermo.T();
T.internalField()[celli] = value;
Code:
volScalarField T = thermo.T();
is copying from thermo.T() to T. And now you have 2 self-contained volScalarFields which are independent on each other. Modifications made to T will not propagate to thermo. This might not be what you want in some situations.
OlegSutyrin and Kummi like this.
Zeppo is offline   Reply With Quote

Old   January 7, 2017, 09:21
Default
  #10
Member
 
Oleg Sutyrin
Join Date: Feb 2016
Location: Russia
Posts: 41
Rep Power: 10
OlegSutyrin is on a distinguished road
Zeppo, thanks again for such an elaborate answer!

The thing that puzzles me is that pThermo is created as non-const:
Code:
autoPtr<basicPsiThermo> pThermo
(
    basicPsiThermo::New(mesh) 
);
basicPsiThermo& thermo = pThermo();
but 'thermo.T()' still returns 'const volScalarField&'.

And I agree, the copy of my 'thermo.T' would be useless for me since I need to update 'rho', which is derived 'thermo'.
OlegSutyrin is offline   Reply With Quote

Old   January 7, 2017, 11:10
Default
  #11
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Quote:
Originally Posted by OlegSutyrin View Post
The thing that puzzles me is that pThermo is created as non-const:
Code:
autoPtr<basicPsiThermo> pThermo
(
    basicPsiThermo::New(mesh) 
);
basicPsiThermo& thermo = pThermo();
but 'thermo.T()' still returns 'const volScalarField&'.
You are right, T() can be called only for constant object:
Code:
const Foam::volScalarField& Foam::basicThermo::T() const
This thermo seems to be designed with the implication that you first initialise it with T then solve your equation for e or h then you can calculate T based on e or h.

Meanwhile, you can try this little hacking:
Code:
volScalarField& T = const_cast<volScalarField&>
(
    static_cast<const basicPsiThermo&>(thermo).T()
);
OlegSutyrin likes this.
Zeppo is offline   Reply With Quote

Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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
[mesh manipulation] Generating a single cell mesh using a patch of a 3d mesh kebsiali OpenFOAM Meshing & Mesh Conversion 3 May 30, 2016 07:36
Journal file error magicalmarshmallow FLUENT 3 April 4, 2014 13:25
[Other] Single cubic cell (full case inc.) with det = 0. Why? :) anothr_acc OpenFOAM Meshing & Mesh Conversion 1 February 21, 2014 06:04
Help Me, what's the Cell Above in 3D. gomane8 Main CFD Forum 0 September 10, 2011 20:09


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