void compute_step_factor(int nelr, double* variables, double* areas, double* step_factors)
{
 { const unsigned long long parallel_for_start = current_time_ns();
#pragma omp parallel for default(shared) schedule(static)
for(int i = 0; i < nelr; i++)
	{
		double density = variables[NVAR*i + VAR_DENSITY];

		cfd_double3 momentum;
		momentum.x = variables[NVAR*i + (VAR_MOMENTUM+0)];
		momentum.y = variables[NVAR*i + (VAR_MOMENTUM+1)];
		momentum.z = variables[NVAR*i + (VAR_MOMENTUM+2)];

		double density_energy = variables[NVAR*i + VAR_DENSITY_ENERGY];
		cfd_double3 velocity;	   compute_velocity(density, momentum, velocity);
		double speed_sqd      = compute_speed_sqd(velocity);
		double pressure       = compute_pressure(density, density_energy, speed_sqd);
		double speed_of_sound = compute_speed_of_sound(density, pressure);

		// dt = double(0.5) * std::sqrt(areas[i]) /  (||v|| + c).... but when we do time stepping, this later would need to be divided by the area, so we just do it all at once
		step_factors[i] = double(0.5) / (std::sqrt(areas[i]) * (std::sqrt(speed_sqd) + speed_of_sound));
	} ; 
const unsigned long long parallel_for_end = current_time_ns();
printf("pragma155_omp_parallel %llu ns\n", parallel_for_end - parallel_for_start); } 

}
Esempio n. 2
0
	void transform_pen_data(Pen::PenEvent& penEvent, PenDataTransform::XformedData& xformed, bool withtilt)
	{
		xformed.x = compute_x_position(penEvent.x);
		xformed.y = compute_y_position(penEvent.y);
		xformed.pressure = compute_pressure(penEvent.pressure);

/*		console::print("\npenEvent.x = ");
		console::printNumber(penEvent.x);
		console::print(", xformed.x = ");
		console::printNumber(xformed.x);
		console::println();
*/
		if(withtilt)
		{
			xformed.tilt_x = penEvent.tilt_x;
			xformed.tilt_y = penEvent.tilt_y;
		}
	}
Esempio n. 3
0
void compute_flux_contributions(int nelr, double* variables, double* fc_momentum_x, double* fc_momentum_y, double* fc_momentum_z, double* fc_density_energy)
{
	#pragma acc kernels
	for(int i = 0; i < nelr; i++)
	{
		double density_i = variables[NVAR*i + VAR_DENSITY];
		double3 momentum_i;
		momentum_i.x = variables[NVAR*i + (VAR_MOMENTUM+0)];
		momentum_i.y = variables[NVAR*i + (VAR_MOMENTUM+1)];
		momentum_i.z = variables[NVAR*i + (VAR_MOMENTUM+2)];
		double density_energy_i = variables[NVAR*i + VAR_DENSITY_ENERGY];

		double3 velocity_i;             				compute_velocity(density_i, momentum_i, velocity_i);
		double speed_sqd_i                          = compute_speed_sqd(velocity_i);
		double speed_i                              = sqrtf(speed_sqd_i);
		double pressure_i                           = compute_pressure(density_i, density_energy_i, speed_sqd_i);
		double speed_of_sound_i                     = compute_speed_of_sound(density_i, pressure_i);
		double3 fc_i_momentum_x, fc_i_momentum_y, fc_i_momentum_z;
		double3 fc_i_density_energy;	
		compute_flux_contribution(density_i, momentum_i, density_energy_i, pressure_i, velocity_i, fc_i_momentum_x, fc_i_momentum_y, fc_i_momentum_z, fc_i_density_energy);

		fc_momentum_x[i*NDIM + 0] = fc_i_momentum_x.x;
		fc_momentum_x[i*NDIM + 1] = fc_i_momentum_x.y;
		fc_momentum_x[i*NDIM+  2] = fc_i_momentum_x.z;

		fc_momentum_y[i*NDIM+ 0] = fc_i_momentum_y.x;
		fc_momentum_y[i*NDIM+ 1] = fc_i_momentum_y.y;
		fc_momentum_y[i*NDIM+ 2] = fc_i_momentum_y.z;


		fc_momentum_z[i*NDIM+ 0] = fc_i_momentum_z.x;
		fc_momentum_z[i*NDIM+ 1] = fc_i_momentum_z.y;
		fc_momentum_z[i*NDIM+ 2] = fc_i_momentum_z.z;

		fc_density_energy[i*NDIM+ 0] = fc_i_density_energy.x;
		fc_density_energy[i*NDIM+ 1] = fc_i_density_energy.y;
		fc_density_energy[i*NDIM+ 2] = fc_i_density_energy.z;
	}

}
Esempio n. 4
0
void compute_step_factor(int nelr, double* variables, double* areas, double* step_factors)
{
	#pragma acc kernels
	for(int i = 0; i < nelr; i++)
	{
		double density = variables[NVAR*i + VAR_DENSITY];

		double3 momentum;
		momentum.x = variables[NVAR*i + (VAR_MOMENTUM+0)];
		momentum.y = variables[NVAR*i + (VAR_MOMENTUM+1)];
		momentum.z = variables[NVAR*i + (VAR_MOMENTUM+2)];

		double density_energy = variables[NVAR*i + VAR_DENSITY_ENERGY];
		double3 velocity;	   compute_velocity(density, momentum, velocity);
		double speed_sqd      = compute_speed_sqd(velocity);
		double pressure       = compute_pressure(density, density_energy, speed_sqd);
		double speed_of_sound = compute_speed_of_sound(density, pressure);

		// dt = double(0.5) * std::sqrt(areas[i]) /  (||v|| + c).... but when we do time stepping, this later would need to be divided by the area, so we just do it all at once
		step_factors[i] = double(0.5) / (std::sqrt(areas[i]) * (std::sqrt(speed_sqd) + speed_of_sound));
	}
}
void compute_flux(int nelr, int* elements_surrounding_elements, double* normals, double* variables, double* fluxes)
{
	double smoothing_coefficient = double(0.2f);

 { const unsigned long long parallel_for_start = current_time_ns();
#pragma omp parallel for default(shared) schedule(static)
for(int i = 0; i < nelr; i++)
	{
		int j, nb;
		cfd_double3 normal; double normal_len;
		double factor;

		double density_i = variables[NVAR*i + VAR_DENSITY];
		cfd_double3 momentum_i;
		momentum_i.x = variables[NVAR*i + (VAR_MOMENTUM+0)];
		momentum_i.y = variables[NVAR*i + (VAR_MOMENTUM+1)];
		momentum_i.z = variables[NVAR*i + (VAR_MOMENTUM+2)];

		double density_energy_i = variables[NVAR*i + VAR_DENSITY_ENERGY];

		cfd_double3 velocity_i;             				 compute_velocity(density_i, momentum_i, velocity_i);
		double speed_sqd_i                          = compute_speed_sqd(velocity_i);
		double speed_i                              = std::sqrt(speed_sqd_i);
		double pressure_i                           = compute_pressure(density_i, density_energy_i, speed_sqd_i);
		double speed_of_sound_i                     = compute_speed_of_sound(density_i, pressure_i);
		cfd_double3 flux_contribution_i_momentum_x, flux_contribution_i_momentum_y, flux_contribution_i_momentum_z;
		cfd_double3 flux_contribution_i_density_energy;
		compute_flux_contribution(density_i, momentum_i, density_energy_i, pressure_i, velocity_i, flux_contribution_i_momentum_x, flux_contribution_i_momentum_y, flux_contribution_i_momentum_z, flux_contribution_i_density_energy);

		double flux_i_density = double(0.0);
		cfd_double3 flux_i_momentum;
		flux_i_momentum.x = double(0.0);
		flux_i_momentum.y = double(0.0);
		flux_i_momentum.z = double(0.0);
		double flux_i_density_energy = double(0.0);

		cfd_double3 velocity_nb;
		double density_nb, density_energy_nb;
		cfd_double3 momentum_nb;
		cfd_double3 flux_contribution_nb_momentum_x, flux_contribution_nb_momentum_y, flux_contribution_nb_momentum_z;
		cfd_double3 flux_contribution_nb_density_energy;
		double speed_sqd_nb, speed_of_sound_nb, pressure_nb;

		for(j = 0; j < NNB; j++)
		{
			nb = elements_surrounding_elements[i*NNB + j];
			normal.x = normals[(i*NNB + j)*NDIM + 0];
			normal.y = normals[(i*NNB + j)*NDIM + 1];
			normal.z = normals[(i*NNB + j)*NDIM + 2];
			normal_len = std::sqrt(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z);

			if(nb >= 0) 	// a legitimate neighbor
			{
				density_nb =        variables[nb*NVAR + VAR_DENSITY];
				momentum_nb.x =     variables[nb*NVAR + (VAR_MOMENTUM+0)];
				momentum_nb.y =     variables[nb*NVAR + (VAR_MOMENTUM+1)];
				momentum_nb.z =     variables[nb*NVAR + (VAR_MOMENTUM+2)];
				density_energy_nb = variables[nb*NVAR + VAR_DENSITY_ENERGY];
													compute_velocity(density_nb, momentum_nb, velocity_nb);
				speed_sqd_nb                      = compute_speed_sqd(velocity_nb);
				pressure_nb                       = compute_pressure(density_nb, density_energy_nb, speed_sqd_nb);
				speed_of_sound_nb                 = compute_speed_of_sound(density_nb, pressure_nb);
													compute_flux_contribution(density_nb, momentum_nb, density_energy_nb, pressure_nb, velocity_nb, flux_contribution_nb_momentum_x, flux_contribution_nb_momentum_y, flux_contribution_nb_momentum_z, flux_contribution_nb_density_energy);

				// artificial viscosity
				factor = -normal_len*smoothing_coefficient*double(0.5)*(speed_i + std::sqrt(speed_sqd_nb) + speed_of_sound_i + speed_of_sound_nb);
				flux_i_density += factor*(density_i-density_nb);
				flux_i_density_energy += factor*(density_energy_i-density_energy_nb);
				flux_i_momentum.x += factor*(momentum_i.x-momentum_nb.x);
				flux_i_momentum.y += factor*(momentum_i.y-momentum_nb.y);
				flux_i_momentum.z += factor*(momentum_i.z-momentum_nb.z);

				// accumulate cell-centered fluxes
				factor = double(0.5)*normal.x;
				flux_i_density += factor*(momentum_nb.x+momentum_i.x);
				flux_i_density_energy += factor*(flux_contribution_nb_density_energy.x+flux_contribution_i_density_energy.x);
				flux_i_momentum.x += factor*(flux_contribution_nb_momentum_x.x+flux_contribution_i_momentum_x.x);
				flux_i_momentum.y += factor*(flux_contribution_nb_momentum_y.x+flux_contribution_i_momentum_y.x);
				flux_i_momentum.z += factor*(flux_contribution_nb_momentum_z.x+flux_contribution_i_momentum_z.x);

				factor = double(0.5)*normal.y;
				flux_i_density += factor*(momentum_nb.y+momentum_i.y);
				flux_i_density_energy += factor*(flux_contribution_nb_density_energy.y+flux_contribution_i_density_energy.y);
				flux_i_momentum.x += factor*(flux_contribution_nb_momentum_x.y+flux_contribution_i_momentum_x.y);
				flux_i_momentum.y += factor*(flux_contribution_nb_momentum_y.y+flux_contribution_i_momentum_y.y);
				flux_i_momentum.z += factor*(flux_contribution_nb_momentum_z.y+flux_contribution_i_momentum_z.y);

				factor = double(0.5)*normal.z;
				flux_i_density += factor*(momentum_nb.z+momentum_i.z);
				flux_i_density_energy += factor*(flux_contribution_nb_density_energy.z+flux_contribution_i_density_energy.z);
				flux_i_momentum.x += factor*(flux_contribution_nb_momentum_x.z+flux_contribution_i_momentum_x.z);
				flux_i_momentum.y += factor*(flux_contribution_nb_momentum_y.z+flux_contribution_i_momentum_y.z);
				flux_i_momentum.z += factor*(flux_contribution_nb_momentum_z.z+flux_contribution_i_momentum_z.z);
			}
			else if(nb == -1)	// a wing boundary
			{
				flux_i_momentum.x += normal.x*pressure_i;
				flux_i_momentum.y += normal.y*pressure_i;
				flux_i_momentum.z += normal.z*pressure_i;
			}
			else if(nb == -2) // a far field boundary
			{
				factor = double(0.5)*normal.x;
				flux_i_density += factor*(ff_variable[VAR_MOMENTUM+0]+momentum_i.x);
				flux_i_density_energy += factor*(ff_flux_contribution_density_energy.x+flux_contribution_i_density_energy.x);
				flux_i_momentum.x += factor*(ff_flux_contribution_momentum_x.x + flux_contribution_i_momentum_x.x);
				flux_i_momentum.y += factor*(ff_flux_contribution_momentum_y.x + flux_contribution_i_momentum_y.x);
				flux_i_momentum.z += factor*(ff_flux_contribution_momentum_z.x + flux_contribution_i_momentum_z.x);

				factor = double(0.5)*normal.y;
				flux_i_density += factor*(ff_variable[VAR_MOMENTUM+1]+momentum_i.y);
				flux_i_density_energy += factor*(ff_flux_contribution_density_energy.y+flux_contribution_i_density_energy.y);
				flux_i_momentum.x += factor*(ff_flux_contribution_momentum_x.y + flux_contribution_i_momentum_x.y);
				flux_i_momentum.y += factor*(ff_flux_contribution_momentum_y.y + flux_contribution_i_momentum_y.y);
				flux_i_momentum.z += factor*(ff_flux_contribution_momentum_z.y + flux_contribution_i_momentum_z.y);

				factor = double(0.5)*normal.z;
				flux_i_density += factor*(ff_variable[VAR_MOMENTUM+2]+momentum_i.z);
				flux_i_density_energy += factor*(ff_flux_contribution_density_energy.z+flux_contribution_i_density_energy.z);
				flux_i_momentum.x += factor*(ff_flux_contribution_momentum_x.z + flux_contribution_i_momentum_x.z);
				flux_i_momentum.y += factor*(ff_flux_contribution_momentum_y.z + flux_contribution_i_momentum_y.z);
				flux_i_momentum.z += factor*(ff_flux_contribution_momentum_z.z + flux_contribution_i_momentum_z.z);

			}
		}

		fluxes[i*NVAR + VAR_DENSITY] = flux_i_density;
		fluxes[i*NVAR + (VAR_MOMENTUM+0)] = flux_i_momentum.x;
		fluxes[i*NVAR + (VAR_MOMENTUM+1)] = flux_i_momentum.y;
		fluxes[i*NVAR + (VAR_MOMENTUM+2)] = flux_i_momentum.z;
		fluxes[i*NVAR + VAR_DENSITY_ENERGY] = flux_i_density_energy;
	} ; 
const unsigned long long parallel_for_end = current_time_ns();
printf("pragma186_omp_parallel %llu ns\n", parallel_for_end - parallel_for_start); } 

}
Esempio n. 6
0
void mmas::mixing_product(int n) {
  delete mixed_product;
  mixed_product = new usm;

  real dm_bin = product->star_mass / n;
  
  real m_prev = 0, m_bin = 0;
  real Mtot = 0, Utot = 0, Vtot = 0, r_mean = 0;
  int  n_in_bin = 0;
  int  j = 0;
  real H1tot = 0, He4tot = 0, O16tot = 0, N14tot = 0, C12tot = 0, Ne20tot = 0, Mg24tot = 0, Si28tot = 0, Fe56tot = 0;
  
  
  for (int i = 0; i < product->get_num_shells(); i++) {
    mass_shell &shell_i = product->get_shell(i);
    real dm = shell_i.mass - m_prev;
    m_prev  = shell_i.mass;

    r_mean += shell_i.radius;
    n_in_bin += 1;
 
    m_bin += dm;
    Mtot  += dm;
    Vtot  += dm/shell_i.density;
    H1tot   += dm*shell_i.composition.H1;
    He4tot  += dm*shell_i.composition.He4;
    O16tot  += dm*shell_i.composition.O16;
    N14tot  += dm*shell_i.composition.N14;
    C12tot  += dm*shell_i.composition.C12;
    Ne20tot += dm*shell_i.composition.Ne20;
    Mg24tot += dm*shell_i.composition.Mg24;
    Si28tot += dm*shell_i.composition.Si28;
    Fe56tot += dm*shell_i.composition.Fe56;
    Utot  += compute_energy(shell_i.density, shell_i.temperature, shell_i.mean_mu) * dm;

    if (m_bin > dm_bin) {
//       PRC(j); PRC(n); PRC(Mtot); PRC(m_bin); PRC(dm_bin); PRL(n_in_bin);

      mass_shell shell_j; j++;
//       mass_shell &shell_j = mixed_product->get_shell(j++);
      shell_j.radius      = r_mean/n_in_bin;
      shell_j.mass        = Mtot;
      shell_j.density     = m_bin/Vtot;
      shell_j.composition.H1   = H1tot/m_bin;
      shell_j.composition.He4  = He4tot/m_bin;
      shell_j.composition.O16  = O16tot/m_bin;
      shell_j.composition.N14  = N14tot/m_bin;
      shell_j.composition.C12  = C12tot/m_bin;
      shell_j.composition.Ne20 = Ne20tot/m_bin;
      shell_j.composition.Mg24 = Mg24tot/m_bin;
      shell_j.composition.Si28 = Si28tot/m_bin;
      shell_j.composition.Fe56 = Fe56tot/m_bin;

#define am(x) (1.0+Amass[x]/2.0)/Amass[x]
      real Amass[] = {1, 4, 16, 14, 12, 20, 24, 28, 56};
      shell_j.mean_mu = 2 * shell_j.composition.H1 + 
	am(1) * shell_j.composition.He4 +
	am(2) * shell_j.composition.O16 +
	am(3) * shell_j.composition.N14 +
	am(4) * shell_j.composition.C12 + 
	am(5) * shell_j.composition.Ne20 + 
	am(6) * shell_j.composition.Mg24 +
	am(7) * shell_j.composition.Si28 + 
	am(8) * shell_j.composition.Fe56;
      shell_j.mean_mu = 1.0/shell_j.mean_mu;

      shell_j.e_thermal   = Utot/m_bin;
      shell_j.pressure    = compute_pressure(shell_j.density, shell_j.e_thermal, shell_j.mean_mu);
      shell_j.temperature = compute_temperature(shell_j.density, shell_j.pressure, shell_j.mean_mu);
      shell_j.entropy     = compute_entropy(shell_j.density, shell_j.temperature, shell_j.mean_mu);
      mixed_product->add_shell(shell_j);

      m_bin -= dm_bin;
      m_bin = Utot = Vtot = r_mean = 0;
      H1tot = He4tot = O16tot = N14tot = C12tot = Ne20tot = Mg24tot = Si28tot = Fe56tot = 0;
      n_in_bin = 0;
    }
  }

  mixed_product->build_hashtable();
}
Esempio n. 7
0
void mmas::smooth_product() {
  int n_shells = product->get_num_shells();   /* number of shells in the product */

  smoothing_params params;

  params.arr_x      = new double[n_shells];
  params.arr_y      = new double[n_shells];
  params.smoothed_y = new double[n_shells];

  /* composition */
  cerr << "Smoothing composition\n";
  for (int i = 0; i < n_shells; i++) {
    mass_shell &shell = product->get_shell(i);
    params.arr_x[i] = shell.radius;
    params.arr_x[i] = shell.mass;
    params.arr_y[i] = (4.0/shell.mean_mu - 3.0)/5.0;
  }
  smoothing_integrate(params, n_shells);
  for (int i = 0; i < n_shells; i++) {
    mass_shell &shell = product->get_shell(i);
    shell.mean_mu = 4.0/(5.0*params.smoothed_y[i] + 3);
  }

  /* thermal energy */
  cerr << "Smoothing thermal energy\n";
  for (int i = 0; i < n_shells; i++) {
    mass_shell &shell = product->get_shell(i);
    params.arr_y[i] = compute_energy(shell.density, shell.temperature, shell.mean_mu);
  }
  smoothing_integrate(params, n_shells);
  for (int i = 0; i < n_shells; i++) {
    mass_shell &shell = product->get_shell(i);
    shell.e_thermal =  params.smoothed_y[i];
//     real x = params.arr_x[i];
//     real y = params.arr_y[i];
//     real ys = params.smoothed_y[i];
//     PRC(x); PRC(y); PRL(ys);
  }

  /* density */
//   cerr << "Smoothing density\n";
//   for (int i = 0; i < n_shells; i++) {
//     mass_shell &shell = product->get_shell(i);
//     params.arr_y[i] = shell.density;
//   }
//   smoothing_integrate(params, n_shells);
//   for (int i = 0; i < n_shells; i++) {
//     mass_shell &shell = product->get_shell(i);
//     shell.density = params.smoothed_y[i];
//   }
  
  for (int i = 0; i < n_shells; i++) {
    mass_shell &shell = product->get_shell(i);
    shell.pressure    = compute_pressure(shell.density, shell.e_thermal, shell.mean_mu);
    shell.temperature = compute_temperature(shell.density, shell.pressure, shell.mean_mu);
    shell.entropy     = compute_entropy(shell.density, shell.temperature, shell.mean_mu);
  }

  delete[] params.arr_x;
  delete[] params.arr_y;
  delete[] params.smoothed_y;

}
Esempio n. 8
0
void compute_flux(int nelr, int* elements_surrounding_elements, double* normals, double* variables, double* fc_momentum_x, double* fc_momentum_y, double* fc_momentum_z, double* fc_density_energy, double* fluxes)
{
	const double smoothing_coefficient = double(0.2);

	#pragma acc kernels
	for(int i = 0; i < nelr; i++)
	{
		int j, nb;
		double3 normal; double normal_len;
		double factor;

		double density_i = variables[NVAR*i + VAR_DENSITY];
		double3 momentum_i;
		momentum_i.x = variables[NVAR*i + (VAR_MOMENTUM+0)];
		momentum_i.y = variables[NVAR*i + (VAR_MOMENTUM+1)];
		momentum_i.z = variables[NVAR*i + (VAR_MOMENTUM+2)];

		double density_energy_i = variables[NVAR*i + VAR_DENSITY_ENERGY];

		double3 velocity_i;             				 compute_velocity(density_i, momentum_i, velocity_i);
		double speed_sqd_i                          = compute_speed_sqd(velocity_i);
		double speed_i                              = std::sqrt(speed_sqd_i);
		double pressure_i                           = compute_pressure(density_i, density_energy_i, speed_sqd_i);
		double speed_of_sound_i                     = compute_speed_of_sound(density_i, pressure_i);
		double3 fc_i_momentum_x, fc_i_momentum_y, fc_i_momentum_z;
		double3 fc_i_density_energy;

		fc_i_momentum_x.x = fc_momentum_x[i*NDIM + 0];
		fc_i_momentum_x.y = fc_momentum_x[i*NDIM + 1];
		fc_i_momentum_x.z = fc_momentum_x[i*NDIM + 2];

		fc_i_momentum_y.x = fc_momentum_y[i*NDIM + 0];
		fc_i_momentum_y.y = fc_momentum_y[i*NDIM + 1];
		fc_i_momentum_y.z = fc_momentum_y[i*NDIM + 2];

		fc_i_momentum_z.x = fc_momentum_z[i*NDIM + 0];
		fc_i_momentum_z.y = fc_momentum_z[i*NDIM + 1];
		fc_i_momentum_z.z = fc_momentum_z[i*NDIM + 2];

		fc_i_density_energy.x = fc_density_energy[i*NDIM + 0];
		fc_i_density_energy.y = fc_density_energy[i*NDIM + 1];
		fc_i_density_energy.z = fc_density_energy[i*NDIM + 2];

		double flux_i_density = double(0.0);
		double3 flux_i_momentum;
		flux_i_momentum.x = double(0.0);
		flux_i_momentum.y = double(0.0);
		flux_i_momentum.z = double(0.0);
		double flux_i_density_energy = double(0.0);

		double3 velocity_nb;
		double density_nb, density_energy_nb;
		double3 momentum_nb;
		double3 fc_nb_momentum_x, fc_nb_momentum_y, fc_nb_momentum_z;
		double3 fc_nb_density_energy;
		double speed_sqd_nb, speed_of_sound_nb, pressure_nb;

		for(j = 0; j < NNB; j++)
		{
			nb = elements_surrounding_elements[i*NNB + j];
			normal.x = normals[(i*NNB + j)*NDIM + 0];
			normal.y = normals[(i*NNB + j)*NDIM + 1];
			normal.z = normals[(i*NNB + j)*NDIM + 2];
			normal_len = std::sqrt(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z);

			if(nb >= 0) 	// a legitimate neighbor
			{
				density_nb =        variables[nb*NVAR + VAR_DENSITY];
				momentum_nb.x =     variables[nb*NVAR + (VAR_MOMENTUM+0)];
				momentum_nb.y =     variables[nb*NVAR + (VAR_MOMENTUM+1)];
				momentum_nb.z =     variables[nb*NVAR + (VAR_MOMENTUM+2)];
				density_energy_nb = variables[nb*NVAR + VAR_DENSITY_ENERGY];
													compute_velocity(density_nb, momentum_nb, velocity_nb);
				speed_sqd_nb                      = compute_speed_sqd(velocity_nb);
				pressure_nb                       = compute_pressure(density_nb, density_energy_nb, speed_sqd_nb);
				speed_of_sound_nb                 = compute_speed_of_sound(density_nb, pressure_nb);

				fc_nb_momentum_x.x = fc_momentum_x[nb*NDIM + 0];
				fc_nb_momentum_x.y = fc_momentum_x[nb*NDIM + 1];
				fc_nb_momentum_x.z = fc_momentum_x[nb*NDIM + 2];

				fc_nb_momentum_y.x = fc_momentum_y[nb*NDIM + 0];
				fc_nb_momentum_y.y = fc_momentum_y[nb*NDIM + 1];
				fc_nb_momentum_y.z = fc_momentum_y[nb*NDIM + 2];

				fc_nb_momentum_z.x = fc_momentum_z[nb*NDIM + 0];
				fc_nb_momentum_z.y = fc_momentum_z[nb*NDIM + 1];
				fc_nb_momentum_z.z = fc_momentum_z[nb*NDIM + 2];

				fc_nb_density_energy.x = fc_density_energy[nb*NDIM + 0];
				fc_nb_density_energy.y = fc_density_energy[nb*NDIM + 1];

				// artificial viscosity
				factor = -normal_len*smoothing_coefficient*double(0.5)*(speed_i + std::sqrt(speed_sqd_nb) + speed_of_sound_i + speed_of_sound_nb);
				flux_i_density += factor*(density_i-density_nb);
				flux_i_density_energy += factor*(density_energy_i-density_energy_nb);
				flux_i_momentum.x += factor*(momentum_i.x-momentum_nb.x);
				flux_i_momentum.y += factor*(momentum_i.y-momentum_nb.y);
				flux_i_momentum.z += factor*(momentum_i.z-momentum_nb.z);

				// accumulate cell-centered fluxes
				factor = double(0.5)*normal.x;
				flux_i_density += factor*(momentum_nb.x+momentum_i.x);
				flux_i_density_energy += factor*(fc_nb_density_energy.x+fc_i_density_energy.x);
				flux_i_momentum.x += factor*(fc_nb_momentum_x.x+fc_i_momentum_x.x);
				flux_i_momentum.y += factor*(fc_nb_momentum_y.x+fc_i_momentum_y.x);
				flux_i_momentum.z += factor*(fc_nb_momentum_z.x+fc_i_momentum_z.x);

				factor = double(0.5)*normal.y;
				flux_i_density += factor*(momentum_nb.y+momentum_i.y);
				flux_i_density_energy += factor*(fc_nb_density_energy.y+fc_i_density_energy.y);
				flux_i_momentum.x += factor*(fc_nb_momentum_x.y+fc_i_momentum_x.y);
				flux_i_momentum.y += factor*(fc_nb_momentum_y.y+fc_i_momentum_y.y);
				flux_i_momentum.z += factor*(fc_nb_momentum_z.y+fc_i_momentum_z.y);

				factor = double(0.5)*normal.z;
				flux_i_density += factor*(momentum_nb.z+momentum_i.z);
				flux_i_density_energy += factor*(fc_nb_density_energy.z+fc_i_density_energy.z);
				flux_i_momentum.x += factor*(fc_nb_momentum_x.z+fc_i_momentum_x.z);
				flux_i_momentum.y += factor*(fc_nb_momentum_y.z+fc_i_momentum_y.z);
				flux_i_momentum.z += factor*(fc_nb_momentum_z.z+fc_i_momentum_z.z);
			}
			else if(nb == -1)	// a wing boundary
			{
				flux_i_momentum.x += normal.x*pressure_i;
				flux_i_momentum.y += normal.y*pressure_i;
				flux_i_momentum.z += normal.z*pressure_i;
			}
			else if(nb == -2) // a far field boundary
			{
				factor = double(0.5)*normal.x;
				flux_i_density += factor*(ff_variable[VAR_MOMENTUM+0]+momentum_i.x);
				flux_i_density_energy += factor*(ff_fc_density_energy.x+fc_i_density_energy.x);
				flux_i_momentum.x += factor*(ff_fc_momentum_x.x + fc_i_momentum_x.x);
				flux_i_momentum.y += factor*(ff_fc_momentum_y.x + fc_i_momentum_y.x);
				flux_i_momentum.z += factor*(ff_fc_momentum_z.x + fc_i_momentum_z.x);

				factor = double(0.5)*normal.y;
				flux_i_density += factor*(ff_variable[VAR_MOMENTUM+1]+momentum_i.y);
				flux_i_density_energy += factor*(ff_fc_density_energy.y+fc_i_density_energy.y);
				flux_i_momentum.x += factor*(ff_fc_momentum_x.y + fc_i_momentum_x.y);
				flux_i_momentum.y += factor*(ff_fc_momentum_y.y + fc_i_momentum_y.y);
				flux_i_momentum.z += factor*(ff_fc_momentum_z.y + fc_i_momentum_z.y);

				factor = double(0.5)*normal.z;
				flux_i_density += factor*(ff_variable[VAR_MOMENTUM+2]+momentum_i.z);
				flux_i_density_energy += factor*(ff_fc_density_energy.z+fc_i_density_energy.z);
				flux_i_momentum.x += factor*(ff_fc_momentum_x.z + fc_i_momentum_x.z);
				flux_i_momentum.y += factor*(ff_fc_momentum_y.z + fc_i_momentum_y.z);
				flux_i_momentum.z += factor*(ff_fc_momentum_z.z + fc_i_momentum_z.z);

			}
		}

		fluxes[i*NVAR + VAR_DENSITY] = flux_i_density;
		fluxes[i*NVAR + (VAR_MOMENTUM+0)] = flux_i_momentum.x;
		fluxes[i*NVAR + (VAR_MOMENTUM+1)] = flux_i_momentum.y;
		fluxes[i*NVAR + (VAR_MOMENTUM+2)] = flux_i_momentum.z;
		fluxes[i*NVAR + VAR_DENSITY_ENERGY] = flux_i_density_energy;
	}
}