static WEPolyhedron *compute_polyhedron( Triangulation *manifold) { int i; WEPolyhedron *polyhedron; static const int num_precisions = 5; static const Real precision[5] = {1e-8, 1e-6, 1e-10, 1e-4, 1e-12}; for (i = 0; i < num_precisions; i++) { polyhedron = Dirichlet( manifold, precision[i], TRUE, Dirichlet_stop_here, TRUE); if (polyhedron != NULL) return polyhedron; } /* * Even after trying five precisions we still couldn't * get a Dirichlet domain. */ return NULL; }
void UZRectMollerup::upperboundary (const GeometryRect& geo, const Soil& soil, const ublas::vector<double>& T, const Surface& surface, std::vector<top_state>& state, const ublas::vector<double>& remaining_water, const ublas::vector<double>& h, const ublas::vector<double>& Kedge, ublas::vector<double>& dq, ublas::banded_matrix<double>& Dm_mat, ublas::vector<double>& Dm_vec, ublas::vector<double>& Gm, ublas::vector<double>& B, const double ddt, const int debug, Treelog& msg, const double BIG_DT) { const std::vector<size_t>& edge_above = geo.cell_edges (Geometry::cell_above); const size_t edge_above_size = edge_above.size (); for (size_t i = 0; i < edge_above_size; i++) { const size_t edge = edge_above[i]; const int cell = geo.edge_other (edge, Geometry::cell_above); daisy_assert (geo.cell_is_internal (cell)); const double in_sign = geo.cell_is_internal (geo.edge_to (edge)) ? 1.0 : -1.0; daisy_assert (in_sign < 0); const double area = geo.edge_area (edge); const double sin_angle = geo.edge_sin_angle (edge); switch (surface.top_type (geo, edge)) { case Surface::forced_flux: { const double flux = -surface.q_top (geo, edge, BIG_DT); Neumann (edge, cell, area, in_sign, flux, dq, B); } break; case Surface::forced_pressure: { const double value = -Kedge (edge) * geo.edge_area_per_length (edge); const double pressure = surface.h_top (geo, edge); Dirichlet (edge, cell, area, in_sign, sin_angle, Kedge (edge), h (cell), value, pressure, dq, Dm_mat, Dm_vec, Gm); } break; case Surface::limited_water: { const double h_top = remaining_water (i); // We pretend that the surface is particlaly saturated. const double K_sat = soil.K (cell, 0.0, 0.0, T (cell)); const double K_cell = Kedge (edge); const double K_edge = 0.5 * (K_cell + K_sat); const double dz = geo.edge_length (edge); daisy_assert (approximate (dz, -geo.cell_z (cell))); double q_in_avail = h_top / ddt; const double q_in_pot = K_edge * (h_top - h (cell) + dz) / dz; // Decide type. bool is_flux = h_top <= 0.0 || q_in_pot > q_in_avail; if (is_flux) { state[i] = top_flux; Neumann (edge, cell, area, in_sign, q_in_avail, dq, B); } else // Pressure { state[i] = top_pressure; if (debug > 0 && q_in_pot < 0.0) { std::ostringstream tmp; tmp << "q_in_pot = " << q_in_pot << ", q_avail = " << q_in_avail << ", h_top = " << h_top << ", h (cell) = " << h (cell) << " K (edge) = " << Kedge (edge) << ", K_sat = " << K_sat << ", K_edge = " << K_edge <<", dz = " << dz << ", ddt = " << ddt << ", is_flux = " << is_flux << "\n"; msg.message (tmp.str ()); } const double value = -K_edge * geo.edge_area_per_length (edge); const double pressure = h_top; Dirichlet (edge, cell, area, in_sign, sin_angle, K_edge, h (cell), value, pressure, dq, Dm_mat, Dm_vec, Gm); } if (debug == 3) { std::ostringstream tmp; tmp << "edge = " << edge << ", K_edge = " << K_edge << ", h_top = " << h_top << ", dz = " << dz << ", q_avail = " << q_in_avail << ", q_pot = " << q_in_pot << ", is_flux = " << is_flux; msg.message (tmp.str ()); } } break; case Surface::soil: throw "Don't know how to handle this surface type"; default: daisy_panic ("Unknown surface type"); } } }
void UZRectMollerup::lowerboundary (const GeometryRect& geo, const Groundwater& groundwater, const std::vector<bool>& active_lysimeter, const ublas::vector<double>& h, const ublas::vector<double>& Kedge, ublas::vector<double>& dq, ublas::banded_matrix<double>& Dm_mat, ublas::vector<double>& Dm_vec, ublas::vector<double>& Gm, ublas::vector<double>& B, Treelog& msg) { const std::vector<size_t>& edge_below = geo.cell_edges (Geometry::cell_below); const size_t edge_below_size = edge_below.size (); for (size_t i = 0; i < edge_below_size; i++) { const size_t edge = edge_below[i]; const int cell = geo.edge_other (edge, Geometry::cell_below); daisy_assert (geo.cell_is_internal (cell)); const double in_sign = geo.cell_is_internal (geo.edge_to (edge)) ? 1.0 : -1.0; daisy_assert (in_sign > 0); const double area = geo.edge_area (edge); const double sin_angle = geo.edge_sin_angle (edge); switch (groundwater.bottom_type ()) { case Groundwater::free_drainage: { const double sin_angle = geo.edge_sin_angle (edge); //const double flux = -in_sign * sin_angle * K (cell) * area; //old const double flux = -in_sign * sin_angle * Kedge (edge); Neumann (edge, cell, area, in_sign, flux, dq, B); } break; case Groundwater::forced_flux: { const double flux = groundwater.q_bottom (edge); Neumann (edge, cell, area, in_sign, flux, dq, B); } break; case Groundwater::pressure: { const double value = -Kedge (edge) * geo.edge_area_per_length (edge); const double pressure = groundwater.table () - geo.zplus (cell); Dirichlet (edge, cell, area, in_sign, sin_angle, Kedge (edge), h (cell), value, pressure, dq, Dm_mat, Dm_vec, Gm); } break; case Groundwater::lysimeter: { if (active_lysimeter[cell]) { //Neumann - not so good //const double flux = -in_sign * sin_angle * K (cell); //Neumann (edge, cell, area, in_sign, flux, dq, B); //Dirichlet - better const double value = -Kedge (edge) * geo.edge_area_per_length (edge); const double pressure = 0.0; Dirichlet (edge, cell, area, in_sign, sin_angle, Kedge (edge), h (cell), value, pressure, dq, Dm_mat, Dm_vec, Gm); } else // Indsat af [email protected] Fri Jul 10 11:21:14 2009 { const double flux = 0.0; Neumann (edge, cell, area, in_sign, flux, dq, B); } } break; default: daisy_panic ("Unknown groundwater type"); } } }
void makeFlux(FVMesh2D &m, FVVect<double> &phi, FVVect< FVPoint2D<double> > &u, FVVect<double> &Vd,FVVect<double> &Vn, FVVect<double> &F,Parameter ¶) { //FVEdge2D *ptr_e; double leftPhi,rightPhi,normal_velocity; FVPoint2D<double> BB; m.beginEdge(); size_t edges = m.getNbEdge(); //avoid getting static values in loops const unsigned int dirCode = para.getUnsigned("DirichletCode"); const unsigned int neuCode = para.getUnsigned("NeumannCode"); const double difusion = getDiffusion(NULL,para); #pragma omp parallel for private(normal_velocity,leftPhi,rightPhi) for(size_t i = 0; i < edges; i++) { FVEdge2D *ptr_e; //ptr_e = m.nextEdge(); ptr_e = m.getEdge(i); normal_velocity = Dot(u[ptr_e->label-1],ptr_e->normal); leftPhi = phi[ptr_e->leftCell->label-1]; if(ptr_e->rightCell) { // edge has the code = 0 rightPhi = phi[ptr_e->rightCell->label-1]; // compute the convection contribution if(normal_velocity<0) { F[ptr_e->label-1] = normal_velocity*rightPhi; } else { F[ptr_e->label-1] = normal_velocity*leftPhi; } // compute the diffusive contribution BB=ptr_e->rightCell->centroid - ptr_e->leftCell->centroid; F[ptr_e->label-1] -= difusion*(rightPhi-leftPhi)/Norm(BB); } else { // we are on the boundary if(ptr_e->code == dirCode) { // we have a Dirichlet condition rightPhi = Dirichlet(ptr_e->centroid,para); // compute the convection contribution if(normal_velocity<0) { F[ptr_e->label-1] = normal_velocity*rightPhi; } else { F[ptr_e->label-1] = normal_velocity*leftPhi; } // compute the diffusive contribution BB = ptr_e->centroid - ptr_e->leftCell->centroid; F[ptr_e->label-1] -= difusion*(rightPhi-leftPhi)/Norm(BB); } if(ptr_e->code == neuCode) { // we have a Neumann condition F[ptr_e->label-1] = Neumann(ptr_e->centroid,para); } } // here, we have all the data to compute the flux F[ptr_e->label-1] *= ptr_e->length; } }
void viterbi(int *x_T, int *x_N, double *x_A, double *x_Pi, double *mu, double *sigma, double *obs, int *overlap, double *overlaps, int *overlap_ids, int *no_overlaps, int *start_overlaps, int *dist, int *L, int *distance, double *P, int *Q, double *mean_ref, double *sd_min, double *mean_sd, int *prior, double *x_W_A, double *W_Pi) { int N = *x_N; int T = *x_T; double A[N][N]; double W_A[N][N]; double Pi[N]; double delta[T][N]; int psi[T][N]; // Fill A and Pi for (int i = 0; i < N; i++) { for (int j = 0, index = i; j < N; j++, index += N) { if (*dist) A[i][j] = x_A[index]; else A[i][j] = safe_log(x_A[index]); W_A[i][j] = x_W_A[index]; } Pi[i] = safe_log(x_Pi[i]); } // Initialization for (int i = 0; i < N; i++) { delta[0][i] = emission_prob(obs[0], mu[i], sigma[i], 1) + Pi[i]; } // Recursion int no_olaps; int start; double sum_olap; double trans; if (T > 1) { for (int t = 1; t < T; t++) { no_olaps = no_overlaps[t]; int olap_ids[no_olaps]; double olaps[no_olaps]; start = start_overlaps[t]; sum_olap = 1.0; if (*overlap) { for (int i = 0; i < no_olaps; i++) { olap_ids[i] = overlap_ids[start + i]; olaps[i] = overlaps[start + i]; sum_olap += olaps[i]; } olaps[no_olaps-1] = 1.0; } for (int j = 0; j < N; j++) { double prev[N]; if (*dist) prev[0] = safe_log(trans_dist(distance[t], A[0][j], *L, N)) + delta[t-1][0]; else prev[0] = A[0][j] + delta[t-1][0]; double max = prev[0]; int maxid = 0; if (N > 1) { for (int i = 1; i < N; i++) { if (*dist) prev[i] = safe_log(trans_dist(distance[t], A[i][j], *L, N)) + delta[t-1][i]; else prev[i] = A[i][j] + delta[t-1][i]; if (prev[i] > max) { maxid = i; max = prev[i]; } } } psi[t][j] = maxid; trans = 0.0; if (*overlap) { int qt[no_olaps]; if (no_olaps > 1) { int q = j; int iter = no_olaps-2; for (int i = t-1; i >= olap_ids[0]; i--) { q = psi[i+1][q]; if (member(i, olap_ids, no_olaps)) { qt[iter] = q; iter--; } } } qt[no_olaps-1] = j; int id; for (int i = 0; i < no_olaps; i++) { id = qt[i]; trans += emission_prob(obs[t], mu[id], sigma[id], 1) + safe_log(olaps[i] / sum_olap); } } else { trans = emission_prob(obs[t], mu[j], sigma[j], 1); } if (*dist) delta[t][j] = delta[t-1][psi[t][j]] + safe_log(trans_dist(distance[t], A[psi[t][j]][j], *L, N)) + trans; else delta[t][j] = delta[t-1][psi[t][j]] + A[psi[t][j]][j] + trans; } } } // Termination double max = delta[T-1][0]; int maxid = 0; if (N > 1) { for (int i = 1; i < N; i++) { if (delta[T-1][i] > max) { maxid = i; max = delta[T-1][i]; } } } Q[T-1] = maxid; *P = delta[T-1][Q[T-1]]; // Calculate parameter prior probability if (*prior) { for (int i = 0; i < N; i++) { *P += safe_log(Dirichlet(A[i], W_A[i], N)); *P += safe_log(*sd_min / sigma[i]) + emission_prob(mu[i], mean_ref[i], *mean_sd, 1); } *P += safe_log(Dirichlet(Pi, W_Pi, N)); } // Path backtracking if (T > 1) { for (int t = T-2; t >= 0; t--) { Q[t] = psi[t+1][Q[t+1]]; } } }