/////////////////////////////////////////////////////////////////////////////// /// 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( )
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; } }
/////////////////////////////////////////////////////////////////////////////// /// 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( )
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); }
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); }
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; }
//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; }
//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); }
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_); }
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(); } }
/////////////////////////////////////////////////////////////////////////////// /// 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( )
/* ************************************************************************* * * 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); } } } }
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; } }
double driftCorrected(double X, double t, double B) { // Corrected drift term return drift(X,t) - B*diffusion(X,t)* diffusionDerivative(X, t); }
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. }
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(); } }
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; }
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; }
//-------------------------------------------------------------- void Rd::step(int numSteps){ for(int i = 0; i < numSteps; i++){ diffusion(); reaction(); } }
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; }
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); }
// 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; }
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; }