CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > OpenFOAM Pre-Processing

groovyBC and probe measurement

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

Reply
 
LinkBack Thread Tools Display Modes
Old   June 19, 2014, 07:54
Default groovyBC and probe measurement
  #1
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Hi,

I'm trying to use groovyBC to implement closed-loop control in a simulation. I have a probe (in the controlDict) set to record a pressure measurement at a particular position in the geometry, and wish to use this value in conjunction with groovyBC to perform some maths operation on the value of pressure at the probe at each timestep, and use this value to update the value of a particular boundary condition for the next timestep.

So far my thinking takes me thus far:
Code:
actuatorBoundary     
{     
type                     groovyBC;     
valueExpression        "0.5*(probeReading)"; // Some function of the probe recording     variables                "probeReading *** NOT SURE HOW TO DO THIS? ***     
value                     uniform (0 0 0);     
}
Can anyone help me with the code to implement this? I can't find an example which does this sort of thing exactly.

Thanks a lot,
Olie
odellar is offline   Reply With Quote

Old   June 19, 2014, 08:15
Default
  #2
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
Hi,

I'm trying to use groovyBC to implement closed-loop control in a simulation. I have a probe (in the controlDict) set to record a pressure measurement at a particular position in the geometry, and wish to use this value in conjunction with groovyBC to perform some maths operation on the value of pressure at the probe at each timestep, and use this value to update the value of a particular boundary condition for the next timestep.

So far my thinking takes me thus far:
Code:
actuatorBoundary     
{     
type                     groovyBC;     
valueExpression        "0.5*(probeReading)"; // Some function of the probe recording     variables                "probeReading *** NOT SURE HOW TO DO THIS? ***     
value                     uniform (0 0 0);     
}
Can anyone help me with the code to implement this? I can't find an example which does this sort of thing exactly.

Thanks a lot,
Olie
What confuses people here mostly is that you don't use a probe but a sampled-set. swak can't access probes for technical reasons (basically: probes don't want to be accessed). But a sampled set of type cloud is equivalent. Examples that do that in the swak-Examples are groovcBC/fillingTheDam and FromPresentations/cleaningTank. Also in the swak-presentation at PennState (see the swak-page) a similar thing is explained
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   June 20, 2014, 06:49
Default
  #3
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Quote:
Originally Posted by gschaider View Post
What confuses people here mostly is that you don't use a probe but a sampled-set. swak can't access probes for technical reasons (basically: probes don't want to be accessed). But a sampled set of type cloud is equivalent. Examples that do that in the swak-Examples are groovcBC/fillingTheDam and FromPresentations/cleaningTank. Also in the swak-presentation at PennState (see the swak-page) a similar thing is explained
Oh okay - didn't realise that. I've not used a cloud type sampled set before - does this just go in the controlDict as the probe would? (Do you know where I can find some documentation on cloud's use?).

Okay so after some more reading and re-reading I think, after I've got a cloud sample correct, the groovyBC boundary in the 0/U file should look something like this:

Code:
actuator
{
   type                     groovyBC;
   variables              "pMeasurement@cloudSampler=p;"
   valueExpression   "10*p";             // Or *SOME* mathematical expression
   value                   uniform (1 0 0); // Or *SOME* initial conditions
}
Is this the right idea? (Note here I've assumed the same usage with a cloud sampled set as that when using a patch.

Thanks again,
Olie

****EDIT****
Oh no - found some documentation on using cloud and it appears you can only use this in sampleDict - so now I'm confused.. How do I use this during runtime so it samples (like a probe) at each time step such that groovyBC can then use the value?
odellar is offline   Reply With Quote

Old   June 20, 2014, 11:50
Default
  #4
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
Oh okay - didn't realise that. I've not used a cloud type sampled set before - does this just go in the controlDict as the probe would? (Do you know where I can find some documentation on cloud's use?).

Okay so after some more reading and re-reading I think, after I've got a cloud sample correct, the groovyBC boundary in the 0/U file should look something like this:

Code:
actuator
{
   type                     groovyBC;
   variables              "pMeasurement@cloudSampler=p;"
   valueExpression   "10*p";             // Or *SOME* mathematical expression
   value                   uniform (1 0 0); // Or *SOME* initial conditions
}
Is this the right idea? (Note here I've assumed the same usage with a cloud sampled set as that when using a patch.

Thanks again,
Olie

****EDIT****
Oh no - found some documentation on using cloud and it appears you can only use this in sampleDict - so now I'm confused.. How do I use this during runtime so it samples (like a probe) at each time step such that groovyBC can then use the value?
Have a look at the cleaningTank-example. It uses a cloud-set to control the run (control is probably a BIT more complicated than what you intend to do)
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   June 23, 2014, 10:35
Default
  #5
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Quote:
Originally Posted by gschaider View Post
Have a look at the cleaningTank-example. It uses a cloud-set to control the run (control is probably a BIT more complicated than what you intend to do)
Okay thank you. I've tried to base my approach on this, and so far now have the addition of the following in my controlDict:

Code:
functions
{
    readpField {
        type readAndUpdateFields;
        fields ( p );
    }

    createMeasurement
    {
    type createSampledSet;
    outputControl outputTime;
    outputInterval 1;
    setName sensor1;
    set {
        type cloud;
        axis x;
        points (
            (0 -0.5 0.5)
        );
    } 
} 
}
in an attempt to 'sample' the value of p at the coordinates (0 -0.5 0.5) at each written timestep, and the following in a funkySetFieldsDict located in system:
Code:
expressions (
    buildP
    {
        field p;
        create true;
    }
);
When I run the solver however, it fails and says --> FOAM FATAL ERROR:
Field p does not exist


From function Foam::readAndUpdateFields::read(const dictionary& dict)
in file misc/readAndUpdateFields/readAndUpdateFields.C at line 128.

FOAM exiting

What am I doing wrong?
Thanks again, Olie
odellar is offline   Reply With Quote

Old   June 27, 2014, 14:22
Default
  #6
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
? Anyone?
odellar is offline   Reply With Quote

Old   July 1, 2014, 12:26
Default Working (I think) but strange results.
  #7
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
I believe I've got it working now - I put this in the functions section of the controlDict:

Code:
createMeasurement 
	{ 
	type createSampledSet; 
	outputControl outputTime; 
	outputInterval 1; 
	setName sensor1; 
	set { 
		type cloud; 
		axis xyz; 
		points ( 
			(0 -0.5 0.5) 
		); 
	} }
and made this the entry in the 0/U directory for the boundary I want to be controlled based on the measurement from sensor1:

Code:
actuator 
    { 
	type groovyBC; 
	value	uniform (0 0 0); 
	variables ( 
		"pressureMeasurement{set'sensor1}=p;" 
		); 
	valueExpression "0.01*vector(0,pressureMeasurement,0)"; 
    }
So sensor1 is meant to measure the pressure at (0,-0.5,0.5), then multiply this value by 0.01 to give the velocity - this velocity value is to be used as a uniform velocity boundary condition for actuator.

I think it's *close* to working, but not quite. The attached image (hope the attaching works) shows the sampled pressure from sensor1, p_wall, the velocity on the actuator boundary v_act, and the ratio of p_wall to v_wall, which *should* be 100, given groovyBC is set to give v_act=0.01*p_wall, but it's more like 200.

Am I doing something wrong? Thanks!

odellar is offline   Reply With Quote

Old   July 2, 2014, 17:45
Default
  #8
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
I believe I've got it working now - I put this in the functions section of the controlDict:

Code:
createMeasurement 
	{ 
	type createSampledSet; 
	outputControl outputTime; 
	outputInterval 1; 
	setName sensor1; 
	set { 
		type cloud; 
		axis xyz; 
		points ( 
			(0 -0.5 0.5) 
		); 
	} }
and made this the entry in the 0/U directory for the boundary I want to be controlled based on the measurement from sensor1:

Code:
actuator 
    { 
	type groovyBC; 
	value	uniform (0 0 0); 
	variables ( 
		"pressureMeasurement{set'sensor1}=p;" 
		); 
	valueExpression "0.01*vector(0,pressureMeasurement,0)"; 
    }
So sensor1 is meant to measure the pressure at (0,-0.5,0.5), then multiply this value by 0.01 to give the velocity - this velocity value is to be used as a uniform velocity boundary condition for actuator.

I think it's *close* to working, but not quite. The attached image (hope the attaching works) shows the sampled pressure from sensor1, p_wall, the velocity on the actuator boundary v_act, and the ratio of p_wall to v_wall, which *should* be 100, given groovyBC is set to give v_act=0.01*p_wall, but it's more like 200.

Am I doing something wrong? Thanks!

That looks strange. Should work. How do you measure the velocity on the boundary?

BTW: just to be sure make it "pressureMeasurement{set'sensor1}=average( p );" (I think otherwise it might break in parallel)
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   July 3, 2014, 04:48
Default
  #9
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Quote:
Originally Posted by gschaider View Post
That looks strange. Should work. How do you measure the velocity on the boundary?

BTW: just to be sure make it "pressureMeasurement{set'sensor1}=average( p );" (I think otherwise it might break in parallel)
I sample velocity afterwards using the following in the sampleDict under sets:
Code:
actuator_velocity
    {
    type        uniform;
    axis         z;

    start       (-0.015 0 0);
        end         (-0.015 0 1);
        nPoints     3;
    }
I know these seems a daft way to sample a point but I've never worked out how else to do it! So given my case is a 2D geometry, so is length 1 in the z-direction (but with just one mesh cell in that direction), I sample a line in the z-direction with 3 points located at z=0, z=0.5 and z=1 and look at the middle one - any help on the proper way of sampling at a point would be greatly appreciated!

Oh thank you I'll put in average().

Also, can you use matrices in groovyBC expressions? Similar to how you can use vectors somehow? If so how do you do this?

Thanks a lot.

Last edited by odellar; July 3, 2014 at 06:37. Reason: Additional question added
odellar is offline   Reply With Quote

Old   July 3, 2014, 08:16
Default Also...
  #10
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Also, I'm using some storedVariables for a boundary condition, which update themselves each timestep, something like storedVariable1 = 0.5*storedVariable1 (there's more to it, but that's the general idea). However my thinking is that it updates the value of the variable every computational timestep which is a variable time step - I only want it to update at every write interval - so how do I specify that it's only to update at, for example, every 0.5 seconds? NOT ever actual computational time step?

Thanks a lot again, Olie
odellar is offline   Reply With Quote

Old   July 3, 2014, 15:22
Default
  #11
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
I sample velocity afterwards using the following in the sampleDict under sets:
Code:
actuator_velocity
    {
    type        uniform;
    axis         z;

    start       (-0.015 0 0);
        end         (-0.015 0 1);
        nPoints     3;
    }
I know these seems a daft way to sample a point but I've never worked out how else to do it! So given my case is a 2D geometry, so is length 1 in the z-direction (but with just one mesh cell in that direction), I sample a line in the z-direction with 3 points located at z=0, z=0.5 and z=1 and look at the middle one - any help on the proper way of sampling at a point would be greatly appreciated!

Oh thank you I'll put in average().

Also, can you use matrices in groovyBC expressions? Similar to how you can use vectors somehow? If so how do you do this?

Thanks a lot.
Sampling the point with a cloud like you did above is the way to do it. Without the average only the processor that has the point would have a value. That's why it is needed

matrixes are called tensors (3x3). swak supports all the operations on them OF supports (see the programmers-guide)
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   July 3, 2014, 15:30
Default
  #12
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
Also, I'm using some storedVariables for a boundary condition, which update themselves each timestep, something like storedVariable1 = 0.5*storedVariable1 (there's more to it, but that's the general idea). However my thinking is that it updates the value of the variable every computational timestep which is a variable time step - I only want it to update at every write interval - so how do I specify that it's only to update at, for example, every 0.5 seconds? NOT ever actual computational time step?

Thanks a lot again, Olie
I don't think that mixing the physical (your BC) with the discretization (output-times) is a good idea. Solution would depend on how often you write something out.

You want your storedVariable1 to "decay" exponentially, right? A bit of fiddling around with deltaT() and exp() will give you a decay with the same rate (it is year 1 mathematics. So don't ask me for formulas. I don't want to embarrass myself)
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   July 4, 2014, 06:32
Default
  #13
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Quote:
Originally Posted by gschaider View Post
I don't think that mixing the physical (your BC) with the discretization (output-times) is a good idea. Solution would depend on how often you write something out.

You want your storedVariable1 to "decay" exponentially, right? A bit of fiddling around with deltaT() and exp() will give you a decay with the same rate (it is year 1 mathematics. So don't ask me for formulas. I don't want to embarrass myself)
Thanks I'll look into tensors.

No that was just an example of the manner in which I'm wanting to use storedVariables - what I'm trying to do with them is actually more complicated, using them as state values for a discrete time state-space controller. But this shouldn't matter - the point is I need it to only update storedVariables at certain times: the times when data is written.

Correct the solution will depend on how often it's written - this is CORRECT in my particular situation (don't ask why, unless you're really interested!). So is this possible?

Thank you for all your help so far! I dare say I'm at the final hurdle!
odellar is offline   Reply With Quote

Old   July 5, 2014, 06:52
Default
  #14
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
Thanks I'll look into tensors.

No that was just an example of the manner in which I'm wanting to use storedVariables - what I'm trying to do with them is actually more complicated, using them as state values for a discrete time state-space controller. But this shouldn't matter - the point is I need it to only update storedVariables at certain times: the times when data is written.

Correct the solution will depend on how often it's written - this is CORRECT in my particular situation (don't ask why, unless you're really interested!). So is this possible?

Thank you for all your help so far! I dare say I'm at the final hurdle!
An example for discrete states would be in Examples/FromPresentations the cleaning-tank examples

General swak-Expressions have no function "outputTime()" that is true for times when OF does output (for the reasons above). What DOES have such a variable is the Python-integration
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   July 7, 2014, 04:51
Default
  #15
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Quote:
Originally Posted by gschaider View Post
An example for discrete states would be in Examples/FromPresentations the cleaning-tank examples

General swak-Expressions have no function "outputTime()" that is true for times when OF does output (for the reasons above). What DOES have such a variable is the Python-integration
Okay thank you - where abouts is the code relating to these situated? Is it anything to do with the commonVariables file?

Thanks, Olie
odellar is offline   Reply With Quote

Old   July 9, 2014, 14:05
Default
  #16
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
Okay thank you - where abouts is the code relating to these situated? Is it anything to do with the commonVariables file?

Thanks, Olie
No. That is for common expressions between BCs (mostly for "smoothing" what goes out on one side to be used as input on the other side). Variables for the state are declared in system/controlDict in the defineState functionObject.
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   July 14, 2014, 07:46
Default
  #17
Member
 
Olie
Join Date: Oct 2013
Posts: 44
Rep Power: 3
odellar is on a distinguished road
Quote:
Originally Posted by gschaider View Post
No. That is for common expressions between BCs (mostly for "smoothing" what goes out on one side to be used as input on the other side). Variables for the state are declared in system/controlDict in the defineState functionObject.
Thank you, this certainly helps, but I'm still not sure - just by reading the code in the example - how to actually use it.

My guess is to put something like this in controlDict:
Code:
defineState {
type addGlobalVariable; 
outputControl runtime; 
outputInterval 0.5; // to output every 0.5 seconds?
globalScope stateInformation;
globalVariables {
state1 {
valueType scalar;
value 0; // What does this mean?
}
state2 {
valueType scalar;
value 0; // What does this mean?
}
}
}
then I don't know where to go from there?

If it helps, the attached image shows what I'm trying to implement - note that state values x do not refer to some physical state (such as pressure, velocity etc), they're just values that are updated at each write interval according to x_k+1 = Ax_k + Bs_k, and in the image when I refer to 'timestep' I also mean write interval, i.e. some fixed interval (in my case 0.5 seconds).

Thanks

odellar is offline   Reply With Quote

Old   July 22, 2014, 16:43
Default
  #18
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 3,915
Rep Power: 40
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by odellar View Post
Thank you, this certainly helps, but I'm still not sure - just by reading the code in the example - how to actually use it.

My guess is to put something like this in controlDict:
Code:
defineState {
type addGlobalVariable; 
outputControl runtime; 
outputInterval 0.5; // to output every 0.5 seconds?
globalScope stateInformation;
globalVariables {
state1 {
valueType scalar;
value 0; // What does this mean?
}
state2 {
valueType scalar;
value 0; // What does this mean?
}
}
}
then I don't know where to go from there?

If it helps, the attached image shows what I'm trying to implement - note that state values x do not refer to some physical state (such as pressure, velocity etc), they're just values that are updated at each write interval according to x_k+1 = Ax_k + Bs_k, and in the image when I refer to 'timestep' I also mean write interval, i.e. some fixed interval (in my case 0.5 seconds).

Thanks

That is a huge picture.

Anyway: For the meaning of value etc see http://openfoamwiki.net/images/c/c0/...rogrammers.pdf starting at page 30. A few pages later calculateGlobalVariables is explained (which would be how you get the sensor values). The groovyBC then will only have to get the global variables (that is also explained there)
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Reply

Tags
groovybc, probe pressure

Thread Tools
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 On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
groovyBC and probe problem, needing your help! wwbbit OpenFOAM 4 April 17, 2010 00:31


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