void MovingMeshFB::moveMesh() { int i, j, k, m; double epsilon = 0.2; double error = 1.; double area, h, l[3], d[3]; while (error > epsilon) { getMoveDirection(); error = 0; for (i = 0;i < n_geometry(2);i ++) { const Point<2>& x0 = point(geometry(2,i).vertex(0)); const Point<2>& x1 = point(geometry(2,i).vertex(1)); const Point<2>& x2 = point(geometry(2,i).vertex(2)); l[0] = (x2[0] - x1[0])*(x2[0] - x1[0]) + (x2[1] - x1[1])*(x2[1] - x1[1]); l[1] = (x0[0] - x2[0])*(x0[0] - x2[0]) + (x0[1] - x2[1])*(x0[1] - x2[1]); l[2] = (x1[0] - x0[0])*(x1[0] - x0[0]) + (x1[1] - x0[1])*(x1[1] - x0[1]); area = (x1[0] - x0[0])*(x2[1] - x0[1]) - (x2[0] - x0[0])*(x1[1] - x0[1]); h = 0.5*area/sqrt(*std::max_element(&l[0], &l[3])); for (k = 0;k < 3;++ k) { m = geometry(2,i).vertex(k); for (d[k] = 0.0, j = 0;j < 2;j ++) { d[k] += move_direction[m][j]*move_direction[m][j]; } } h = sqrt(*std::max_element(&d[0], &d[3]))/h; if (error < h) error = h; } std::cerr << "mesh moving error = " << error << std::endl; getMoveStepLength(); for (i = 0;i < n_move_step;i ++) { updateSolution(); updateMesh(); }; }; }
void layout1(Rectangle rectangles[4]){ Rectangle pack={0,0}; for(int i=0;i<4;i++){ if(pack.height<rectangles[i].height) pack.height=rectangles[i].height; pack.width+=rectangles[i].width; } updateSolution(pack); }
//----------------------------------------------------------------------- void EBConsBackwardEulerIntegrator:: computeDiffusion(LevelData<EBCellFAB>& a_diffusionTerm, const LevelData<EBCellFAB>& a_oldTemperature, Real a_specificHeat, const LevelData<EBCellFAB>& a_oldDensity, const LevelData<EBCellFAB>& a_newDensity, const LevelData<EBCellFAB>& a_source, Real a_time, Real a_timeStep, bool a_zeroTemp) { // Allocate storage for the new temperature. LevelData<EBCellFAB> newTemp; EBCellFactory fact(m_eblg.getEBISL()); newTemp.define(m_eblg.getDBL(), 1, 4*IntVect::Unit, fact); EBLevelDataOps::setVal(newTemp, 0.0); // n+1 // Compute T. updateSolution(newTemp, a_oldTemperature, a_specificHeat, a_oldDensity, a_newDensity, a_source, a_time, a_timeStep, a_zeroTemp); // n+1 n // ([rho Cv T] - [rho Cv T] ) // ----------------------------- - a_source -> a_diffusionTerm. // dt a_oldTemperature.copyTo(a_diffusionTerm); for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit) { EBCellFAB& diff = a_diffusionTerm[dit()]; // n // [rho Cv T] -> diff diff *= a_oldDensity[dit()]; diff *= a_specificHeat; // n+1 // [rho Cv T] -> newRhoCvT EBCellFAB& newRhoCvT = newTemp[dit()]; newRhoCvT *= a_newDensity[dit()]; newRhoCvT *= a_specificHeat; // Subtract newRhoCvT from diff, and divide by -dt. diff -= newRhoCvT; diff /= -a_timeStep; // Subtract off the source. diff -= a_source[dit()]; } }
void layout2(Rectangle rectangles[4]){ for(int bottom=0;bottom<4;bottom++){ Rectangle pack={0,0}; for(int i=0;i<4;i++) if(i!=bottom){ if(pack.height<rectangles[i].height) pack.height=rectangles[i].height; pack.width+=rectangles[i].width; } pack.height+=rectangles[bottom].height; if(pack.width<rectangles[bottom].width) pack.width=rectangles[bottom].width; updateSolution(pack); } }
void layout4(Rectangle rectangles[4]){ for(int left=0;left<4;left++) for(int right=0;right<4;right++){ if(left==right) continue; Rectangle pack={0,0}; for(int i=0;i<4;i++) if(i!=left && i!=right){ pack.height+=rectangles[i].height; if(pack.width<rectangles[i].width) pack.width=rectangles[i].width; } if(pack.height<std::max(rectangles[left].height,rectangles[right].height)) pack.height=std::max(rectangles[left].height,rectangles[right].height); pack.width+=rectangles[left].width+rectangles[right].width; updateSolution(pack); } }
void layout3(Rectangle rectangles[4]){ for(int bottom=0;bottom<4;bottom++) for(int right=0;right<4;right++){ if(bottom==right) continue; Rectangle pack={0,0}; for(int i=0;i<4;i++) if(i!=bottom && i!=right){ if(pack.height<rectangles[i].height) pack.height=rectangles[i].height; pack.width+=rectangles[i].width; } pack.height+=rectangles[bottom].height; if(pack.width<rectangles[bottom].width) pack.width=rectangles[bottom].width; if(pack.height<rectangles[right].height) pack.height=rectangles[right].height; pack.width+=rectangles[right].width; updateSolution(pack); } }
void layout5(Rectangle rectangles[4]){ int sequence[4]={0,1,2,3}; do{ Rectangle pack={0,0}; pack.height=std::max( rectangles[sequence[0]].height+rectangles[sequence[1]].height, rectangles[sequence[2]].height+rectangles[sequence[3]].height); if(rectangles[sequence[0]].width>=rectangles[sequence[1]].width){ if(rectangles[sequence[2]].height<rectangles[sequence[0]].height) pack.width=rectangles[sequence[0]].width+std::max( rectangles[sequence[2]].width, rectangles[sequence[3]].width); else if(rectangles[sequence[2]].height<rectangles[sequence[0]].height+rectangles[sequence[1]].height) pack.width=std::max(rectangles[sequence[0]].width+rectangles[sequence[2]].width, rectangles[sequence[1]].width+rectangles[sequence[3]].width); else pack.width=std::max(rectangles[sequence[0]].width+rectangles[sequence[2]].width, rectangles[sequence[3]].width); } else continue; updateSolution(pack); }while(std::next_permutation(sequence,sequence+4)); }
SimulatorReport nonlinearIteration(const int iteration, const SimulatorTimerInterface& timer, NonlinearSolverType& nonlinear_solver) { SimulatorReport report; failureReport_ = SimulatorReport(); Dune::Timer perfTimer; perfTimer.start(); if (iteration == 0) { // For each iteration we store in a vector the norms of the residual of // the mass balance for each active phase, the well flux and the well equations. residual_norms_history_.clear(); current_relaxation_ = 1.0; dx_old_ = 0.0; convergence_reports_.push_back({timer.reportStepNum(), timer.currentStepNum(), {}}); convergence_reports_.back().report.reserve(11); } report.total_linearizations = 1; try { report += assembleReservoir(timer, iteration); report.assemble_time += perfTimer.stop(); } catch (...) { report.assemble_time += perfTimer.stop(); failureReport_ += report; // todo (?): make the report an attribute of the class throw; // continue throwing the stick } std::vector<double> residual_norms; perfTimer.reset(); perfTimer.start(); // the step is not considered converged until at least minIter iterations is done { auto convrep = getConvergence(timer, iteration,residual_norms); report.converged = convrep.converged() && iteration > nonlinear_solver.minIter();; ConvergenceReport::Severity severity = convrep.severityOfWorstFailure(); convergence_reports_.back().report.push_back(std::move(convrep)); // Throw if any NaN or too large residual found. if (severity == ConvergenceReport::Severity::NotANumber) { OPM_THROW(Opm::NumericalIssue, "NaN residual found!"); } else if (severity == ConvergenceReport::Severity::TooLarge) { OPM_THROW(Opm::NumericalIssue, "Too large residual found!"); } } // checking whether the group targets are converged if (wellModel().wellCollection().groupControlActive()) { report.converged = report.converged && wellModel().wellCollection().groupTargetConverged(wellModel().wellState().wellRates()); } report.update_time += perfTimer.stop(); residual_norms_history_.push_back(residual_norms); if (!report.converged) { perfTimer.reset(); perfTimer.start(); report.total_newton_iterations = 1; // enable single precision for solvers when dt is smaller then 20 days //residual_.singlePrecision = (unit::convert::to(dt, unit::day) < 20.) ; // Compute the nonlinear update. const int nc = UgGridHelpers::numCells(grid_); BVector x(nc); // apply the Schur compliment of the well model to the reservoir linearized // equations wellModel().linearize(ebosSimulator().model().linearizer().jacobian(), ebosSimulator().model().linearizer().residual()); // Solve the linear system. linear_solve_setup_time_ = 0.0; try { solveJacobianSystem(x); report.linear_solve_setup_time += linear_solve_setup_time_; report.linear_solve_time += perfTimer.stop(); report.total_linear_iterations += linearIterationsLastSolve(); } catch (...) { report.linear_solve_setup_time += linear_solve_setup_time_; report.linear_solve_time += perfTimer.stop(); report.total_linear_iterations += linearIterationsLastSolve(); failureReport_ += report; throw; // re-throw up } perfTimer.reset(); perfTimer.start(); // handling well state update before oscillation treatment is a decision based // on observation to avoid some big performance degeneration under some circumstances. // there is no theorectical explanation which way is better for sure. wellModel().postSolve(x); if (param_.use_update_stabilization_) { // Stabilize the nonlinear update. bool isOscillate = false; bool isStagnate = false; nonlinear_solver.detectOscillations(residual_norms_history_, iteration, isOscillate, isStagnate); if (isOscillate) { current_relaxation_ -= nonlinear_solver.relaxIncrement(); current_relaxation_ = std::max(current_relaxation_, nonlinear_solver.relaxMax()); if (terminalOutputEnabled()) { std::string msg = " Oscillating behavior detected: Relaxation set to " + std::to_string(current_relaxation_); OpmLog::info(msg); } } nonlinear_solver.stabilizeNonlinearUpdate(x, dx_old_, current_relaxation_); } // Apply the update, with considering model-dependent limitations and // chopping of the update. updateSolution(x); report.update_time += perfTimer.stop(); } return report; }
// ################################################################## // // step solution // // ################################################################## void SOLVER::stepSolution(void) { double coef; // // Euler explicit // if (strcmp(stepType,"euler") == 0 ) { if (sb->visc) { cout << "Not yet implemented. exit.\n"; exit(1); // computeRHSv; } else computeRHS("explicit"); coef = 1.; updateSolution(sb->q,sb->q,coef); } // // Runge - Kutta 3 // else if (strcmp(stepType,"rk3") == 0 ) { // RK step 1 computeRHS("explicit"); coef=0.25; updateSolution(sb->q,sb->qt,coef); coef=8.0/15; updateSolution(sb->q,sb->q,coef); // RK step 2 computeRHS("explicit"); coef=5.0/12; updateSolution(sb->qt,sb->q,coef); // RK step 3 computeRHS("explicit"); coef=3.0/4.0; updateSolution(sb->qt,sb->q,coef); } // // ADI ( Alternating Direction Implicit) // else if (strcmp(stepType,"ADI")==0) { // if(sb->idual==0) // { computeRHS("implicit"); ADI(); // } // else //dual time stepping // { // printf("Error. Dual Time stepping not yet implemented.\n"); // exit(1); // // for (i = 0; i < NQ*mb->nCell; i++) sb->pq[i] = sb->q[i]; // // for(k = 0; k < sb->ndual; k++) // // { // // DualcomputeRHSk(g,s,l2norm,s->cflnum); // // DualADI(g,s,s->cflnum,dt); // // } // // for (i=0;i<NVAR*g->ncells;i++) s->q[i] = s->pq[i]; // } } }