// Pressup�e que inc e target sejam positivos e menores que 360!!!! bool circularApproximate(double &val, const double inc, const double target) { if (val == target) return false; if ((inc < 0) || (inc > 360)) return approximate(val, inc, target); if ((target < 0) || (target > 360)) return approximate(val, inc, target); if (val < 0) val = 360.0 + fmod(val, 360.0); else if (val > 360) val = fmod(val, 360.0); if (fabs(val - target) < inc) val = target; else if (target < val) { if ((val - target) < 180) { val -= inc; } else { val += inc; } } else { if ((target - val) > 180) { val -= inc; } else { val += inc; } } return true; }
bool verify (const Metalib&, const Frame& frame, const symbol key, Treelog& msg) const { daisy_assert (key == "SOM_fractions"); daisy_assert (frame.check (key)); daisy_assert (frame.lookup (key) == Attribute::Number); daisy_assert (frame.type_size (key) == Attribute::Variable); std::vector<double> fractions = frame.number_sequence ("SOM_fractions"); bool has_negative = false; double sum = 0.0; for (unsigned int i = 0; i < fractions.size (); i++) { if (fractions[i] < 0) has_negative = true; else sum += fractions[i]; } if (!has_negative && !approximate (sum, 1.0)) { msg.error ("sum must be 1.0"); return false; } if (sum > 1.0 && !approximate (sum, 1.0)) { msg.error ("sum must be at most 1.0"); return false; } return true; };
/** * @brief approximate an Offset */ Polygon_with_holes_2 approximate( const Offset_polygon_with_holes_2 & polygon, const int & n = 0 ){ Polygon_with_holes_2 result( approximate( polygon.outer_boundary(), n ) ); for ( Offset_polygon_with_holes_2::Hole_const_iterator it = polygon.holes_begin(); it != polygon.holes_end(); ++it ){ result.add_hole( approximate( *it, n ) ); } return result ; }
void Ridge::Implementation::update_water (const Geometry1D& geo, const Soil& soil, const std::vector<double>& S_, std::vector<double>& h_, std::vector<double>& Theta_, std::vector<double>& q, const std::vector<double>& q_p, const double dt) { const double E = -(q[last_cell + 1] + q_p[last_cell + 1]); Theta = (I - E) * dt; for (int i = 0; i <= last_cell; i++) Theta += (Theta_[i] - S_[i] * dt) * geo.dz (i); Theta /= dz; const double Theta_sat = soil.Theta (0, 0.0, 0.0); daisy_assert (Theta < Theta_sat); h = soil.h (0, Theta); q[0] = -I; for (int i = 0; i <= last_cell; i++) { q[i+1] = q[i] + geo.dz (i) * (S_[i] + (Theta - Theta_[i]) / dt ) - q_p[i+1]; Theta_[i] = Theta; h_[i] = h; if (!approximate (soil.h (i, Theta), h)) { daisy_assert (i > 0); throw ("Soil hydraulic paramteres change in ridge area"); } } daisy_assert (approximate (E, -(q[last_cell + 1] + q_p[last_cell + 1]))); }
int LexerFlux::read_cell (std::istream& in) { // Internal cell. if (in.peek () == '(') { in.get (); double z; double x; in >> z >> x; if (in.get () != ')') return Geometry::cell_error; if (in.fail ()) return Geometry::cell_error; daisy_assert (center_z.size () == center_x.size ()); int c = 0; for (; c < center_z.size (); c++) if (approximate (center_z[c], z) && approximate (center_x[c], x)) return c; center_z.push_back (z); center_x.push_back (x); daisy_assert (center_x.size () == c + 1); return c; }
bool Robot::animateGoingInitialPosition() { if (!flying && isInBase()) { bool action1 = approximate(pos.x, step, initialPos.x); bool action2 = approximate(pos.z, step, initialPos.z); bool action3 = animateInitialAngles(); return (action1 || action2 || action3); } return false; }
bool valid (const PLF& plf, Treelog& msg) const { if (plf.size () < 1) { msg.error ("PLF must be non-empty"); return false; } const size_t first = 0; const size_t last = plf.size () - 1; const double first_x = plf.x (first); const double first_y = plf.y (first); const double last_x = plf.x (last); const double last_y = plf.y (last); if (first_x < 1 || last_x > 366) { msg.error ("Julian day must be between 1 and 366"); return false; } if (!approximate (first_y, last_y)) { std::ostringstream tmp; tmp << "First (" << first_y << ") and last (" << last_y << ") value must be identical"; msg.error (tmp.str ()); return false; } return true; }
bool Robot::animateRescue() { if (!flying || isOverBase()) return false; if (approximate(propellerAceleration, 1, 50)) { armBase.rotate(propellerAceleration); double s = step*4; double dy = s - (propellerAceleration/50)*s; approximate(pos.y, dy, minY-2); if (pos.y < minY) { lives--; alive = false; return false; } return true; } return false; }
bool Robot::animateStartFlying() { if (!flying) return false; // anima��es paralelas bool action1, action2; double angleArm = arm.getRotation(); if ((action1 = circularApproximate(angleArm, 2, 90))) arm.setRotation(angleArm); double angleClaw = claw.getRotation(); if ((action2 = circularApproximate(angleClaw, 2, 0))) claw.setRotation(angleClaw); // anima��es sequenciais if (!(action1 || action2)) { // novo conjunto de anima��es paralelas double angleProp = claw.getAngle(); if ((action1 = circularApproximate(angleProp, 2, 90))) claw.setAngle(angleProp); double angleAttack = claw.getAttack(); if ((action2 = circularApproximate(angleAttack, 0.2, 10))) claw.setAttack(angleAttack); if (!(action1 || action2)) { if (approximate(propellerAceleration, 1, 50)) armBase.rotate(propellerAceleration); else // se terminaram todas as anima��es, informa return false; } } // ainda existem anima��es // (ou existe a �ltima verifica��o na pr�xima rodada) return true; }
int CollisionList::checkCollisions() { int counter = 0; ListIterator<Object> objIterator1 = *ListIterator<Object>(objList).SetFirst(); ListIterator<Object> objIterator2 = *ListIterator<Object>(objList).SetFirst(); clearCollisionList(); while(!objIterator1.IsLast()) { while(!objIterator2.IsLast()) { if(objIterator1.GetCurrent() == objIterator2.GetCurrent()) { objIterator2.Next(); continue; } if(approximate(objIterator1.GetCurrent(), objIterator2.GetCurrent())) if(collide(objIterator1.GetCurrent(), objIterator2.GetCurrent())) counter++; objIterator2.Next(); } objIterator1.Next(); objIterator2.SetFirst(); } return counter; }
bool VolumeBox::check_border (const Border& border, const Volume& default_volume, Treelog& msg) const { if (const VolumeBox* box_volume = dynamic_cast<const VolumeBox*> (&default_volume)) { bool ok = true; for (size_t i = 0; i < bounds_size; i++) { const Bound& bound = *(this->*(bounds[i].bound)); if (bound.type () != Bound::finite) continue; const Bound& other = *(box_volume->*(bounds[i].bound)); if (other.type () != Bound::finite) continue; if (approximate (bound.value (), other.value ())) continue; if (!((border.*(bounds[i].check_border)) (bound.value (), msg))) ok = false; } return ok; } return check_border (border, msg); }
bool Robot::animateLanding() { if (!flying) return false; if (isOverBase()) { armBase.rotate(propellerAceleration); return approximate(pos.y, step, baseY); } else { if (approximate(propellerAceleration, 1, 0)) armBase.rotate(propellerAceleration); } if (pos.y < minY) { lives--; alive = false; return false; } return approximate(pos.y, step*4, minY-2); }
bool VCheck::SumEqual::valid (double value, Treelog& msg) const { if (approximate (value, sum)) return true; std::ostringstream tmp; tmp << "Sum is " << value << " but should be " << sum; msg.error (tmp.str ()); return false; }
/** * @brief convert Offset_polygon_set_2 to MultiPolygon */ std::auto_ptr< MultiPolygon > polygonSetToMultiPolygon( const Offset_polygon_set_2 & polygonSet, const int & n ) { std::list<Offset_polygon_with_holes_2> res; polygonSet.polygons_with_holes( std::back_inserter(res) ) ; std::auto_ptr< MultiPolygon > result( new MultiPolygon ); for ( std::list<Offset_polygon_with_holes_2>::const_iterator it = res.begin(); it != res.end(); ++it ){ result->addGeometry( new Polygon( approximate( *it, n ) ) ); } return result ; }
bool VCheck::EndValue::valid (double value, Treelog& msg) const { if (approximate (value, fixed)) return true; std::ostringstream tmp; tmp << "End value is " << value << " but should be " << fixed; msg.error (tmp.str ()); return false; }
bool VCheck::FixedPoint::valid (const PLF& plf, Treelog& msg) const { if (approximate (plf (fixed_x), fixed_y)) return true; std::ostringstream tmp; tmp << "Value at " << fixed_x << " should be " << fixed_y << " but is << " << plf (fixed_x); msg.error (tmp.str ()); return false; }
Texture::Texture (const std::vector<double>& lim, const std::vector<double>& frac, double hum, double chalk_) : limit (lim), fraction (frac), accumulated (build_accumulated (lim, fraction)), humus (hum), chalk (chalk_) { daisy_assert (limit.size () == fraction.size ()); daisy_assert (approximate (accumulate (fraction.begin (), fraction.end (), 0.0), 1.0)); }
void SoilWater::mass_balance (const Geometry& geo, double dt, Treelog& msg) { const size_t edge_size = geo.edge_size (); const double total_sink = 10 * geo.total_surface (S_sum_) * dt; const double total_old = 10 * geo.total_surface (Theta_old_); const double total_new = 10 * geo.total_surface (Theta_); double total_boundary_input = 0.0; for (size_t e = 0; e < edge_size; e++) { if (geo.edge_is_internal (e)) continue; const double in_sign = geo.cell_is_internal (geo.edge_to (e)) ? 1.0 : -1.0; const double q = q_primary_[e] + q_secondary_[e]; const double area = geo.edge_area (e); total_boundary_input += q * area * in_sign * dt; } total_boundary_input /= geo.surface_area (); total_boundary_input *= 10; if (!balance (total_old, total_new, total_boundary_input - total_sink)) { const double total_expected = total_old - total_sink + total_boundary_input; const double total_diff = total_new - total_old; const double total_error = total_expected - total_new; static double accumulated_error = 0.0; accumulated_error += total_error; std::ostringstream tmp; tmp << "Water balance: old (" << total_old << ") - sink (" << total_sink << ") + boundary input (" << total_boundary_input << ") != " << total_expected << " mm, got " << total_new << " mm, difference is " << total_diff << " mm, error is " << (total_expected - total_new) << " mm, accumulated " << accumulated_error << " mm"; for (size_t e = 0; e < edge_size; e++) { if (geo.edge_is_internal (e)) continue; tmp << "\nedge " << geo.edge_name (e) << ": primary " << q_primary_[e] << ", secondary = " << q_secondary_[e]; if (!approximate (q_primary_[e] + q_secondary_[e], q_matrix_[e])) tmp << ", NOT MATCHING matrix = " << q_matrix_[e]; tmp << ", tertiary = " << q_tertiary_[e] << ", area = " << geo.edge_area (e); } msg.error (tmp.str ()); } }
void DrainLateral::tick (const Time& time, const Scope& scope, const Geometry& geo, const Soil& soil, const SoilHeat& soil_heat, const Surface& surface, SoilWater& soil_water, Treelog& msg) { // Current pipe level. pipe_outlet->tick (time, scope, msg); set_pipe_level (); const size_t cell_size = geo.cell_size (); // Empty source. fill (S.begin (), S.end (), 0.0); // Find groundwater height. const double old_height = height; height = surface.ponding_average () * 0.1; double lowest = 0.0; for (size_t i = 0; i < cell_size; i++) { // Look for an unsaturated node. const double h = soil_water.h (i); if (h >= 0) continue; // as low as possible. const double z = geo.cell_top (i); if (approximate (z, lowest)) { const double new_height = z + h; // Use closest value to old height; if (height >= 0.0 || (std::fabs (new_height - old_height) < std::fabs (height - old_height))) height = new_height; } else if (z < lowest) { lowest = z; height = z + h; } } // Find sink term. EqDrnFlow = EquilibriumDrainFlow (geo, soil, soil_heat); DrainFlow= geo.total_surface (S); soil_water.drain (S, msg); }
const PLF Texture::build_accumulated (const std::vector<double>& lim, const std::vector<double>& frac) { PLF result; daisy_assert (lim.size () == frac.size ()); double sum = 0.0; for (unsigned int i = 0; i < lim.size (); i++) { sum += frac[i]; result.add (log(lim[i]), sum); } daisy_assert (approximate (sum, 1.0)); return result; }
int main(int argc, char * argv[]) { if (argc != 2) { throw std::invalid_argument("usage: sqrt2 prec"); } else { const std::regex r("[0-9]*"); if (std::regex_match(argv[1], r)) { int n = atoi(std::string(argv[1]).c_str()); if (n < 1) { throw std::invalid_argument("argument must be integer larger than zero"); } else { Rational approx = 1 + approximate(n-1); std::cout << approx << " ~ " << approx.value() << "\n"; } } else { throw std::invalid_argument("argument must be integer larger than zero"); } } }
bool RobotWindow::animateReset() { // definição empírica de uma desaceleração da queda double niceApproximation = (abs(cameraRadius - DEFAUL_RADIUS) / 20) + 0.3; // anima a reposição para o raio inicial bool action1 = approximate(cameraRadius, niceApproximation, DEFAUL_RADIUS); // anima a reposição para a longitude inicial bool action2 = circularApproximate(cameraLongitude, 1.5, DEFAULT_LONGITUDE); // anima a reposição para a latitude inicial bool action3 = circularApproximate(cameraLatitude, 1.5, DEFAULT_LATITUDE); // anima a reposição inicial das parte do robô bool action4 = robot.animateGoingInitialPosition(); // se qualquer animação que afeta a câmera foi feita if (action1 || action2 || action3) { // ajusta a posição da câmera setCameraPosition(cameraLongitude, cameraLatitude); } // retorna indicando se ainda existe animação sendo feita return (action1 || action2 || action3 || action4); }
void wn_trans_problem_feasible ( int *pcode, wn_sparse_matrix *presult, wn_sparse_matrix cost_mat, double i_capacities[], double j_capacities[] ) { int code; initialize(cost_mat,i_capacities,j_capacities); approximate(&code,cost_mat); if(code == WN_SUBOPTIMAL) { wn_sort_sparse_matrix(first_result); } else { simplex_solve(&code,cost_mat); } if(code == WN_SUBOPTIMAL) { wn_gppush(top_group); wn_copy_sparse_matrix(presult,first_result); wn_gppop(); *pcode = WN_SUBOPTIMAL; } else { *presult = NULL; *pcode = WN_INFEASIBLE; } finish(); }
/*Coupon Bond Prices*/ double CB_T0(int M,double t,int generator) { int i; double cb,*g; double x_value,in; g = malloc((d+1)*sizeof(double)); cb=0.; for(i=1;i<=d;i++) { approximate(M,i,t,generator,&x_value,&in); g[i]=x_value; e[i]=in; } for(i=1;i<=N_coupon;i++) cb=cb+C[i]*P(T[0],T[i],g); free(g); return cb; }
bool Robot::animateStopFlying() { if (flying) return false; // anima��es sequenciais if (approximate(propellerAceleration, 1, 0)) { armBase.rotate(propellerAceleration); } else { // anima��es paralelas bool actionS1, actionS2; double angleProp = claw.getAngle(); if ((actionS1 = circularApproximate(angleProp, 2, 0))) claw.setAngle(angleProp); double angleAttack = claw.getAttack(); if ((actionS2 = circularApproximate(angleAttack, 0.2, 0))) claw.setAttack(angleAttack); if (!(actionS1 || actionS2)) { return animateInitialAngles(); } } // ainda existem anima��es // (ou existe a �ltima verifica��o na pr�xima rodada) return true; }
// uses Ipopt to solve problem. void ColaModel::initialSolveIPM() { #if defined(__CPLEX__) #endif #if defined(__MOSEK__) #endif // create ipopt object OsiConicSolverInterface * ipopt_solver = new OsiIpoptSolverInterface(this); ipopt_solver->initialSolve(); // more than one of the following conditions may be true but this is OK for // now. if (ipopt_solver->isAbandoned()) { soco_status_ = ABANDONED; } else if (ipopt_solver->isProvenOptimal()) { soco_status_ = OPTIMAL; } else if (ipopt_solver->isProvenPrimalInfeasible()) { soco_status_ = PRIMAL_INFEASIBLE; } else if (ipopt_solver->isProvenDualInfeasible()) { soco_status_ = DUAL_INFEASIBLE; } else if (ipopt_solver->isPrimalObjectiveLimitReached()) { soco_status_= PRIMAL_OBJECTIVE_LIMIT_REACHED; } else if (ipopt_solver->isDualObjectiveLimitReached()) { soco_status_= DUAL_OBJECTIVE_LIMIT_REACHED; } else if (ipopt_solver->isIterationLimitReached()) { soco_status_= ITERATION_LIMIT_REACHED; } // get ipopt solution double const * sol = ipopt_solver->getColSolution(); delete ipopt_solver; // relax conic constraints using ipopt solution approximate(sol); }
bool Robot::animateSafeLanding() { if (!flying) return false; armBase.rotate(propellerAceleration); if (landingSafePosition) { // anima��es paralelas bool action1, action2; double previus = pos.x; action1 = approximate(pos.x, step, initialPos.x); if (action1 && hasBaseColision()) { pos.x = previus; } action2 = approximate(pos.z, step, initialPos.z); if (!(action1 || action2)) { if (!approximate(pos.y, step, initialPos.y)) { landingSafePosition = false; return false; } } } else { bool action1, action2, action3; double previus; previus = pos.x; if ((action1 = approximate(pos.x, step, -4))) { if (hasBaseColision()) pos.x = previus; } previus = pos.y; if ((action2 = approximate(pos.y, step, 2))) { if (hasBaseColision()) pos.y = previus; } previus = pos.z; if ((action3 = approximate(pos.z, step, -4))) { if (hasBaseColision()) pos.z = previus; } landingSafePosition = !(action1 || action2 || action3); } return true; }
MainWindow::MainWindow(QString filename, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle(QApplication::applicationName()+" "+ QApplication::applicationVersion()); //ui->lastValuesBox->hide(); bytesRead=0; bytesWritten=0; lastValueDoubleClick=new DoubleClickEventFilter(this); ui->lastValuesBox->installEventFilter(lastValueDoubleClick); connect (lastValueDoubleClick,SIGNAL(doubleClicked()),this,SLOT(clearLastValues())); connect (lastValueDoubleClick,SIGNAL(doubleClicked()),this,SLOT(initLastValues())); appSettings=new QSettings(QSettings::IniFormat,QSettings::UserScope,QApplication::organizationName(),QApplication::applicationName(),this); data=new ExperimentData(this); dilatometerData=new DilatometerData(this); data->setDilatometerData(dilatometerData); experiment=new Experiment(&tcpClient,this); dilatometerPlot=NULL; plot=new Plot(this); plot->setExperimentData(data); plot->setAxisTitle(QwtPlot::xBottom,tr("t, sec")); ui->plotLayout->addWidget(plot); connect(ui->actionFullscreen,SIGNAL(triggered(bool)),this,SLOT(setFullscreen(bool))); connect(ui->actionExit,SIGNAL(triggered()),this,SLOT(close())); connect(ui->actionConnect_to,SIGNAL(triggered()),this,SLOT(connectTo())); connect(ui->actionDisconnect,SIGNAL(triggered()),this,SLOT(socketDisconnect())); connect(ui->actionViewData,SIGNAL(triggered()),this,SLOT(showDataViewWindow())); connect(ui->actionReplot,SIGNAL(triggered()),plot,SLOT(replot())); connect(ui->actionClear_plot,SIGNAL(triggered()),plot,SLOT(clear())); connect(ui->actionInitialize,SIGNAL(triggered()),plot,SLOT(initialize())); connect(ui->actionSelect_points,SIGNAL(toggled(bool)),plot,SLOT(selectPointsMode(bool))); connect(ui->actionZoom_to_extents,SIGNAL(triggered()),plot,SLOT(zoomExtents())); connect(ui->actionDraw_incremental,SIGNAL(triggered(bool)),plot,SLOT(setIncrementalDraw(bool))); connect(ui->actionOpen_file,SIGNAL(triggered()),SLOT(openFile())); connect(ui->actionSave_as,SIGNAL(triggered()),SLOT(saveFile())); connect(ui->actionMonitoring_interval,SIGNAL(triggered()),SLOT(setMonitoringInterval())); connect(ui->actionSetup,SIGNAL(triggered()),SLOT(showSetupCurvesDialog())); connect(ui->actionSet_interval,SIGNAL(triggered()),SLOT(setInterval())); connect(ui->actionControl,SIGNAL(triggered()),SLOT(viewExperimentControlDialog())); connect(ui->actionStart,SIGNAL(triggered(bool)),&tcpClient,SLOT(start(bool))); connect(ui->actionApproximate,SIGNAL(triggered()),SLOT(approximate())); connect(ui->actionShow_approximations,SIGNAL(triggered(bool)),plot,SLOT(showApproximationCurves(bool))); connect(ui->actionConfiguration,SIGNAL(triggered()),SLOT(showConfigurationDialog())); connect(ui->actionLast_calculation,SIGNAL(triggered()),SLOT(showCalculationLog())); connect(ui->actionDilatometry,SIGNAL(toggled(bool)),SLOT(showDilatometryPlot(bool))); connect(ui->actionZoom_yLeft_to_extents,SIGNAL(triggered()),SLOT(zoomYLeftToExtents())); connect(ui->actionAbout_Qt,SIGNAL(triggered()),QApplication::instance(),SLOT(aboutQt())); connect(ui->actionAbout,SIGNAL(triggered()),SLOT(showAbout())); connect(ui->actionSet_tolerance_alarm,SIGNAL(triggered()),plot,SLOT(setToleranceAlarm())); connect(ui->actionRemove_tolerance_alarm,SIGNAL(triggered()),plot,SLOT(removeToleranceAlarm())); connect(ui->actionView_tolerance,SIGNAL(triggered()),SLOT(showToleranceAlarmState())); plot->enableAutoZoom(ui->actionAuto_zoom->isChecked()); connect(ui->actionAuto_zoom,SIGNAL(triggered(bool)),plot,SLOT(enableAutoZoom(bool))); //ui->actionDraw_incremental->trigger(); connect(plot,SIGNAL(message(QString)),statusBar(),SLOT(showMessage(QString))); connect(ui->actionSelectT0,SIGNAL(toggled(bool)),plot,SLOT(selectT0(bool))); connect(plot,SIGNAL(T0Selected(bool)),ui->actionSelectT0,SLOT(trigger())); connect(plot,SIGNAL(T0Selected(bool)),ui->actionSelect_points,SLOT(setChecked(bool))); connect(plot,SIGNAL(toleranceAlarmSet(bool)),SLOT(toleranceAlarmStatusChange(bool))); connect(plot,SIGNAL(curvePointClicked(QwtPlotCurve*,int)),this,SLOT(updateSelectedValue(QwtPlotCurve*,int))); connect(&tcpClient,SIGNAL(connected()),this,SLOT(socketConnectedToServer())); connect(&tcpClient,SIGNAL(disconnected()),this,SLOT(socketDisconnectedFromServer())); connect(&tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(socketStateChanged(QAbstractSocket::SocketState))); connect(&tcpClient,SIGNAL(dataLine(QByteArray&)),data,SLOT(parseLine(QByteArray&))); connect(&tcpClient,SIGNAL(initialData()),plot,SLOT(clear())); connect(&tcpClient,SIGNAL(initialData()),data,SLOT(resetData())); connect(&tcpClient,SIGNAL(serverStatus(bool)),ui->actionStart,SLOT(setChecked(bool))); connect(&tcpClient,SIGNAL(bytesWritten(int)),this,SLOT(appendBytesWritten(int))); connect(&tcpClient,SIGNAL(bytesRead(int)),this,SLOT(appendBytesRead(int))); connect(&tcpClient,SIGNAL(serverInterval(int)),experiment,SLOT(setInterval(int))); connect(data,SIGNAL(initialized()),plot,SLOT(initialize())); connect(data,SIGNAL(initialized()),this,SLOT(initLastValues())); connect(data,SIGNAL(pointCount(int)),&pointCountLabel,SLOT(setNum(int))); connect(data,SIGNAL(pointCount(int)),plot,SLOT(drawLastPoint())); /** This connection will cause to plot VLine markers*/ //connect(data,SIGNAL(marker(QPointF,int)),plot,SLOT(appendMarker(QPointF,int))); connect(data,SIGNAL(marker(int)),plot,SLOT(appendMarker(int))); connect(data,SIGNAL(pointCount(int)),this,SLOT(updateLastValues())); connect(data,SIGNAL(heaterPower(int)),this,SLOT(setHeaterPower(int))); connectionLabel.setText("*"); connectionLabel.setToolTip(tr("Connection status:\nGreen - connected\nRed - disconnected")); connectionLabel.setStyleSheet("QLabel {color:red; font-weight:bold;}"); pointCountLabel.setText("0"); pointCountLabel.setToolTip(tr("Number of points")); bytesWrittenLabel.setText("0"); bytesWrittenLabel.setToolTip("Bytes written to network"); bytesReadLabel.setText("0"); bytesReadLabel.setToolTip("Bytes read from network"); ui->heaterPowerBar->setStyleSheet("QProgressBar::chunk {margin: 0px; width: 1px;}"); ui->statusBar->addPermanentWidget(&bytesReadLabel); ui->statusBar->addPermanentWidget(&bytesWrittenLabel); ui->statusBar->addPermanentWidget(&pointCountLabel); ui->statusBar->addPermanentWidget(&connectionLabel); //if file was specified on startup - try open it if (!filename.isEmpty()) openFile(filename); }
double DrainLateral::EquilibriumDrainFlow (const Geometry& geo, const Soil& soil, const SoilHeat& soil_heat) { // If groundwater table is below pipes, there is no flow. if (height <= pipe_level) return 0.0; const size_t cell_size = geo.cell_size (); double Ha = 0.0; // Volume above pipes. double Ka = 0.0; // Conductivity above pipes. double Hb = 0.0; // Volume below pipes. double Kb = 0.0; // Conductivity below pipes. for (size_t i = 0; i < cell_size; i++) { const double z_bottom = geo.cell_bottom (i); // No contribution from cells wholy above the groundwater table. if (z_bottom >= height) continue; // Do not count part of cell above groundwater level. const double z_top = std::min (geo.cell_top (i), height); // Ignore insignificant intervals. if (approximate (z_top, z_bottom)) continue; // Sanity check. daisy_assert (z_top > z_bottom); // Find fraction above and below pipes. const double f_above = (z_top > pipe_level) ? geo.fraction_in_z_interval (i, z_top, pipe_level) : 0.0; const double f_below = (z_bottom < pipe_level) ? geo.fraction_in_z_interval (i, pipe_level, z_bottom) : 0.0; #if 1 const double volume = geo.cell_volume (i); #else const double volume = geo.cell_bottom (i) - geo.cell_top (i); #endif const double K = K_to_pipes (i, soil, soil_heat); Ha += f_above * volume; Ka += f_above * volume * K; Hb += f_below * volume; Kb += f_below * volume * K; } // There may be no nodes with pipe_level < z < height. if (iszero (Ha)) return 0.0; // Make it 1D. Only works for rectangular domain. const double soil_width = geo.right () - geo.left (); Ha /= soil_width; Hb /= soil_width; // Average conductivity. Ka /= (Ha*soil_width); daisy_assert (std::isnormal (Hb)); Kb /= (Hb*soil_width); //--- Calculate equivalent depth --- double De; if (Hb<=0) De = 0.0; else De = eq_depth->value (L, rad, Hb); //---------------------------------- //const double Flow = (4*Ka*Ha*Ha + 2*Kb*Hb*Ha) / (L*x - x*x); //original // const double Flow = (Ka*Ha*Ha + 2*Kb*Hb*Ha) / (L*x - x*x); //corrected const double Flow_a = Ka*Ha*Ha / (L*x - x*x); //Flow above drainpipes const double Flow_b = 2*Kb*De*Ha / (L*x - x*x); //Flow below drainpipes const double Flow = Flow_a + Flow_b; //-------old----- //// Distribution of drain flow among numeric soil layers #if 0 const double a = Flow / (Ka*Ha + Kb*Hb); for (size_t i = 0; i < cell_size; i++) { const double soil_bottom = geo.bottom (); const double f = geo.fraction_in_z_interval (i, height, soil_bottom); S[i] = f * a * K_to_pipes (i, soil, soil_heat); } #endif //--------------- #if 1 // New Distribution of drain flow among numeric soil layers for (size_t i = 0; i < cell_size; i++) { // Find fraction above and below pipes. double z_bottom = geo.cell_bottom (i); double z_top = std::min (geo.cell_top (i), height); // double Deltaz = z_top - z_bottom; double f_above = (z_top > pipe_level) ? geo.fraction_in_z_interval (i, z_top, pipe_level) : 0.0; double f_below = (z_bottom < pipe_level) ? geo.fraction_in_z_interval (i, pipe_level, z_bottom) : 0.0; S[i] = Flow_a * f_above * K_to_pipes (i, soil, soil_heat) / (Ka*Ha); S[i] += Flow_b * f_below * K_to_pipes (i, soil, soil_heat) / (Kb*Hb); } #endif daisy_assert (std::isfinite (Flow)); return Flow; }
Rational approximate(int n) { if (n == 0) return Rational(0,1); Rational r = 1 / (2 + approximate(--n)); return r; }