예제 #1
0
파일: famg_system.C 프로젝트: rolk/ug
int FAMGSystem::GMRES()
{
	assert(0); // to port
#ifdef FAMG_GMRES
    double rlimit,alimit,reduction,limit,defectnorm,startdefect;
    int maxit;
    double H[famgnv*famgnv], G[famgnv*famgnv], Q[(famgnv+1)*(famgnv+1)], P[(famgnv+1)*(famgnv+1)], *vec[famgnv], *sol, *rhs, *def, q0;
    int i, k, newtv, con, nv;
    ostrstream ostr;

    maxit = famgparaptr->Getmaxit();
    rlimit = famgparaptr->Getrlimit();
    alimit = famgparaptr->Getalimit();
    reduction = famgparaptr->Getreduction();
    nv = famgparaptr->Getnv();

    FAMGMarkHeap(FAMG_FROM_BOTTOM);

    sol = (double *) FAMGGetMem(n*sizeof(double),FAMG_FROM_BOTTOM);
    if(sol == NULL)
		RETURN(1);
    rhs = (double *) FAMGGetMem(n*sizeof(double),FAMG_FROM_BOTTOM);
    if(rhs == NULL)
		RETURN(1);
    
    // test
    def = (double *) FAMGGetMem(n*sizeof(double),FAMG_FROM_BOTTOM);
    if(def == NULL)
		RETURN(1);

    for(i = 0; i < nv; i++)
    {
        vec[i] = (double *) FAMGGetMem(n*sizeof(double),FAMG_FROM_BOTTOM);
        if(vec[i] == NULL)
			RETURN(1);
    }
    

    FAMGSetVector(n,vector[FAMGUNKNOWN],0.0);
    FAMGSetVector(n,sol,0.0);
    FAMGCopyVector(n,vector[FAMGDEFECT],vector[FAMGRHS]);

    startdefect = defectnorm = FAMGNorm(n,vector[FAMGDEFECT]);
    limit = rlimit*defectnorm;
    ostr << "start defect: " << defectnorm  << endl;
    FAMGWrite(ostr);


    // FAMGMultiGrid * mg0 = CreateMultiGrid();
    // if(mg0 == NULL) RETURN(1);
    // if (mg0->Init(*this)) RETURN(1);
    // if (mg0->Construct()) RETURN(1);
    FAMGMultiGrid *mg0 = mg[0];

    newtv = 0;
    con = 1;

    for(k = 0; k*nv < maxit; k++)
    {

        // construct preconditioner
        if(newtv)
        {
            if(con) 
            {
                if(mg0->Deconstruct())
					RETURN(1);
            }
            if (mg0->Construct())
				RETURN(1);
            con = 1;
       }

 
        FAMGCopyVector(n,rhs,vector[FAMGRHS]);
        FAMGCopyVector(n,sol,vector[FAMGUNKNOWN]);
        //test
        FAMGCopyVector(n,def,vector[FAMGDEFECT]);

        if(Arnoldi(mg0,vec,H,G,Q,P,q0,con))
			RETURN(1);

        newtv = 0;
        // status = ComputeEigenVector(mg0,vec,G,P,con);
        // if(status > 0) RETURN(1); // error
        // if(status < 0) 
        // {
        //     newtv = 1; // restart with new TV
        // }


        if(UpdateSolution(mg0,vec,H,Q,q0,con))
			RETURN(1);

        FAMGAddVector(n,vector[FAMGUNKNOWN],sol);

        FAMGCopyVector(n,vector[FAMGRHS],rhs);
        mg0->GetGrid(0)->Defect();
        defectnorm = FAMGNorm(n,vector[FAMGDEFECT]);
        ostr << defectnorm << endl;
        FAMGWrite(ostr);
        if( (defectnorm < alimit) || (defectnorm < limit)) break;
    }

    if(!con) 
    {
        ostr  << __FILE__ << __LINE__ << endl;
        FAMGError(ostr);
        RETURN(1);
    }

    FAMGReleaseHeap(FAMG_FROM_BOTTOM);

    if (defectnorm < startdefect*reduction)
    {
        // Yeah, problem solved !!!

        return 0;
    }
#endif

    return 1;
}
예제 #2
0
/* ******************************************************************** */
int Integrate (Data *d, Riemann_Solver *Solver, Time_Step *Dts, Grid *grid)
/*!
 * Advance equations by a single time-step.

 * \param  d      pointer to PLUTO Data structure;
 * \param  Solver pointer to a Riemann solver function;
 * \param  Dts    pointer to time Step structure;
 * \param  grid   pointer to grid structure.
 * 
 * \return An integer giving success / failure (development).
 * 
 ********************************************************************** */
{
  int idim, err = 0;

  g_maxMach = 0.0;
  g_maxRiemannIter = 0;
  g_maxRootIter    = 0;

/* -------------------------------------------------------
    Initialize max propagation speed in Dedner's approach
   ------------------------------------------------------- */

  #ifdef GLM_MHD  /* -- initialize glm_ch -- */
   GLM_Init (d, Dts, grid);   
   GLM_Source (d->Vc, 0.5*g_dt, grid);
  #endif

  /* ---------------------------------------------
        perform Strang Splitting on directions 
        (if necessary) and sources 
     --------------------------------------------- */

  FlagReset (d);

  #ifdef FARGO
   FARGO_ComputeVelocity(d, grid);
  #endif
  if ((g_stepNumber%2) == 0){
    g_operatorStep = HYPERBOLIC_STEP;
    #if DIMENSIONAL_SPLITTING == YES
     for (g_dir = 0; g_dir < DIMENSIONS; g_dir++){
       if (UpdateSolution (d, Solver, Dts, grid) != 0) return (1);
     }
    #else
     if (UpdateSolution (d, Solver, Dts, grid) != 0) return(1);
    #endif
    g_operatorStep = PARABOLIC_STEP;
    SplitSource (d, g_dt, Dts, grid);
  }else{
    g_operatorStep = PARABOLIC_STEP;
    SplitSource (d, g_dt, Dts, grid);
    g_operatorStep = HYPERBOLIC_STEP;
    #if DIMENSIONAL_SPLITTING == YES
     for (g_dir = DIMENSIONS - 1; g_dir >= 0; g_dir--){
       if (UpdateSolution(d, Solver, Dts, grid) != 0) return (1);
     }
    #else
     if (UpdateSolution (d, Solver, Dts, grid) != 0) return(1);
    #endif
  }       

  #ifdef GLM_MHD  /* -- GLM source for dt/2 -- */
   GLM_Source (d->Vc, 0.5*g_dt, grid);
  #endif

  return (0); /* -- ok, step achieved -- */
}