Is it possible/reasonable to count the number of field lines that terminate on an object in Garfield++?

I am plotting an electric field map that I made in Elmer, and I wanted to calculate the transparency of the electric field (number of field lines terminating at the end / total number of field lines). The idea is identical to the transparency of the electron (a question that I see has already been answered on this forum), but running full particle simulations can be quite time intensive, and I was looking for a much faster way to run some simulations. I want to optimize the design of my amplification structure, but this will require many small iterations that can be reasonably understood by a simple field map rather than a full particle simulation. Is it possible to count the number of field lines that terminate at a certain point (say, within a specific range of z values), and if so, how could I go about doing so? Would it be better for me to just send the .vtu file into a jupyter notebook and manually script something, or is there a way that I can do it directly in Garfield++? Thank you for any assistance that you can provide.

Additional details:
ROOT Version: 6.32.06
Platform: Ubuntu Virtual Machine (Windows Host)
Compiler: I don’t know (I’m new at this)


Hi,

Welcome to the ROOT Community. I am adding @hschindl in the loop.

Cheers,
D

Hi,
yes, that should be possible. There is a function (ViewField::PlotFieldLines) which can be used to make a field line plot (see this example). It doesn’t allow you to retrieve the endpoints of the field lines, but you can do what’s done internally in this function quite easily yourself; something along these lines:

// Set up the electric field, active medium, etc.
Sensor sensor;

DriftLineRKF drift(&sensor);
// Might need to do some tweaking of the parameters of DriftLineRKF, e. g. impose a max. step size.

// Starting point of the field line
double x0 = 0., y0 = 0., z0 = 0.;
std::vector<std::array<float, 3> > xl;
// Calculate a field line.
drift.FieldLine(x0, y0, z0, xl);
// xl should now hold the coordinates of all points along the field line.

Let me know if you run into any issues…

Dear hschindl,
Thank you for your reply. I have implemented this into my code, but the output doesn’t seem to follow my field lines, which has me slightly confused. They seem to be a fairly random assortment of points after a while. I have attached the field map and the output below, along with the relevant portion of my code.

Relevant code:

Sensor sensor;
sensor.AddComponent(elm);
sensor.SetArea(xmin, ymin, zmin, xmax, ymax, zmax);

DriftLineRKF drift(&sensor);
std::vector<std::array<float, 3> > Line;
drift.FieldLine(0, 0, zmax, Line);

std::cout << “\n”;
int size = sizeof(Line);
std::cout << “The size of the array is:” << size << “\n”;
int Num = size - 1;
std::cout << “The points of the field line are: \n”;
for(int i = 0; i<Num; ++i)
{
std::cout << "x = " << Line[i][0] << ", y = " << Line[i][1] << ", z = " << Line[i][2] << “\n”;
}


Hi,
you need to use the size method of std::vector instead of the sizeof operator.

auto size = Line.size();
std::cout << “The size of the array is:” << size << “\n”;
std::cout << “The points of the field line are: \n”;
for (int i = 0; i < size; ++i) {
  std::cout << "x = " << Line[i][0] << ", y = " << Line[i][1] << ", z = " << Line[i][2] << “\n”;
}

This is making much more sense now. Thank you for your help!