CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Running, Solving & CFD (https://www.cfd-online.com/Forums/openfoam-solving/)
-   -   How to get motionU_ (https://www.cfd-online.com/Forums/openfoam-solving/59627-how-get-motionu_.html)

liu June 12, 2006 16:31

I found class tetDecomposition
 
I found class tetDecompositionMotionSolver has a member function which returns motionU_ reference. But I only get a pointer to motionSolver by following line in my code:
autoPtr<foam::motionsolver> motionPtr = motionSolver::New(mesh);

I know the code created an instance of class laplaceTetDecompositionMotionSolver (which is derived from tetDecompositionMotionSolver).

My question is: how can I get the motionU_ field on which I want to do some operation?

hjasak June 13, 2006 01:39

Look it up from the database,
 
Look it up from the database, e.g.

tetPointVectorField& motionU =
const_cast<tetpointvectorfield&>
(
mesh.objectRegistry::lookupObject<tetpointvectorfi eld>
(
"motionU"
)
);


Hrv

liu June 13, 2006 09:00

Thank you, Hrv. It's a wor
 
Thank you, Hrv.

It's a work around. But I am still wondering whether it is better to have motionU() as an virtual member function of class motionSolver.

hjasak June 13, 2006 09:14

Nope. The virtual base class
 
Nope. The virtual base class also supports various other kinds of mesh motion that do not involve my tet decomposition FEM motion solver. Therefore, it is possible to move the mesh without having the motionU.

Additionally, the virtual base class for all tet FEM motion solvers is tetDecompositionMotionSolver in tetDecompositionMotionSolver/tetDecompositionMotionSolver/tetDecompositionMotion Solver.H

and that one has got the motionU() member function. However, it's no good for you because you only know the base-base class.

Hrv

liu June 13, 2006 09:16

I tried to add the following l
 
I tried to add the following line to motionSolver.H:
//- Return motionU_
virtual tetPointVectorField& motionU() = 0;
It works fine now. Need a lot of time to recompile though.
Now I can construct motionSolver object and get the motionU field like this:
autoPtr<foam::motionsolver> motionPtr = motionSolver::New(mesh);
tetPointVectorField& motionU = motionPtr->motionU();
...

hjasak June 13, 2006 09:20

You are a bad boy - this is pr
 
You are a bad boy - this is precisely what I don't like. Now, if I move the mesh by simple geometrical motion I need to lie in virtual functions.

Bad boy, bad boy....

Hrv

liu June 13, 2006 09:23

Yes, I know exactly what you m
 
Yes, I know exactly what you mean.
But how can I get an object of tetDecompositionMotionSolver such that calling motionU() is possible?

All I can see to use motion solver is like this:
autoPtr<foam::motionsolver> motionPtr = motionSolver::New(mesh);
and the motion solver type is run time selectable.

hjasak June 13, 2006 09:27

You can then case you motionSo
 
You can then case you motionSolver pointer into tetDecompositionMotionSolver and call the function. Anyway, I prefer the database trick: this is why we had it in the first place.

Hrv

hjasak August 6, 2006 11:18

Hi, The symbol you need is
 
Hi,

The symbol you need is defined in the tetDecompositionFiniteElement library, but you have to be csareful regarding the face and cell decompisition. In Make/options you need to have 2 entries:

Under EXE_INC $(WM_DECOMP_INC)

Under EXE_LIBS $(WM_DECOMP_LIBS)

Check the variables to see which one you're running + make sure you don't explicitly refer to any of the "FaceDecomp" or "CellDecomp" stuff bacause this is handled through the macros.

Incidentally, have a look at some animations of my new fluid-structure interaction stuff using my automatic mesh motion solver and all the mapping and integration tools.

irc August 6, 2006 13:15

Thanks Hrv - I had just tracke
 
Thanks Hrv - I had just tracked down the tetDecompositionFiniteElement library as you posted your reply, through searching through the Make options in the src\tetDecompositionFiniteElement directory.

I can now find the relevant patch and print out the initial motionU settings - all well so far. They match what I specify in the 0/motionU dictionary. I am now trying to work out how to change the values. The following plainly has no effect:

motionU.boundaryField()[movingPatchI] = vector (0.003, cylVelocity, 0.0);

which probably shows a total lack of understanding on my part! Back to the Doxygen pages, and perhaps a little more thought.

hjasak August 6, 2006 14:25

Try double equals (==) - I bet
 
Try double equals (==) - I bet you are forcing assignment on a fixed value patch.

Hrv

irc August 6, 2006 14:50

Fantastic - that does indeed d
 
Fantastic - that does indeed do the trick. I had wondered what the == operator was doing.

Can you explain one other (basic) thing to me: motionU.boundaryField()[movingPatchI] contains a list of data for the patch in question, size 120 in my case (from .size()), but my assignment is to a single vector:
motionU.boundaryField()[movingPatchI] == vector (0.003, cylVelocity, 0.0)
How does this work? Is this built into the class definition?

In the Doxygen documentation, for the GeometricField class template (http://foam.sourceforge.net/doc/Doxygen/html/de/d5c/classFoam_1_1GeometricField. html#a49) I tracked down the following member function definition:
void operator== (const dimensioned<type>&)
Is this answering my above question?

Apologies for asking some basic stuff, but if I can understand how to use Doxygen effectively, then I should be able to work things out myself in the future. There's a healthy optimism!

martin August 22, 2006 08:00

Hi, I have a similar question
 
Hi,
I have a similar question. I need to define the boundary motion for each point in the boundaryField due to a function that will change over the boundaryField and time. I don't have any problem to define the motion for the whole boundaryField for example like (I am testing this in a icoDyMFoam based application):

motionU.boundaryField()[movingWallPatchI] == vector(2.0, 0.0, 0.0);

But I can't change the motion for one point (pointI). I have tried it like:

motionU.boundaryField()[movingWallPatchID][pointI]==vector(2.0, 0.0, 0.0);

which result in the following compilation error:

error: no match for 'operator[]' in '((Foam::GeometricField<foam::vector<double>, Foam::tetPolyPatchField, Foam::tetPointMesh>::GeometricBoundaryField*)((Foa m::tetPointVectorField*)motion U)->Foam::GeometricField<type,>::boundaryField [with Type = Foam::Vector<double>, PatchField = Foam::tetPolyPatchField, GeoMesh = Foam::tetPointMesh]())->Foam::GeometricField<foam::vector<double>, Foam::tetPolyPatchField, Foam::tetPointMesh>::GeometricBoundaryField::<anon ymous>.Foam::FieldField<foam:: tetpolypatchfield,> >::<anonymous>.Foam::PtrList<t>::operator[] [with T = Foam::tetPolyPatchField<foam::vector<double> >](movingWallPatchID)[pointI]'

How should I define the motion for one point of the boundaryField?

Regards,
Martin

martin September 6, 2006 14:02

I solved the problem with a wa
 
I solved the problem with a walk around, see the example below (not implemented in a general manner yet).

//Initialization

tetPointVectorField& motion=const_cast<tetpointvectorfield&>(mesh.objec tRegistry::lockupObject<tetpoi ntvectorfield>("motionU")); //Look up motionU from the data base as above.

tetPolyMesh& tetMesh=const_cast<tetpolymesh&>(motionU.mesh()); //Look up tetMesh from the data base. See http://www.cfd-online.com/OpenFOAM_D...ges/1/101.html

const vectorField& tetBoundaryPoints=tetMesh.boundary()[movingWallPatchID].localPoints(); //Reference to coordinates for the boundary points.

tetPolyPatchVectorField& motionUMovingPatch(motionU.boundaryField()[movingWallPatchID]); //Reference to the motionU vector field of the moving patch.

vectorField calculatedMotionU(motionUMovingPatch.size());


//Calculate new boundary motion as a function of point coordinate
forAll(calculatedMotionU, pointI)
{
calculatedMotionU[pointI] = vector(0.01, 0.0, 0.0) * (vector(0.0, 1.0, 0.0) & tetBoundaryPoints[pointI])
}

// Alternative method
calculatedMotionU = vector(0.01, 0.0, 0.0) * (vector(0.0, 1.0, 0.0) & tetBoundaryPoints)

//Set motionU
motionUMovingPatch ==calculatedMotionU;

Does anyone have a better idea of how to change motionU for one or more point(s)?

Regards
Martin

hjasak September 6, 2006 18:00

Hi, tetPointVectorField&
 
Hi,


tetPointVectorField& motion = const_cast<tetpointvectorfield&>
(
mesh.objectRegistry::lookupObject<tetpointvectorfi eld>("motionU")
);


Fine. All you need then is to throw away all the wrapping and it will look elegant:

motionU.boundaryField()[movingWallPatchID] ==
vector(0.01, 0.0, 0.0)*
(
vector(0.0, 1.0, 0.0)
& tetMesh.boundary()[movingWallPatchID].localPoints()
);


This looks like FOAM to me :-) Do you have a problem that I cannot see?

Hrv

martin September 7, 2006 07:26

Hi Hrv, No I claim I don't
 
Hi Hrv,

No I claim I don't have a problem you cannot see ☺ Just wanted a hint if I implemented this in good manner. Next I need to define the motion different if the y-coordinate is less than a given value, therefore I use a loop, does this look like FOAM for you or should I do it in some other way?

forAll(calculatedMotion, pointI)
{
if(tetMesh.boundary()[movingWallPatchID].localPoints()[pointI][1] > 0.
01)
{

calculatedMotion[pointI] = vector(0.01, 0.0, 0.0)*
(
vector(0.0, 1.0, 0.0)
& tetMesh.boundary()[movingWallPatchID].localPoints()[pointI]
);

}
}

motionU.boundaryField()[movingWallPatchID] == calculatedMotion;

Thanks,
Martin

hjasak September 7, 2006 08:30

Hehe, Try using: pos(tet
 
Hehe,

Try using:

pos(tetMesh.boundary()[movingWallPatchID].localPoints().component(vector::Y))

The first bit takes the y-component of point position and returns it as a scalar field. pos(...) returns 1 if this is positive and 0 if negative.

I am sure you can work out the rest.

Enjoy,

Hrv

martin September 7, 2006 09:06

Nice, I will check that. T
 
Nice, I will check that.

Thanks,
Martin

chiconuclear June 20, 2007 13:34

Hi everybody, I'm trying to a
 
Hi everybody,
I'm trying to assign to the motionU field a non uniform value for a patch. I am having problems with the mapping.
For the initialization I have:

volVectorField velEspesores
(
IOobject
(
"velEspesores",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector("vE",dimLength/dimTime,vector::zero)
);

tetPointVectorField& motionU = const_cast<tetpointvectorfield&>
(
mesh.objectRegistry::lookupObject<tetpointvectorfi eld>
(
"motionU"
)
);

Then the program calculates velEspesores, and what I want is to assign those values to motionU, basically,

motionU.boundaryField()[patchID] == velEspesores.boundaryField()[patchID];

I know that I need to do some mapping, but I can't figure out how to do it. If I do nothing it compiles but the run finishes with

--> FOAM FATAL ERROR : given patch field does not correspond to the mesh. Field size: 73672 mesh size: 15320

From function
void PointPatchField<patchfield,>::setInInternalField(F ield<type1>& iF, const Field<type1>& iF) const
in file /nfs/hjlnx/home/hj/OpenFOAM/OpenFOAM-1.3/src/OpenFOAM/lnInclude/PointPatchField. C at line 351.

FOAM aborting

The BC in motionU for the patch I want to move is fixedValue. I am using OpenFOAM 1.3, 28-03-07 development version.

Thanks in advance,
Marcelo


All times are GMT -4. The time now is 15:45.