Exemple #1
0
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);
}
Exemple #2
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;
	}
}
Exemple #4
0
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;
}
Exemple #7
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); }
		}
Exemple #8
0
/* 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;
}
Exemple #9
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);
}
Exemple #10
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);

  // 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;
}
Exemple #11
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;
  }
}