|
[Sponsors] |
May 30, 2017, 09:59 |
|
#41 | ||
New Member
Simone Colucci
Join Date: Mar 2016
Location: Pisa (Italy)
Posts: 23
Rep Power: 10 |
Dear Philip,
thanks for your reply! I tried by simplifying the code, but I get the same error lnInclude/Henry.C:132:53: error: passing ‘const Foam::fvPatchField<double>’ as ‘this’ argument of ‘void Foam::fvPatchField<Type>:perator=(const Foam::UList<T>&) [with Type = double]’ discards qualifiers [-fpermissive] IndexTest[0][0].boundaryField()[patchi] = newPatchValues; This is the code: Quote:
Quote:
Simone |
|||
May 30, 2017, 10:10 |
|
#42 | ||
New Member
Simone Colucci
Join Date: Mar 2016
Location: Pisa (Italy)
Posts: 23
Rep Power: 10 |
I tried also to copy the code above outside the function, directly in a *.H in the folder reactingTwoPhaseEulerFoam in order to substitute
Quote:
Quote:
error: passing ‘const Foam::fvPatchField<double>’ as ‘this’ argument of ‘void Foam::fvPatchField<Type>:perator=(const Foam::UList<T>&) [with Type = double]’ discards qualifiers [-fpermissive] IndexTest[0][0].boundaryField()[patchi] = newPatchValues; Any idea? Thanks Simone |
|||
November 8, 2017, 07:42 |
|
#43 | |
Member
Amir
Join Date: Jan 2017
Posts: 32
Rep Power: 9 |
Dear Philip,
I have followed your comments on how to update the BC contents with coding in solver. I want to write a Dirichlet BC with nonuniform values for omega at the wall. The omega should be calculated from friction velocity for each cell of the wall (I calculated it from U field). My solver is simpleFoam. I use the method you mentioned below for calculating omega in the simpleFoam solver. I have written my code but the problem is I don't know how can I insert the calculated values in omega field? (BTW I am not experienced in coding in c++) any hints are really appreciated. Many thanks in advance. Amir Quote:
|
||
November 8, 2017, 09:20 |
|
#44 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34 |
Hi Amir,
Can you give your code that you have so far? And where are you inserting this code? Philip |
|
November 8, 2017, 13:45 |
|
#45 | |
Member
Amir
Join Date: Jan 2017
Posts: 32
Rep Power: 9 |
Quote:
I don't think my code structure is easily understandable. First I calculated the velocity and the distance from the wall for the centre of the cells on the wall. Then, I used the dimensionless van Driest near-wall velocity profile and used an iterative method (Newton-Raphson method) to calculate the friction velocity in each cell face of the wall, and calculated omega at the wall by the method that has been mentioned in Wilcox (2006) for both smooth and rough walls. the problem is I don't know how can I insert the calculated omega into omega field. Because the omega has not been defined in the main solver and it is defined in turbulence models. I simply tried to define a volScalarField for omega in the createFields.H and saving the calculated omega in it, but it seems that the solver does not use it. I started my code exactly after the starting loop of the simpleFoam Code:
while (simple.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; // I started my code from here. Thank you very much for your help in advance, Regards, Amir |
||
November 8, 2017, 14:26 |
|
#46 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34 |
Hi Amir,
The cleanest method would be to write a new boundary condition for omega where you can directly update the boundary values for omega. However, it is possible to do it by adding code to your solver: one way to do it would be to "look up" the omega field from the turbulence model using the objectRegistry (this keeps track of all the significant objects) and then update it using your proposed method (however, this method requires const_cast which is evil: const cast is evil). For example, you could do the following: Code:
while (simple.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; // Lookup omega field from the objectRegistry and use const_cast to // remove the "read only" protection volScalarField& omega = const_cast<volScalarField&> ( mesh.lookupObject<volScalarField>("omega") ); // Find the patch of interest const label patchID = mesh.boundaryMesh().findPatchID("myInterestingPatch"); // Check the patch was found if (patchID == -1) { FatalError << "patch was not found!" << abort(FatalError); } // Cast the patch field to let the solver know what class the boundary condition is // I am guessing it is a wall function patch for omega? fixedInternalValueFvPatchScalarField& omegaPatch = refCast<fixedInternalValueFvPatchScalarField>(omega.boundaryField()[patchID]); // Set values on/near the patch forAll(omegaPatch, faceI) { // Set values here // omegaPatch.refValue()[faceI] = ...; } // code for solving U and p equations etc. // ... } Also, you would need to add the following header file at the top of the solver e.g. just under #include "fvCFD.H": Code:
#include "fixedInternalValueFvPatchFields.H" But if you are trying to create an omega wall function boundary condition, I would suggest making a copy of omegaWallFunctionFvPatchScalarField and renaming to myOmegaWallFunctionFvPatchScalarField and then you can edit the code in the updateCoeffs() function. Philip |
|
November 8, 2017, 16:21 |
|
#47 | |
Member
Amir
Join Date: Jan 2017
Posts: 32
Rep Power: 9 |
Quote:
I have learned a lot from this post and this thread. Actually, I want to use omega on the wall (y=0), and not as a wall function, that is why I have not tried changing the omegaWallFunction. In this case, I should use codedFixedValue instead of fixedInternalValueFvPatchScalarField in your code? Regards, Amir |
||
November 8, 2017, 16:55 |
|
#48 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34 |
Hi Amir,
OK, so if you intend to set the value of omega at the patch faces then I suggest you use the fixedValue patch type (for your patch in 0/omega); then the code becomes more simple: Code:
while (simple.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; // Lookup omega field from the objectRegistry and use const_cast to // remove the "read only" protection volScalarField& omega = const_cast<volScalarField&> ( mesh.lookupObject<volScalarField>("omega") ); // Find the patch of interest const label patchID = mesh.boundaryMesh().findPatchID("myInterestingPatch"); // Check the patch was found if (patchID == -1) { FatalError << "patch was not found!" << abort(FatalError); } // Take a reference to the patch field (values at the patch faces) scalarField& omegaPatch = omega.boundaryField()[patchID]; // You might find some of these patch functions useful when setting the omega // values // Patch face centres const vectorField& patchCf = mesh.boundary()[patchID].Cf(); // Patch face area vectors const vectorField& patchSf = mesh.boundary()[patchID].Sf(); // Patch delta vectors (from face centre to closest cell centre) // Note: this returns a value not a reference (no '&') const vectorField patchDelta = mesh.boundary()[patchID].delta(); // Set face values the patch forAll(omegaPatch, faceI) { // Set values here // It could be based on patchCf[faceI], patchSf[faceI], patchDelta[faceI], etc. // omegaPatch[faceI] = ...; } // code for solving U and p equations etc. // ... } Philip |
|
July 20, 2018, 11:57 |
|
#49 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Dear Philip,
Hope you have been monitoring this thread. I try to compile the following code (based on yours) for fixedGradient but I have the following error. I wonder if you could tell what the problem is. I tryed "#include "fixedGradientFvPatchFields.H.H" but it didn't help. Code: Code:
**body of solver is here** label patchID = mesh.boundaryMesh().findPatchID("frontAndBack"); if(patchID == -1) { FatalError << "patch not found!" << exit(FatalError); } if ( PotE.boundaryField()[patchID].type() == fixedGradientFvPatchVectorField::typeName ) { fixedGradientFvPatchVectorField& PotEpatch = refCast<fixedGradientFvPatchVectorField>(PotE.boundaryField()[patchID]); PotEpatch.gradient() = vector(0,0,0); } Code:
In file included from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/token.H:46:0, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/UListIO.C:28, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/UList.C:233, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/UList.H:484, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/List.H:43, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/labelList.H:48, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/UPstream.H:42, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/Pstream.H:42, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/parRun.H:35, from /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/finiteVolume/lnInclude/fvCFD.H:4, from mhdEpot5Foam.C:37: /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/typeInfo.H: In instantiation of ‘To& Foam::refCast(From&) [with To = Foam::fixedGradientFvPatchField<Foam::Vector<double> >; From = const Foam::fvPatchField<double>]’: mhdEpot5Foam.C:157:76: required from here /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/typeInfo.H:110:35: error: cannot dynamic_cast ‘r’ (of type ‘const class Foam::fvPatchField<double>’) to type ‘class Foam::fixedGradientFvPatchField<Foam::Vector<double> >&’ (conversion casts away constness) return dynamic_cast<To&>(r); ^ /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/typeInfo.H:119:35: error: cannot dynamic_cast ‘r’ (of type ‘const class Foam::fvPatchField<double>’) to type ‘class Foam::fixedGradientFvPatchField<Foam::Vector<double> >&’ (conversion casts away constness) return dynamic_cast<To&>(r); ^ /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/typeInfo.H: In function ‘To& Foam::refCast(From&) [with To = Foam::fixedGradientFvPatchField<Foam::Vector<double> >; From = const Foam::fvPatchField<double>]’: /data/OpenFoams/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/typeInfo.H:121:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ make: *** [Make/linux64GccDPInt64Opt/mhdEpot5Foam.o] Error 1 Code:
fixedGradientFvPatchVectorField& PotEpatch = refCast<fixedGradientFvPatchVectorField>(PotE.boundaryField()[patchID]); Best regards, Tar |
|
July 20, 2018, 17:59 |
|
#51 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Dear Philip,
Thank you very much for your answer. Your link helped me a lot to understand the reason. Best regards, Tar |
|
July 23, 2018, 11:04 |
|
#52 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Dear Philip,
Sorry to bother you again. I faced one more problem. My code is following: Code:
label patchID = mesh.boundaryMesh().findPatchID("frontAndBack"); if(patchID == -1) { FatalError << "patch not found!" << exit(FatalError); } if ( PotE.boundaryFieldRef()[patchID].type() == fixedGradientFvPatchScalarField::typeName ) { fixedGradientFvPatchScalarField& PotEpatch = refCast<fixedGradientFvPatchScalarField>(PotE.boundaryFieldRef()[patchID]); forAll(PotEpatch, faceI) { PotEpatch.gradient()[faceI] = PotE; } } Code:
dynamicBC.H: In function ‘int main(int, char**)’: dynamicBC.H:23:35: error: cannot convert ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ to ‘double’ in assignment PotEpatch.gradient()[faceI] = PotE; ^ make: *** [Make/linux64GccDPInt64Opt/mhdEpot5Foam.o] Error 1 A also noticed that if I remove [faceI] from this line: Code:
PotEpatch.gradient()[faceI] = PotE; Best regards, Tar Last edited by Kombinator; July 23, 2018 at 12:04. |
|
July 23, 2018, 12:34 |
|
#53 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
One more update:
When I tried this Code:
PotEpatch.gradient()[faceI] = PotE.internalField()[faceI]; Best regards, Tar |
|
July 23, 2018, 12:56 |
|
#54 | |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34 |
Quote:
What are you trying to set as the boundary gradient? It is not clear to me what you are actually trying to do. Philip |
||
July 23, 2018, 13:14 |
|
#55 | |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Quote:
Thank you for your answer. The general goal is implementation the following dynamic boundary condition: = a where is electric potential (Scalar Field, PotE in openFoam code, I acquire this value on the wall every iteration and then I update BC), a is constant, is tangential Laplacian at the wall. But right now I try to implement something more simple in order to understand the algorithm. So of course, this equation Code:
PotEpatch.gradient()[faceI] = PotE.internalField()[faceI]; doesn't make sense. But I use this just to see how I can realize this connection in openFoam. Best regards, Tar |
||
July 23, 2018, 15:12 |
|
#56 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34 |
OK, I understand.
Something like the following should work: Code:
if ( PotE.boundaryFieldRef()[patchID].type() == fixedGradientFvPatchScalarField::typeName ) { fixedGradientFvPatchScalarField& PotEpatch = refCast<fixedGradientFvPatchScalarField>(PotE.boundaryFieldRef()[patchID]); // PotEpatch is also a list of face values at the patch PotEpatch.gradient() = PotEpatch; } By the way, the following does not make sense: Code:
PotE.internalField()[faceI] |
|
July 24, 2018, 04:06 |
|
#57 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Dear Philip,
Thank you very much for your advice. It works now and I understood my error and algorithm. I also would like to ask two more questions (hope last questions) if you don't mind: 1. In your suggestion I get uniform boundary condition, but I would like to get nonuniform. I wrote the following code to cope with this problem, it compiles and seems logical but I kindly ask you to take a look (maybe I still have some silly mistakes): Code:
if ( PotE.boundaryFieldRef()[patchID].type() == fixedGradientFvPatchScalarField::typeName ) { fixedGradientFvPatchScalarField& PotEpatch = refCast<fixedGradientFvPatchScalarField>(PotE.boundaryFieldRef()[patchID]); forAll(PotEpatch, faceI) { PotEpatch.gradient()[faceI] = PotEpatch[faceI]; } } For instance I would like to realize something like this: = You wrote some information about the tangential part in this post Updating Boundary Conditions Each Iteration but to be honest I am not fully sure how to do this. Thanks in advance again. Best regards, Tar Last edited by Kombinator; July 24, 2018 at 08:05. |
|
July 24, 2018, 08:55 |
|
#58 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34 |
Your proposed code for applying a spatially varying condition look fine to me.
As regards the tangential gradient at the boundary, OpenFOAM uses the tangential gradient at the closest cell-centre (so-called patch-internal-field) by default i.e. extrapolates tangential gradient from the internal field using a zero gradient approach. it is possible to directly calculate the tangential gradient at the boundary using, for example, the finite area method (you can google this for more information); however, I suggest you try the former method first. An example approach could be: Code:
// Calculate the gradient of PotE everywhere const volVectorField gradPotE = fvc:grad(PotE); fixedGradientFvPatchScalarField& PotEpatch = refCast<fixedGradientFvPatchScalarField> ( PotE.boundaryFieldRef()[patchID] ); // Get patch unit normals const vectorField nf = PotEpatch.patch().nf(); // Get tangential component of gradPotE at the boundary const vectorField tangGradPotE = ((I - sqr(nf)) & gradPotE.boundaryFieldRef()[patchID].patchInternalField()); // Set the normal gradient equal to the magnitude of the tangential gradient for each face forAll(PotEpatch, faceI) { PotEpatch.gradient()[faceI] = mag(tangGradPotE[faceI]); } |
|
July 24, 2018, 10:27 |
|
#59 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Dear Philip,
Thank you for your answer, it helps me a lot. But when I try to compile your code it shows the following error (openFoam 4.1): Code:
dynamicBC.H: In function ‘int main(int, char**)’: dynamicBC.H:27:48: error: passing ‘const volVectorField {aka const Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>}’ as ‘this’ argument of ‘Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary& Foam::GeometricField<Type, PatchField, GeoMesh>::boundaryFieldRef() [with Type = Foam::Vector<double>; PatchField = Foam::fvPatchField; GeoMesh = Foam::volMesh]’ discards qualifiers [-fpermissive] ((I - sqr(nf)) & gradPotE.boundaryFieldRef()[patchID].patchInternalField()); ^ make: *** [Make/linux64GccDPInt64Opt/mhdEpot5Foam.o] Error 1 Now I will try to do the same for the tangential laplacian. When I get something I will share my results in this topic. Thank you very much for your help again. Best regards, Tar |
|
July 24, 2018, 12:59 |
|
#60 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34 |
Hi Tar,
Removing the "const" in this case will fix it; also, you could use boundaryField instead of boundaryFieldRef for the boundary of gradPotE. Both will act the same. Philip |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Impinging Jet Boundary Conditions | Anindya | Main CFD Forum | 25 | February 27, 2016 13:58 |
OpenFOAM Variable Velocity Boundary Conditions | NickolasPl | OpenFOAM Programming & Development | 2 | May 19, 2011 06:37 |
Concentric tube heat exchanger (Air-Water) | Young | CFX | 5 | October 7, 2008 00:17 |
[Commercial meshers] Trimmed cell and embedded refinement mesh conversion issues | michele | OpenFOAM Meshing & Mesh Conversion | 2 | July 15, 2005 05:15 |
A problem about setting boundary conditions | lyang | Main CFD Forum | 0 | September 19, 1999 19:29 |