int solve_quadratic(double *a, double *r) { double d; double s; d = a[1] * a[1] - 4 * a[2] * a[0]; if (a[2] == 0.) return (solve_linear(a[1], a[0], &r[0])); if (d > 0) { if (a[1] == 0.) { s = fabs(0.5 * sqrt(d) / a[0]); *r = -s; r[1] = s; } else fill_roots(a, d, r); return (2); } else if (d == 0.) { r[0] = -0.5 * a[1] / a[2]; r[1] = r[0]; return (2); } return (0); }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements (optional). //mesh.refine_all_elements(); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_vector_form(callback(linear_form)); // Solve the linear problem. Solution sln; // The NULL pointer means that we do not want the coefficient vector. solve_linear(&space, &wf, matrix_solver, &sln); // Visualize the solution. ScalarView view("Solution", new WinGeom(0, 0, 440, 350)); view.show(&sln); // Wait for the view to be closed. View::wait(); return 0; }
UInt solve_quadratic(double a, double b, double c, double* roots) { if (a == 0) { return solve_linear(b, c, roots); } else { double d = b*b - 4*a*c; if (d < 0) return 0; roots[0] = (-b - sqrt(d)) / (2*a); roots[1] = (-b + sqrt(d)) / (2*a); return 2; } }
int solve_quadratic ( float a, float b, float c, float* x1, float* x2 ) { /* * 2 * Solve ax + bx + c = 0 * * Return values: 0 - no solution * -1 - infinite number of solutions * 1 - one real root, possibly of multiplicity 2. * returned in *x1 * 2 - two distinct real roots of mutiplicity 1 * returned in *x1 and *x2; * -2 - two complex roots (conjugates), * real part returned in *x1, * imaginary part returned in *x2 */ double d; if (a == 0) return(solve_linear (b, c, x1)); d = b*b - 4*a*c; Zero_test2 (d, b*b, 4*a*c); if (d == 0) { *x1 = *x2 = -b/(2*a); return (1); } if (d > 0) { d = sqrt(d); *x1 = (-b + d)/(2*a); Zero_test2 (*x1, -b/2*a, d/2*a); *x2 = (-b - d)/(2*a); Zero_test2 (*x2, -b/2*a, -d/2*a); return (2); } if (d < 0) { d = sqrt(-d); *x1 = -b/(2*a); *x2 = d/(2*a); return (-2); } return 0; }
// Quadratic solver int solve_quadratic(double c[3], double x0[2]) { if (is_zero(c[2])) return solve_linear(c, x0); const double ainv = 1.0/c[2]; // ax^2 + bx + c = 0 const double p = 0.5 * c[1] * ainv; // -b/2a const double q = c[0] * ainv; // c/a double D = p*p-q; if (is_zero(D)) { // quadratic has one repeated root x0[0] = -p; return 1; } if (D > 0) { // quadratic has two real roots D = sqrt(D); x0[0] = D - p; x0[1] = -D - p; return 2; } return 0; // quadratic has no real roots }
/* This is the AC netlist solver. It prepares the circuit list for each requested frequency and solves it then. */ int acsolver::solve (void) { runs++; // run additional noise analysis ? noise = !strcmp (getPropertyString ("Noise"), "yes") ? 1 : 0; // create frequency sweep if necessary if (swp == NULL) { swp = createSweep ("acfrequency"); } // initialize node voltages, first guess for non-linear circuits and // generate extra circuits if necessary init (); setCalculation ((calculate_func_t) &calc); solve_pre (); swp->reset (); for (int i = 0; i < swp->getSize (); i++) { freq = swp->next (); if (progress) logprogressbar (i, swp->getSize (), 40); #if DEBUG && 0 logprint (LOG_STATUS, "NOTIFY: %s: solving netlist for f = %e\n", getName (), (double) freq); #endif // start the linear solver eqnAlgo = ALGO_LU_DECOMPOSITION; solve_linear (); // compute noise if requested if (noise) solve_noise (); // save results saveAllResults (freq); } solve_post (); if (progress) logprogressclear (40); return 0; }
void solve(T const & a , T const & b, T const & c) { if (a == 0) { solve_linear(b, c); } else { solve_quadratic(a, b, c); } }
/* This is the DC netlist solver. It prepares the circuit list and solves it then. */ int dcsolver::solve (void) { // fetch simulation properties saveOPs |= !strcmp (getPropertyString ("saveOPs"), "yes") ? SAVE_OPS : 0; saveOPs |= !strcmp (getPropertyString ("saveAll"), "yes") ? SAVE_ALL : 0; char * solver = getPropertyString ("Solver"); // initialize node voltages, first guess for non-linear circuits and // generate extra circuits if necessary init (); setCalculation ((calculate_func_t) &calc); // start the iterative solver solve_pre (); // choose a solver if (!strcmp (solver, "CroutLU")) eqnAlgo = ALGO_LU_DECOMPOSITION_CROUT; else if (!strcmp (solver, "DoolittleLU")) eqnAlgo = ALGO_LU_DECOMPOSITION_DOOLITTLE; else if (!strcmp (solver, "HouseholderQR")) eqnAlgo = ALGO_QR_DECOMPOSITION; else if (!strcmp (solver, "HouseholderLQ")) eqnAlgo = ALGO_QR_DECOMPOSITION_LS; else if (!strcmp (solver, "GolubSVD")) eqnAlgo = ALGO_SV_DECOMPOSITION; // local variables for the fallback thingies int retry = -1, error, fallback = 0, preferred; int helpers[] = { CONV_SourceStepping, CONV_GMinStepping, CONV_SteepestDescent, CONV_LineSearch, CONV_Attenuation, -1 }; // is a certain convergence helper requested? char * helper = getPropertyString ("convHelper"); convHelper = CONV_None; if (!strcmp (helper, "LineSearch")) { convHelper = CONV_LineSearch; } else if (!strcmp (helper, "SteepestDescent")) { convHelper = CONV_SteepestDescent; } else if (!strcmp (helper, "Attenuation")) { convHelper = CONV_Attenuation; } else if (!strcmp (helper, "gMinStepping")) { convHelper = CONV_GMinStepping; } else if (!strcmp (helper, "SourceStepping")) { convHelper = CONV_SourceStepping; } preferred = convHelper; if (!subnet->isNonLinear ()) { // Start the linear solver. convHelper = CONV_None; error = solve_linear (); } else do { // Run the DC solver once. try_running () { applyNodeset (); error = solve_nonlinear (); #if DEBUG if (!error) { logprint (LOG_STATUS, "NOTIFY: %s: convergence reached after %d iterations\n", getName (), iterations); } #endif /* DEBUG */ if (!error) retry = -1; } // Appropriate exception handling. catch_exception () { case EXCEPTION_NO_CONVERGENCE: pop_exception (); if (preferred == helpers[fallback] && preferred) fallback++; convHelper = helpers[fallback++]; if (convHelper != -1) { logprint (LOG_ERROR, "WARNING: %s: %s analysis failed, using fallback " "#%d (%s)\n", getName (), getDescription (), fallback, getHelperDescription ()); retry++; restart (); } else { retry = -1; } break; default: // Otherwise return. estack.print (); error++; break; } } while (retry != -1); // save results and cleanup the solver saveOperatingPoints (); saveResults ("V", "I", saveOPs); solve_post (); return 0; }
/* solve natural mobility problem with lubrication * with fixed particles in FT version * for both periodic and non-periodic boundary conditions * INPUT * sys : system parameters * f [nm * 3] : * t [nm * 3] : * uf [nf * 3] : * of [nf * 3] : * OUTPUT * u [nm * 3] : * o [nm * 3] : * ff [nf * 3] : * tf [nf * 3] : */ void solve_mix_3ft_matrix (struct stokes * sys, const double *f, const double *t, const double *uf, const double *of, double *u, double *o, double *ff, double *tf) { if (sys->version != 1) { fprintf (stderr, "libstokes solve_mix_3ft_matrix :" " the version is wrong. reset to FT\n"); sys->version = 1; } int np = sys->np; int nm = sys->nm; if (np == nm) { solve_mob_3ft_matrix (sys, f, t, u, o); return; } int n6 = np * 6; int nf = np - nm; int nm6 = nm * 6; int nl = nm * 6; int nh = n6 - nl; double *uf0 = (double *) malloc (sizeof (double) * nf * 3); double *of0 = (double *) malloc (sizeof (double) * nf * 3); double *mat = (double *) malloc (sizeof (double) * n6 * n6); double *mat_ll = (double *) malloc (sizeof (double) * nl * nl); double *mat_lh = (double *) malloc (sizeof (double) * nl * nh); double *mat_hl = (double *) malloc (sizeof (double) * nh * nl); double *mat_hh = (double *) malloc (sizeof (double) * nh * nh); double *mob_ll = (double *) malloc (sizeof (double) * nl * nl); double *mob_lh = (double *) malloc (sizeof (double) * nl * nh); double *mob_hl = (double *) malloc (sizeof (double) * nh * nl); double *mob_hh = (double *) malloc (sizeof (double) * nh * nh); double *b = (double *) malloc (sizeof (double) * n6); double *x = (double *) malloc (sizeof (double) * n6); CHECK_MALLOC (uf0, "solve_mix_3ft_matrix"); CHECK_MALLOC (of0, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_ll, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_lh, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_hl, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_hh, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_ll, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_lh, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_hl, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_hh, "solve_mix_3ft_matrix"); CHECK_MALLOC (b, "solve_mix_3ft_matrix"); CHECK_MALLOC (x, "solve_mix_3ft_matrix"); shift_labo_to_rest_U (sys, nf, uf, uf0); shift_labo_to_rest_O (sys, nf, of, of0); /* the main calculation is done in the the fluid-rest frame; * u(x)=0 as |x|-> infty */ /* b := (FT,UfOf) */ set_ft_by_FT (nm, b, f, t); //set_ft_by_FT (nf, b + nm6, uf, of); set_ft_by_FT (nf, b + nm6, uf0, of0); free (uf0); free (of0); /* mobility matrix in EXTRACTED form */ make_matrix_mob_3all (sys, mat); // sys->version is 1 (FT) split_matrix_fix_3ft (np, nm, mat, mat_ll, mat_lh, mat_hl, mat_hh); solve_linear (nh, nl, mat_hh, mat_hl, mat_lh, mat_ll, mob_hh, mob_hl, mob_lh, mob_ll); merge_matrix_fix_3ft (np, nm, mob_ll, mob_lh, mob_hl, mob_hh, mat); dot_prod_matrix (mat, n6, n6, b, x); set_FT_by_ft (nm, u, o, x); set_FT_by_ft (nf, ff, tf, x + nm6); free (mat); free (mat_ll); free (mat_lh); free (mat_hl); free (mat_hh); free (mob_ll); free (mob_lh); free (mob_hl); free (mob_hh); free (b); free (x); /* for the interface, we are in the labo frame, that is * u(x) is given by the imposed flow field as |x|-> infty */ shift_rest_to_labo_U (sys, nm, u); shift_rest_to_labo_O (sys, nm, o); }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create an H1 space. H1Space* phi_space = new H1Space(&mesh, bc_types, essential_bc_values, P_INIT); H1Space* psi_space = new H1Space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = get_num_dofs(Tuple<Space *>(phi_space, psi_space)); info("ndof = %d.", ndof); // Initialize previous time level solutions. Solution phi_prev_time, psi_prev_time; phi_prev_time.set_exact(&mesh, init_cond_phi); psi_prev_time.set_exact(&mesh, init_cond_psi); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(biform_euler_0_0)); wf.add_matrix_form(0, 1, callback(biform_euler_0_1)); wf.add_matrix_form(1, 0, callback(biform_euler_1_0)); wf.add_matrix_form(1, 1, callback(biform_euler_1_1)); wf.add_vector_form(0, callback(liform_euler_0), H2D_ANY, &phi_prev_time); wf.add_vector_form(1, callback(liform_euler_1), H2D_ANY, &psi_prev_time); // Initialize views. ScalarView view("Psi", 0, 0, 600, 500); view.fix_scale_width(80); // Time stepping loop: int nstep = (int)(T_FINAL/TAU + 0.5); for(int ts = 1; ts <= nstep; ts++) { info("Time step %d:", ts); // Newton's method. info("Solving linear system."); Solution phi, psi; bool is_complex = true; if (!solve_linear(Tuple<Space *>(phi_space, psi_space), &wf, matrix_solver, Tuple<Solution *>(&phi, &psi), NULL, is_complex)) error("Linear solve failed."); // Update previous time level solution. phi_prev_time.copy(&phi); psi_prev_time.copy(&psi); // Show the new time level solution. char title[100]; sprintf(title, "Time step %d", ts); view.set_title(title); view.show(&psi_prev_time); } // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create an H1 space. H1Space* phi_space = new H1Space(&mesh, bc_types, essential_bc_values, P_INIT); H1Space* psi_space = new H1Space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = get_num_dofs(Tuple<Space *>(phi_space, psi_space)); info("ndof = %d.", ndof); // Initialize previous time level solutions. Solution phi_prev_time, psi_prev_time; phi_prev_time.set_exact(&mesh, init_cond_phi); psi_prev_time.set_exact(&mesh, init_cond_psi); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(biform_euler_0_0)); wf.add_matrix_form(0, 1, callback(biform_euler_0_1)); wf.add_matrix_form(1, 0, callback(biform_euler_1_0)); wf.add_matrix_form(1, 1, callback(biform_euler_1_1)); wf.add_vector_form(0, callback(liform_euler_0), H2D_ANY, &phi_prev_time); wf.add_vector_form(1, callback(liform_euler_1), H2D_ANY, &psi_prev_time); // Time stepping loop: int nstep = T_FINAL; for(int ts = 1; ts <= nstep; ts++) { info("Time step %d:", ts); // Newton's method. info("Solving linear system."); Solution phi, psi; bool is_complex = true; if (!solve_linear(Tuple<Space *>(phi_space, psi_space), &wf, matrix_solver, Tuple<Solution *>(&phi, &psi), NULL, is_complex)) error("Linear solve failed."); // Update previous time level solution. phi_prev_time.copy(&phi); psi_prev_time.copy(&psi); } AbsFilter mag2(&psi_prev_time); AbsFilter mag3(&phi_prev_time); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int success = 1; double eps = 1e-5; double val = std::abs(mag2.get_pt_value(0.0, 0.0)); info("Coordinate ( 0, 0) psi value = %lf", std::abs(mag2.get_pt_value(0.0, 0.0))); if (fabs(val - (0.000008)) > eps) { printf("Coordinate ( 0, 0) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(-0.5, -0.5)); info("Coordinate (-0.5,-0.5) psi value = %lf", std::abs(mag2.get_pt_value(-0.5, -0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate (-0.5,-0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.5, -0.5)); info("Coordinate ( 0.5,-0.5) psi value = %lf", std::abs(mag2.get_pt_value(0.5, -0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate ( 0.5,-0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.5, 0.5) psi value = %lf", std::abs(mag2.get_pt_value(0.5, 0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate ( 0.5, 0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(-0.5, 0.5)); info("Coordinate (-0.5, 0.5) psi value = %lf", std::abs(mag2.get_pt_value(-0.5, 0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate (-0.5, 0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.0, 0.0)); info("Coordinate ( 0, 0) phi value = %lf", std::abs(mag3.get_pt_value(0.0, 0.0))); if (fabs(val - (0.000003)) > eps) { printf("Coordinate ( 0, 0) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(-0.5, -0.5)); info("Coordinate (-0.5,-0.5) phi value = %lf", std::abs(mag3.get_pt_value(-0.5, -0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate (-0.5,-0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.5, -0.5)); info("Coordinate ( 0.5,-0.5) phi value = %lf", std::abs(mag3.get_pt_value(0.5, -0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate ( 0.5,-0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.5, 0.5) phi value = %lf", std::abs(mag3.get_pt_value(0.5, 0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate ( 0.5, 0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(-0.5, 0.5)); info("Coordinate (-0.5, 0.5) phi value = %lf", std::abs(mag3.get_pt_value(-0.5, 0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate (-0.5, 0.5) phi value = %lf\n", val); success = 0; } if (success == 1) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }