Issue in Electrostatic Potential conversion from TCAD TDR file

Dear developers,

I report here an issue I encountered when converting TCAD Electrostatic potential maps from TDR files.

When I open in TCAD the Electrostatic potential map, I obtain the following map, which is not empty:

After this, I tried to convert it into an .init file by using the mesh_converter tool. The command line I used is:

./mesh_converter -c configuration.conf -f iv_50_1.2_-2_0.0_0.81_1px_allpix

And the configuration.conf file looks like this, which I hope is correct:

model = "init"
dimension = 3
region = "substrate"
observable = "ElectrostaticPotential"
divisions = 100 100 150
xyz = z x y

The output of the conversion contains a WARNING regarding the units (could this be a cause for the problem I’ll describe below?):

MacBook-Pro-di-Lorenzo:converted_mesh lorenzodecilladi$ ../../bin/mesh_converter -c configuration.conf -f iv_50_1.2_-2_0.0_0.81_1px_allpix
|10:55:50.313| **(STATUS)** Welcome to the Mesh Converter Tool of Allpix^2 v1.5.0+6^g3b9c7c98
|10:55:50.313| **(STATUS)** Using configuration.conf configuration file
|10:55:50.313| **(STATUS)** Reading mesh grid from grid file "iv_50_1.2_-2_0.0_0.81_1px_allpix.grd"
|10:55:51.046| **(INFO)** Parsing grid file: done.
|10:55:51.077| **(INFO)** Grid sizes for all regions:
|10:55:51.077| **(INFO)** Ntop1 85
|10:55:51.077| **(INFO)** Pbot 85
|10:55:51.077| **(INFO)** Ptop 68
|10:55:51.077| **(INFO)** substrate 7801
|10:55:51.077| **(STATUS)** Reading electric field from data file "iv_50_1.2_-2_0.0_0.81_1px_allpix.dat"
|10:55:51.205| **(INFO)** Parsing field data file: done.
|10:55:51.205| **(INFO)** Field sizes for all regions and observables:
|10:55:51.205| **(INFO)** substrate:
|10:55:51.205| **(INFO)** DopingConcentration 7801
|10:55:51.205| **(INFO)** ElectricField 7801
|10:55:51.205| **(INFO)** ElectrostaticPotential 7801
|10:55:51.205| **(INFO)** Using initial neighbor search radius of 0.1
|10:55:51.205| **(STATUS)** TCAD mesh (x,y,z) coords. transformation into: (z,x,y)
|10:55:51.205| **(STATUS)** Mesh dimensions: 50 x 10 x 50
New mesh element dimension: 0.5 x 0.1 x 0.333333 ==> Volume = 0.0166667
|10:55:51.205| **(INFO)** Reading the files took 0 seconds.
|10:55:51.206| **(STATUS)** Starting regular grid interpolation with 4 threads.
|12:01:50.585| **(INFO)** Interpolating new mesh: 9999 of 10000, 99%
|12:01:50.585| **(INFO)** New mesh created in 3960 seconds.
|12:01:50.624| **(WARNING)** No field units provided, writing field data in internal units.
|12:01:58.701| **(INFO)** Writing field data: finished.
|12:01:58.707| **(STATUS)** New mesh written to file "iv_50_1.2_-2_0.0_0.81_1px_allpix_ElectrostaticPotential.init"
|12:01:58.707| **(STATUS)** Interpolation and conversion completed in 3968 seconds.
MacBook-Pro-di-Lorenzo:converted_mesh lorenzodecilladi$

Unfortunately, the output init file looks empty (i.e. all the Electrostatic potential entries are empty; you can find the file here:

If I plot the relative map with the mesh_plotter using the command

./mesh_plotter -f iv_50_1.2_-2_0.0_0.81_1px_allpix_ElectrostaticPotential.init

I obtain the following output (again with a WARNING) and the following empty map:

MacBook-Pro-di-Lorenzo:converted_mesh lorenzodecilladi$ ../mesh_plotter -f iv_50_1.2_-2_0.0_0.81_1px_allpix_ElectrostaticPotential.init
|12:04:55.929| **(STATUS)** Welcome to the Mesh Plotter Tool of Allpix^2 v1.5.0+6^g3b9c7c98
|12:04:55.929| **(STATUS)** Reading file: iv_50_1.2_-2_0.0_0.81_1px_allpix_ElectrostaticPotential.init
|12:04:55.929| **(WARNING)** No field units provided, interpreting field data in internal units, this might lead to unexpected results.
|12:04:57.287| **(INFO)** Reading field data: finished.
|12:04:57.287| **(STATUS)** Number of divisions in x/y/z: 100/100/150
Info in <TCanvas::Print>: png file iv_50_1.2_-2_0.0_0.81_1px_allpix_ElectrostaticPotential_yz_50.png has been created
MacBook-Pro-di-Lorenzo:converted_mesh lorenzodecilladi$

Am I doing something wrong? Or do you have any advice based on your experience?

Thank you for your kind support, I’m looking forward to contributing when I gain more experience with the Allpix-squared framework,

Best regards,

As an addition to the previous post, I can already confirm that, considering the .dat file which originates from the TDR file conversion with the TCAD command

tdx -dd fieltToConvert.tdr

the section corresponding to the electrostatic potential

Data {

  Dataset ("ElectrostaticPotential") {
    function  = ElectrostaticPotential
    type      = scalar
    dimension = 1
    location  = vertex
    validity  = [ "substrate" ]
    Values (10147) {

is not empty.

Best, Lorenzo

Could this be an issue with which dimensions you select for interpolation? The README says:

The program can be used to convert 3D and 2D TCAD mesh files. Note that when converting 2D meshes, the x coordinate will be fixed to 1 and the interpolation will happen over the yz plane.

Dear @simonspa ,

it is actually a 3D mesh, so dimension = 3 is correct. I’m sorry, in the figure I just showed a 2D cut.


Dear @simonspa,

I’ll try to make a few guesses that you may confirm or reject based on your experience:

  • could this relate to a minimum sensitivity (i.e. decimal numbers)? Could numbers that are too small be considered as 0 in the conversion process? I do not think this guess is correct, but it is a hypothesis anyway.
  • Should the final grid be coarser or finer compared to the original one in order to have an optimal result from the interpolation? Could this be an issue?
  • Could this be an effect of a wrong initial radius, although the conversion actually “converts” my dat/grd files in a reasonable time (2 hours with 24 threads)?

Thank you very much for your support,
Best regards,


Also, when converting the ElectrostaticPotential I obtain the following warning that I do not obtain when converting an Electric Field:

**(WARNING)** No field units provided, writing field data in internal units.

Could this also help in understanding the issue? How can I provide field units to the converter?

Thanks a lot,


Dear @simonspa and developers,

I did more in-depth investigations of the issue I described in the previous messages. I tried with different node numbers and different initial radii, but nothing changed. The output INIT file after ElectrostaticPotential conversion is empty; here follows an extract:

Allpix Squared v1.5.0+271^g6133e8d TCAD Mesh Converter, observable: ElectrostaticPotential
internal ##EVENTS##
##TURN## ##TILT## 1.0
0.0 0.0 0.0
50 50 10 0.0 0.0 0.0 0.0 200 200 200 0.0

1 1 1 0
1 1 2 0
1 1 3 0
1 1 4 0
1 1 5 0
1 1 6 0
1 1 7 0

and so on, the fourth column (the one that should contain the Electrostatic Potential value) is always ZERO.

Therefore, I ran the mesh_converter with DEBUG verbosity level, and I obtained output like this extract:

|13:36:25.918|   (DEBUG) Tetrahedron vertex (0, 2.5, 46.875) -  Distance: 4.53125 - Electric field: (0, -21.9345, 0)
                         Tetrahedron vertex (0, 5, 43.75) -  Distance: 4.92188 - Electric field: (0, -20.0201, 0)
                         Tetrahedron vertex (0, 0, 43.75) -  Distance: 11.1719 - Electric field: (0, -20.0201, 0)
                         Tetrahedron vertex (3.125, 2.5, 46.875) -  Distance: 11.9531 - Electric field: (0, -21.9329, 0)
                         Volume: -8.13802
|13:36:25.917|   (DEBUG) Tetrahedron vertex (0, 5, 40.625) -  Distance: 5.54125 - Electric field: (0, -18.1362, 0)
                         Tetrahedron vertex (0, 5, 37.5) -  Distance: 5.93188 - Electric field: (0, -16.29, 0)
                         Tetrahedron vertex (0, 0, 40.625) -  Distance: 12.7912 - Electric field: (0, -18.1362, 0)
                         Tetrahedron vertex (6.25, 5, 40.625) -  Distance: 39.9163 - Electric field: (0, -18.1362, 0)
                         Volume: -16.276
|13:36:25.917|   (DEBUG) Search radius: 1.05
|13:36:25.919|   (DEBUG) Sub volume 0: -1.70898
|13:36:25.918|   (DEBUG) Sub volume 2: -2.4821
|13:36:25.918|   (DEBUG) Search radius: 1.05
|13:36:25.919|   (DEBUG) Sub volume 3: -0.976562
|13:36:25.919|   (DEBUG) Number of vertices found: 0
|13:36:25.919|   (DEBUG) Interpolated electric field: (0,-19.6468,0)

As you can notice from the last line (even though I don’t understand why it calls it electric FIELD) the mesh converter actually calculates the Electrostatic Potential, but puts it in the second component of a 3D vector.

My guess is the following: is the FIRST component of such 3D vector (e.g. (0, -19.6468, 0) ) the one that is written in the INIT file? If so, the second component should be written instead of the first.

Could you please help me with this?

Thanks a lot and kind regards,

Hi Lorenzo,

sorry for the late reply on this - and thanks for the investigative testing. I’ll have a look at this now and come back to you soon.

concerning the “field” name in the debug output: it still is a field, but only a scalar one - so I guess from a “technical” point of view it is not wrong, but I do understand that it is misleading.

Let me check what goes wrong here.


Hi @ldecilla

you were right about your assumption with the field component. Here: we only select the x component for scalar fields and add y and z for vector fields. Now we need to find out what goes wrong there.

My guess would be that this somehow just is a coordinate transformation issue. Looking at your initial post I see that you use xyz = z x y to convert from TCAD to APSQ reference frames. But somehow the potential you are reading does not seem to be stored in the z component?

(for a quick fix, simply swap that x out for a y but that of course just works around it…)


Dear @simonspa,

no problem at all, it was actually very instructive for me to try and look into the problem and to start understanding how the allpix-squared code works, even though I was not able to solve my issue. Thanks a lot for your help! I hope I’ll be able to contribute once I become more familiar with the framework.

Yes, you are totally right. I was in fact misled by the fact that the two different options are “ElectricField” (vector field) and “ElectrostaticPotential” (scalar field).

Thanks for the support in trying to solve this issue,

Best regards,

Dear @ldecilla

so swapping for the y component worked for you now so you can continue with the generated potential?


Hi @simonspa,

thanks a lot for your quick reply.

Mmm, the coordinate conversion xyz = z x y I used was just the result of geometrical considerations I made. If I am not wrong, the beam axis coordinate in Allpix2 is the z, while in TCAD it is the y (in my case). The conversion I wrote above maps a TCAD xyz in an Allpix2 yzx, am I right?

I don’t actually know where does TCAD store the component of the electrostatic potential. But if it stores it in the x-component, and my conversion maps it in the y Allpix2 coordinate, the fact that I found the final interpolated value on the y could make sense… but this is just a guess.

As for the quick fix, do you mean to swap the x for a y here: , and then recompile allpix-squared?


Hi @ldecilla

yes you are right - with a minor correction: the beam axis (global coordinates) is not of interest here but the local (detector) coordinates. Here, the thickness of the device goes along z - so same as what you described. Probably that is the problem then - we swap the scalar field around together with the coordinates. So probably what we should do is remember which one was x and use that as the scalar component?

Yes, that’s exactly the swap I meant.


Dear @simonspa,

thanks for the explanation, now I also better understand the reference systems used. Yes, if the guess that TCAD stores the electrostatic potential on the x-component is correct (which I might try to confirm you after a bit of investigation), that’s exactly what could be needed to solve the issue: just to “remember” which new Allpix2 coordinate corresponds to the original TCAD x-coordinate and use that new one as the scalar component. Or, alternatively, always write to the first component (i.e. Allpix2 x-coordinate) of the field vector when the option “ElectrostaticPotential” (or any other scalar field) is used.

Anyway, I made the swap you suggest in MeshConverter.cpp and I rebuilt an updated Docker image on my local (I did not push it); it now seems to work properly! Here follows an extract:

Allpix Squared v1.5.0+271^g6133e8d TCAD Mesh Converter, observable: ElectrostaticPotential
internal ##EVENTS##
##TURN## ##TILT## 1.0

0.0 0.0 0.0
50 50 10 0.0 0.0 0.0 0.0 50 50 50 0.0
1 1 1 -0.447405
1 1 2 -0.363302
1 1 3 -0.283988
1 1 4 0.0502702
1 1 5 0.233081

I’m super happy about this, thanks a lot for your help!


1 Like