Simple Proportional Feedback Control- Errors with UDF

Numerical methods and mathematical models of Elmer
Post Reply
Hal
Posts: 13
Joined: 24 Jun 2013, 19:56
Antispam: Yes

Simple Proportional Feedback Control- Errors with UDF

Post by Hal »

Hi,

I'm trying to construct a toy problem for feedback control; in this problem, a 2D cantilevered beam undergoes a static force downwards on one end. I'd like a control force to push the system back up proportional to the maximum deflection of the beam. I don't necessarily care about the application or how good the controller is, I just want to be able to take outputs from ElmerSolver, send them to a UDF, and have the UDF calculate a restoring force.

In my sif file I extract the minimum and maximum deflection of the beam:

Code: Select all

Solver 2
 Equation = SaveScalars
  Operator 1 = max
  Variable 1 = Displacement 2
  Procedure = "SaveData" "SaveScalars"
  Target Variable 1 = String dispmax
  Exec Solver=Always
End

Solver 3
  Equation = SaveScalars2
  Operator 1 = min
  Variable 1 = Displacement 2
  Procedure = "SaveData" "SaveScalars"
  Target Variable 1 = String dispmin
  Exec Solver=Always
End
Then, I use these parameters to define a restoring force:

Code: Select all

Boundary Condition 3
Target Boundaries = 3
  Force 2 = Variable Time
        Real Procedure "PID" "doPID"
End

It shows up in the UDF like this:

Code: Select all

FUNCTION doPID( Model, n, x ) RESULT( f)
  USE Types
  USE DefUtils
  TYPE(Model_t) :: Model
  INTEGER :: n
  TYPE(Variable_t), POINTER :: dMinP, dMaxP !pointers pointing to displacement
  REAL(KIND=dp):: x
  REAL(KIND=dp) :: t, p, dMin, dMax, f
  LOGICAL GotMin, GotMax       
        p= 1000 !proportional control


        !extract the max/min displacements from the pointers
        dMaxP= VariableGet(Model % Variables, 'dispmax',GotMax)
        dMax=dMaxP%Values(1)
        
        dMinP= VariableGet(Model % Variables, 'dispmin',GotMin)
        dMin=dMinP%Values(1)

        !success?
        print *, GotMax
        print *, GotMin

        !return control force
        f=-p*dMin
END FUNCTION doPID
And when I run this, I get a segfault. I know dispmax/dispmin are being correctly calculated; I see them output to the terminal each timestep. I know that my UDF is talking to my SIF, because if I change the output to 'p', this shows up as a static force in my simulation. I've played around, and it turns out I segfault whenever I try to do operations with 'dMin' or 'dMax', even if GotMax/GotMin return true.

How do I do operations on a user defined global variables like 'dispmax' and 'dispmin' without an error?

Thanks for any help!
Attachments
PIDshare.f90
(670 Bytes) Downloaded 288 times
beamCont.grd
(543 Bytes) Downloaded 283 times
beamContShare.sif
(1.8 KiB) Downloaded 305 times
Hal
Posts: 13
Joined: 24 Jun 2013, 19:56
Antispam: Yes

Re: Simple Proportional Feedback Control- Errors with UDF

Post by Hal »

For what it's worth, I have also tried

Code: Select all

 dMaxP=> VariableGet(Model % Variables, 'dispmax',GotMax)
in place of

Code: Select all

 dMaxP= VariableGet(Model % Variables, 'dispmax',GotMax)
It compiles in both cases, but I still get a segfault. To be honest, I'm not too experienced with Fortran pointers, but I think there is a larger problem with the code.
raback
Site Admin
Posts: 4812
Joined: 22 Aug 2009, 11:57
Antispam: Yes
Location: Espoo, Finland
Contact:

Re: Simple Proportional Feedback Control- Errors with UDF

Post by raback »

Hi Hal

The control forces are there the 1st time the equation is assembled. So do like this:

Code: Select all

dMinP => VariableGet(Model % Variables, 'dispmin',GotMin)
IF( GotMin ) THEN
  dMin=dMinP%Values(1)
ELSE
  dMin = 0.0_dp
END IF
Having just a simple feedback is prone to result to numerical errors. There is a generic contact model in Elmer that could be used. Look at the test cases LimitDisplacement*. In short add to solver section

Code: Select all

Apply Limiter = Logical True
and to the boundary condition some lower limit, e.g. against a parabolic profile like in the test case.

Code: Select all

  Displacement 2 Lower Limit = Variable Coordinate 1
    Real MATC "-0.5-0.2*(tx-5.5)^2"
The result also returns nodal loads at the contact.

-Peter
Post Reply