Parallel processing mpirun模式下的PETSC时间步进

Parallel processing mpirun模式下的PETSC时间步进,parallel-processing,mpi,numerical-methods,finite-element-analysis,petsc,Parallel Processing,Mpi,Numerical Methods,Finite Element Analysis,Petsc,亲爱的各位, 我是学习PETSC的新生。我基于PETSC库编写了一个非常简单的一维扩散问题代码(只是简单的FDM代码)。我想在每个时间步中使用PETSC的并行解算器。以下是伪代码: Initial(C0); for(timestep=0;timestep<MaxTimeStep;timestep++) { Assemble(A,C,F); // Assemble system's A*C=F matrix and vector KSP.solve(A,C,F); // U

亲爱的各位, 我是学习PETSC的新生。我基于PETSC库编写了一个非常简单的一维扩散问题代码(只是简单的FDM代码)。我想在每个时间步中使用PETSC的并行解算器。以下是伪代码:

Initial(C0);
for(timestep=0;timestep<MaxTimeStep;timestep++)
{
    Assemble(A,C,F);  // Assemble system's A*C=F matrix and vector
    KSP.solve(A,C,F); // Use PETSC's ksp solver to solve A*C=F
                      // I just want to make the solve step paralleled
                      // other part don't need to be paralleled
    C0=C;             // Update
    SaveResult(C0);   // Output the result C0
}

请上传一个最短的完整代码。@Shibli:嗨,谢谢你的回复。我在问题中添加了我的代码。对不起,实际上不需要最小的代码,我的错。对于此类问题,使用PETSC的时间步进器。下面是一维扩散问题的示例。如果您在任何时候遇到困难,请告诉我,以便我们可以在聊天中解决问题。关于你的两个问题,阿福,不,你不能。嗨,Shibli,谢谢你的回答。我知道TS功能,TS时间步。让我困惑的是,如果在我的代码的另一个地方的TS timestepper之外还有一些其他循环(例如网格生成,我希望它按顺序执行,而不是并行执行),是否可能?或者,在PETSc中,TS是唯一可以确保这些循环逐个执行的选择,除了所有循环代码将并行执行之外?网格生成可以通过具有条件的特定列组执行,例如
if(rank==MASTER)
。Petsc的优点之一是它能够处理并行性。因此,每当您发现自己处于上述情况时,请查看Petsc文档以找到合适的上下文。
#include "petscksp.h"

void PrintToVTU(PetscInt k,PetscReal dx,Vec u);


int main(int argc,char **args)
{
    Vec u,u0;
    Mat A;
    KSP ksp;
  PetscRandom rctx;
  PetscReal norm;
  PetscInt ne;
  PetscReal Length,dx,D;
  PetscReal Ca,Cb,alpha;
  PetscReal T,dt,ti;
  PetscInt i,j,Ii,J,Istart,Iend,m,n,its;
  PetscBool flg=PETSC_FALSE;
  PetscScalar v;

  printf("Input the Length:");
  scanf("%f",&Length);
  printf("Input the element number:");
  scanf("%d",&ne);
  printf("Input the Ca,Cb and D:");
  scanf("%f %f %f",&Ca,&Cb,&D);
  printf("Input dt and T:");
  scanf("%f %f",&dt,&T);
  n=ne+1;m=n;
  dx=Length/ne;

  alpha=dt*D/(dx*dx);

  #if defined(PETSC_USE_LOG)
   PetscLogStage stage;
  #endif

  static char help[] = "Solves a linear system in parallel with 
  KSP.\n\
  Iput parameters include:\n-random_exact_sol : use a random exact 
  solution vector\n\
 -view_exact_sol   : write exact solution vector to stdout\n\
 -m <mesh_x>       : number of mesh points in x-direction\n\
 -n <mesh_n>       : number of mesh points in y-direction\n\n";
 PetscInitialize(&argc,&args,(char*)0,help);
 PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);

 PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
 printf("m=%d\tn=%d\n",m,n);


// Create Matrix
MatCreate(PETSC_COMM_WORLD,&A);
MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m,n);
MatSetFromOptions(A);
MatMPIAIJSetPreallocation(A,5,NULL,5,NULL);
MatSeqAIJSetPreallocation(A,5,NULL);
MatSeqSBAIJSetPreallocation(A,1,5,NULL);
// Create Vector
VecCreate(PETSC_COMM_WORLD,&u0);
VecSetSizes(u0,PETSC_DECIDE,m);
VecSetFromOptions(u0);
VecDuplicate(u0,&u);

MatGetOwnershipRange(A,&Istart,&Iend);

PetscLogStageRegister("Assembly",&stage);
PetscLogStagePush(stage);

for(Ii=Istart;Ii<Iend;Ii++)
{
    if(Ii==0)
    {
        v=1.0+2.0*alpha;J=Ii;
        MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);

        v=-2.0*alpha;J=Ii+1;
        MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
    }
    else if(Ii==n-1)
    {
        v=-2.0*alpha;J=Ii-1;
        MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);

        v=1.0+2.0*alpha;J=Ii;
        MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
    }
    else
    {
        v=-alpha;J=Ii-1;
        MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);

        v=1.0+2.0*alpha;J=Ii;
        MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);

        v=-alpha;J=Ii+1;
        MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
    }
    if(Ii<=m/2)
    {
        VecSetValues(u0,1,&Ii,&Ca,ADD_VALUES);
    }
    else
    {
        VecSetValues(u0,1,&Ii,&Cb,ADD_VALUES);
    }
}
MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
VecAssemblyBegin(u0);
VecAssemblyEnd(u0);

KSPCreate(PETSC_COMM_WORLD,&ksp);
KSPSetOperators(ksp,A,A);
KSPSetFromOptions(ksp);



dt=1.0;T=2.0;i=0;
PrintToVTU(i,dx,u0);
printf("Hello\n");
for(ti=0.0;ti<=T;ti+=dt)
{
    i+=1;
    KSPSolve(ksp,u0,u);
    VecCopy(u,u0);
    PrintToVTU(i,dx,u0);
}
}