FastFieldSolvers Forum
FastFieldSolvers Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ
Username:
Password:
Save Password
 All Forums
 FastFieldSolvers
 FastHenry2
 Mutual inductance impact
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

qmle

Vietnam
5 Posts

Posted - Jun 28 2017 :  17:47:36  Show Profile  Reply with Quote
Hi,
I was able to export R,L,M matrices from FastHenry to do some further study in Mutual Inductance in Matlab. My plan was to delete all of the non-diagonal terms in the L matrix, and then recompute the loop inductance to see the partial mutual inductance contribution. However, when I exported the matrices above to Matlab, the dimensions seem to be mismatching so I cant compute M*(R+jwL)*M'. Do you have any suggestion for this.
Thanks and Regards


qmle

Enrico

531 Posts

Posted - Jun 28 2017 :  19:19:20  Show Profile  Reply with Quote
How did you export the matrices? Can you share your example?

Best Regards,
Enrico
Go to Top of Page

qmle

Vietnam
5 Posts

Posted - Jun 28 2017 :  21:43:39  Show Profile  Reply with Quote
Hi Enrico,
Thanks for the quick response, here is the simple example I have made:
#--------------------------------------
NA1s x=0.0 y=0.0 z=0.41
NA1e x=0.0 y=19.55 z=0.41
NA2s x=0.0 y=19.55 z=0.41
NA2e x=15 y=19.55 z=0.41
NA3s x=15 y=19.55 z=0.41
NA3e x=15 y=0.0 z=0.41
EA1 NA1s NA1e w=5 h=0.64 sigma=58000.0
EA2 NA2s NA2e w=5 h=0.64 sigma=58000.0
EA3 NA3s NA3e w=5 h=0.64 sigma=58000.0
+nwinc=1 nhinc=1
.equiv NA1e NA2s
.equiv NA2s NA3e
.external NA1s NA3s
.freq fmin=100000 fmax=100000
.end
#-----------------------------------------
I intentionally set the nwinc and nhinc to 1 to study how would this affect the matrix sizes. I have run Fasthenry using this setting:
-d: on # dumped the internal matrix
-a: on # allow multipole algorithm to refine structure
-m: direct
This exports the M.mat, b.mat, MZMt.mat and RL.mat. I am trying to delete non-diagonal terms in the L matrix. However, the size for M and L are mismatching: M [16x3] and L[23x23]. This is why I cant perform the matrix multiplication from FastHenry's paper manually.
Best Regards,
Quang




quote:
Originally posted by Enrico

How did you export the matrices? Can you share your example?

Best Regards,
Enrico




qmle
Go to Top of Page

Enrico

531 Posts

Posted - Jun 30 2017 :  18:38:43  Show Profile  Reply with Quote
I'm afraid it is not so simple. These dumps are intended for debugging, you need to be familiar with the FastHenry code to use them.

The dumped M matrix is actually done by the routine 'dump_M_to_xxx()' in the file 'induct.c':

dump_M_to_text(fp, Mlist, num_mesh, nnz)
FILE *fp;
MELEMENT **Mlist;
int num_mesh, nnz;
{
  int counter, i;
  MELEMENT *mesh;

  counter = 0;

  for(i = 0; i < num_mesh; i++)
    for(mesh = Mlist[i]; mesh != NULL; mesh = mesh->mnext) {
      fprintf(fp, "%d\t%d\t%d\n", i+1, mesh->filindex+1, mesh->sign);
      counter++;
    }

  if (counter != nnz)
    fprintf(stderr,"Internal Warning: nnz %d != counter %d\n",nnz,counter);

}


As you can see, it will always be a three column matrix, as the first column is the index of the mesh, the second are the filaments composing the mesh, and the third is the sign of the filament within the mesh. This is a compact form. The actual multiplication is therefore not direct, but done in 'formMZMt()' again in the file 'induct.c'.

/* this does L*(Mt)_i where (Mt)_i is a single column (row) of Mt (M) and
     saves it in the temp space, tcol */
  for(mesh = 0; mesh < num_mesh; mesh++) {
    for(j = 0; j< nfils; j++)
      tcol[j] = 0;
    /* note, this next set of nested loops could be reversed, but I think
       this might be more efficient for pipelining, ? */
    for(melem = Mlist[mesh]; melem != NULL; melem = melem->mnext)
      for(j = 0; j < nfils; j++)
	    tcol[j] += L[j][melem->filindex]*melem->sign;
    for(mesh2 = 0; mesh2 < num_mesh; mesh2++) {
      tempsum = 0;
      for(melem2 = Mlist[mesh2]; melem2 != NULL; melem2 = melem2->mnext)
	    tempsum += melem2->sign*tcol[melem2->filindex];
      Zm[mesh2][mesh].imag = tempsum;
    }
  }


You can of course analyze the code, and modify and recompile it, if you would like different matrix dumps. This is the advantage of the open source.

Best Regards,
Enrico
Go to Top of Page

qmle

Vietnam
5 Posts

Posted - Jun 30 2017 :  21:28:49  Show Profile  Reply with Quote
Again thanks for the quick response, I will check the source code.
quote:
Originally posted by Enrico

I'm afraid it is not so simple. These dumps are intended for debugging, you need to be familiar with the FastHenry code to use them.

The dumped M matrix is actually done by the routine 'dump_M_to_xxx()' in the file 'induct.c':

dump_M_to_text(fp, Mlist, num_mesh, nnz)
FILE *fp;
MELEMENT **Mlist;
int num_mesh, nnz;
{
  int counter, i;
  MELEMENT *mesh;

  counter = 0;

  for(i = 0; i < num_mesh; i++)
    for(mesh = Mlist[i]; mesh != NULL; mesh = mesh->mnext) {
      fprintf(fp, "%d\t%d\t%d\n", i+1, mesh->filindex+1, mesh->sign);
      counter++;
    }

  if (counter != nnz)
    fprintf(stderr,"Internal Warning: nnz %d != counter %d\n",nnz,counter);

}


As you can see, it will always be a three column matrix, as the first column is the index of the mesh, the second are the filaments composing the mesh, and the third is the sign of the filament within the mesh. This is a compact form. The actual multiplication is therefore not direct, but done in 'formMZMt()' again in the file 'induct.c'.

/* this does L*(Mt)_i where (Mt)_i is a single column (row) of Mt (M) and
     saves it in the temp space, tcol */
  for(mesh = 0; mesh < num_mesh; mesh++) {
    for(j = 0; j< nfils; j++)
      tcol[j] = 0;
    /* note, this next set of nested loops could be reversed, but I think
       this might be more efficient for pipelining, ? */
    for(melem = Mlist[mesh]; melem != NULL; melem = melem->mnext)
      for(j = 0; j < nfils; j++)
	    tcol[j] += L[j][melem->filindex]*melem->sign;
    for(mesh2 = 0; mesh2 < num_mesh; mesh2++) {
      tempsum = 0;
      for(melem2 = Mlist[mesh2]; melem2 != NULL; melem2 = melem2->mnext)
	    tempsum += melem2->sign*tcol[melem2->filindex];
      Zm[mesh2][mesh].imag = tempsum;
    }
  }


You can of course analyze the code, and modify and recompile it, if you would like different matrix dumps. This is the advantage of the open source.

Best Regards,
Enrico




qmle
Go to Top of Page

Enrico

531 Posts

Posted - Jul 01 2017 :  00:23:11  Show Profile  Reply with Quote
For completeness, you get a 17x3 matrix only because you defined the end points on two segments only, so the third segment, and the filaments that are generated breaking up the segments, does not participate to the (single) loop.

Now in case you modify the source file to actually define one loop over the 'C' shaped segments, as for instance with:

* qmls

.units m

NA1s x=0.0 y=0.0 z=0.41
NA1e x=0.0 y=19.55 z=0.41
NA2s x=0.0 y=19.55 z=0.41
NA2e x=15 y=19.55 z=0.41
NA3s x=15 y=19.55 z=0.41
NA3e x=15 y=0.0 z=0.41

EA1 NA1s NA1e w=5 h=0.64 sigma=58000.0
EA2 NA2s NA2e w=5 h=0.64 sigma=58000.0
EA3 NA3s NA3e w=5 h=0.64 sigma=58000.0


.equiv NA1e NA2s
.equiv NA2e NA3s
.external NA1s NA3e
.freq fmin=100000 fmax=100000

.end


Then your M matrix becomes, correctly, 23 x 3. You have 23 filaments and one loop, and the one loop comprises all the 23 segments. Actually the M matrix reads:

1	1	1
1	2	1
1	3	1
1	4	1
1	5	1
1	6	1
1	7	1
1	8	1
1	9	1
1	10	1
1	11	1
1	12	1
1	13	1
1	14	1
1	15	1
1	16	1
1	17	1
1	18	1
1	19	1
1	20	1
1	21	1
1	22	1
1	23	1

where the first element of each row is the mesh number (only number 1 because there is a single loop); the second element is a reference to the filaments composing the loop, in order; and the third element is the sign, here always +1 as all elements are ordered in the same direction w.r.t. the loop current (you may try inverting one segment and see the sign change).

Best Regards,
Enrico
Go to Top of Page

qmle

Vietnam
5 Posts

Posted - Jul 01 2017 :  08:54:31  Show Profile  Reply with Quote
Hi Enrico,
I took your suggestions and modified the source code. I simply added the chunk of code below to the formMZmt function:
--------------------------------------------------------------------
for(i=0;i<nfils;i++){
for(j=0;j<nfils;j++)
if(i!=j){
L[i][j]=0;

}

/* this does L*(Mt)_i where (Mt)_i is a single column (row) of Mt (M) and
saves it in the temp space, tcol */
for(mesh = 0; mesh < num_mesh; mesh++) {
for(j = 0; j< nfils; j++)
tcol[j] = 0;
/* note, this next set of nested loops could be reversed, but I think
this might be more efficient for pipelining, ? */
for(melem = Mlist[mesh]; melem != NULL; melem = melem->mnext)
for(j = 0; j < nfils; j++)
tcol[j] += L[j][melem->filindex]*melem->sign;
for(mesh2 = 0; mesh2 < num_mesh; mesh2++) {
tempsum = 0;
for(melem2 = Mlist[mesh2]; melem2 != NULL; melem2 = melem2->mnext)
tempsum += melem2->sign*tcol[melem2->filindex];
Zm[mesh2][mesh].imag = tempsum;
}
}
--------------------------------------------------------------------
Then compile the whole thing again. I was able to study the impact of Mutual Inductance in my layout by using the -s lumpecompe option.
Thanks and Regards,
Quang


qmle
Go to Top of Page

qmle

Vietnam
5 Posts

Posted - Jul 03 2017 :  18:32:13  Show Profile  Reply with Quote
Hi Enrico,
I need you to confirm this before using the code below. As I see in the L matrix, the diagonal terms contain information of self-inductance elements. However, since fasthenry defines a rectangular trace by multiple filaments, some of the non-diagonal (mutual) are used to compute the self-inductance of a trace. From what I see from the L matrix:
L=
'L1 0 M M '
'0 L2 0 M '
'M 0 L3 0 '
'M M 0 L4 '
Where L1,L2,L3, L4 are square matrices. I don't want to cancel out the Mutual elements of these matrices themselves. My question is: Was FastHenry setup so that 2 consecutive traces in the L matrix (in a loop) are orthogonal (Assume there is only 90 degree turn in the layout)? This will ensure the L(i) square matrices to have zeroes at their boundary.
Thanks and Regards,
quote:
Originally posted by qmle

Hi Enrico,
I took your suggestions and modified the source code. I simply added the chunk of code below to the formMZmt function:
--------------------------------------------------------------------
for(i=0;i<nfils;i++){
for(j=0;j<nfils;j++)
if(i!=j){
L[i][j]=0;

}

/* this does L*(Mt)_i where (Mt)_i is a single column (row) of Mt (M) and
saves it in the temp space, tcol */
for(mesh = 0; mesh < num_mesh; mesh++) {
for(j = 0; j< nfils; j++)
tcol[j] = 0;
/* note, this next set of nested loops could be reversed, but I think
this might be more efficient for pipelining, ? */
for(melem = Mlist[mesh]; melem != NULL; melem = melem->mnext)
for(j = 0; j < nfils; j++)
tcol[j] += L[j][melem->filindex]*melem->sign;
for(mesh2 = 0; mesh2 < num_mesh; mesh2++) {
tempsum = 0;
for(melem2 = Mlist[mesh2]; melem2 != NULL; melem2 = melem2->mnext)
tempsum += melem2->sign*tcol[melem2->filindex];
Zm[mesh2][mesh].imag = tempsum;
}
}
--------------------------------------------------------------------
Then compile the whole thing again. I was able to study the impact of Mutual Inductance in my layout by using the -s lumpecompe option.
Thanks and Regards,
Quang


qmle



qmle

Edited by - qmle on Jul 03 2017 18:39:32
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
FastFieldSolvers Forum © 2020 FastFieldSolvers S.R.L. Go To Top Of Page
Powered By: Snitz Forums 2000 Version 3.4.06