void ParsedVelocitySource<Mu>::compute_postprocessed_quantity( unsigned int quantity_index,
                                                            const AssemblyContext& context,
                                                            const libMesh::Point& point,
                                                            libMesh::Real& value )
  {
    libMesh::DenseVector<libMesh::Number> output_vec(3);

    if( quantity_index == this->_parsed_velocity_source_x_index )
      {
        (*this->velocity_source_function)(context, point, context.time, output_vec);

        value = output_vec(0);
      }
    else if( quantity_index == this->_parsed_velocity_source_y_index )
      {
        (*this->velocity_source_function)(context, point, context.time, output_vec);

        value = output_vec(1);
      }
    else if( quantity_index == this->_parsed_velocity_source_z_index )
      {
        (*this->velocity_source_function)(context, point, context.time, output_vec);

        value = output_vec(2);
      }

    return;
  }
Esempio n. 2
0
int main() 
{
  // Change this type definition to double if your gpu supports that
  typedef float       ScalarType;
  
  // Create vectors of eight complex values (represented as pairs of floating point values: [real_0, imag_0, real_1, imag_1, etc.])
  viennacl::vector<ScalarType> input_vec(16);  
  viennacl::vector<ScalarType> output_vec(16); 
  
  // Fill with values (use viennacl::copy() for larger data!)
  for (std::size_t i=0; i<input_vec.size(); ++i)
  {
    if (i%2 == 0)
      input_vec(i) = ScalarType(i/2);  // even indices represent real part
    else
      input_vec(i) = 0;                // odd indices represent imaginary part
  }
  
  // Print the vector
  std::cout << "input_vec: " << input_vec << std::endl;
  
  // Compute FFT and store result in 'output_vec'
  std::cout << "Computing FFT..." << std::endl;
  viennacl::fft(input_vec, output_vec);
  
  // Compute FFT and store result directly in 'input_vec'
  viennacl::inplace_fft(input_vec);
  
  // Print result
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "output_vec: " << output_vec << std::endl;

  std::cout << "Computing inverse FFT..." << std::endl;
  viennacl::ifft(input_vec, output_vec); // either store result into output_vec
  viennacl::inplace_ifft(input_vec);     // or compute in-place  
  
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "output_vec: " << output_vec << std::endl;
  
  //
  //  That's it.
  //
  std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;

  return EXIT_SUCCESS;
}
Esempio n. 3
0
  void VelocityPenalty<Mu>::compute_postprocessed_quantity( unsigned int quantity_index,
                                                            const AssemblyContext& context,
                                                            const libMesh::Point& point,
                                                            libMesh::Real& value )
  {
    libMesh::DenseVector<libMesh::Number> output_vec(3);

    if( quantity_index == this->_velocity_penalty_x_index )
      {
        (*this->normal_vector_function)(context, point, context.time, output_vec);

        value = output_vec(0);
      }
    else if( quantity_index == this->_velocity_penalty_y_index )
      {
        (*this->normal_vector_function)(context, point, context.time, output_vec);

        value = output_vec(1);
      }
    else if( quantity_index == this->_velocity_penalty_z_index )
      {
        (*this->normal_vector_function)(context, point, context.time, output_vec);

        value = output_vec(2);
      }
    else if( quantity_index == this->_velocity_penalty_base_x_index )
      {
        (*this->base_velocity_function)(context, point, context.time, output_vec);

        value = output_vec(0);
      }
    else if( quantity_index == this->_velocity_penalty_base_y_index )
      {
        (*this->base_velocity_function)(context, point, context.time, output_vec);

        value = output_vec(1);
      }
    else if( quantity_index == this->_velocity_penalty_base_z_index )
      {
        (*this->base_velocity_function)(context, point, context.time, output_vec);

        value = output_vec(2);
      }

    return;
  }
Esempio n. 4
0
/**
*   In the main()-routine we create a few vectors and matrices and then run FFT on them.
**/
int main()
{
  // Feel free to change this type definition to double if your gpu supports that
  typedef float ScalarType;

  // Create vectors of eight complex values (represented as pairs of floating point values: [real_0, imag_0, real_1, imag_1, etc.])
  viennacl::vector<ScalarType> input_vec(16);
  viennacl::vector<ScalarType> output_vec(16);
  viennacl::vector<ScalarType> input2_vec(16);

  viennacl::matrix<ScalarType> m(4, 8);
  viennacl::matrix<ScalarType> o(4, 8);

  for (std::size_t i = 0; i < m.size1(); i++)
    for (std::size_t s = 0; s < m.size2(); s++)
      m(i, s) = ScalarType((i + s) / 2);

  /**
  *  Fill the vectors and matrices with values by using operator(). Use viennacl::copy() for larger data!
  **/
  for (std::size_t i = 0; i < input_vec.size(); ++i)
  {
    if (i % 2 == 0)
    {
      input_vec(i) = ScalarType(i / 2); // even indices represent real part
      input2_vec(i) = ScalarType(i / 2);
    } else
      input_vec(i) = 0;            // odd indices represent imaginary part
  }

  /**
  * Compute the FFT and store result in 'output_vec'
  **/
  std::cout << "Computing FFT Matrix" << std::endl;
  std::cout << "m: " << m << std::endl;
  std::cout << "o: " << o << std::endl;
  viennacl::fft(m, o);
  std::cout << "Done" << std::endl;
  std::cout << "m: " << m << std::endl;
  std::cout << "o: " << o << std::endl;
  std::cout << "Transpose" << std::endl;

  viennacl::linalg::transpose(m, o);
  //viennacl::linalg::transpose(m);
  std::cout << "m: " << m << std::endl;
  std::cout << "o: " << o << std::endl;

  std::cout << "---------------------" << std::endl;

  /**
  *  Compute the FFT using the Bluestein algorithm (usually faster, but higher memory footprint)
  **/
  std::cout << "Computing FFT bluestein" << std::endl;
  // Print the vector
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "Done" << std::endl;
  viennacl::linalg::bluestein(input_vec, output_vec, 0);
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "output_vec: " << output_vec << std::endl;
  std::cout << "---------------------" << std::endl;

  /**
  *  Computing the standard radix-FFT for a vector
  **/
  std::cout << "Computing FFT " << std::endl;
  // Print the vector
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "Done" << std::endl;
  viennacl::fft(input_vec, output_vec);
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "output_vec: " << output_vec << std::endl;
  std::cout << "---------------------" << std::endl;

  /**
  *  Computing the standard inverse radix-FFT for a vector
  **/
  std::cout << "Computing inverse FFT..." << std::endl;
  //viennacl::ifft(output_vec, input_vec); // either store result into output_vec
  viennacl::inplace_ifft(output_vec);     // or compute in-place
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "output_vec: " << output_vec << std::endl;
  std::cout << "---------------------" << std::endl;

  /**
  *  Convert a real vector to an interleaved complex vector and back.
  *  Entries with even indices represent real parts, odd indices imaginary parts.
  **/
  std::cout << "Computing real to complex..." << std::endl;
  std::cout << "input_vec: " << input_vec << std::endl;
  viennacl::linalg::real_to_complex(input_vec, output_vec, input_vec.size() / 2); // or compute in-place
  std::cout << "output_vec: " << output_vec << std::endl;
  std::cout << "---------------------" << std::endl;

  std::cout << "Computing complex to real..." << std::endl;
  std::cout << "input_vec: " << input_vec << std::endl;
  //viennacl::ifft(output_vec, input_vec); // either store result into output_vec
  viennacl::linalg::complex_to_real(input_vec, output_vec, input_vec.size() / 2); // or compute in-place
  std::cout << "output_vec: " << output_vec << std::endl;
  std::cout << "---------------------" << std::endl;

  /**
  *  Point-wise multiplication of two complex vectors.
  **/
  std::cout << "Computing multiply complex" << std::endl;
  // Print the vector
  std::cout << "input_vec: " << input_vec << std::endl;
  std::cout << "input2_vec: " << input2_vec << std::endl;
  viennacl::linalg::multiply_complex(input_vec, input2_vec, output_vec);
  std::cout << "Done" << std::endl;
  std::cout << "output_vec: " << output_vec << std::endl;
  std::cout << "---------------------" << std::endl;

  /**
  *  That's it.
  **/
  std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;
  return EXIT_SUCCESS;
}
Esempio n. 5
0
  bool AveragedFanBase<Mu>::compute_force
  ( const libMesh::Point& point,
    const libMesh::Real time,
    const libMesh::NumberVectorValue& U,
    libMesh::NumberVectorValue& F,
    libMesh::NumberTensorValue *dFdU)
  {
    // Find base velocity of moving fan at this point
    libMesh::DenseVector<libMesh::Number> output_vec(3);

    base_velocity_function(point, time,
                           output_vec);

    const libMesh::NumberVectorValue U_B(output_vec(0),
                                         output_vec(1),
                                         output_vec(2));

    const libMesh::Number U_B_size = U_B.norm();

    // If there's no base velocity there's no fan
    if (!U_B_size)
      return false;

    // Normal in fan velocity direction
    const libMesh::NumberVectorValue N_B =
      libMesh::NumberVectorValue(U_B/U_B_size);

    local_vertical_function(point, time,
                            output_vec);

    // Normal in fan vertical direction
    const libMesh::NumberVectorValue N_V(output_vec(0),
                                         output_vec(1),
                                         output_vec(2));

    // Normal in radial direction (or opposite radial direction,
    // for fans turning clockwise!)
    const libMesh::NumberVectorValue N_R = N_B.cross(N_V);

    // Fan-wing-plane component of local relative velocity
    const libMesh::NumberVectorValue U_P = U - (U*N_R)*N_R - U_B;

    const libMesh::Number U_P_size = U_P.norm();

    // If there's no flow in the fan's frame of reference, there's no
    // lift or drag.  FIXME - should we account for drag in the
    // out-of-plane direction?
    if (!U_P_size)
      return false;

    // Direction opposing drag
    const libMesh::NumberVectorValue N_drag =
      libMesh::NumberVectorValue(-U_P/U_P_size);

    // Direction opposing lift
    const libMesh::NumberVectorValue N_lift = N_drag.cross(N_R);

    // "Forward" velocity
    const libMesh::Number u_fwd = -(U_P * N_B);

    // "Upward" velocity
    const libMesh::Number u_up = U_P * N_V;

    // If there's no forward or upward velocity we should have already
    // returned false
    libmesh_assert (u_up || u_fwd);

    // Angle WRT fan velocity direction
    const libMesh::Number part_angle = std::atan2(u_up, u_fwd);

    // Angle WRT fan chord
    const libMesh::Number angle = part_angle +
      aoa_function(point, time);

    const libMesh::Number C_lift  = lift_function(point, angle);
    const libMesh::Number C_drag  = drag_function(point, angle);

    const libMesh::Number chord = chord_function(point, time);
    const libMesh::Number area  = area_swept_function(point, time);

    const libMesh::Number v_sq = U_P*U_P;

    const libMesh::Number LDfactor = 0.5 * this->_rho * v_sq * chord / area;
    const libMesh::Number lift = C_lift * LDfactor;
    const libMesh::Number drag = C_drag * LDfactor;

    // Force
    F = lift * N_lift + drag * N_drag;

    if (dFdU)
      {
        // FIXME: Jacobians here are very inexact!
        // Dropping all AoA dependence on U terms!
        const libMesh::NumberVectorValue LDderivfactor =
          (N_lift*C_lift+N_drag*C_drag) *
          this->_rho * chord / area;

        for (unsigned int i=0; i != 3; ++i)
          for (unsigned int j=0; j != 3; ++j)
            (*dFdU)(i,j) = LDderivfactor(i) * U_P(j);
      }

    return true;
  }
Esempio n. 6
0
  bool VelocityPenaltyBase<Mu>::compute_force
    ( const libMesh::Point& point,
      const libMesh::Real time,
      const libMesh::NumberVectorValue& U,
      libMesh::NumberVectorValue& F,
      libMesh::NumberTensorValue *dFdU)
  {
    // Velocity discrepancy (current velocity minus base velocity)
    // normal to constraint plane, scaled by constraint penalty
    // value
    libmesh_assert(normal_vector_function.get());
    libmesh_assert(base_velocity_function.get());

    libMesh::DenseVector<libMesh::Number> output_vec(3);

    (*normal_vector_function)(point, time,
                              output_vec);

    libMesh::NumberVectorValue U_N(output_vec(0),
                                   output_vec(1),
                                   output_vec(2));

    (*base_velocity_function)(point, time,
                              output_vec);

    const libMesh::NumberVectorValue U_B(output_vec(0),
                                         output_vec(1),
                                         output_vec(2));

    const libMesh::NumberVectorValue U_Rel = U-U_B;

    // Old code
    // const libMesh::NumberVectorValue F1 = (U_Rel*U_N)*U_N; //

    // With correct sign and more natural normalization
    const libMesh::Number U_N_mag = std::sqrt(U_N*U_N);

    if (!U_N_mag)
      return false;

    const libMesh::NumberVectorValue U_N_unit = U_N/U_N_mag;

    F = -(U_Rel*U_N)*U_N_unit;

    if (dFdU)
      for (unsigned int i=0; i != 3; ++i)
        for (unsigned int j=0; j != 3; ++j)
          (*dFdU)(i,j) = -(U_N(j))*U_N_unit(i);

    // With quadratic scaling
    if (_quadratic_scaling)
      {
        const libMesh::Number U_Rel_mag = std::sqrt(U_Rel * U_Rel);

        // Modify dFdU first so as to reuse the old value of F
        if (dFdU)
          {
            // dU_Rel/dU = I
            // d(U_Rel*U_Rel)/dU = 2*U_Rel
            // d|U_Rel|/dU = U_Rel/|U_Rel|

            const libMesh::NumberVectorValue U_Rel_unit = U_Rel/U_Rel_mag;

            (*dFdU) *= U_Rel_mag;

            if (U_Rel_mag)
              for (unsigned int i=0; i != 3; ++i)
                for (unsigned int j=0; j != 3; ++j)
                  (*dFdU)(i,j) += F(i)*U_Rel_unit(j);
          }

        F *= U_Rel_mag;
      }

    // With correction term to avoid doing work on flow
    bool do_correction = false;
    if (do_correction)
      {
        if (dFdU)
          libmesh_not_implemented();

        const libMesh::Number U_Rel_mag_sq = U_Rel * U_Rel;
        if (U_Rel_mag_sq)
          {
            F -= (U_Rel*F)*U_Rel/U_Rel_mag_sq;
          }
      }
    return true;
  }