#include #include #include #include "belasolv.h" #include "belasolvDlg.h" #include "mesh.h" #include "spars.h" #include "FemmeDocCore.h" //conversion to internal working units of mm double units[]={25.4,1.,10.,1000.,0.0254,0.001}; double sq(double x){ return x*x; } BOOL CFemmeDocCore::AnalyzeProblem(CBigLinProb &L) { int i,j,k,pctr=0; double Me[3][3],be[3]; // element matrices; double l[3],p[3],q[3]; // element shape parameters; int n[3],ne[3]; // numbers of nodes for a particular element; double a,K,r,z,kludge; CElement *El; double c = (1.e-6)/eo; Depth*=units[LengthUnits]; extRo*=units[LengthUnits]; extRi*=units[LengthUnits]; extZo*=units[LengthUnits]; kludge=1; TheView->SetDlgItemText(IDC_FRAME1,"Matrix Construction"); // do some book-keeping related to fixed boundary conditions; // The P vector denotes which nodes have an assigned value // The V vector denotes the assigned value for(i=0;i=0) if(nodeproplist[meshnode[i].bc].qp==0) { L.V[i]=nodeproplist[meshnode[i].bc].V; L.Q[i]=-1; } if(meshnode[i].InConductor>=0) if(circproplist[meshnode[i].InConductor].CircType==1) { L.V[i]=circproplist[meshnode[i].InConductor].V; L.Q[i]=meshnode[i].InConductor; } } // account for fixed boundary conditions along segments; for(i=0;i=0) { if(lineproplist[ meshele[i].e[j] ].BdryFormat==0) { L.V[meshele[i].p[j]]=lineproplist[meshele[i].e[j]].V; L.V[meshele[i].p[k]]=lineproplist[meshele[i].e[j]].V; L.Q[meshele[i].p[j]]=-1; L.Q[meshele[i].p[k]]=-1; } } } } // build element matrices using the matrices derived in Allaire's book. for(i=0;im_prog1.SetPos(pctr); } // zero out Me, be; for(j=0;j<3;j++){ for(k=0;k<3;k++) Me[j][k]=0; be[j]=0; } // Determine shape parameters. // l's are element side lengths; // p's corresponds to the `b' parameter in Allaire // q's corresponds to the `c' parameter in Allaire El=&meshele[i]; for(k=0;k<3;k++) n[k]=El->p[k]; p[0]=meshnode[n[1]].y - meshnode[n[2]].y; p[1]=meshnode[n[2]].y - meshnode[n[0]].y; p[2]=meshnode[n[0]].y - meshnode[n[1]].y; q[0]=meshnode[n[2]].x - meshnode[n[1]].x; q[1]=meshnode[n[0]].x - meshnode[n[2]].x; q[2]=meshnode[n[1]].x - meshnode[n[0]].x; for(j=0,k=1;j<3;k++,j++){ if (k==3) k=0; l[j]=sqrt( sq(meshnode[n[k]].x-meshnode[n[j]].x) + sq(meshnode[n[k]].y-meshnode[n[j]].y) ); } a=(p[0]*q[1]-p[1]*q[0])/2.; r=(meshnode[n[0]].x+meshnode[n[1]].x+meshnode[n[2]].x)/3.; if (ProblemType==AXISYMMETRIC){ Depth=2.*PI*r; // "Warp" the permeability of this element is part of // the conformally mapped external region if(labellist[meshele[i].lbl].IsExternal) { z=(meshnode[n[0]].y+meshnode[n[1]].y+meshnode[n[2]].y)/3. - extZo; kludge=(r*r+z*z)/(extRi*extRo); } else kludge=1; } // x-contribution; K = -Depth*blockproplist[El->blk].ex/(4.*a)/kludge; for(j=0;j<3;j++) for(k=j;k<3;k++) { Me[j][k] += K*p[j]*p[k]; if (j!=k) Me[k][j]+=K*p[j]*p[k]; } // y-contribution; K = -Depth*blockproplist[El->blk].ey/(4.*a)/kludge; for(j=0;j<3;j++) for(k=j;k<3;k++) { Me[j][k] +=K*q[j]*q[k]; if (j!=k) Me[k][j]+=K*q[j]*q[k]; } // contribution to be[] from volume charge density for(j = 0;j<3;j++){ K = -Depth*c*(blockproplist[El->blk].qv)*a/3.; be[j]+=K; } for(j=0;j<3;j++) { if (El->e[j] >= 0) { k=j+1; if(k==3) k=0; if (ProblemType==AXISYMMETRIC) Depth=PI*(meshnode[n[j]].x + meshnode[n[k]].x); // contributions to Me, be from derivative boundary conditions; if (lineproplist[El->e[j]].BdryFormat==1) { K =-1000.*Depth*c*lineproplist[El->e[j]].c0*l[j]/6.; Me[j][j]+=K*2.; Me[k][k]+=K*2.; Me[j][k]+=K; Me[k][j]+=K; K = 1000.*Depth*c*lineproplist[El->e[j]].c1*l[j]/2.; be[j]+=K; be[k]+=K; } // contribution to be[] from surface charge density; if (lineproplist[El->e[j]].BdryFormat==2) { K =-1000.*Depth*c*lineproplist[El->e[j]].qs*l[j]/2.; be[j]+=K; be[k]+=K; } } } // process any prescribed nodal values; for(j=0;j<3;j++) { if(L.Q[n[j]]!=-2) { for(k=0;k<3;k++) { if(j!=k){ be[k]-=Me[k][j]*L.V[n[j]]; Me[k][j]=0; Me[j][k]=0; } } be[j]=L.V[n[j]]*Me[j][j]; } } // combine block matrices into global matrices; for (j=0;j<3;j++) { ne[j]=n[j]; if(meshnode[n[j]].InConductor>=0) if(circproplist[meshnode[n[j]].InConductor].CircType==0) ne[j]=meshnode[n[j]].InConductor+NumNodes; } for (j=0;j<3;j++){ for (k=j;k<3;k++) L.Put(L.Get(ne[j],ne[k])-Me[j][k],ne[j],ne[k]); L.b[ne[j]]-=be[j]; if(ne[j]!=n[j]) { L.Put(L.Get(n[j],n[j])-Me[j][j],n[j],n[j]); L.Put(L.Get(n[j],ne[j])+Me[j][j],n[j],ne[j]); } } } // end of loop that builds element matrices // add in contribution from point charge density; for(i=0;i=0) && (L.Q[i]==-2)) { if (ProblemType==AXISYMMETRIC) Depth=2.*PI*meshnode[i].x; L.b[i]+=((1.e6)*Depth*c*nodeproplist[meshnode[i].bc].qp); L.Q[i]=-1; } // some bookkeeping to denote which nodes we can smooth over if(meshnode[i].InConductor>=0) L.Q[i]=meshnode[i].InConductor; } // Apply any periodicity/antiperiodicity boundary conditions that we have for(k=0,pctr=0;k