CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Running, Solving & CFD (http://www.cfd-online.com/Forums/openfoam-solving/)
-   -   How to create initiate a volScalarField p without reading from disk NO_READ does not seem to work (http://www.cfd-online.com/Forums/openfoam-solving/59781-how-create-initiate-volscalarfield-p-without-reading-disk-no_read-does-not-seem-work.html)

dbxmcf March 15, 2007 04:40

Hi, all: I intended to spec
 
Hi, all:

I intended to specify a volScalarField p with boundaryField and internal Field specified by another function call instead of read from case file on hard drive, e.g. cavity/0/p, and in the creatFields.H for icoFoam.C I found the p was constructed using the following:
//-------------------------------------
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);

I tried change the readoption IOobject::MUST_READ to IOobject::NO_READ, it compiles but then when the program runs I got:

--> FOAM FATAL IO ERROR : NO_READ specified for read-constructor

After searching the Doxygen and read the source file of GeometryField.C it seems that the createFields.H file of icoFoam.C used a constructor that will create a read-only volScalarField, I am not sure if there is some example to create such kind of volScalarField p that does not necessarily have to initiate from the disk file? I tried to use the IOobject::READ_IF_PRESENT, but the compiled program still tried to read from file and gave me an fatal error:

--> FOAM FATAL IO ERROR : cannot open file

file: /.../OpenFOAM/foamCases/run/cavity/p/0 at line 0.

Function: regIOobject::readStream(const word&)
in file: db/regIOobject/regIOobjectRead.C at line: 68.

FOAM exiting

I guess I need to use other constructor for class GeometricField but there are so many of them (totally 12 constructors) and it seems difficult for me to figure out how to use each of these? I searched the forum with the keyword "NO_READ", although this topic has been discussed for several times, I didn't find a satisfactory answer.

And kind of help is welcome!
Thanks a lot!

eugene March 15, 2007 07:47

volScalarField p ( IOobject
 
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("p", dimensionSet(0,2,-2,0,0,0,0), 0.0),
boundaryTypes
);

where boundaryTypes is a wordList containing the boundary types, i.e. fixedValue, zeroGradient etc.

Of course this still provides you with limited boundary specification control (i.e. some BCs might not initialise correctly), but perhaps it is sufficient for your purposes?

dbxmcf March 15, 2007 21:44

Thanks Villiers, is it possibl
 
Thanks Villiers, is it possible to change the boundary condition during the iterations?

I have searched the forum and found a post:

http://www.cfd-online.com/OpenFOAM_D...ges/1/202.html

It seems that using:
"
U.boundaryField()[patchI] == blah blah;

where the double equals sign enforces the assignment irrespective of what the boundary condition actually is. Beware, since the fixedValue b.c. (for example) wants to be fixed, operator=() for it will do nothing!"

but it seems that after I used "==" operator, the B.C didn't change?

I know this might be another issue but it should be easy?

hjasak March 15, 2007 21:54

You are missing something: a b
 
You are missing something: a boundary condition has got a type and a value or controlling values. For example, a type could be fixedValue or fixedGradient, each of which is controlled by some parameters.

You can easily change the controlling parameters of each boundary condition durign the simulation, but changing the actual TYPE would very tricky.

Hrv

dbxmcf March 16, 2007 02:42

Thanks a lot Jasak, your sugge
 
Thanks a lot Jasak, your suggestion is very helpful.
Maybe I have found a way to solve this problem, in my current program, icoFoam is used as a dynamically linked library and is being called by another main program, there is a variable globalTime passed to icoFoam which controls the global time, my intention is to let icoFoam read the fields from disk file for globalTime=0, but when globalTime>0, I need the p and U field values to be recorded for the next call (runTime is set via this globalTime using runTime.setTime(globalTime), but I do NOT want the p and U to be read from disk but kept in memory because that will need icoFoam to read disk file for maybe tens of thousands of times and will greatly delay the execution. Therefore I need two global variables 'lastU' and 'lastp' to record p and U for last call of icoFoam, since icoFoam is used as a dynamically linked library.

Simply define volScalarField globalp and U outside icoFoam will cause compiler complain about not using the constructor, therefore I used two variables: scalarField pInternal and vectorField UInternal outside icoFoam to record the internal field of p and U, and used two std::vectors: std::vector<scalarfield> pBoundary and std::vector<vectorfield> UBoundary to record the boundary field, but first and formost I need is to let icoFoam create p and U which is independent of disk file (i.e. /0/p/xxx), the way I use right now is:
//**************************************
volVectorField* ptrU; //I define this to call different constructor of volVectorField
if (globalTime=0)
{
ptrU = new volVectorField
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
}
else
{
ptrU = new volVectorField
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector("U", dimensionSet(0,1,-1,0,0,0,0), vector(0,0,0)),
boundaryType
);
}
volVectorField U=*ptrU
//*******************************************
//p will use the similar way
and the record & restore of the p and U is:
//record U at the end of the call
UInternal = U.internalField(); //internal field
forAll(U.boundaryField(), UI)//boundary field
{
UBoundary.push_back(U.boundaryField()[UI]);
}
//this is for the volVecorField constructor
boundaryType = U.boundaryField().types();

//restore U at the beginning of the call
U.internalField()=UInternal;
forAll(U.boundaryField(), UI)
{
U.boundaryField()[UI]==UBoundary[UI];
}

Look like a very complex procedure, ehhttp://www.cfd-online.com/OpenFOAM_D...part/happy.gif, and it might be stupid, but the main program calling icoFoam is completely another system and is very difficult (currently I think impossible) to let it use OpenFOAM data types, e.g. volScalarField.

I wonder if it is proper to program the whole process in this way, and if there is a better way to do that?

I am not sure if I have made the problem clear to all, but thanks again for your nice help and I appreciate your patience to read this long posthttp://www.cfd-online.com/OpenFOAM_D...part/happy.gif

hjasak March 16, 2007 06:06

Tell me, are you doing optimiz
 
Tell me, are you doing optimization or code-to-code coupling? If it is the first, you may be storing local variables as pointers, passing the work to somebody else etc. along the lines you are doing now. If it is the second, it is more likely that the other code will give you some temporal changes of the boundary conditions.

In any case, I find it a bit strange that you need to specify all of the internal field and all of the boundary field simultaneously. Unless the other code is a CFD solver with precisely the same discretisation, the field you have specified will not satisfy the equations and after only 1 iteration/time-step in OpenFOAM you will get something different.

What I am trying to say is that the internal solution you provide will be only the initial guess and OpenFOAM solvers will "sort it out" pretty quickly. Unless you strongly depend on the initial field that MUST be different from what you had last time, there's no point messing with it.

In any case, this is just my thoughts, but it may be useful if you could think about the big picture.

Hrv

dbxmcf March 16, 2007 15:51

I think it should be code-to-c
 
I think it should be code-to-code coupling, where particles are moving in a fluid field, particles are calculated using a DEM (Discrete Element Method) code, what I need is the fluid field values (U and grad(p)) at specified times, therefore, the big procedure will be: at certain times, I will let the DEM main program to "probe" field values from icoFoam and then use these "probed" values to calculate drag force caused by the fluid field. The DEM code is not another CFD solver, but it need the p and U for each "probe" at certain time, say "tProbe", but the time marching for both DEM code and icoFoam should be "synchronized", the next time "tProbe+deltaT" I probe p and U, the icoFoam should provide the fluid field change from this time to the next time (tProbe ==> tProbe+deltaT), and, from my understanding, the p and U values should start from p[tProbe], U[tProbe] to p[tProbe+deltaT], U[tProbe+deltaT], that is the reason I store the boundary value and internal values for the previous time (tProbe) since I didn't succeed in making p and U as Global objects.

dbxmcf March 16, 2007 21:53

Today I made an experiment of
 
Today I made an experiment of std::vector with volScalarField, and found that there might be problem with std::vector<volscalarfield>, I defined a line:

std::vector<volscalarfield> pVector;
pvector.push_back(p);
and then:
Info << pvector[0] << endl;

However I got an error when printing the boundary field.

....
Boundary Field {

Segmentation fault.

darlopez December 16, 2011 12:52

Quote:

Originally Posted by hjasak (Post 180061)
You are missing something: a boundary condition has got a type and a value or controlling values. For example, a type could be fixedValue or fixedGradient, each of which is controlled by some parameters.

You can easily change the controlling parameters of each boundary condition durign the simulation, but changing the actual TYPE would very tricky.

Hrv

Sorry, I was searching about how to change the value of a boundary condition during the simulation and I saw this.

If the boundary condition is type "fixedValue" and I use

p.boundaryField()[patchIndex] == auxaccelMass;

the boundary condition changes, but if it is type "fixedGradient" it doesn't work, I have in my p file:

paredobstinf
{
type fixedGradient;
gradient uniform 0;
}

How can I change the value of the gradient during the simulation?

Thanks a lot

marupio December 16, 2011 14:11

You can't do it through fvPatchField. You have to do it through fixedGradientFvPatchField. I believe at the top level of a solver you only have fvPatchField, so you have to refcast to fixedGradientFvPatchField. Something like this:

Code:

fixedGradientPatchField& fgPatchField
(
    refCast<fixedGradientPatchField>(p.boundaryField()[patchIndex])
);
fgPatchField.gradient() = newGradientValue;

Not sure if it works. Share and enjoy!

darlopez December 19, 2011 08:25

Quote:

Originally Posted by marupio (Post 336115)
You can't do it through fvPatchField. You have to do it through fixedGradientFvPatchField. I believe at the top level of a solver you only have fvPatchField, so you have to refcast to fixedGradientFvPatchField. Something like this:

Code:

fixedGradientPatchField& fgPatchField
(
    refCast<fixedGradientPatchField>(p.boundaryField()[patchIndex])
);
fgPatchField.gradient() = newGradientValue;

Not sure if it works. Share and enjoy!


IT WORKS !!

thank you very much!!

victorconan August 31, 2012 21:24

Dear Marupio,
I wanna interpolate grad(p),so I tried to establish a volScalarField about grad(p). I did this:
volScalarField surfP
(
IOobject
(
"surfP",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("zero",dimensionSet(0,1,-2,0,0,0,0),0.0)
);
surfP.internalField()=fvc::grad(p);

but it did not successfully wmake. Could you please tell me what is wrong and how can I correct it? Thanks!

nishant_hull August 22, 2013 07:32

hi
 
Hi Marupio,

Have you find the way around of it?

Nishant


All times are GMT -4. The time now is 03:35.