# Efficient method to calculate green's function between points

I am working on an analytical model for sound radiation from a cylinder. As part of this work I am using the boundary element method to predict the sound pressure at a particular location away from a vibrating cylinder.

This requires the cylinder to be split into a number of elements and a function to be evaluated which is dependent on the vectors between the centroid of each element and a selected location in space. Therefore I ultimately require a n x 1 matrix (where n is the number of elements the cylinder is split into).

I have managed to produce what I require using the below code, however, this appears (to me) to be a very inefficient method as the code produces a n x n matrix and then cuts this down to a n x 1 matrix. In this case the extra elements of the n x n matrix are not required. My method is outlined below.

Variables to be defined;

• ro, θo, zo = the r , theta and z coordinates of the point of interest.
• nn and mm are used to divide the cylinder up into nn x mm elements.
• a = cylinder radius; L = cylinder length; co = speed of sound (343); ω = frequency of vibration

.

a = 0.1096; nn = 1; mm = 4; L = 1.408; co = 343; ω = 500; ko =ω/co; ro = 3; θo = π/4; zo = 4;


Then randomList creates a list of all the elements centroids and the point of interest,

randomList = Prepend[Flatten[
Table[{a, (i*π)/mm, (j*L)/(2*nn)}, {i, 1, 2*mm, 2}, {j, 1,
2*nn}], 1], {ro, θo, zo}];


Now ggr[] is the function which I wish to apply to the randomList. Ideally this function would only be evaluated for the vectors between element 1 and element 2, 3, 4, etc. of randomList.

ggr[{a1_, a2_, a3_}, {b1_, b2_,
b3_}] := (-(1/4*π*
Sqrt[(a1*Cos[a2] - b1*Cos[b2])^2 + (a1*Sin[a2] -
b1*Sin[b2])^2 + (a3 - b3)^2]^2) - ((I*ko)/4*π*
Sqrt[(a1*Cos[a2] - b1*Cos[b2])^2 + (a1*Sin[a2] -
b1*Sin[b2])^2 + (a3 - b3)^2]))*Exp[-I*ko*
Sqrt[(a1*Cos[a2] - b1*Cos[b2])^2 + (a1*Sin[a2] -
b1*Sin[b2])^2 + (a3 - b3)^2]];


Finally the following code produces the matrix I require by first calculating a n x n matrix and then extracting the required information out to produce the final n x 1 matrix,

Take[Transpose[Take[Table[
ggr[randomList[[i]], randomList[[j]]], {i, 1,
Length[randomList], 2}, {j, 1, Length[randomList], 2}], {1,
1}]], {2, mm*nn + 1}] // MatrixForm


Is there a more efficient way to directly calculate the required n x 1 matrix?

• Have you looked at GreenFunction[]? – J. M. will be back soon Jul 14 '16 at 2:55
• I have looked at GreenFunction[], I thought it would be easier to write out the ggr[] function, which is the derivative of the Green's function, rather than use GreenFunction[] in it's place. – ElHeatho Jul 14 '16 at 3:24

If I am not mistaken your final expression may be reduced to:

Table[
{ ggr[ randomList[], randomList[[1 + 2 j]] ] },
{j, mm*nn}
]

{{-7.01292 - 10.5223 I},
{-8.64938 - 9.92198 I},
{-10.2158 - 9.0987 I},
{-8.64938 - 9.92198 I}}


Or equivalently:

Array[{ggr[randomList[], randomList[[1 + 2 #]]]} &, mm*nn]