📄 sparsem_anslysis.cpp
字号:
#include"stdafx.h"
#include"Analysis.h"
#include"Sparsem.h"
#include ".\analysis.h"
CSparseMatrix znmna_list; //声明一个稀疏矩阵类对象
void Analysis::GetVBrNum()
{
int i,j,k,t,tt;
bNUM_vbNUM=new int[BranchNumber+1];
vBranchNumber=0;
for(i=1;i<BranchNumber+1;i++) bNUM_vbNUM[i]=0;//初始化
for(i=1;i<BranchNumber+1;i++)
{
t=Branch[i].type;
if(t==VS||t==VCVS||t==OPAMP)//必然的电压定义之路
{
vBranchNumber++;
bNUM_vbNUM[i]=vBranchNumber;
}
else if(t==CCVS)
{
vBranchNumber++;//本身为电压定义支路
bNUM_vbNUM[i]=vBranchNumber;
k=Branch[i].ncfrom;
tt=Branch[k].type;
if((tt==G||tt==R)&&Branch[k].ncfrom==0&&Branch[k].ncto==0)
{
vBranchNumber++;//控制之路也为电压定义支路
bNUM_vbNUM[k]=vBranchNumber;
Branch[k].ncto=1;//做一个标记
}
}
else if(t==CCCS){
k=Branch[i].ncfrom;
tt=Branch[k].type;
if((tt==G||tt==R)&&Branch[k].ncfrom==0&&Branch[k].ncto==0)
{
vBranchNumber++;//控制之路作为电压定义支路
bNUM_vbNUM[k]=vBranchNumber;
Branch[k].ncto=1;
}
}
else if((t==G||t==R)&&Branch[i].ncfrom==1)
{ //指定为电压定义支路
vBranchNumber++;
bNUM_vbNUM[i]=vBranchNumber;
}
}
vbNUM_bNUM=new int[vBranchNumber+1];
for (i=1;i<BranchNumber+1;i++)//电压定义支路到支路的映射
{
j=bNUM_vbNUM[i];
vbNUM_bNUM[j]=i;
}
}
/********************************************************/
void Analysis::Fromlist_symlu()
{
znmna_list.newList(RANK,NONZERO,1);//秩为100,稀疏度为0.3 ,全主元排序
znmna_list.setRankList(NodeNumber+vBranchNumber);//置list的阶数
int k,kk,nb,t,nf,nt,ncf,nct;
nb=NodeNumber+vBranchNumber+1;
for(int i=1;i<BranchNumber+1;i++)
{
br=Branch+i;
t=br->type;
nf=br->nfrom;
nt=br->nto;
ncf=br->ncfrom;
nct=br->ncto;
if(t==R)
{
if(ncf==0&&nct==0)//非电压定义支路
{
if(nf==0) znmna_list.insertListEle(nt,nt);
else if(nt==0)znmna_list.insertListEle(nf,nf);
else{
znmna_list.insertListEle(nf,nf);
znmna_list.insertListEle(nt,nt);
znmna_list.insertListEle(nf,nt);
znmna_list.insertListEle(nt,nf);//对Y的贡献
}
}
else
{
k=br->number;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertListEle(nf,k);//
znmna_list.insertListEle(nt,k);//对B的贡献,即对节电电流的贡献
znmna_list.insertListEle(k,nf);/////对C的贡献
znmna_list.insertListEle(k,nt);///// 为支路特性
znmna_list.insertListEle(k,k);//////对D的贡献
}
}
else if(t==G)
{
if(ncf==0&&nct==0)
{
if(nf==0) znmna_list.insertListEle(nt,nt);
else if(nt==0) znmna_list.insertListEle(nf,nf);
else{
znmna_list.insertListEle(nf,nf);
znmna_list.insertListEle(nt,nt);
znmna_list.insertListEle(nt,nf);///////对Y的贡献
znmna_list.insertListEle(nf,nt);
}
}
else{
k=br->number;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertListEle(nf,k);//
znmna_list.insertListEle(nt,k);//对B的贡献
znmna_list.insertListEle(k,nf);///对C的贡献
znmna_list.insertListEle(k,nt);///
znmna_list.insertListEle(k,k);//////对D的贡献
}
}
else if(t==VCCS) //电压控制电流源支路
{
znmna_list.insertListEle(nf,ncf);// 修正,书上有误
znmna_list.insertListEle(nf,nct);
znmna_list.insertListEle(nt,ncf);
znmna_list.insertListEle(nt,nct);
}
else if(t==CCCS) //电流控制电流源支路
{
k=ncf;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertListEle(nf,k);
znmna_list.insertListEle(nt,k);
}
else if(t==VCVS)
{
k=br->number;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertListEle(nf,k);
znmna_list.insertListEle(nt,k);
znmna_list.insertListEle(k,nf);
znmna_list.insertListEle(k,nt);
znmna_list.insertListEle(k,ncf);
znmna_list.insertListEle(k,nct);
}
else if(t==CCVS)
{
kk=ncf; //修正
kk=bNUM_vbNUM[kk];
kk+=NodeNumber;
k=br->number;
k=bNUM_vbNUM[k];
k+=NodeNumber;
znmna_list.insertListEle(nf,k);
znmna_list.insertListEle(nt,k);
znmna_list.insertListEle(k,nf);
znmna_list.insertListEle(k,nt);
znmna_list.insertListEle(k,kk);
}
else if(t==OPAMP)
{
k=br->number;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertListEle(nf,k);
znmna_list.insertListEle(nt,k);
znmna_list.insertListEle(k,ncf);
znmna_list.insertListEle(k,nct);
}
else if(t==VS)
{
k=br->number;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertListEle(nf,k);
znmna_list.insertListEle(nt,k);
znmna_list.insertListEle(k,nf);
znmna_list.insertListEle(k,nt);
}
}
znmna_list.covListTab();
//先优化排序,在转化成三角形表,因为双链表是动态结构
//方便生成,插入,删除,和优化排序,
//然后再转化成三角形表进行LU分解
}
void Analysis::InsertB_symFE()//插入右端向量,并进行符号前消
{
for(int i=1;i<BranchNumber+1;i++)
{
BRANCH* br=Branch+i;
int t=br->type;
int nf=br->nfrom;
int nt=br->nto;
if(t==CS)
{
if(nf==0)znmna_list.insertB(nt);
else if(nt==0)znmna_list.insertB(nf);
else {
znmna_list.insertB(nf);
znmna_list.insertB(nt);
}
}
else if (t==VS){
int k=br->number;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertB(k);
}
}
znmna_list.symFE();//先有端向量填元处理,再符号前消
}
void Analysis:: LoadAData_numLU()//装配数值,进行数值分解
{
int k,kk;
for(int i=1;i<BranchNumber+1;i++)
{
BRANCH* br=Branch+i;
char t=br->type;
int nf=br->nfrom;
int nt=br->nto;
int ncf=br->ncfrom;
int nct=br->ncto;
double val=br->value;
if(t==R)//电阻支路
{
if(ncf==0&&nct==0)//非电压定义支路
{
val=1.0/val;//转换成电导
if(nf==0)znmna_list.insertCoef(nt,nt,val);//始节点为0
else if(nt==0)znmna_list.insertCoef(nf,nf,val);//终节点为零
else
{
znmna_list.insertCoef(nf,nf,val);
znmna_list.insertCoef(nt,nt,val);
znmna_list.insertCoef(nf,nt,-val);
znmna_list.insertCoef(nt,nf,-val);
//对Y的导纳贡献,通过节点-节点关系来写
//其实此时看做电导,形势是一样的·
}
}
else
{ //电压定义电阻支路
k=br->number;
k=bNUM_vbNUM[k];//电压定义支路号
k=k+NodeNumber;
znmna_list.insertCoef(nf,k,1);//修正 书上为val,对B贡献,即对该节点节点电流贡献
znmna_list.insertCoef(nt,k,-1);//修正
znmna_list.insertCoef(k,nf,1.0); //
znmna_list.insertCoef(k,nt,-1.0);//这3项为支路特性 Unf-Unto-val*jk=0
znmna_list.insertCoef(k,k,-1.0*val);
}
}
else if(t==G)//电导支路
{
if(ncf==0&&nct==0)//非电压定义支路
{
if(nf==0)znmna_list.insertCoef(nt,nt,val);
else if(nt==0)znmna_list.insertCoef(nf,nf,val);
else
{
znmna_list.insertCoef(nf,nf,val);
znmna_list.insertCoef(nt,nt,val);
znmna_list.insertCoef(nf,nt,-1.0*val);
znmna_list.insertCoef(nt,nf,-1.0*val);
}
}
else//电压定义电导支路
{
k=br->number;
k=bNUM_vbNUM[k];//电压定义支路号
k=k+NodeNumber;
znmna_list.insertCoef(nf,k,1.0);
znmna_list.insertCoef(nt,k,-1.0); //导纳贡献
znmna_list.insertCoef(k,nf,1.0); //对C贡献
znmna_list.insertCoef(k,nt,-1.0);
znmna_list.insertCoef(k,k,-1.0/val); //对D贡献,注意此时支路特性为Unf-Unto-jk/G=0
}
}
else if(t==VCCS)//电压控制电流源支路
{
znmna_list.insertCoef(nf,ncf,val); //对节点nf的电流贡献用g(Uncf-Uncto) 表示
znmna_list.insertCoef(nf,nct,-1*val);
znmna_list.insertCoef(nt,ncf,-1*val);//对nto贡献,左边为流出节点的电流
znmna_list.insertCoef(nt,nct,val);
}
else if(t==CCCS)//电流控制电流源支路
{
k=ncf;
k=bNUM_vbNUM[k];//控制支路号
k=k+NodeNumber;//电压定义支路号
znmna_list.insertCoef(nf,k,val); ///对B的贡献,流出nf的电流a*jk
znmna_list.insertCoef(nt,k,-1.0*val); //流出nto的电流为-a*jk
}
else if(t==VCVS)//电压控制电压源支路
{
k=br->number;//支路号
k=bNUM_vbNUM[k];//电压定义支路号
k=k+NodeNumber;
znmna_list.insertCoef(nf,k,1.0); //
znmna_list.insertCoef(nt,k,-1.0);// 对B的贡献,即电压定义支路对节点的电流贡献
znmna_list.insertCoef(k,nf,1.0);
znmna_list.insertCoef(k,nt,-1.0);
znmna_list.insertCoef(k,ncf,-1.0*val);
znmna_list.insertCoef(k,nct,val);// 以上四个为支路特性,即Unf-Unto-(Uncf-Uncto)=0
}
else if(t==CCVS)//电流控制电压源支路
{
kk=ncf;//控制支路号
kk=bNUM_vbNUM[kk];
kk=kk+NodeNumber;
k=br->number;//支路号
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertCoef(nf,k,1.0);//对节点电流的贡献
znmna_list.insertCoef(nt,k,-1.0);//
znmna_list.insertCoef(k,nf,1.0);// 支路特性Unf_Unto-rm*jk=0
znmna_list.insertCoef(k,nt,-1.0);//对C的贡献
znmna_list.insertCoef(k,kk,-1.0*val);//对D的贡献
}
else if(t==OPAMP)//理想运算放大器,因为虚断,没有电流贡献多一看作一条电压定义支路
{
k=br->number;//支路号
k=bNUM_vbNUM[k];//电压定义支路号
k=k+NodeNumber;
znmna_list.insertCoef(nf,k,1.0);//
znmna_list.insertCoef(nt,k,-1.0);//对Y的贡献,
znmna_list.insertCoef(k,ncf,1.0);// 输入口支路特性即虚短,Ui-Uj=0;
znmna_list.insertCoef(k,nct,-1.0);
}
else if(t==VS)//独立电压源
{
k=br->number;//支路号
k=bNUM_vbNUM[k];//电压定义支路号
k=k+NodeNumber;
znmna_list.insertCoef(nf,k,1.0); //对节点电流的贡献即Y
znmna_list.insertCoef(nt,k,-1.0); //
znmna_list.insertCoef(k,nf,1.0); //Unf-Unto=0
znmna_list.insertCoef(k,nt,-1.0); // 支路特性,C
}
}
znmna_list.numLU();
}
void Analysis:: LoadBData_BS()
{
int i,t,nf,nt,ncf,nct,k;
double val;//装配右端向量数值
for(i=1;i<BranchNumber+1;i++)
{
BRANCH*br=Branch+i;
t=br->type;
nf=br->nfrom;
nt=br->nto;
ncf=br->ncfrom;
nct=br->ncto;
val=br->value;
if(t==CS)
{
znmna_list.insertBVal( nf,-1*val);//修正
znmna_list.insertBVal(nt,val);///因为右边是流入节点的独立电流源的和
//而我们规定电流源的方向为nf->nto
}
else if(t==VS)
{
k=br->number;
k=bNUM_vbNUM[k];
k=k+NodeNumber;
znmna_list.insertBVal(k,val); //第k条电压定义支路
}
}
znmna_list. makeSolution();// 数值前消、后代,获得Tab中的解
CString Total;
CString outmsg;
double m_out;
for( i=1;i<NodeNumber+vBranchNumber+1;i++)
{
m_out=znmna_list.getX(i);
if(i<NodeNumber+1)
outmsg.Format("u[%d]=%4.4f\n",i,m_out);
else {
int v=vbNUM_bNUM[i-NodeNumber];
outmsg.Format("vBranchNumber=%d; I[%d]=%4.8f\n",v,i-NodeNumber, (double) m_out);
}
Total=Total+outmsg;
}
AfxMessageBox(Total,MB_OK|MB_ICONINFORMATION);
znmna_list.deleteList();
znmna_list.delete_tableT();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -