Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register

Implement convolution of continuous functions symbolically in Modelica

Implement convolution of continuous functions symbolically in Modelica

Hi there!

I'm attempting to develop a custom library in MapleSim (a Modelica solver engine) that can use convolution integrals to model the hydrodynamic behaviour of floating bodies. The convolution integral is mathematically represented as follows: https://i.stack.imgur.com/uNQ7W.png

And the equation I'm particularly interested in solving is as follows: https://i.stack.imgur.com/DWUWY.png

I'm trying to solve this convolution integral in Modelica using a model that can be imported to MapleSim. So far, I've had no luck in implementing this convolution for continuous functions symbolically. I have used a numerical approach on 2 arrays using the following approach in Modelica:

Code:


// Modelica function
function convIntegral
  input Real simTime;  // Simulation time
  input Real f[:];     // Kernel function array
  input Real g[:];     // Second function array

  output Real h[(2*simTime) - 1];    // Output the convolution integral in the form of an array
 
  // Define the algorithm to numerically compute the convolution integral of 2 arrays
  algorithm
    // Initialize the output array with zeroes
    for i in 1:((2*simTime) - 1) loop
      h[i] := 0;
    end for;
   
    // Iterate over the simulation time
    // Recursively increment the convolution array with the pointwise product of the 2 functions
    for i in 1:simTime loop
      for j in 1:simTime loop
        h[i+j-1] := (f[i] * g[j]) + h[i+j-1];
      end for;
    end for;
end convIntegral;
// End of function to compute the convolution integral

This works perfectly for discrete samples and I have verified it with output from MATLAB's inbuilt function

Code:


conv(A,B)  % For 2 arrays A and B

However, I would like to implement this on 2 continuous functions and this numerical approach does not work since MapleSim does not support conversion between discrete and continuous signals.

I understand that convolution is essentially an operation between two functions, where we time-flip one of the functions (kernel) and then slide it across the other function while measuring the bounded area and outputting that as the result of the convolution. I include this image from Wikipedia that sums up convolution: https://i.stack.imgur.com/TdIfa.png

I've tried implementing this in Modelica using the following code:

Code:


// Model to perform convolution on 2 continuous functions
model ConvolutionalIntegral

  extends Modelica.Blocks.Icons.Block;

  // Define model variables
  Real kernelFunction = (e ^ (-0.5 * time)) * cos(0.5 * time);  // I've taken an example of a function I might use
  Real kernelFunctionFlipped = (e ^ (-0.5 * (T_sim - time))) * cos(0.5 * (T_sim - time));  // I've flipped the kernel function about the vertical axis by converting the (time) variable to (T_sim - time) where (T_sim) is a variable storing the simulation duration
  Real secondFunction;  // The other function for the convolution
  Real convolutionIntegralOutput;  // Function to store the output
 
  equation
    // Convolution implementation
    der(convolutionIntegralOutput) = kernelFunctionFlipped * secondFunction;

    // Final equation to solve
    der(secondFunction) + convolutionIntegralOutput = 0;
    // An example of a differential equation I'd like to solve involving the convolution integral
   
end ConvolutionIntegral;

I had hoped that this would yield the output of the convolution since I'm essentially multiplying the time-flipped kernel and the other function and then integrating them over time. However, the output does not provide the expected result and it appears that Modelica interprets my code to mean that I'm integrating the pointwise product of these 2 functions over time instead of sliding the kernel over the other function.

I'd appreciate it if you could take a look at my code and my approach to solving the convolution integral symbolically, and point out where I'm making a mistake and what a possible fix might be.

Thank you!

There are 0 guests and 0 other users also viewing this topic
You are here: