Advertisement
Guest User

Untitled

a guest
Nov 10th, 2014
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 6.37 KB | None | 0 0
  1. import std.stdio, std.math,std.complex, std.conv,std.parallelism,std.algorithm,std.range;
  2.  
  3. alias Creal = Complex!real;
  4.  
  5. ///fysical constants in our problem
  6. immutable static real sigma=56_000_000.0;
  7. immutable static real vacPermOver2Pi=2*0.000_000_1; //permeability = 4*pi*10^-7
  8. immutable static real copperRelPerm= 0.999994;
  9.  
  10. ///the configuration of our problem. Changing this implies recalculating L
  11. immutable static real width=0.002;
  12. immutable static real height=0.002;
  13. immutable static real distance=0.001;
  14.  
  15. ///a magical number that analytically cancels out but can potentially boost precision by eliminating small numbers
  16. immutable static real compensator=1.0;
  17.  
  18. ///the function we have to integrate
  19. real analyticalresult(real x1,real x2,real a){
  20.     a=(a==0)?0.0000000000001:a;//cheap trick to avoid numerical problems
  21.     return 1.0/4*(3*x1*x1 - 6*x1*x2 + x2*x2 - 4*a*(x1-x2)*atan((x1-x2)/a) + (a*a - (x1-x2)*(x1-x2))*log(a*a+(x1-x2)*(x1-x2)));
  22. }
  23.  
  24. void main()
  25. {  
  26.     writeln("generating L things");
  27.     Grid problemGrid=simpleGrid(3,3,width,height,distance);
  28.     auto N = problemGrid.length;
  29.     auto L = generateLmatrix(problemGrid);
  30.    
  31.    
  32.     foreach(freq;[100,1_000_000,10_000_000,100_000_000,1_000_000_000,10_000_000_000,100_000_000_000]){
  33.         writeln("generating data for freq = ",freq);
  34.        
  35.         auto omega = 2*PI*freq.to!real();
  36.        
  37.         auto coefMatrix = new Creal[][](N+1,N+1);
  38.         coefMatrix[N][N]=Creal(0.0,0.0);
  39.        
  40.         for(int row=0;row<N;row++)
  41.             for(int col=0;col<N;col++)
  42.                 coefMatrix[row][col]=Creal(0.0,-omega*vacPermOver2Pi*L[row][col]);
  43.        
  44.         for(int i=0;i<N;i++){
  45.             coefMatrix[i][i]+=Creal(problemGrid[i].area()*compensator/sigma); //diagonal
  46.             coefMatrix[N][i]=Creal(1.0*problemGrid[i].area()*compensator); //lowest row
  47.             coefMatrix[i][N]=Creal(-100.0*problemGrid[i].area()*compensator); //furthest right col
  48.         }
  49.        
  50.         auto inv=computeInverse(coefMatrix);
  51.  
  52.         Creal[] currents;
  53.         for(int i=0;i<N;i++)
  54.             currents~=inv[i][N]*100.0*compensator;//*problemGrid[i].area();
  55.         //saveCurrentVisualization(problemGrid,currents,freq.to!string()); //not in slimem
  56.        
  57.         auto concoction = inv[N][N]*100.0*compensator; //this is R+jwL
  58.         writeln("R : ",concoction.re * 1_000," miliohm/meter");
  59.         writeln("L : ",concoction.im/omega*1_000_000_000, " nanohenri/meter");
  60.        
  61.         writeln();
  62.        
  63.     }
  64.    
  65.     writeln("press enter you twat");
  66.     stdin.readln();
  67. }
  68.  
  69. real[][] generateLmatrix(const ref Grid problemGrid){
  70.     auto N = problemGrid.length;
  71.    
  72.     real[][] L = new real[][](N,N);
  73.    
  74.     foreach(row/*index*/,ref real[] currow;taskPool.parallel(L)){  
  75.         PointTuple p1=problemGrid[row];
  76.         foreach(ind,ref curcel;currow){
  77.             PointTuple p2=problemGrid[ind];
  78.             //readability is only useful if you plan  to read it
  79.             curcel=integrate2d( (y1,y2) => compensator*(analyticalresult(p1.endx,p2.endx,abs(y1-y2)) - analyticalresult(p1.endx,p2.startx,abs(y1-y2)) -analyticalresult(p1.startx,p2.endx,abs(y1-y2)) + analyticalresult(p1.startx,p2.startx,abs(y1-y2))
  80.                                                             -1*(analyticalresult(p1.endx,p2.endx,abs(y1+y2)) - analyticalresult(p1.endx,p2.startx,abs(y1+y2)) -analyticalresult(p1.startx,p2.endx,abs(y1+y2)) + analyticalresult(p1.startx,p2.startx,abs(y1+y2))))
  81.                         , p1.starty, p1.endy, p2.starty, p2.endy);
  82.             writeln("(",row,",",ind,") : ",curcel);
  83.         }
  84.     }
  85.     return L;
  86. }
  87.  
  88. ///calculates the L21 norm of the given matrix abs(T element) has to be defined
  89. real getNorm(T)(T[][] mat){
  90.     real retval=0.0;
  91.     for(int col=0;col<mat.length;col++){
  92.         real rowThing=0.0;
  93.         for(int row=0;row<mat.length;row++){
  94.             rowThing+=abs(mat[row][col])*abs(mat[row][col]);
  95.         }
  96.         retval+=sqrt(rowThing);
  97.     }
  98.     return retval;
  99. }
  100.  
  101. ///using partial pivoting
  102. ///Todo : templatize? (not that trivial)
  103. Creal [][] computeInverse(Creal [][] mat){
  104.     auto inverse=new Creal [][] (mat.length,mat.length);
  105.     for(int i=0;i<mat.length;i++)
  106.         for(int j=0;j<mat.length;j++)
  107.             inverse[i][j]=(i==j)?Creal(1.0):Creal(0.0);
  108.    
  109.     for(int i=0;i<mat.length;i++){
  110.         //search the biggest spiel
  111.         auto newSpiel=Creal(0.0);
  112.         auto newSpielIndex=0;
  113.         for(int iterator=i;iterator<mat.length;iterator++){
  114.             if(abs(mat[iterator][i])>abs(newSpiel)){
  115.                 newSpiel=mat[iterator][i];
  116.                 newSpielIndex=iterator;
  117.             }
  118.         }
  119.        
  120.         if(abs(newSpiel)==0.0) // should be 'almost zero'
  121.             throw new Exception("you dun goofed up");
  122.        
  123.         //rotate our biggest spiel-row to the right place
  124.         for(int col=0;col<mat.length;col++){
  125.             auto matDup=mat[newSpielIndex][col];
  126.             auto invDup=inverse[newSpielIndex][col];
  127.            
  128.             mat[newSpielIndex][col]=mat[i][col];
  129.             inverse[newSpielIndex][col]=inverse[i][col];
  130.            
  131.             mat[i][col]=matDup;
  132.             inverse[i][col]=invDup;
  133.         }
  134.        
  135.         auto multfact=Creal(1.0)/newSpiel;
  136.         for(int col=0;col<mat.length;col++){//make diag element 1
  137.             mat[i][col]*=multfact;
  138.             inverse[i][col]*=multfact;
  139.         }
  140.         for(int row=0;row<mat.length;row++){//make elements at col i zero above our spiel
  141.             if(row==i)
  142.                 continue;
  143.             multfact=mat[row][i];
  144.             for(int col=0;col<mat.length;col++){
  145.                 mat[row][col]-=multfact*mat[i][col];
  146.                 inverse[row][col]-=multfact*inverse[i][col];
  147.             }
  148.         }
  149.    
  150.     }
  151.     return inverse;
  152. }
  153.  
  154. ///verry naive implementation of an integration algorithm (riemann sums)
  155. real integrate2d(in real delegate(real,real) fun,in real x1,in real x2,in real y1,in real y2,in int numpieces=100 /*actually the numpieces is this squared*/){
  156.     assert(x1<x2);
  157.     assert(y1<y2);
  158.    
  159.     real xSegmentLength=(x2-x1)/numpieces;
  160.     real ySegmentLength=(y2-y1)/numpieces;
  161.    
  162.     real retval=0.0;
  163.     for(int i=0;i<numpieces*numpieces;i++)
  164.         retval+=fun(x1 + (i%numpieces)*xSegmentLength + xSegmentLength/2,y1 + (i/numpieces)*ySegmentLength + ySegmentLength/2);
  165.    
  166.     return retval* xSegmentLength*ySegmentLength; //by only multiplying by the area(<<1) at the end we can potentially save a little precision
  167. }
  168.  
  169. struct PointTuple{
  170.     real startx;
  171.     real starty;
  172.     real endx;
  173.     real endy;
  174.     real area (){return (endy-starty)*(endx-startx);}
  175. }
  176.  
  177. ///by abstracting everything away, we can create really exotic grids
  178. alias PointTuple[] Grid;
  179.  
  180. Grid simpleGrid(in uint widthPieces,in uint heightPieces,in real width,in real height,in real distance){
  181.     Grid retval;
  182.     for(int number=0;number<widthPieces*heightPieces;number++){
  183.         PointTuple toret= PointTuple(width/widthPieces*(number/heightPieces),height/heightPieces*(number%heightPieces)+distance);
  184.         toret.endx=toret.startx+width/widthPieces;
  185.         toret.endy=toret.starty+height/heightPieces;
  186.         retval~=toret;
  187.     }
  188.     return retval;
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement