예제 #1
0
///////////////////////////////////////////////////////////////////////////////
/// Calculate the velocity
///
///\param para Pointer to FFD parameters
///\param var Pointer to FFD simulation variables
///\param BINDEX Pointer to boundary index
///
///\return 0 if no error occurred
/////////////////////////////////////////////////////////////////////////////// 
int vel_step(PARA_DATA *para, REAL **var,int **BINDEX) {
  REAL *u  = var[VX],  *v  = var[VY],    *w  = var[VZ];
  REAL *u0 = var[TMP1], *v0 = var[TMP2], *w0 = var[TMP3];
  int flag = 0;

  flag = advect(para, var, VX, 0, u0, u, BINDEX);
  if(flag!=0) {
    ffd_log("vel_step(): Could not advect for velocity X.", FFD_ERROR);
    return flag;
  }

  flag = advect(para, var, VY, 0, v0, v, BINDEX);
  if(flag!=0) {
    ffd_log("vel_step(): Could not advect for velocity Y.", FFD_ERROR);
    return flag;
  }

  flag = advect(para, var, VZ, 0, w0, w, BINDEX); 
  if(flag!=0) {
    ffd_log("vel_step(): Could not advect for velocity Z.", FFD_ERROR);
    return flag;
  }

  flag = diffusion(para, var, VX, 0, u, u0, BINDEX);
  if(flag!=0) {
    ffd_log("vel_step(): Could not diffuse velocity X.", FFD_ERROR);
    return flag;
  }

  flag = diffusion(para, var, VY, 0, v, v0, BINDEX);
  if(flag!=0) {
    ffd_log("vel_step(): Could not diffuse velocity Y.", FFD_ERROR);
    return flag;
  }

  flag = diffusion(para, var, VZ, 0, w, w0, BINDEX); 
  if(flag!=0) {
    ffd_log("vel_step(): Could not diffuse velocity Z.", FFD_ERROR);
    return flag;
  }

  flag = project(para, var,BINDEX);
  if(flag!=0) {
    ffd_log("vel_step(): Could not project velocity.", FFD_ERROR);
    return flag;
  }

  if(para->bc->nb_outlet!=0) flag = mass_conservation(para, var,BINDEX);
  if(flag!=0) {
    ffd_log("vel_step(): Could not conduct mass conservation correction.",
            FFD_ERROR);
    return flag;
  }

  return flag;
} // End of vel_step( )
예제 #2
0
void predcorr(double *x, double *v, double *w, int *ix, int *iw, int *pcd, double dt, params *p, gsl_rng *rg)
/* simplified weak order 2.0 adapted predictor-corrector scheme
( see E. Platen, N. Bruti-Liberati; Numerical Solution of Stochastic Differential Equations with Jumps in Finance; Springer 2010; p. 503, p. 532 )
*/
{
  int i;
  double l_xt, l_xtt, l_vt, l_vtt, l_wt, l_wtt, predl_x, predl_v, predl_w, l_x, l_v, l_w;
  double basex = 1.0,
	basew = PI2;

  for (i = (p->paths)==1?0:(p->paths); i < (p->paths)*2; ++i){
    l_x = x[i];
    l_v = v[i];
    l_w = w[i];

    l_xt = l_v;
    l_vt = drift(l_x, l_v, l_w, p);
    l_wt = p->omega;

    predl_x = l_x + l_xt*dt;
    predl_v = l_v + l_vt*dt + diffusion(dt, p, rg);
    predl_w = l_w + l_wt*dt;

    l_xtt = predl_v;
    l_vtt = drift(predl_x, predl_v, predl_w, p);
    l_wtt = p->omega;

    predl_x = l_x + 0.5*(l_xt + l_xtt)*dt;
    predl_v = l_v + 0.5*(l_vt + l_vtt)*dt + diffusion(dt, p, rg);
    predl_w = l_w + 0.5*(l_wt + l_wtt)*dt;

    l_xtt = predl_v;
    l_vtt = drift(predl_x, predl_v, predl_w, p);
    //l_wtt = p->omega;

    l_x += 0.5*(l_xt + l_xtt)*dt;
    l_v += 0.5*(l_vt + l_vtt)*dt + diffusion(dt, p, rg) + adapted_jump(pcd, dt, p, rg);
    l_w += 0.5*(l_wt + l_wtt)*dt;

    //fold path parameters
    //if (fabs(l_x) > basex){
    //  l_x -= floor(l_x/basex)*basex;
    //  ix[i]++;
    //}
    
    if (l_w > basew){
      l_w -= floor(l_w/basew)*basew;
      iw[i]++;
    }

    x[i] = l_x;
    v[i] = l_v;
    w[i] = l_w;
  }

}
예제 #3
0
///////////////////////////////////////////////////////////////////////////////
/// Calculate the contaminant concentration
///
///\param para Pointer to FFD parameters
///\param var Pointer to FFD simulation variables
///\param BINDEX Pointer to boundary index
///
///\return 0 if no error occurred
/////////////////////////////////////////////////////////////////////////////// 
int den_step(PARA_DATA *para, REAL **var, int **BINDEX) {
  REAL *den, *den0 = var[TMP1];
  int i, flag = 0;

  /****************************************************************************
  | Solve the species
  ****************************************************************************/
  for(i=0; i<para->bc->nb_Xi; i++) {
    if(para->outp->version==DEBUG) {
      sprintf(msg, "den_step(): start to solve Xi%d", i+1);
      ffd_log(msg, FFD_NORMAL);
    }
    den = var[Xi1+i];
    flag = advect(para, var, Xi1+i, i, den0, den, BINDEX);
    if(flag!=0) {
      sprintf(msg, "den_step(): Could not advect species %d", i+1);
      ffd_log(msg, FFD_ERROR);
      return flag;
    }

    flag = diffusion(para, var, Xi1+i, i, den, den0, BINDEX);
    if(flag!=0) {
      sprintf(msg, "den_step(): Could not diffuse species %d", i+1);
      ffd_log(msg, FFD_ERROR);
      return flag;
    }
  }

  /****************************************************************************
  | Solve the trace substances
  ****************************************************************************/
  for(i=0; i<para->bc->nb_C; i++) {
    if(para->outp->version==DEBUG) {
      sprintf(msg, "den_step(): start to solve C%d", i+1);
      ffd_log(msg, FFD_NORMAL);
    }
    den = var[C1+i];
    flag = advect(para, var, Xi1, i, den0, den, BINDEX);
    if(flag!=0) {
      sprintf(msg, "den_step(): Could not advect trace substance %d", i+1);
      ffd_log(msg, FFD_ERROR);
      return flag;
    }

    flag = diffusion(para, var, Xi1, i, den, den0, BINDEX);
    if(flag!=0) {
      sprintf(msg, "den_step(): Could not diffuse trace substance %d", i+1);
      ffd_log(msg, FFD_ERROR);
      return flag;
    }
  }

  return flag;
} // End of den_step( )
예제 #4
0
void FluidSimulator::step_velocity(float *u, float *v, float *u0,
				   float *v0, float viscosity){
  add_source(u,u0);
  add_source(v,v0);
  swap(u0,u); diffusion(1, u, u0, viscosity);
  swap(v0,v); diffusion(2, v, v0, viscosity);
  project(u,v,u0,v0);
  swap(u0,u); swap(v0,v);
  advection(1,u,u0,u0,v0);
  advection(2,v,v0,u0,v0);
  project(u,v,u0,v0);
}
예제 #5
0
void StableSolver2D::anim_tex()
{
	if(running == 0) return;

	SWAP(tx0, tx); 
	SWAP(ty0, ty); 
	advection(tx, tx0, vx, vy, 0);
	advection(ty, ty0, vx, vy, 0);

	SWAP(tx0, tx); 
	SWAP(ty0, ty);  
	diffusion(tx, tx0, diff, 0);
	diffusion(ty, ty0, diff, 0);
}
예제 #6
0
 inline Disposable<Matrix> StochasticProcess1D::diffusion(
                                            Time t, const Array& x) const {
     #if defined(QL_EXTRA_SAFETY_CHECKS)
     QL_REQUIRE(x.size() == 1, "1-D array required");
     #endif
     Matrix m(1, 1, diffusion(t, x[0]));
     return m;
 }
예제 #7
0
//Animating Velocity
void StableSolver2D::anim_vel()
{
	if(running == 0) return;

	SWAP(vx0, vx); 
	SWAP(vy0, vy); 
	diffusion(vx, vx0, visc, 1);
	diffusion(vy, vy0, visc, 2);

	projection();

	SWAP(vx0, vx);
	SWAP(vy0, vy);
	advection(vx, vx0, vx0, vy0, 1);
	advection(vy, vy0, vx0, vy0, 2);

	projection();
}
 Real GeneralizedBlackScholesProcess::drift(Time t, Real x) const {
     Real sigma = diffusion(t,x);
     // we could be more anticipatory if we know the right dt
     // for which the drift will be used
     Time t1 = t + 0.0001;
     return riskFreeRate_->forwardRate(t,t1,Continuous,NoFrequency,true)
          - dividendYield_->forwardRate(t,t1,Continuous,NoFrequency,true)
          - 0.5 * sigma * sigma;
 }
예제 #9
0
//Animating Density
void StableSolver2D::anim_den()
{
	if(running == 0) return;

	SWAP(d0, d); 
	advection(d, d0, vx, vy, 0);

	SWAP(d0, d); 
	diffusion(d, d0, diff, 0);
}
예제 #10
0
파일: Events.cpp 프로젝트: adamsikora/kmc
void Events::execute()
{
	evolve();

newChoose:;

	double chooseEvent = _random() * rates.total;

	if (chooseEvent < rates.totalAds) {
		int index = static_cast<int> (floor(chooseEvent / rates.ads));

		adsorption(index, atomType::metal);
	}
	else if (chooseEvent < rates.totalAds + rates.totalDes) {
		chooseEvent -= rates.totalAds;
		double cumulateRates = 0;
		unsigned ei = 0, ej = 0;
      while (cumulateRates + rates.sumsofDes[ei] < chooseEvent) {
         if (ei >= c::nDesTypes) {
            goto newChoose;
         }
         cumulateRates += rates.sumsofDes[ei++];
      }
      ej = static_cast<int> (floor((chooseEvent - cumulateRates) / rates.des[ei]));
      if (ej >= eventLists._desEvents[ei].size()) {
         goto newChoose;
      }/*

		if (ei % c::nNeighCount == 0)
			_nFreeDes++;

      _nDesorbNeigh[ei % c::nNeighCount]++;*/

		desorption(eventLists._desEvents[ei][ej]);
	}
	else {
		chooseEvent -= rates.totalAds + rates.totalDes;
		double cumulateRates = 0;
		unsigned ei = 0, ej = 0;
      while (cumulateRates + rates.sumsofDiff[ei] < chooseEvent) {
         if (ei >= c::nDiffTypes) {
            goto newChoose;
         }
         cumulateRates += rates.sumsofDiff[ei++];
      }
		ej = static_cast<int> (floor((chooseEvent - cumulateRates) / rates.diff[ei]));
      if (ej >= eventLists._diffEvents[ei].size()) {
         goto newChoose;
      }
		checkDiff(ei, eventLists._diffEvents[ei][ej]);
		diffusion(eventLists._diffEvents[ei][ej]);
   }
   _nEvents++;
}
void Foam::pseudoSolidTetDecompositionMotionSolver::solve()
{
    // Solve for mesh motion

    if (!frozen_ && !firstMotion_)
    {
        Pout << "Correct mesh motion diffusion field." << endl;

        diffusionPtr_->correct();
    }

    int iCorr = 0;
    scalar initialResidual = 0;

    do
    {
        Pout << "Correction: " << ++iCorr << endl;

        tetFemVectorMatrix motionEqn
        (
            tetFem::laplacian(diffusion().motionGamma(), motionU())
          + tetFem::laplacianTranspose(diffusion().motionGamma(), motionU())
          + tetFem::laplacianTrace
            (
                (2*nu_/(1+2*nu_))*diffusion().motionGamma(), 
                motionU()
            )
        );

        // Apply motion constraints
        applyConstraints(motionEqn);

        // Solve the motion equation
        initialResidual = motionEqn.solve().initialResidual();

        Pout << "Initial residual: " << initialResidual << endl;
    }
    while (initialResidual > convergenceTolerance_ && iCorr < nCorrectors_);
}
예제 #12
0
void yeseulWhitneyScene::draw(){
    
    ofPushMatrix();
    
    ofTranslate(dimensions.width/2, dimensions.height/2);
    
    drawPattern();
    
    diffusion();
    
    ofPopMatrix();
    
}
void Foam::laplaceTetMotionSolver::solve()
{
    // Solve for mesh motion

    if (!frozen_ && !firstMotion_)
    {
        Info << "Correct mesh motion diffusion field." << endl;

        diffusionPtr_->correct();
    }

    tetFemVectorMatrix motionEqn
    (
        tetFem::laplacian
        (
            diffusion().motionGamma(),
            motionU()
        )
    );

    // Apply motion constraints
    applyConstraints(motionEqn);

    // Solve the motion equation
    if (firstMotion_)
    {
        firstMotion_ = false;

        // In the first solution, solve the motion twice to avoid relative
        // tolerance problem
        for (label i = 0; i < 2; i++)
        {
            solverPerf_ = motionEqn.solve();
        }
    }
    else
    {
        solverPerf_ = motionEqn.solve();
    }


    if (needTotDisplacement())
    {
        totDisplacement() += motionU()*tetMesh().time().deltaT();
    }
}
예제 #14
0
///////////////////////////////////////////////////////////////////////////////
/// Calculate the temperature
///
///\param para Pointer to FFD parameters
///\param var Pointer to FFD simulation variables
///\param BINDEX Pointer to boundary index
///
///\return 0 if no error occurred
///////////////////////////////////////////////////////////////////////////////
int temp_step(PARA_DATA *para, REAL **var, int **BINDEX) {
  REAL *T = var[TEMP], *T0 = var[TMP1];
  int flag = 0;

  flag = advect(para, var, TEMP, 0, T0, T, BINDEX); 
  if(flag!=0) {
    ffd_log("temp_step(): Could not advect temperature.", FFD_ERROR);
    return flag;
  }

  flag = diffusion(para, var, TEMP, 0, T, T0, BINDEX);
  if(flag!=0) {
    ffd_log("temp_step(): Could not diffuse temperature.", FFD_ERROR);
    return flag;
  }

  return flag;
} // End of temp_step( )
예제 #15
0
파일: CVODEModel.C 프로젝트: LLNL/SAMRAI
/*
 *************************************************************************
 *
 * Set initial conditions for CVODE solver
 *
 *************************************************************************
 */
void
CVODEModel::setInitialConditions(
   SundialsAbstractVector* soln_init)
{
   std::shared_ptr<SAMRAIVectorReal<double> > soln_init_samvect(
      Sundials_SAMRAIVector::getSAMRAIVector(soln_init));

   std::shared_ptr<PatchHierarchy> hierarchy(
      soln_init_samvect->getPatchHierarchy());

   for (int ln = 0; ln < hierarchy->getNumberOfLevels(); ++ln) {
      std::shared_ptr<PatchLevel> level(hierarchy->getPatchLevel(ln));

      for (int cn = 0; cn < soln_init_samvect->getNumberOfComponents(); ++cn) {
         for (PatchLevel::iterator p(level->begin()); p != level->end(); ++p) {
            const std::shared_ptr<Patch>& patch = *p;

            /*
             * Set initial conditions for y
             */
            std::shared_ptr<CellData<double> > y_init(
               SAMRAI_SHARED_PTR_CAST<CellData<double>, PatchData>(
                  soln_init_samvect->getComponentPatchData(cn, *patch)));
            TBOX_ASSERT(y_init);
            y_init->fillAll(d_initial_value);

            /*
             * Set initial diffusion coeff values.
             * NOTE: in a "real" application, the diffusion coefficient is
             * some function of y.  Here, we just do a simple minded
             * approach and set it to 1.
             */
            std::shared_ptr<SideData<double> > diffusion(
               SAMRAI_SHARED_PTR_CAST<SideData<double>, PatchData>(
                  patch->getPatchData(d_diff_id)));
            TBOX_ASSERT(diffusion);

            diffusion->fillAll(1.0);
         }
      }
   }
}
예제 #16
0
void eulermaruyama(double *x, double *v, double *w, int *ix, int *iw, double dt, params *p, gsl_rng *rg)
/* simplified weak order 1.0 regular euler-maruyama scheme 
( see E. Platen, N. Bruti-Liberati; Numerical Solution of Stochastic Differential Equations with Jumps in Finance; Springer 2010; p. 508, 
  C. Kim, E. Lee, P. Talkner, and P.Hanggi; Phys. Rev. E 76; 011109; 2007 ) 
*/ 
{
  int i;
  double l_xt, l_vt, l_wt, l_x, l_v, l_w;
  double basex = 1.0,
	basew = PI2;

  for (i = (p->paths)==1?0:(p->paths); i < (p->paths)*2; ++i){
    l_x = x[i];
    l_v = v[i];
    l_w = w[i];

    l_xt = l_x + l_v*dt;
    l_vt = l_v + drift(l_x, l_v, l_w, p)*dt 
      + diffusion(dt, p, rg) 
      + regular_jump(dt, p, rg);
    l_wt = l_w + (p->omega)*dt;

    //fold path parameters
    //if (fabs(l_xt) > basex){
    //  l_xt -= floor(l_xt/basex)*basex;
    //  ix[i]++;
    //}
     
    if (l_wt > basew){
      l_wt -= floor(l_wt/basew)*basew;
      iw[i]++;
    }
    
    x[i] = l_xt;
    v[i] = l_vt;
    w[i] = l_wt;
  }
}
예제 #17
0
		double driftCorrected(double X, double t, double B)
		{ // Corrected drift term
	
			return drift(X,t) - B*diffusion(X,t)* diffusionDerivative(X, t);
		}
예제 #18
0
void 
UZRectMollerup::tick (const GeometryRect& geo,
		      const std::vector<size_t>& drain_cell,
		      const double drain_water_level,
		      const Soil& soil, 
		      SoilWater& soil_water, const SoilHeat& soil_heat,
		      const Surface& surface, const Groundwater& groundwater,
		      const double dt, Treelog& msg)

{
  daisy_assert (K_average.get ());
  const size_t edge_size = geo.edge_size (); // number of edges 
  const size_t cell_size = geo.cell_size (); // number of cells 

  // Insert magic here.
  
  ublas::vector<double> Theta (cell_size); // water content 
  ublas::vector<double> Theta_previous (cell_size); // at start of small t-step
  ublas::vector<double> h (cell_size); // matrix pressure
  ublas::vector<double> h_previous (cell_size); // at start of small timestep
  ublas::vector<double> h_ice (cell_size); // 
  ublas::vector<double> S (cell_size); // sink term
  ublas::vector<double> S_vol (cell_size); // sink term
#ifdef TEST_OM_DEN_ER_BRUGT
  ublas::vector<double> S_macro (cell_size);  // sink term
  std::vector<double> S_drain (cell_size, 0.0); // matrix-> macro -> drain flow 
  std::vector<double> S_drain_sum (cell_size, 0.0); // For large timestep
  const std::vector<double> S_matrix (cell_size, 0.0);  // matrix -> macro 
  std::vector<double> S_matrix_sum (cell_size, 0.0); // for large timestep
#endif
  ublas::vector<double> T (cell_size); // temperature 
  ublas::vector<double> Kold (edge_size); // old hydraulic conductivity
  ublas::vector<double> Ksum (edge_size); // Hansen hydraulic conductivity
  ublas::vector<double> Kcell (cell_size); // hydraulic conductivity
  ublas::vector<double> Kold_cell (cell_size); // old hydraulic conductivity
  ublas::vector<double> Ksum_cell (cell_size); // Hansen hydraulic conductivity
  ublas::vector<double> h_lysimeter (cell_size);
  std::vector<bool> active_lysimeter (cell_size);
  const std::vector<size_t>& edge_above = geo.cell_edges (Geometry::cell_above);
  const size_t edge_above_size = edge_above.size ();
  ublas::vector<double> remaining_water (edge_above_size);
  std::vector<bool> drain_cell_on (drain_cell.size (),false); 
  

  for (size_t i = 0; i < edge_above_size; i++)
    {
      const size_t edge = edge_above[i];
      remaining_water (i) = surface.h_top (geo, edge);
    }
  ublas::vector<double> q;	// Accumulated flux
  q = ublas::zero_vector<double> (edge_size);
  ublas::vector<double> dq (edge_size); // Flux in small timestep.
  dq = ublas::zero_vector<double> (edge_size);

  //Make Qmat area diagonal matrix 
  //Note: This only needs to be calculated once... 
  ublas::banded_matrix<double> Qmat (cell_size, cell_size, 0, 0);
  for (int c = 0; c < cell_size; c++)
    Qmat (c, c) = geo.cell_volume (c);
 
  // make vectors 
  for (size_t cell = 0; cell != cell_size ; ++cell) 
    {				
      Theta (cell) = soil_water.Theta (cell);
      h (cell) =  soil_water.h (cell);
      h_ice (cell) = soil_water.h_ice (cell);
      S (cell) =  soil_water.S_sum (cell);
      S_vol (cell) = S (cell) * geo.cell_volume (cell);
      if (use_forced_T)
	T (cell) = forced_T;
      else 
	T (cell) = soil_heat.T (cell); 
      h_lysimeter (cell) = geo.zplus (cell) - geo.cell_z (cell);
    }

  // Remember old value.
  Theta_error = Theta;

  // Start time loop 
  double time_left = dt;	// How much of the large time step left.
  double ddt = dt;		// We start with small == large time step.
  int number_of_time_step_reductions = 0;
  int iterations_with_this_time_step = 0;
  

  int n_small_time_steps = 0;
  
  while (time_left > 0.0)
    {
      if (ddt > time_left)
	ddt = time_left;

      std::ostringstream tmp_ddt;
      tmp_ddt << "Time t = " << (dt - time_left) 
              << "; ddt = " << ddt
              << "; steps " << n_small_time_steps 
              << "; time left = " << time_left;
      Treelog::Open nest (msg, tmp_ddt.str ());

      if (n_small_time_steps > 0
          && (n_small_time_steps%msg_number_of_small_time_steps) == 0)
        {
          msg.touch ();
          msg.flush ();
        }
      
      n_small_time_steps++;
      if (n_small_time_steps > max_number_of_small_time_steps) 
        {
          msg.debug ("Too many small timesteps");
          throw "Too many small timesteps";
        }
      
      // Initialization for each small time step.

      if (debug > 0)
	{
	  std::ostringstream tmp;
	  tmp << "h = " << h << "\n";
	  tmp << "Theta = " << Theta;
	  msg.message (tmp.str ());
	}

      int iterations_used = 0;
      h_previous = h;
      Theta_previous = Theta;

      if (debug == 5)
	{
	  std::ostringstream tmp;
	  tmp << "Remaining water at start: " << remaining_water;
	  msg.message (tmp.str ());
	}

      ublas::vector<double> h_conv;

      for (size_t cell = 0; cell != cell_size ; ++cell)
        active_lysimeter[cell] = h (cell) > h_lysimeter (cell);

      for (size_t edge = 0; edge != edge_size ; ++edge)
        {
          Kold[edge] = find_K_edge (soil, geo, edge, h, h_ice, h_previous, T);
          Ksum [edge] = 0.0;
        }

      std::vector<top_state> state (edge_above.size (), top_undecided);
      
      // We try harder with smaller timesteps.
      const int max_loop_iter 
        = max_iterations * (number_of_time_step_reductions 
                            * max_iterations_timestep_reduction_factor + 1);
      do // Start iteration loop
	{
	  h_conv = h;
	  iterations_used++;
          

          std::ostringstream tmp_conv;
          tmp_conv << "Convergence " << iterations_used; 
          Treelog::Open nest (msg, tmp_conv.str ());
          if (debug == 7)
            msg.touch ();

	  // Calculate conductivity - The Hansen method
	  for (size_t e = 0; e < edge_size; e++)
	    {
              Ksum[e] += find_K_edge (soil, geo, e, h, h_ice, h_previous, T);
              Kedge[e] = (Ksum[e] / (iterations_used  + 0.0)+ Kold[e]) / 2.0;
	    }

	  //Initialize diffusive matrix
	  Solver::Matrix diff (cell_size);
	  // diff = ublas::zero_matrix<double> (cell_size, cell_size);
	  diffusion (geo, Kedge, diff);

	  //Initialize gravitational matrix
	  ublas::vector<double> grav (cell_size); //ublass compatibility
	  grav = ublas::zero_vector<double> (cell_size);
	  gravitation (geo, Kedge, grav);

	  // Boundary matrices and vectors
	  ublas::banded_matrix<double>  Dm_mat (cell_size, cell_size, 
                                                0, 0); // Dir bc
	  Dm_mat = ublas::zero_matrix<double> (cell_size, cell_size);
	  ublas::vector<double>  Dm_vec (cell_size); // Dir bc
	  Dm_vec = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> Gm (cell_size); // Dir bc
	  Gm = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> B (cell_size); // Neu bc 
	  B = ublas::zero_vector<double> (cell_size);

	  lowerboundary (geo, groundwater, active_lysimeter, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, msg);
	  upperboundary (geo, soil, T, surface, state, remaining_water, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, ddt, debug, msg, dt);
          Darcy (geo, Kedge, h, dq); //for calculating drain fluxes 


	  //Initialize water capacity  matrix
	  ublas::banded_matrix<double> Cw (cell_size, cell_size, 0, 0);
	  for (size_t c = 0; c < cell_size; c++)
	    Cw (c, c) = soil.Cw2 (c, h[c]);
	  
          std::vector<double> h_std (cell_size);
          //ublas vector -> std vector 
          std::copy(h.begin (), h.end (), h_std.begin ());

#ifdef TEST_OM_DEN_ER_BRUGT
          for (size_t cell = 0; cell != cell_size ; ++cell) 
            {				
              S_macro (cell) = (S_matrix[cell] + S_drain[cell]) 
                * geo.cell_volume (cell);
            }
#endif

	  //Initialize sum matrix
	  Solver::Matrix summat (cell_size);  
	  noalias (summat) = diff + Dm_mat;

	  //Initialize sum vector
	  ublas::vector<double> sumvec (cell_size);  
	  sumvec = grav + B + Gm + Dm_vec - S_vol
#ifdef TEST_OM_DEN_ER_BRUGT
            - S_macro
#endif
            ; 

	  // QCw is shorthand for Qmatrix * Cw
	  Solver::Matrix Q_Cw (cell_size);
	  noalias (Q_Cw) = prod (Qmat, Cw);

	  //Initialize A-matrix
	  Solver::Matrix A (cell_size);  
	  noalias (A) = (1.0 / ddt) * Q_Cw - summat;  

	  // Q_Cw_h is shorthand for Qmatrix * Cw * h
	  const ublas::vector<double> Q_Cw_h = prod (Q_Cw, h);

	  //Initialize b-vector
	  ublas::vector<double> b (cell_size);  
	  //b = sumvec + (1.0 / ddt) * (Qmatrix * Cw * h + Qmatrix *(Wxx-Wyy));
	  b = sumvec + (1.0 / ddt) * (Q_Cw_h
				      + prod (Qmat, Theta_previous-Theta));

	  // Force active drains to zero h.
          drain (geo, drain_cell, drain_water_level,
		 h, Theta_previous, Theta, S_vol,
#ifdef TEST_OM_DEN_ER_BRUGT
                 S_macro,
#endif
                 dq, ddt, drain_cell_on, A, b, debug, msg);  
          
          try {
            solver->solve (A, b, h); // Solve Ah=b with regard to h.
          } catch (const char *const error) {
              std::ostringstream tmp;
              tmp << "Could not solve equation system: " << error;
              msg.warning (tmp.str ());
              // Try smaller timestep.
              iterations_used = max_loop_iter + 100;
              break;
          }

	  for (int c=0; c < cell_size; c++) // update Theta 
	    Theta (c) = soil.Theta (c, h (c), h_ice (c)); 

	  if (debug > 1)
	    {
	      std::ostringstream tmp;
	      tmp << "Time left = " << time_left << ", ddt = " << ddt 
		  << ", iteration = " << iterations_used << "\n";
	      tmp << "B = " << B << "\n";
	      tmp << "h = " << h << "\n";
	      tmp << "Theta = " << Theta;
	      msg.message (tmp.str ());
	    }
          
          for (int c=0; c < cell_size; c++)
            {
              if (h (c) < min_pressure_potential || h (c) > max_pressure_potential)
                {
                  std::ostringstream tmp;
                  tmp << "Pressure potential out of realistic range, h[" 
                      << c << "] = " << h (c);
                  msg.debug (tmp.str ());
                  iterations_used = max_loop_iter + 100;
                  break;
                } 
            }
        }

      while (!converges (h_conv, h) && iterations_used <= max_loop_iter);
      

      if (iterations_used > max_loop_iter)
	{
          number_of_time_step_reductions++;
          
	  if (number_of_time_step_reductions > max_time_step_reductions)
            {
              msg.debug ("Could not find solution");
              throw "Could not find solution";
            }

          iterations_with_this_time_step = 0;
	  ddt /= time_step_reduction;
	  h = h_previous;
	  Theta = Theta_previous;
	}
      else
	{
          // Update dq for new h.
	  ublas::banded_matrix<double>  Dm_mat (cell_size, cell_size, 
                                                0, 0); // Dir bc
	  Dm_mat = ublas::zero_matrix<double> (cell_size, cell_size);
	  ublas::vector<double>  Dm_vec (cell_size); // Dir bc
	  Dm_vec = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> Gm (cell_size); // Dir bc
	  Gm = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> B (cell_size); // Neu bc 
	  B = ublas::zero_vector<double> (cell_size);
	  lowerboundary (geo, groundwater, active_lysimeter, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, msg);
	  upperboundary (geo, soil, T, surface, state, remaining_water, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, ddt, debug, msg, dt);
          Darcy (geo, Kedge, h, dq);

#ifdef TEST_OM_DEN_ER_BRUGT
          // update macropore flow components 
          for (int c = 0; c < cell_size; c++)
            {
              S_drain_sum[c] += S_drain[c] * ddt/dt;
              S_matrix_sum[c] += S_matrix[c] * ddt/dt;
            }
#endif

          std::vector<double> h_std_new (cell_size);
          std::copy(h.begin (), h.end (), h_std_new.begin ());

	  // Update remaining_water.
	  for (size_t i = 0; i < edge_above.size (); i++)
	    {
	      const int edge = edge_above[i];
	      const int cell = geo.edge_other (edge, Geometry::cell_above);
	      const double out_sign = (cell == geo.edge_from (edge))
		? 1.0 : -1.0;
	      remaining_water[i] += out_sign * dq (edge) * ddt;
              daisy_assert (std::isfinite (dq (edge)));
	    }

	  if (debug == 5)
	    {
	      std::ostringstream tmp;
	      tmp << "Remaining water at end: " << remaining_water;
	      msg.message (tmp.str ());
	    }

	  // Contribution to large time step.
          daisy_assert (std::isnormal (dt));
          daisy_assert (std::isnormal (ddt));
	  q += dq * ddt / dt;
          for (size_t e = 0; e < edge_size; e++)
            {
              daisy_assert (std::isfinite (dq (e)));
              daisy_assert (std::isfinite (q (e)));
            }
          for (size_t e = 0; e < edge_size; e++)
            {
              daisy_assert (std::isfinite (dq (e)));
              daisy_assert (std::isfinite (q (e)));
            }

	  time_left -= ddt;
	  iterations_with_this_time_step++;

	  if (iterations_with_this_time_step > time_step_reduction)
	    {
	      number_of_time_step_reductions--;
	      iterations_with_this_time_step = 0;
	      ddt *= time_step_reduction;
	    }
	}
      // End of small time step.
    }

  // Mass balance.
  // New = Old - S * dt + q_in * dt - q_out * dt + Error =>
  // 0 = Old - New - S * dt + q_in * dt - q_out * dt + Error
  Theta_error -= Theta;         // Old - New
  Theta_error -= S * dt;
#ifdef TEST_OM_DEN_ER_BRUGT
  for (size_t c = 0; c < cell_size; c++)
    Theta_error (c) -= (S_matrix_sum[c] + S_drain_sum[c]) * dt;
#endif
  
  for (size_t edge = 0; edge != edge_size; ++edge) 
    {
      const int from = geo.edge_from (edge);
      const int to = geo.edge_to (edge);
      const double flux = q (edge) * geo.edge_area (edge) * dt;
      if (geo.cell_is_internal (from))
        Theta_error (from) -= flux / geo.cell_volume (from);
      if (geo.cell_is_internal (to))
        Theta_error (to) += flux / geo.cell_volume (to);
    }

  // Find drain sink from mass balance.
#ifdef TEST_OM_DEN_ER_BRUGT
  std::fill(S_drain.begin (), S_drain.end (), 0.0);
#else
  std::vector<double> S_drain (cell_size);
#endif
  for (size_t i = 0; i < drain_cell.size (); i++)
    {
      const size_t cell = drain_cell[i];
      S_drain[cell] = Theta_error (cell) / dt;
      Theta_error (cell) -= S_drain[cell] * dt;
    }

  if (debug == 2)
    {
      double total_error = 0.0;
      double total_abs_error = 0.0;
      double max_error = 0.0;
      int max_cell = -1;
      for (size_t cell = 0; cell != cell_size; ++cell) 
        {
          const double volume = geo.cell_volume (cell);
          const double error = Theta_error (cell);
          total_error += volume * error;
          total_abs_error += std::fabs (volume * error);
          if (std::fabs (error) > std::fabs (max_error))
            {
              max_error = error;
              max_cell = cell;
            }
        }
      std::ostringstream tmp;
      tmp << "Total error = " << total_error << " [cm^3], abs = " 
	  << total_abs_error << " [cm^3], max = " << max_error << " [] in cell " 
	  << max_cell;
      msg.message (tmp.str ());
    }
  
  // Make it official.
  for (size_t cell = 0; cell != cell_size; ++cell) 
    soil_water.set_content (cell, h (cell), Theta (cell));
  
#ifdef TEST_OM_DEN_ER_BRUGT
  soil_water.add_tertiary_sink (S_matrix_sum);
  soil_water.drain (S_drain_sum, msg);
#endif


  for (size_t edge = 0; edge != edge_size; ++edge) 
    {
      daisy_assert (std::isfinite (q[edge]));
      soil_water.set_flux (edge, q[edge]);
    }

  soil_water.drain (S_drain, msg);

  // End of large time step.
}
예제 #19
0
 double DiffusionProcess::variance(double t0, double x0, double dt) const
 {
     double dSigma = diffusion(t0, x0);
     return dSigma * dSigma * dt;
 }
int main(){
	
	bool deposit = true;

	printf("Enter value for diffusion rate D: ");
	scanf(" %f", &D);

	printf("Enter value for deposition rate F: ");
	scanf(" %f", &F);

	printf("Enter total number of steps: ");
	scanf(" %d", &steps);

	FILE *file = fopen("Output.txt", "w");
	fclose(file);
	
	int deposition_ct=0;
	
	create_lattice();
	//sets inverse pointer array to -1 
	for(i=0;i<L;i++){
	  for(j=0;j<L;j++){
	    ipointa[i][j]=-1;
	  }}

	//initialize ip and im arrays to take care to pbc's easilyn
	for(i=0;i<L;i++){
	  ip[i]=i+1;
	  im[i]=i-1;
	}
	ip[L-1]=0;
	im[0]=L-1;
	//initialize nbxa[L][4] and nbya[L][4] for the 4 directions
	for(i=0;i<L;i++){
	  nbxa[i][0]=ip[i];
	  nbya[i][0]=i;
	  nbxa[i][1]=i;
	  nbya[i][1]=im[i];
	  nbxa[i][2]=im[i];
	  nbya[i][2]=i;
	  nbxa[i][3]=i;
	  nbya[i][3]=ip[i];
	}	  

	

	for(int i = 0; i <steps; i++){
		

		float Rdep = F*(L^2);
		float Rdiff = monomer_ct * D;

		P_d = Rdep / (Rdep + Rdiff);
		P_f = 1 - P_d;

		float random = (rand() % 10000)/10000.0;
		fprintf(debug, "P_d %f, random %f\n", P_d, random);

		fprintf(debug, "monomer_ct %d\n", monomer_ct);
		
		
		if((random < P_d) /*&& (deposit)*/){
			
			deposition();
			fprintf(debug, "Deposition \n");
			deposition_ct++;
		}
		else{
			fprintf(debug, "Carrying out diffusion\n");
			diffusion();
			//printf("Diffusion \n");
		}
		
		pbc();
		print_walkers();
		output();		
		//draw();
	}

}
예제 #21
0
int main(int argc, char* argv[])
{
    acc_set_device_num(0, acc_device_nvidia);

    // read command line arguments
    readcmdline(&options, argc, argv);
    int nx = options.nx;
    int ny = options.ny;
    int N  = options.N;
    int nt = options.nt;

    printf("========================================================================\n");
    printf("                      Welcome to mini-stencil!\n");
    printf("mesh :: %d * %d, dx = %f\n", nx, ny, options.dx);
    printf("time :: %d, time steps from 0 .. %f\n", nt, options.nt * options.dt);
    printf("========================================================================\n");

    // allocate global fields
    x_new = (double*) malloc(sizeof(double)*nx*ny);
    x_old = (double*) malloc(sizeof(double)*nx*ny); 
    bndN  = (double*) malloc(sizeof(double)*nx);
    bndS  = (double*) malloc(sizeof(double)*nx); 
    bndE  = (double*) malloc(sizeof(double)*ny); 
    bndW  = (double*) malloc(sizeof(double)*ny); 

    double* b      = (double*) malloc(N*sizeof(double));
    double* deltax = (double*) malloc(N*sizeof(double));

    // set dirichlet boundary conditions to 0 all around
    memset(x_old, 0, sizeof(double) * nx * ny);
    memset(bndN, 0, sizeof(double) * nx);
    memset(bndS, 0, sizeof(double) * nx);
    memset(bndE, 0, sizeof(double) * ny);
    memset(bndW, 0, sizeof(double) * ny);
    memset(deltax, 0, sizeof(double) * N);

    // set the initial condition
    // a circle of concentration 0.1 centred at (xdim/4, ydim/4) with radius
    // no larger than 1/8 of both xdim and ydim
    memset(x_new, 0, sizeof(double) * nx * ny);
    double xc = 1.0 / 4.0;
    double yc = (ny - 1) * options.dx / 4;
    double radius = fmin(xc, yc) / 2.0;
    int i,j;
    //
    for (j = 0; j < ny; j++)
    {
        double y = (j - 1) * options.dx;
        for (i = 0; i < nx; i++)
        {
            double x = (i - 1) * options.dx;
            if ((x - xc) * (x - xc) + (y - yc) * (y - yc) < radius * radius)
                //((double(*)[nx])x_new)[j][i] = 0.1;
                x_new[i+j*nx] = 0.1;
        }
    }

    flops_bc = 0;
    flops_diff = 0;
    flops_blas1 = 0;
    verbose_output = 0;
    iters_cg = 0;
    iters_newton = 0;

    // initialize temporary storage fields used by the cg solver
    // I do this here so that the fields are persistent between calls
    // to the CG solver. This is useful if we want to avoid malloc/free calls
    // on the device for the OpenACC implementation (feel free to suggest a better
    // method for doing this)
    printf("INITIALIZING CG STATE\n");
    Ap    = (double*) malloc(N*sizeof(double));
    r     = (double*) malloc(N*sizeof(double)); 
    p     = (double*) malloc(N*sizeof(double));
    Fx    = (double*) malloc(N*sizeof(double));
    Fxold = (double*) malloc(N*sizeof(double));
    v     = (double*) malloc(N*sizeof(double));
    xold  = (double*) malloc(N*sizeof(double));

    int cg_converged = 1;

    double timespent;

    // start timer
    timespent = -omp_get_wtime();

    // main timeloop
    double tolerance = 1.e-6;
    int timestep;

    for (timestep = 1; timestep <= nt; timestep++)
      {
	// set x_new and x_old to be the solution
	ss_copy(x_old, x_new, N);

	double residual;
	int    converged = 0;
	int    it = 1;
	for ( ; it <= 50; it++)
	  {
	    // compute residual : requires both x_new and x_old
	    diffusion(x_new, b);
	    residual = ss_norm2(b, N);

	    // check for convergence
	    if (residual < tolerance)
	      {
		converged = 1;
		break;
	      }

	    // solve linear system to get -deltax
	    ss_cg(deltax, b, 200, tolerance, &cg_converged);

	    // check that the CG solver converged
	    if (!cg_converged) break;

	    // update solution
	    ss_axpy(x_new, -1.0, deltax, N);
	  }
	iters_newton += it;

	// output some statistics
	//if (converged && verbose_output)
	if (converged && verbose_output)
	  printf("step %d required %d iterations for residual %E\n", timestep, it, residual);
	if (!converged)
	  {
	    fprintf(stderr, "step %d ERROR : nonlinear iterations failed to converge\n", timestep);
	    break;
	  }
      }

    // get times
    timespent += omp_get_wtime();
    unsigned long long flops_total = flops_diff + flops_blas1;

    ////////////////////////////////////////////////////////////////////
    // write final solution to BOV file for visualization
    ////////////////////////////////////////////////////////////////////

    // binary data
    {
        FILE* output = fopen("output.bin", "w");
        fwrite(x_new, sizeof(double), nx * ny, output);
        fclose(output);
    }

    // metadata
    {
        FILE* output = fopen("output.bov", "wb");
        fprintf(output, "TIME: 0.0\n");
        fprintf(output, "DATA_FILE: output.bin\n");
        fprintf(output, "DATA_SIZE: %d, %d, 1\n", nx, ny);
        fprintf(output, "DATA_FORMAT: DOUBLE\n");
        fprintf(output, "VARIABLE: phi\n");
        fprintf(output, "DATA_ENDIAN: LITTLE\n");
        fprintf(output, "CENTERING: nodal\n");
        //fprintf(output, "BYTE_OFFSET: 4\n");
        fprintf(output, "BRICK_SIZE: 1.0 %f 1.0\n", (ny - 1) * options.dx);
        fclose(output);
    }

    // print table sumarizing results
    printf("--------------------------------------------------------------------------------\n");
    printf("simulation took %f seconds (%f GFLOP/s)\n", timespent, flops_total / 1e9 / timespent);
    printf("%u conjugate gradient iterations\n", iters_cg);
    printf("%u newton iterations\n", iters_newton);
    printf("--------------------------------------------------------------------------------\n");

    // deallocate global fields
    free (x_new);
    free (x_old);
    free (bndN);
    free (bndS);
    free (bndE);
    free (bndW);

    printf("Goodbye!\n");

    return 0;
}
예제 #22
0
 Real VarianceGammaProcess::omega(Time t, Real x) const {
     Real sigma = diffusion(t, x);
     return  1 / nu() * std::log(1 - theta() * nu() - sigma * sigma * nu() * 0.5);
 }
int main(int argc, char *argv[])
{
  int step, ie, iside, i, j, k;
  double mflops, tmax, nelt_tot = 0.0;
  char Class;
  logical ifmortar = false, verified;

  double t2, trecs[t_last+1];
  char *t_names[t_last+1];

	//--------------------------------------------------------------------
	// Initialize NUMA control
	//--------------------------------------------------------------------
	numa_initialize_env(NUMA_MIGRATE_EXISTING);

  //---------------------------------------------------------------------
  // Read input file (if it exists), else take
  // defaults from parameters
  //---------------------------------------------------------------------
  FILE *fp;
  if ((fp = fopen("timer.flag", "r")) != NULL) {
    timeron = true;
    t_names[t_total] = "total";
    t_names[t_init] = "init";
    t_names[t_convect] = "convect";
    t_names[t_transfb_c] = "transfb_c";
    t_names[t_diffusion] = "diffusion";
    t_names[t_transf] = "transf";
    t_names[t_transfb] = "transfb";
    t_names[t_adaptation] = "adaptation";
    t_names[t_transf2] = "transf+b";
    t_names[t_add2] = "add2";
    fclose(fp);
  } else {
    timeron = false;
  }

  printf("\n\n NAS Parallel Benchmarks (NPB3.3-OMP-C) - UA Benchmark\n\n");

  if ((fp = fopen("inputua.data", "r")) != NULL) {
    int result;
    printf(" Reading from input file inputua.data\n");
    result = fscanf(fp, "%d", &fre);
    while (fgetc(fp) != '\n');
    result = fscanf(fp, "%d", &niter);
    while (fgetc(fp) != '\n');
    result = fscanf(fp, "%d", &nmxh);
    while (fgetc(fp) != '\n');
    result = fscanf(fp, "%lf", &alpha);
    Class = 'U';
    fclose(fp);
  } else {
    printf(" No input file inputua.data. Using compiled defaults\n");
    fre   = FRE_DEFAULT;
    niter = NITER_DEFAULT;
    nmxh  = NMXH_DEFAULT;
    alpha = ALPHA_DEFAULT;
    Class = CLASS_DEFAULT;
  }

  dlmin = pow(0.5, REFINE_MAX);
  dtime = 0.04*dlmin;

  printf(" Levels of refinement:        %8d\n", REFINE_MAX);
  printf(" Adaptation frequency:        %8d\n", fre);
  printf(" Time steps:                  %8d    dt: %15.6E\n", niter, dtime);
  printf(" CG iterations:               %8d\n", nmxh);
  printf(" Heat source radius:          %8.4f\n", alpha);
  printf(" Number of available threads: %8d\n", omp_get_max_threads());
  printf("\n");

  top_constants();

  for (i = 1; i <= t_last; i++) {
    timer_clear(i);
  }
  if (timeron) timer_start(t_init);

  // set up initial mesh (single element) and solution (all zero)
  create_initial_grid();

  r_init_omp((double *)ta1, ntot, 0.0);
  nr_init_omp((int *)sje, 4*6*nelt, -1);

  init_locks();

  // compute tables of coefficients and weights      
  coef();
  geom1();

  // compute the discrete laplacian operators
  setdef();

  // prepare for the preconditioner
  setpcmo_pre();

  // refine initial mesh and do some preliminary work
  time = 0.0;
  mortar();
  prepwork();
  adaptation(&ifmortar, 0);
  if (timeron) timer_stop(t_init);

  timer_clear(1);

  time = 0.0;
  for (step = 0; step <= niter; step++) {
    if (step == 1) {
      // reset the solution and start the timer, keep track of total no elms
      r_init((double *)ta1, ntot, 0.0);

      time = 0.0;
      nelt_tot = 0.0;
      for (i = 1; i <= t_last; i++) {
        if (i != t_init) timer_clear(i);
      }
      timer_start(1);
    }

    // advance the convection step 
    convect(ifmortar);

    if (timeron) timer_start(t_transf2);
    // prepare the intital guess for cg
    transf(tmort, (double *)ta1);

    // compute residual for diffusion term based on intital guess

    // compute the left hand side of equation, lapacian t
    #pragma omp parallel default(shared) private(ie,k,j,i) 
    {
    #pragma omp for
    for (ie = 0; ie < nelt; ie++) {
      laplacian(ta2[ie], ta1[ie], size_e[ie]);
    }

    // compute the residual 
    #pragma omp for
    for (ie = 0; ie < nelt; ie++) {
      for (k = 0; k < LX1; k++) {
        for (j = 0; j < LX1; j++) {
          for (i = 0; i < LX1; i++) {
            trhs[ie][k][j][i] = trhs[ie][k][j][i] - ta2[ie][k][j][i];
          }
        }
      }
    }
    } //end parallel

    // get the residual on mortar 
    transfb(rmor, (double *)trhs);
    if (timeron) timer_stop(t_transf2);

    // apply boundary condition: zero out the residual on domain boundaries

    // apply boundary conidtion to trhs
    #pragma omp parallel for default(shared) private(ie,iside)
    for (ie = 0; ie < nelt; ie++) {
      for (iside = 0; iside < NSIDES; iside++) {
        if (cbc[ie][iside] == 0) {
          facev(trhs[ie], iside, 0.0);
        }
      }
    }
    // apply boundary condition to rmor
    col2(rmor, tmmor, nmor);

    // call the conjugate gradient iterative solver
    diffusion(ifmortar);

    // add convection and diffusion
    if (timeron) timer_start(t_add2);
    add2((double *)ta1, (double *)t, ntot);
    if (timeron) timer_stop(t_add2);

    // perform mesh adaptation
    time = time + dtime;
    if ((step != 0) && (step/fre*fre == step)) {
      if (step != niter) {
        adaptation(&ifmortar, step);
      }
    } else {
      ifmortar = false;
    }
    nelt_tot = nelt_tot + (double)(nelt);
  }

  timer_stop(1);
  tmax = timer_read(1);

  verify(&Class, &verified);

  // compute millions of collocation points advanced per second.
  // diffusion: nmxh advancements, convection: 1 advancement
  mflops = nelt_tot*(double)(LX1*LX1*LX1*(nmxh+1))/(tmax*1.e6);

  print_results("UA", Class, REFINE_MAX, 0, 0, niter, 
                tmax, mflops, "    coll. point advanced", 
                verified, NPBVERSION, COMPILETIME, CS1, CS2, CS3, CS4, CS5, 
                CS6, "(none)");

  //---------------------------------------------------------------------
  // More timers
  //---------------------------------------------------------------------
  if (timeron) {
    for (i = 1; i <= t_last; i++) {
      trecs[i] = timer_read(i);
    }
    if (tmax == 0.0) tmax = 1.0;

    printf("  SECTION     Time (secs)\n");
    for (i = 1; i <= t_last; i++) {
      printf("  %-10s:%9.3f  (%6.2f%%)\n",
          t_names[i], trecs[i], trecs[i]*100./tmax);
      if (i == t_transfb_c) {
        t2 = trecs[t_convect] - trecs[t_transfb_c];
        printf("    --> %11s:%9.3f  (%6.2f%%)\n", 
            "sub-convect", t2, t2*100./tmax);
      } else if (i == t_transfb) {
        t2 = trecs[t_diffusion] - trecs[t_transf] - trecs[t_transfb];
        printf("    --> %11s:%9.3f  (%6.2f%%)\n", 
            "sub-diffuse", t2, t2*100./tmax);
      }
    }
  }

	//--------------------------------------------------------------------
	// Teardown NUMA control
	//--------------------------------------------------------------------
	numa_shutdown();

  return 0;
}
예제 #24
0
//--------------------------------------------------------------
void Rd::step(int numSteps){
	for(int i = 0; i < numSteps; i++){
		diffusion();
		reaction();
	}
}
예제 #25
0
파일: CVODEModel.C 프로젝트: LLNL/SAMRAI
int CVODEModel::CVSpgmrPrecondSet(
   double t,
   SundialsAbstractVector* y,
   SundialsAbstractVector* fy,
   int jok,
   int* jcurPtr,
   double gamma,
   SundialsAbstractVector* vtemp1,
   SundialsAbstractVector* vtemp2,
   SundialsAbstractVector* vtemp3)
{
#ifndef USE_FAC_PRECONDITIONER
   NULL_USE(t);
   NULL_USE(y);
   NULL_USE(gamma);
#endif
   NULL_USE(fy);
   NULL_USE(jok);
   NULL_USE(jcurPtr);
   NULL_USE(vtemp1);
   NULL_USE(vtemp2);
   NULL_USE(vtemp3);

#ifdef USE_FAC_PRECONDITIONER

   /*
    * Convert passed-in CVODE vectors into SAMRAI vectors
    */
   std::shared_ptr<SAMRAIVectorReal<double> > y_samvect(
      Sundials_SAMRAIVector::getSAMRAIVector(y));

   std::shared_ptr<PatchHierarchy> hierarchy(
      y_samvect->getPatchHierarchy());

   int y_indx = y_samvect->getComponentDescriptorIndex(0);

   /*
    * Construct refine algorithm to fill boundaries of solution vector
    */
   RefineAlgorithm fill_soln_vector_bounds;
   std::shared_ptr<RefineOperator> refine_op(d_grid_geometry->
                                               lookupRefineOperator(d_soln_var,
                                                  "CONSERVATIVE_LINEAR_REFINE"));
   fill_soln_vector_bounds.registerRefine(d_soln_scr_id,
      y_samvect->getComponentDescriptorIndex(0),
      d_soln_scr_id,
      refine_op);

   /*
    * Construct coarsen algorithm to fill interiors on coarser levels
    * with solution on finer level.
    */
   CoarsenAlgorithm fill_soln_interior_on_coarser(d_dim);
   std::shared_ptr<CoarsenOperator> coarsen_op(d_grid_geometry->
                                                 lookupCoarsenOperator(d_soln_var,
                                                    "CONSERVATIVE_COARSEN"));

   fill_soln_interior_on_coarser.registerCoarsen(y_indx,
      y_indx,
      coarsen_op);

   /*
    * Step through levels - largest to smallest
    */
   for (int amr_level = hierarchy->getFinestLevelNumber();
        amr_level >= 0;
        --amr_level) {
      std::shared_ptr<PatchLevel> level(
         hierarchy->getPatchLevel(amr_level));

      std::shared_ptr<RefineSchedule> fill_soln_vector_bounds_sched =
         fill_soln_vector_bounds.createSchedule(level,
            amr_level - 1,
            hierarchy,
            this);

      if (!level->checkAllocated(d_soln_scr_id)) {
         level->allocatePatchData(d_soln_scr_id);
      }
      fill_soln_vector_bounds_sched->fillData(t);

      /*
       * Construct a coarsen schedule for all levels larger than coarsest,
       * and fill interiors of solution vector on coarser levels using fine
       * data.
       */
      if (amr_level > 0) {
         std::shared_ptr<PatchLevel> coarser_level(
            hierarchy->getPatchLevel(amr_level - 1));

         std::shared_ptr<CoarsenSchedule> fill_soln_interior_on_coarser_sched(
            fill_soln_interior_on_coarser.createSchedule(coarser_level,
               level));

         fill_soln_interior_on_coarser_sched->coarsenData();
      }

      for (PatchLevel::iterator p(level->begin()); p != level->end(); ++p) {
         const std::shared_ptr<Patch>& patch = *p;

         const Index ifirst(patch->getBox().lower());
         const Index ilast(patch->getBox().upper());

         std::shared_ptr<SideData<double> > diffusion(
            SAMRAI_SHARED_PTR_CAST<SideData<double>, PatchData>(
               patch->getPatchData(d_diff_id)));
         TBOX_ASSERT(diffusion);

         diffusion->fillAll(1.0);

         TBOX_ASSERT((t - d_current_soln_time) >= 0.);

         /*
          * Set Neumann fluxes and flag array (if desired)
          */
         if (d_use_neumann_bcs) {

            std::shared_ptr<OuterfaceData<int> > flag_data(
               SAMRAI_SHARED_PTR_CAST<OuterfaceData<int>, PatchData>(
                  patch->getPatchData(d_flag_id)));
            std::shared_ptr<OuterfaceData<double> > neuf_data(
               SAMRAI_SHARED_PTR_CAST<OuterfaceData<double>, PatchData>(
                  patch->getPatchData(d_neuf_id)));
            TBOX_ASSERT(flag_data);
            TBOX_ASSERT(neuf_data);

            /*
             * Outerface data access:
             *    neuf_data->getPointer(axis,face);
             * where axis specifies X, Y, or Z (0,1,2 respectively)
             * and face specifies lower or upper (0,1 respectively)
             */

            if (d_dim == Dimension(2)) {
               SAMRAI_F77_FUNC(setneufluxvalues2d, SETNEUFLUXVALUES2D) (
                  ifirst(0), ilast(0),
                  ifirst(1), ilast(1),
                  d_bdry_types,
                  &d_bdry_edge_val[0],
                  flag_data->getPointer(0, 0), // x lower
                  flag_data->getPointer(0, 1), // x upper
                  flag_data->getPointer(1, 0), // y lower
                  flag_data->getPointer(1, 1), // y upper
                  neuf_data->getPointer(0, 0), // x lower
                  neuf_data->getPointer(0, 1), // x upper
                  neuf_data->getPointer(1, 0), // y lower
                  neuf_data->getPointer(1, 1)); // y upper
            } else if (d_dim == Dimension(3)) {
               SAMRAI_F77_FUNC(setneufluxvalues3d, SETNEUFLUXVALUES3D) (
                  ifirst(0), ilast(0),
                  ifirst(1), ilast(1),
                  ifirst(2), ilast(2),
                  d_bdry_types,
                  &d_bdry_face_val[0],
                  flag_data->getPointer(0, 0), // x lower
                  flag_data->getPointer(0, 1), // x upper
                  flag_data->getPointer(1, 0), // y lower
                  flag_data->getPointer(1, 1), // y upper
                  flag_data->getPointer(2, 0), // z lower
                  flag_data->getPointer(2, 1), // z lower
                  neuf_data->getPointer(0, 0), // x lower
                  neuf_data->getPointer(0, 1), // x upper
                  neuf_data->getPointer(1, 0), // y lower
                  neuf_data->getPointer(1, 1), // y upper
                  neuf_data->getPointer(2, 0), // z lower
                  neuf_data->getPointer(2, 1)); // z upper
            }
         }

      } // patch loop

      level->deallocatePatchData(d_soln_scr_id);

   } // level loop

   /*
    * Set boundaries.  The "bdry_types" array holds a set of integers
    * where 0 = dirichlet and 1 = neumann boundary conditions.
    */
   if (d_use_neumann_bcs) {
      d_FAC_solver->setBoundaries("Mixed", d_neuf_id, d_flag_id, d_bdry_types);
   } else {
      d_FAC_solver->setBoundaries("Dirichlet");
   }

   d_FAC_solver->setCConstant(1.0 / gamma);
   d_FAC_solver->setDPatchDataId(d_diff_id);

   /*
    * increment counter for number of precond setup calls
    */
   ++d_number_precond_setup;

#endif
   /*
    * We return 0 or 1 here - 0 if it passes, 1 if it fails.  For now,
    * just be optimistic and return 0. Eventually we should add some
    * assertion handling above to set what this value should be.
    */
   return 0;
}
예제 #26
0
void FluidSimulator::step_density(float *x, float *x0, float*u,
				  float *v, float diffusion_rate){
  add_source(x, x0);
  swap(x0, x); diffusion(0, x, x0, diffusion_rate);
  swap(x0, x); advection(0, x, x0, u, v);
}
예제 #27
0
파일: main.cpp 프로젝트: abzaremba/BS_model
	// returns the variance of the process after a time reversal
	// returns Var(x_{t_0 + Delta t} | x_{t_0} = x_0)
	// By default, it returns the Euler approximation defined by
	// sigma(t_0, x_0)^2 \Delta t
	virtual double variance(Time t0, double x0, Time dt) const {
		double sigma = diffusion(t0, x0);
		return sigma * sigma * dt;
	}
예제 #28
0
void tetDecompositionEngineMesh::move()
{
    scalar deltaZ = engineDB_.pistonDisplacement().value();
    Info<< "deltaZ = " << deltaZ << endl;

    // Position of the top of the static mesh layers above the piston
    scalar pistonPlusLayers = pistonPosition_.value() + pistonLayers_.value();

    pointField newPoints = points();

    tetPolyMesh tetMesh(*this);

    // Select the set of boundary condition types.  For symmetry planes
    // and wedge boundaries, the slip condition should be used;
    // otherwise, use the fixedValue
    wordList boundaryTypes
    (
        boundary().size(),
        fixedValueTetPolyPatchScalarField::typeName
    );

    forAll (boundary(), patchI)
    {
        if
        (
            isType<symmetryFvPatch>(boundary()[patchI])
         || isType<wedgeFvPatch>(boundary()[patchI])
         || isType<emptyFvPatch>(boundary()[patchI])
        )
        {
            boundaryTypes[patchI] = slipTetPolyPatchScalarField::typeName;
        }
    }

    tetPointScalarField motionUz
    (
        IOobject
        (
            "motionUz",
            engineDB_.timeName(),
            engineDB_,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        tetMesh,
        dimensionedScalar("0", dimLength, 0),
        boundaryTypes
    );

    motionUz.boundaryField()[pistonIndex_] == deltaZ;

    {
        scalarField linerPoints =
            motionUz.boundaryField()[linerIndex_].patch()
            .localPoints().component(vector::Z);

        motionUz.boundaryField()[linerIndex_] ==
            deltaZ*pos(deckHeight_.value() - linerPoints)
            *(deckHeight_.value() - linerPoints)
            /(deckHeight_.value() - pistonPlusLayers);
    }

    elementScalarField diffusion
    (
        IOobject
        (
            "motionDiffusion",
            engineDB_.timeName(),
            engineDB_,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        tetMesh,
        dimensionedScalar("d", dimless, 1.0)
    );

    const fvPatchList& patches = boundary();

    forAll (patches, patchI)
    {
        const unallocLabelList& fc = patches[patchI].faceCells();

        forAll (fc, fcI)
        {
            diffusion[fc[fcI]] = 2;
        }
    }

    solve(tetFem::laplacian(diffusion, motionUz));

    newPoints.replace
    (
        vector::Z,
        newPoints.component(vector::Z)
      + scalarField::subField
        (
            motionUz.internalField(),
            newPoints.size()
        )
    );

    if (engineDB_.foundObject<surfaceScalarField>("phi"))
    {
        surfaceScalarField& phi = 
            const_cast<surfaceScalarField&>
            (engineDB_.lookupObject<surfaceScalarField>("phi"));

        const volScalarField& rho =
            engineDB_.lookupObject<volScalarField>("rho");

        const volVectorField& U = 
            engineDB_.lookupObject<volVectorField>("U");

        bool absolutePhi = false;
        if (moving())
        {
            phi += fvc::interpolate(rho)*fvc::meshPhi(rho, U);
            absolutePhi = true;
        }

        movePoints(newPoints);

        if (absolutePhi)
        {
            phi -= fvc::interpolate(rho)*fvc::meshPhi(rho, U);
        }
    }

    pistonPosition_.value() += deltaZ;
    scalar pistonSpeed = deltaZ/engineDB_.deltaT().value();

    Info<< "clearance: " << deckHeight_.value() - pistonPosition_.value() << nl
        << "Piston speed = " << pistonSpeed << " m/s" << endl;
}