首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实际电容的模拟计算

实际电容的模拟计算
EN

Code Review用户
提问于 2023-03-04 16:09:05
回答 1查看 92关注 0票数 2

目的是在二维环境下模拟一个真正的平板电容器。电枢的电位固定在+V和-V上,在模拟单元的边缘电位为零。在电容器板之间放置介质材料。通过数值确定板上的电荷和积分电场的流动,计算了电容。结果与不考虑边缘效应的公式进行了比较。

我正在寻找使它更高效的方法,以及如何使用一些功能,因为我不认为它看起来很清楚。

代码语言:javascript
复制
#include 
#include 
#include 
#include 

using namespace std;

int main(int argc, const char * argv[])
{
    double Lx,Ly;//lunghezze lati cella di simulazione
    int Nx,Ny;//numero punti lungo x e y
    double Px,Py;//posizione rispetto all'origine del vertice della prima piastra
    double Zx,Zy;//posizione rispetto all'angolo del bordo a destra del vertice della seconda piastra
    double Lc;//spessore della piastra
    double Hc;//altezza piastra
    int    dist_type;//tipo di distribuzione di carica: 1-uniforme
    double thrs;//valore soglia per convergenza
    double V;
    double Nstampa;

    int   iCount;
    int   phi_bordo=0.;//funzione phi sul bordo
    double hx,hy;
    double diff=1e10;

    ofstream fphi,fcharge, ffield;


    cout.precision(10);
    cout << "Lato cella lungo x\n";
    cin >>  Lx;
    cout << "Lato cella lungo y\n";
    cin >>  Ly;
    cout << "Numero punti lungo x\n";
    cin >>  Nx;
    cout << "Numero punti lungo y\n";
    cin >>  Ny;
    cout << "Vertice piastra 1 in x\n";
    cin >>  Px;
    cout << "Vertice piastra 2 in y\n";
    cin >>  Py;
    cout << "Vertice piastra 1 in x\n";
    cin >>  Zx;
    Zx = Lx - Zx;
    cout << "Vertice piastra 2 in y\n";
    cin >>  Zy;
    cout << "Spessore piastra \n";
    cin >>  Lc;
    cout << "Altezza piastra \n";
    cin >>  Hc;
    cout << "Potenziale piastre (in Volt) \n";
    cin >>  V;
    cout << "Soglia per convergenza \n";
    cin >>  thrs;

    double* phi0= new double[Nx*Ny];//funzione da trovare
    double* phi1= new double[Nx*Ny];//funzione da trovare
    double* phi2= new double[Nx*Ny];//funzione da trovare
    double* ftilde=new double[Nx*Ny];//distribuzione di carica e fattori bordo
    double* mphi= new double[Nx*Ny];

    hx=Lx/(Nx-1.);
    hy=Ly/(Ny-1.);


    iCount=0; //iCount corrisponde all'indice l delle dispense l = j*Nx + i con i,j indici rispettivamente di xi e yj
              //infatti stiamo calcolando ftilde che è l'array indicizzato con l
    for(int j=0;j=Px && x<=(Px+Lc) && y>=Py && y<=(Py+Hc)) {
                ftilde[iCount]=V;
            }
            else if(x>=Zx && x<=(Zx+Lc) && y>=Zy && y<=(Zy+Hc)){
              ftilde[iCount]=-V;
            }
            else{
                ftilde[iCount]=0.;
            }
            //potenziale sul bordo della cella
            if(i==0 || i==(Nx-1) || j==0 || j==(Ny-1)){
                ftilde[iCount]+=phi_bordo;
            }
            iCount++;

        }
    }

    //metti phi0 in condizioni iniziali quindi pari a 0
    for(int i=0;ithrs){
         for(int i=0;i0){
                         jCount=j*Nx+(i-1); // m = l-1
                         mphi[iCount]+=-phi0[jCount]/pow(hx,2)/div;
                     }
                     if(i0){
                         jCount=(j-1)*Nx+i;// m = l - Nx
                         mphi[iCount]+=-phi0[jCount]/pow(hy,2)/div;
                     }
                     if(j
EN

回答 1

Code Review用户

发布于 2023-03-05 14:23:27

关于混合语言的

我看你的程序是为意大利用户准备的。但是开发人员说的是什么语言呢?注释也都是意大利语,但是变量的名称是意大利语(例如,NstampaFlusso1)和英语(dist_typeiCount)的混合。

在使用哪种语言时要保持一致。当然,C++语言的关键字以及标准库中的函数和类型的名称都是英语,这一点也没有帮助。所以我建议你用英语写你所有的代码。如果您希望只有意大利开发人员在这个项目上工作,那么在注释中使用意大利语是可以的。当然,写到std::cout的文本应该是用户所期望的语言,所以如果这是意大利语的话,那也没关系。

避免短变量名

短变量名可以节省一些输入量,但很难准确地说明它们的含义。如果我看到代码中使用了Lx,我不确定L是否代表长度,但是即使我知道,长度是多少?电容器本身的长度?还是其中的一个细胞?一个更好的变量名是cell_size_x

为什么有三个数组-- phi0phi1phi2phi到底是什么意思?通量?阶段?角度?声明中的评论根本没有提到这一点。

如果您使用的是一本书或一篇文章中的一些公式,并且希望在代码中使用与它们在这些公式中使用的符号相同的符号,这是保持变量名简短的一个有效理由,但在这种情况下,您必须在代码中添加到图书或纸张的链接。

集团相关信息汇集在structs

我看到您创建了5个数组,保存了模拟中每个单元格的信息。考虑创建一个保存有关单个单元格的所有信息的struct,然后只需创建一个数组:

代码语言:javascript
复制
struct Cell {
    double phi0;
    double phi1;
    double phi2;
    double ftilde;
    double mphi;
};

Cell* cells = new Cell[Nx * Ny];
…
for (int i = 0; i < Nx * Ny; i++) {
    cells[i].phi1 = cells[i].ftilde;
    cells[i].phi0 = cells[i].ftilde;
    cells[i].phi2 = 0;
}

你也有几个二维矢量。为此创建一个struct也很有帮助。例如:

代码语言:javascript
复制
struct Vec2 {
    double x;
    double y;
};

Vec2 cell_size; // replaces Lx and Ly

如果添加运算符重载,它们就会变得更有用,因此您可以像使用常规的ints和doubles那样对它们进行计算。但是,自己创建这个库可能需要很多工作,所以我建议您选择一个为您实现向量类型的库,例如GLM,但也有许多其他人

避免手动分配内存

而不是用new分配数组,而必须记住要使用delete,而是使用std::vector。内存泄漏,因为您注释掉了EmatED34语句。

使用std::vector还有其他好处:您可以在某些地方使用range-for语句。考虑:

代码语言:javascript
复制
struct Cell {…};

std::vector cells(Nx * Ny);
…
for (auto& cell: cells) {
    cell.phi1 = cell.ftilde;
    cell.phi0 = cell.ftilde;
    cell.phi2 = 0;
}

给常量命名为

我看到8.8541878e-12在您的代码中多次使用的数字。与其每次写出来,不如为它定义一个常量,例如:

代码语言:javascript
复制
constexpr double e0 = 8.854187812813e-12; // Vacuum permitivity in Farads/meter

请注意,e0类似于这个常量通常使用的数学表示法\epsilon_0,如果不熟悉它的人正在阅读代码,注释将对其进行更详细的解释。

将代码拆分为多个函数

您已经注意到代码看起来不太好,并且可以从函数中受益。一种很好的开始方法是将main()重写成描述您需要在很高级别上做的事情的东西。例如,程序中有以下步骤:

  • 读取参数
  • 初始化数据
  • 运行模拟
  • 处理结果
  • 将结果写入磁盘

您可以这样编写您的main()

代码语言:javascript
复制
struct State {
    // All the variables needed to run the simulation
    …
}

static void read_parameters(State& state) {
    cout << "Lato cella lungo x\n";
    cin >> state.Lx;
    …
}

static void initialize_state(State& state) {
    …
    state.cells.resize(state.Nx * state.Ny);
    …
    for (auto& cell: state.cells) {
        cell.phi1 = cell.ftilde;
        cell.phi0 = cell.ftilde;
        cell.phi2 = 0;
    }
    …
}

static void run_simulation(State& state) {
    …
}

static void process_results(State& state) {
    …
}

static void write_results(State &state) {
    std::ofstream fcharge("carica.dat");
    std::ofstream fphi("phi.dat");
    std::ofstream ffield("campo.dat");
    …
}

int main() {
    State state;
    read_parameters(state);
    initialize_state(state);
    run_simulation(state);
    process_results(state);
    write_results(state);
}

一些新功能也会非常大,您可以进一步将它们分开。一个好的经验法则是函数不应该大于一个屏幕。此外,在示例中,程序中使用的所有状态都在struct State中,并传递给每个函数。然而,并不是每个函数都需要访问所有的东西,所以struct State可能会被分成多个structs,因此限制了每个函数可以获得哪些信息。您可能需要迭代这个过程几次才能达到这样一种情况:您有许多小的、简洁的函数和类型,这些函数和类型共同构成了一个内聚程序。

创建函数和structs的另一个好处是,它们的名字将描述它们所做的事情。这有助于记录代码,减少添加注释的需要。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/283725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档