Пример #1
0
double DLL_FUNC integrated_refraction( const double latitude,
                  const double observed_alt, const double wavelength_microns,
                  const double height_in_meters, const double rel_humid_pct,
                  const double temp_kelvins, const double pressure_mb)
{
   const double g_bar = 9.784 * (1. - .0026 * cos( 2. * latitude)
                        - 2.8e-7 * height_in_meters);      /* (3.281-4) */
   const double Pw0 = rel_humid_pct * pow( temp_kelvins / 247.1, delta) / 100.;
   const double l2 = wavelength_microns * wavelength_microns;
   const double A = (273.15e-6 / 1013.25)
                        * (287.607 + 1.6288 / l2 + .0136 / (l2 * l2));
   REFRACT ref;
   double c5, rval;
   LOCALS l0, lt, ls;

   ref.r0 = re + height_in_meters;
   ref.c2 = g_bar * Md / R;
   ref.gamma = ref.c2 / alpha;    /* = C3 */
   c5 = Pw0 * (1. - Mw / Md) * ref.gamma / (delta - ref.gamma);
   ref.c6 = A * (pressure_mb + c5) / temp_kelvins;
   ref.c7 = (A * c5 + 11.2684e-6 * Pw0) / temp_kelvins;
   ref.c8 = alpha * (ref.gamma - 1.) * ref.c6 / temp_kelvins;
   ref.c9 = alpha * (delta - 1.) * ref.c7 / temp_kelvins;
   ref.temp_0 = temp_kelvins;

   l0.r = ref.r0;
   compute_refractive_index( &ref, &l0, 1);
   l0.z = PI / 2. - observed_alt;
   compute_integrand( &l0);

   lt.r = rt;
   compute_refractive_index( &ref, &lt, 1);
   lt.z = asin( l0.n * ref.r0 * sin( l0.z) / (lt.n * rt));     /* (3.281-9) */
   compute_integrand( &lt);

   ref.nt = lt.n;
   ref.n0_r0_sin_z0 = l0.n * l0.r * sin( l0.z);
   rval = total_refraction( &ref, &l0, &lt, 1, 0);

         /* Now for the stratospheric portion... we need to recompute */
         /* dn/dr at the tropopause, because there's a discontinuity  */
         /* in the derivative as r crosses that point;  which also    */
         /* means we gotta recompute the integrand at r = rt.  So:    */
   compute_refractive_index( &ref, &lt, 0);
   compute_integrand( &lt);

   ls.r = rs;
   compute_refractive_index( &ref, &ls, 0);
   ls.z = asin( ls.n * ref.r0 * sin( l0.z) / (ls.n * rs));
   compute_integrand( &ls);

   return( rval + total_refraction( &ref, &lt, &ls, 0, 0));
}
Пример #2
0
float LineEnergy::calc_energy() {
    // The surface energy of a simple torus is the path integral of the square
    // of the principal curvatures along the arm (as opposed to around it).
    double energy = 0.0;

	int numPoints = torus->getNumControlPoints();
	double dt = 1.0/numPoints;

    for (int v = 0; v < numPoints; v++) {
        energy += compute_integrand(((double) v)/numPoints, dt);
    }

    double twist = torus->getGlobalTwist() * PI / 180;
    energy += twist_weight * (twist*twist);

    return (float) energy;
}
Пример #3
0
static double total_refraction( const REFRACT *ref,
        const LOCALS *l1, const LOCALS *l2, const int is_troposphere,
        const int recursion_depth)
{
   LOCALS mid;
   double change;
   const double iteration_limit = 1.;     /* get 'r' within a meter */
   const double integration_tolerance = .0001;
   const int max_recursion_depth = 20;

   mid.z = (l1->z + l2->z) * .5;
   mid.r = (l1->r + l2->r) * .5;
   do
      {
      compute_refractive_index( ref, &mid, is_troposphere);
      change = -(mid.n * mid.r - ref->n0_r0_sin_z0 / sin( mid.z));
      change /= mid.n + mid.r * mid.dn_dr;           /* (3.281-5) */
      mid.r += change;
      }
      while( fabs( change) > iteration_limit);

   compute_integrand( &mid);
            /* Compute difference between a Simpson's rule integration */
            /* and a trapezoidal one... */
   change = 2. * mid.integrand - (l1->integrand + l2->integrand);
// if( recursion_depth >= max_recursion_depth)
//    printf( "!!! recursed too deep\n");
            /* ...and if it's too great,  recurse with each half: */
   if( fabs( change) > integration_tolerance && recursion_depth < max_recursion_depth)
      return( total_refraction( ref, l1, &mid, is_troposphere, recursion_depth + 1)
            + total_refraction( ref, &mid, l2, is_troposphere, recursion_depth + 1));
   else
      {                    /* Simpson's rule is good enough: */
      const double h = (l2->z - l1->z) / 6.;

      return( h * (4. * mid.integrand + l1->integrand + l2->integrand));
      }
}