void IsotropicParticleMesher::_getSliceMask(int startidx, int endidx, Array3d<bool> &mask) {
	mask.fill(true);

	int width, height, depth;
	double dx;
	_getSubdividedGridDimensions(&width, &height, &depth, &dx);

	bool isStartSlice = startidx == 0;
	bool isEndSlice = endidx == width - 1;

	if (!isStartSlice) {
		int idx = 0;
		for (int k = 0; k < mask.depth; k++) {
			for (int j = 0; j < mask.height; j++) {
				mask.set(idx, j, k, false);
			}
		}
	}

	if (!isEndSlice) {
		int idx = mask.width - 1;
		for (int k = 0; k < mask.depth; k++) {
			for (int j = 0; j < mask.height; j++) {
				mask.set(idx, j, k, false);
			}
		}
	}
}
void calculateChargesPotential(LSMSCommunication &comm, LSMSSystemParameters &lsms, LocalTypeInfo &local, CrystalParameters &crystal, int chargeSwitch)
{

  Real *qsub;
  Array3d<Real> rhoTemp;

  //qsub = new Real[crystal.num_types];
  qsub = (Real*)shmalloc(crystal.num_types*sizeof(Real));

  for (int i=0; i<crystal.num_types; i++) qsub[i] = 0.0;

  rhoTemp.resize(lsms.global.iprpts+1, 2, local.num_local);
  rhoTemp = 0.0;

  printf("%d:calculateCharges\n",comm.comm.rank);
  calculateCharges(comm, lsms, local, crystal, qsub, rhoTemp, chargeSwitch);  

  // for (int i=0; i<crystal.num_types; i++) printf("i, qsub = %5d %25.15f\n", i, qsub[i]);
  printf("%d:calculatePotential\n",comm.comm.rank);
  calculatePotential(comm, lsms, local, crystal, qsub, rhoTemp, chargeSwitch);
  printf("%d:end of calculatePotential\n",comm.comm.rank);

  //delete[] qsub;
  shfree(qsub);

  return;
}
void DiffuseParticleSimulation::_removeDiffuseParticles() {
    Array3d<int> countGrid = Array3d<int>(_isize, _jsize, _ksize, 0);

    std::vector<bool> isRemoved;
    isRemoved.reserve(_diffuseParticles.size());

    DiffuseParticle dp;
    GridIndex g;
    for (unsigned int i = 0; i < _diffuseParticles.size(); i++) {
        dp = _diffuseParticles[i];

        if (dp.lifetime <= 0.0) {
            isRemoved.push_back(true);
            continue;
        }

        g = Grid3d::positionToGridIndex(dp.position, _dx);
        if (countGrid(g) >= _maxDiffuseParticlesPerCell) {
            isRemoved.push_back(true);
            continue;
        }
        countGrid.add(g, 1);

        isRemoved.push_back(false);
    }

    _removeItemsFromVector(_diffuseParticles, isRemoved);
}
예제 #4
0
void create_dumbbell_signed_distance( const Vec3d& sphere_a_centre, 
                                     const Vec3d& sphere_b_centre, 
                                     double sphere_radius, 
                                     double handle_width,
                                     double dx,
                                     const Vec3d& domain_low,
                                     const Vec3d& domain_high,                                     
                                     Array3d& phi )
{
    
    phi.resize( (int) ceil( (domain_high[0]-domain_low[0]) / dx), (int) ceil( (domain_high[1]-domain_low[1]) / dx), (int) ceil( (domain_high[2]-domain_low[2]) / dx) );
    
    std::cout << "Generating signed distance function.  Grid resolution: " << phi.ni << " x " << phi.nj << " x " << phi.nk << std::endl;
    
    for ( int i = 0; i < phi.ni; ++i )
    {
        for ( int j = 0; j < phi.nj; ++j )
        {
            for ( int k = 0; k < phi.nk; ++k )
            {
                Vec3d pt = domain_low + dx * Vec3d(i,j,k);
                phi(i,j,k) = signed_distance_dumbbell( pt, sphere_a_centre, sphere_b_centre, sphere_radius, handle_width ); 
                
            }
        }
    }
}
예제 #5
0
void create_cube_signed_distance( const Vec3d& cube_low, 
                                 const Vec3d& cube_high, 
                                 double dx,
                                 const Vec3d& domain_low,
                                 const Vec3d& domain_high,                                     
                                 Array3d& phi )
{
    phi.resize( (int) ceil( (domain_high[0]-domain_low[0]) / dx), (int) ceil( (domain_high[1]-domain_low[1]) / dx), (int) ceil( (domain_high[2]-domain_low[2]) / dx) );
    
    std::cout << "Generating signed distance function.  Grid resolution: " << phi.ni << " x " << phi.nj << " x " << phi.nk << std::endl;
    
    for ( int i = 0; i < phi.ni; ++i )
    {
        for ( int j = 0; j < phi.nj; ++j )
        {
            for ( int k = 0; k < phi.nk; ++k )
            {
                Vec3d pt = domain_low + dx * Vec3d(i,j,k);
                
                double dist_low_x = cube_low[0] - pt[0];
                double dist_high_x = pt[0] - cube_high[0];
                
                double dist_low_y = cube_low[1] - pt[1];
                double dist_high_y = pt[1] - cube_high[1];
                
                double dist_low_z = cube_low[2] - pt[2];
                double dist_high_z = pt[2] - cube_high[2];
                
                phi(i,j,k) = max( dist_low_x, dist_high_x, dist_low_y, dist_high_y, dist_low_z, dist_high_z );
                
            }
        }
    }
}
예제 #6
0
void create_capsule_signed_distance( const Vec3d& capsule_end_a, 
                                    const Vec3d& capsule_end_b, 
                                    double capsule_radius,
                                    double dx,
                                    const Vec3d& domain_low,
                                    const Vec3d& domain_high,                                     
                                    Array3d& phi )
{ 
    phi.resize( (int) ceil( (domain_high[0]-domain_low[0]) / dx), (int) ceil( (domain_high[1]-domain_low[1]) / dx), (int) ceil( (domain_high[2]-domain_low[2]) / dx) );
    
    std::cout << "Generating signed distance function.  Grid resolution: " << phi.ni << " x " << phi.nj << " x " << phi.nk << std::endl;
    
    for ( int i = 0; i < phi.ni; ++i )
    {
        for ( int j = 0; j < phi.nj; ++j )
        {
            for ( int k = 0; k < phi.nk; ++k )
            {
                Vec3d pt = domain_low + dx * Vec3d(i,j,k);
                
                double distance;
                
                Vec3d central_segment(capsule_end_b - capsule_end_a);
                double m2=mag2(central_segment);
                
                // find parameter value of closest point on infinite line
                double s = dot(capsule_end_b - pt, central_segment)/m2;
                
                if ( s < 0.0 )
                {
                    // dist = distance to the cylinder disc at end b
                    
                    distance = dist(pt, capsule_end_b);
                    distance -= capsule_radius;
                    
                    
                } 
                else if ( s > 1.0 )
                {
                    // dist = distance to the cylinder disc at end b
                    distance = dist(pt, capsule_end_a );
                    distance -= capsule_radius;
                    
                }
                else
                {
                    // dist = distance to the cylinder's central axis
                    
                    distance = dist(pt, s*capsule_end_a + (1-s)*capsule_end_b);
                    distance -= capsule_radius;
                }
                
                phi(i,j,k) = distance;
                
            }
        }
    }
}
예제 #7
0
void TurbulenceField::_getVelocityGrid(MACVelocityField *macfield, 
                                       Array3d<glm::vec3> &vgrid) {
    glm::vec3 v;
    for (int k = 0; k < vgrid.depth; k++) {
        for (int j = 0; j < vgrid.height; j++) {
            for (int i = 0; i < vgrid.width; i++) {
                v = macfield->evaluateVelocityAtCellCenter(i, j, k);
                vgrid.set(i, j, k, v);
            }
        }
    }
}
예제 #8
0
void ScalarField::getSetScalarFieldValues(Array3d<bool> &isVertexSet) {
    FLUIDSIM_ASSERT(isVertexSet.width == _isVertexSet.width && 
           isVertexSet.height == _isVertexSet.height && 
           isVertexSet.depth == _isVertexSet.depth);

    for (int k = 0; k < isVertexSet.depth; k++) {
        for (int j = 0; j < isVertexSet.height; j++) {
            for (int i = 0; i < isVertexSet.width; i++) {
                isVertexSet.set(i, j, k, _isVertexSet(i, j, k));
            }
        }
    }
}
예제 #9
0
void ScalarField::getWeightField(Array3d<float> &field) {
    if (!_isWeightFieldEnabled) {
        return;
    }

    FLUIDSIM_ASSERT(field.width == _field.width && 
           field.height == _field.height && 
           field.depth == _field.depth);

    for (int k = 0; k < field.depth; k++) {
        for (int j = 0; j < field.height; j++) {
            for (int i = 0; i < field.width; i++) {
                field.set(i, j, k, _weightField(i, j, k));
            }
        }
    }
}
예제 #10
0
void LevelSet::_getLayerCells(int idx, std::vector<GridIndex> &layer, 
                                       std::vector<GridIndex> &nextLayer,
                                       Array3d<int> &layerGrid) {
    GridIndex ns[6];
    GridIndex g, n;
    for (unsigned int i = 0; i < layer.size(); i++) {
        g = layer[i];
        _getNeighbourGridIndices6(g, ns);
        for (int j = 0; j < 6; j++) {
            n = ns[j];
            if (Grid3d::isGridIndexInRange(n, _isize, _jsize, _ksize) && 
                    layerGrid(n) == -1) {
                nextLayer.push_back(n);
                layerGrid.set(n, idx);
            }
        }
    }
}
예제 #11
0
void ScalarField::getScalarField(Array3d<float> &field) {
    FLUIDSIM_ASSERT(field.width == _field.width && 
           field.height == _field.height && 
           field.depth == _field.depth);

    double val;
    for (int k = 0; k < field.depth; k++) {
        for (int j = 0; j < field.height; j++) {
            for (int i = 0; i < field.width; i++) {
                val = _field(i, j, k);
                if (_isVertexSolid(i, j, k) && val > _surfaceThreshold) {
                    val = _surfaceThreshold;
                } 

                field.set(i, j, k, (float)val);
            }
        }
    }
}
void calculateLocalCharges(LSMSSystemParameters &lsms, LocalTypeInfo &local, int chargeSwitch)
{

  Array3d<Real> rhoTemp;
  rhoTemp.resize(lsms.global.iprpts+1, 2, local.num_local);

  // Compute integrated densities of states and store in xval**
  // (from mufind_c.f)
  for(int i=0; i<local.num_local; i++)
  {
    if (lsms.n_spin_cant == 2)         // nspin >=3
    {
      local.atom[i].qvalmt = local.atom[i].dosckint[0];
      local.atom[i].qvalws = local.atom[i].dosint[0];
      local.atom[i].mvalws = local.atom[i].dosint[1] * local.atom[i].evecNew[0] + \
                             local.atom[i].dosint[2] * local.atom[i].evecNew[1] + \
                             local.atom[i].dosint[3] * local.atom[i].evecNew[2];
      local.atom[i].mvalmt = local.atom[i].dosckint[1] * local.atom[i].evecNew[0] + \
                             local.atom[i].dosckint[2] * local.atom[i].evecNew[1] + \
                             local.atom[i].dosckint[3] * local.atom[i].evecNew[2];
      local.atom[i].xvalmt[0]    = 0.5 * (local.atom[i].qvalmt + local.atom[i].mvalmt);
      local.atom[i].xvalwsNew[0] = 0.5 * (local.atom[i].qvalws + local.atom[i].mvalws);
      local.atom[i].xvalmt[1]    = 0.5 * (local.atom[i].qvalmt - local.atom[i].mvalmt);
      local.atom[i].xvalwsNew[1] = 0.5 * (local.atom[i].qvalws - local.atom[i].mvalws);
    }
    else if (lsms.n_spin_pola == 2)    // nspin = 2
    {
      local.atom[i].qvalmt = local.atom[i].dosckint[0] + local.atom[i].dosckint[1];
      local.atom[i].qvalws = local.atom[i].dosint[0] + local.atom[i].dosint[1];
      local.atom[i].mvalmt = local.atom[i].dosckint[0] - local.atom[i].dosckint[1];
      local.atom[i].mvalws = local.atom[i].dosint[0] - local.atom[i].dosint[1];

      local.atom[i].xvalmt[0] = local.atom[i].dosckint[0];
      local.atom[i].xvalwsNew[0] = local.atom[i].dosint[0];
      local.atom[i].xvalmt[1] = local.atom[i].dosckint[1];
      local.atom[i].xvalwsNew[1] = local.atom[i].dosint[1];
    }
    else                               // nspin = 1
    {
      local.atom[i].qvalmt = local.atom[i].dosckint[0];
      local.atom[i].qvalws = local.atom[i].dosint[0];
      local.atom[i].mvalmt = 0.0;
      local.atom[i].mvalws = 0.0;

      local.atom[i].xvalmt[0] = local.atom[i].dosckint[0];
      local.atom[i].xvalwsNew[0] = local.atom[i].dosint[0];
    }

    if (lsms.global.iprint > 0)
    {
      printf(" LOCAL WS Int[n(e)] = %18.11f\n", local.atom[i].qvalws);
      printf(" LOCAL MT Int[n(e)] = %18.11f\n", local.atom[i].qvalmt);
      printf(" LOCAL interstial Q = %18.11f\n", local.atom[i].qvalws - local.atom[i].qvalmt);
      
      if (lsms.n_spin_pola == 2)
      {
        printf(" LOCAL WS Int[m(e)] = %18.11f\n", local.atom[i].mvalws);
        printf(" LOCAL MT Int[m(e)] = %18.11f\n", local.atom[i].mvalmt);
      }

      printf(" LOCAL interstial M = %18.11f\n", local.atom[i].mvalws - local.atom[i].mvalmt);
      printf(" Spin = 1 LOCAL WS Int[n(e)] = %18.11f\n", local.atom[i].xvalwsNew[0]);
      printf(" Spin = 2 LOCAL WS Int[n(e)] = %18.11f\n", local.atom[i].xvalwsNew[1]);
      printf(" Spin = 1 LOCAL MT Int[n(e)] = %18.11f\n", local.atom[i].xvalmt[0]);
      printf(" Spin = 2 LOCAL MT Int[n(e)] = %18.11f\n", local.atom[i].xvalmt[1]);
      printf(" Spin = 1 LOCAL interstial Q = %18.11f\n", local.atom[i].xvalwsNew[0] - local.atom[i].xvalmt[0]);
      printf(" Spin = 2 LOCAL interstial Q = %18.11f\n", local.atom[i].xvalwsNew[1] - local.atom[i].xvalmt[1]);
      printf(" LOCAL Moment orientation = (%18.11f, %18.11f, %18.11f)\n", local.atom[i].evecNew[0], local.atom[i].evecNew[1], local.atom[i].evecNew[2]);
    }

 // Calculate qtotws and mtotws

    switch (chargeSwitch)
    {
      case 1:
      {
        local.atom[i].qtotws = local.atom[i].xvalws[0] + \
                               (lsms.n_spin_pola-1) * local.atom[i].xvalws[lsms.n_spin_pola-1] + \
                               local.atom[i].zsemss + \
                               local.atom[i].zcorss;
        local.atom[i].mtotws = local.atom[i].xvalws[0] - local.atom[i].xvalws[lsms.n_spin_pola-1];
        break;
      }
      default:
      {
        local.atom[i].qtotws = local.atom[i].xvalwsNew[0] + \
                               (lsms.n_spin_pola-1) * local.atom[i].xvalwsNew[lsms.n_spin_pola-1] + \
                               local.atom[i].zsemss + \
                               local.atom[i].zcorss;
        local.atom[i].mtotws = local.atom[i].xvalwsNew[0] - local.atom[i].xvalwsNew[lsms.n_spin_pola-1];
      }
    }

//    printf("qtotws = %12.8f\n", local.atom[i].qtotws);
//    printf("mtotws = %12.8f\n", local.atom[i].mtotws);

// from genpot_c.f
//   ================================================================
//   calculate qtotmt and mtotmt.....................................
//   ----------------------------------------------------------------

    Real rSphere;

    switch (lsms.mtasa)
    {
      case 1:
        rSphere = local.atom[i].rws;
        break;
      case 2:
        rSphere = local.atom[i].rws;
        break;
      default:
        rSphere = local.atom[i].rInscribed;
    }

    Real *rTemp;
    rTemp = new Real[local.atom[i].jmt+3];

    rTemp[0] = 0.0;
    for (int j=0; j<local.atom[i].jmt+2; j++)
    {
      //rTemp's indices need to be shifted by 1 for passing into getqm_mt!
      rTemp[j+1] = std::sqrt(local.atom[i].r_mesh[j]);
    }

    switch (chargeSwitch) 
    {
      case 1:
      {
        if (local.atom[i].rhotot(local.atom[i].jmt,0) == 0.0) 
          local.atom[i].rhotot(local.atom[i].jmt,0) = local.atom[i].rhotot(local.atom[i].jmt-1,0);
        if (local.atom[i].rhotot(local.atom[i].jmt+1,0) == 0.0) 
          local.atom[i].rhotot(local.atom[i].jmt+1,0) = local.atom[i].rhotot(local.atom[i].jmt-1,0);
        if (local.atom[i].rhotot(local.atom[i].jmt,lsms.n_spin_pola-1) == 0.0)
          local.atom[i].rhotot(local.atom[i].jmt,lsms.n_spin_pola-1) = local.atom[i].rhotot(local.atom[i].jmt-1,lsms.n_spin_pola-1);
        if (local.atom[i].rhotot(local.atom[i].jmt+1,lsms.n_spin_pola-1) == 0.0) 
          local.atom[i].rhotot(local.atom[i].jmt+1,lsms.n_spin_pola-1) = local.atom[i].rhotot(local.atom[i].jmt-1,lsms.n_spin_pola-1);
    
        if (lsms.global.iprint > 0)
        {
          printf("Spin = 1 rhotot[jmt-1], [jmt], [jmt+1] = %20.16f %20.16f %20.16f\n", local.atom[i].rhotot(local.atom[i].jmt-1,0), local.atom[i].rhotot(local.atom[i].jmt,0), local.atom[i].rhotot(local.atom[i].jmt+1,0));
          printf("Spin = 2 rhotot[jmt-1], [jmt], [jmt+1] = %20.16f %20.16f %20.16f\n", local.atom[i].rhotot(local.atom[i].jmt-1,lsms.n_spin_pola-1), local.atom[i].rhotot(local.atom[i].jmt,lsms.n_spin_pola-1), local.atom[i].rhotot(local.atom[i].jmt+1,lsms.n_spin_pola-1));
        }
    
        getqm_mt_(&lsms.n_spin_pola, &local.atom[i].jmt, &local.atom[i].rInscribed, rTemp, &local.atom[i].rhotot(0,0), &lsms.global.iprpts, &rhoTemp(0,0,i), &lsms.mtasa, &local.atom[i].qtotmt, &local.atom[i].mtotmt, &rSphere, &lsms.global.iprint);
    
        break;
      }
      default:
      {
        if (local.atom[i].rhoNew(local.atom[i].jmt,0) == 0.0) 
          local.atom[i].rhoNew(local.atom[i].jmt,0) = local.atom[i].rhoNew(local.atom[i].jmt-1,0);
        if (local.atom[i].rhoNew(local.atom[i].jmt+1,0) == 0.0) 
          local.atom[i].rhoNew(local.atom[i].jmt+1,0) = local.atom[i].rhoNew(local.atom[i].jmt-1,0);
        if (local.atom[i].rhoNew(local.atom[i].jmt,lsms.n_spin_pola-1) == 0.0)
          local.atom[i].rhoNew(local.atom[i].jmt,lsms.n_spin_pola-1) = local.atom[i].rhoNew(local.atom[i].jmt-1,lsms.n_spin_pola-1);
        if (local.atom[i].rhoNew(local.atom[i].jmt+1,lsms.n_spin_pola-1) == 0.0) 
          local.atom[i].rhoNew(local.atom[i].jmt+1,lsms.n_spin_pola-1) = local.atom[i].rhoNew(local.atom[i].jmt-1,lsms.n_spin_pola-1);
    
        if (lsms.global.iprint > 0)
        {   
          printf("Spin = 1 rhoNew[jmt-1], [jmt], [jmt+1] = %20.16f %20.16f %20.16f\n", local.atom[i].rhoNew(local.atom[i].jmt-1,0), local.atom[i].rhoNew(local.atom[i].jmt,0), local.atom[i].rhoNew(local.atom[i].jmt+1,0));
          printf("Spin = 2 rhoNew[jmt-1], [jmt], [jmt+1] = %20.16f %20.16f %20.16f\n", local.atom[i].rhoNew(local.atom[i].jmt-1,lsms.n_spin_pola-1), local.atom[i].rhoNew(local.atom[i].jmt,lsms.n_spin_pola-1), local.atom[i].rhoNew(local.atom[i].jmt+1,lsms.n_spin_pola-1));
        }
    
        getqm_mt_(&lsms.n_spin_pola, &local.atom[i].jmt, &local.atom[i].rInscribed, rTemp, &local.atom[i].rhoNew(0,0), &lsms.global.iprpts, &rhoTemp(0,0,i), &lsms.mtasa, &local.atom[i].qtotmt, &local.atom[i].mtotmt, &rSphere, &lsms.global.iprint);
      }
    }

    if (lsms.global.iprint >= 0)
    {
      printf("\n");
      printf(" GENPOT / calculateLocalCharges: \n");
      printf(" Total charge and moment in W-S cell:\n");
      printf(" qtotws = %18.11f\n", local.atom[i].qtotws);
      printf(" mtotws = %18.11f\n", local.atom[i].mtotws);
    }

    delete[] rTemp;

  }
}
예제 #13
0
파일: Analysis.cpp 프로젝트: xyuan/gkc
int Analysis::writeData(Timing timing, double dt)

{
      if (timing.check(dataOutputMoments, dt)       )   {

           FA_Mom_Tp->write(getTemperatureParallel().data());
           FA_Mom_HeatFlux->write(getHeatFlux().data());
           FA_Mom_Density->write(getNumberDensity().data());
           FA_Mom_Time->write(&timing);
            
           writeMessage("Data I/O : Moments output");

      }
      if (timing.check(dataOutputStatistics, dt)       )   {
      // Ugly and error-prone
      getPowerSpectrum();
      Array2d pSpecX(Range(1, plasma->nfields), Range(0, Nx/2)); pSpecX(Range(1, plasma->nfields), Range(0, Nx/2)) = pSpec((int) DIR_X, Range(1, plasma->nfields), Range(0, Nx/2));
      Array2d pSpecY(Range(1, plasma->nfields), Range(0, Nky)); pSpecY(Range(1, plasma->nfields), Range(0, Nky)) = pSpec((int) DIR_Y, Range(1, plasma->nfields), Range(0, Nky));
      
      Array2d pPhaseX(Range(1, plasma->nfields), Range(0, Nx/2)); pPhaseX(Range(1, plasma->nfields), Range(0, Nx/2)) = pPhase((int) DIR_X, Range(1, plasma->nfields), Range(0, Nx/2));
      Array2d pPhaseY(Range(1, plasma->nfields), Range(0, Nky)) ; pPhaseY(Range(1, plasma->nfields), Range(0, Nky))  = pPhase((int) DIR_Y, Range(1, plasma->nfields), Range(0, Nky));

      FA_grow_x->write( pSpecX.data()); FA_grow_y->write( pSpecY.data()); FA_grow_t->write(&timing);
      FA_freq_x->write(pPhaseX.data()); FA_freq_y->write(pPhaseY.data()); FA_freq_t->write(&timing);


      // Heat Flux
      Array3d heatKy; heatKy.reference(getHeatFluxKy());
      FA_heatKy->write(heatKy.data());
      Array3d particleKy; particleKy.reference(getParticleFluxKy());
      FA_particleKy->write(particleKy.data());
      
  
      ScalarValues scalarValues;


            // calculate kineic Energy first, need for initial_e ! sum over sumdomains
            scalarValues.timestep = timing.step;
            scalarValues.time     = timing.time;
              
            getFieldEnergy(scalarValues.phiEnergy, scalarValues.ApEnergy, scalarValues.BpEnergy);

            //  Get scalar Values for every species
            for(int s = NsGlD; s <= NsGuD; s++) {
                scalarValues.particle_number[s-1]  = getParticelNumber(s)                           ;
                scalarValues.entropy        [s-1]  = getEntropy(s)                                  ;
                scalarValues.kinetic_energy [s-1]  = getKineticEnergy(s)                            ;
                scalarValues.particle_flux  [s-1]  = getTotalParticleFlux(s)                             ;
                scalarValues.heat_flux      [s-1]  = getTotalHeatFlux(s)                                 ;
            }
            SVTable->append(&scalarValues);

            // write out to Terminal/File
            std::stringstream messageStream;
            messageStream << "Step : " << scalarValues.timestep      << "  Time " << scalarValues.time        
			  << " Field : (phi)" << scalarValues.phiEnergy  << "   (Ap)" << scalarValues.ApEnergy  <<  " (Bp) " << scalarValues.BpEnergy << std::endl; 
            double charge = 0., kinetic_energy=0.;
            for(int s = NsGlD; s <= NsGuD; s++) {
                            messageStream << plasma->species(s).name << "   N :" << scalarValues.particle_number[s-1]  << "  Kinetic Energy : " << scalarValues.kinetic_energy[s-1] ;
                            messageStream << "   Particle Flux :" << scalarValues.particle_flux[s-1]    << "  Heat Flux : " << scalarValues.heat_flux[s-1] << std::endl;
                            charge += plasma->species(s).q  * scalarValues.particle_number[s-1];
                            kinetic_energy += scalarValues.kinetic_energy[s-1];
            }
            messageStream << std::endl << "------------------------------------------------------------------" <<
                                        std::endl << "Total Energy " << kinetic_energy+scalarValues.phiEnergy + scalarValues.ApEnergy + scalarValues.BpEnergy << "    Total Charge = " << ((plasma->species(0).n0 != 0.) ? 0. : charge) << std::endl;  
            parallel->print(messageStream);
      
      }
             return HELIOS_SUCCESS;
  }
예제 #14
0
void make_level_set3(const std::vector<Vec3ui> &tri, const std::vector<Vec3d> &x,
                     const Vec3d &origin, double dx, int ni, int nj, int nk,
                     Array3d &phi, Array3i& closest_tri, const int exact_band )
{

   phi.resize(ni, nj, nk);
   phi.assign((ni+nj+nk)*dx); // upper bound on distance
   closest_tri.clear();
   closest_tri.resize(ni, nj, nk, -1);
   Array3i intersection_count(ni, nj, nk, 0); // intersection_count(i,j,k) is # of tri intersections in (i-1,i]x{j}x{k}
   // we begin by initializing distances near the mesh, and figuring out intersection counts
   Vec3d ijkmin, ijkmax;
   for(unsigned int t=0; t<tri.size(); ++t){
      unsigned int p, q, r; assign(tri[t], p, q, r);
      // coordinates in grid to high precision
      double fip=((double)x[p][0]-origin[0])/dx, fjp=((double)x[p][1]-origin[1])/dx, fkp=((double)x[p][2]-origin[2])/dx;
      double fiq=((double)x[q][0]-origin[0])/dx, fjq=((double)x[q][1]-origin[1])/dx, fkq=((double)x[q][2]-origin[2])/dx;
      double fir=((double)x[r][0]-origin[0])/dx, fjr=((double)x[r][1]-origin[1])/dx, fkr=((double)x[r][2]-origin[2])/dx;
      // do distances nearby
      int i0=clamp(int(min(fip,fiq,fir))-exact_band, 0, ni-1), i1=clamp(int(max(fip,fiq,fir))+exact_band+1, 0, ni-1);
      int j0=clamp(int(min(fjp,fjq,fjr))-exact_band, 0, nj-1), j1=clamp(int(max(fjp,fjq,fjr))+exact_band+1, 0, nj-1);
      int k0=clamp(int(min(fkp,fkq,fkr))-exact_band, 0, nk-1), k1=clamp(int(max(fkp,fkq,fkr))+exact_band+1, 0, nk-1);
      for(int k=k0; k<=k1; ++k) for(int j=j0; j<=j1; ++j) for(int i=i0; i<=i1; ++i){
         Vec3d gx(i*dx+origin[0], j*dx+origin[1], k*dx+origin[2]);
         double d=point_triangle_distance(gx, x[p], x[q], x[r]);
         if(d<phi(i,j,k)){
            phi(i,j,k)=d;
            closest_tri(i,j,k)=t;
         }
      }
      // and do intersection counts
      j0=clamp((int)std::ceil(min(fjp,fjq,fjr)), 0, nj-1);
      j1=clamp((int)std::floor(max(fjp,fjq,fjr)), 0, nj-1);
      k0=clamp((int)std::ceil(min(fkp,fkq,fkr)), 0, nk-1);
      k1=clamp((int)std::floor(max(fkp,fkq,fkr)), 0, nk-1);
      for(int k=k0; k<=k1; ++k) for(int j=j0; j<=j1; ++j){
         double a, b, c;
         if(point_in_triangle_2d(j, k, fjp, fkp, fjq, fkq, fjr, fkr, a, b, c)){
            double fi=a*fip+b*fiq+c*fir; // intersection i coordinate
            int i_interval=int(std::ceil(fi)); // intersection is in (i_interval-1,i_interval]
            if(i_interval<0) ++intersection_count(0, j, k); // we enlarge the first interval to include everything to the -x direction
            else if(i_interval<ni) ++intersection_count(i_interval,j,k);
            // we ignore intersections that are beyond the +x side of the grid
         }
      }
   }
   // and now we fill in the rest of the distances with fast sweeping
   for(unsigned int pass=0; pass<2; ++pass){
      sweep(tri, x, phi, closest_tri, origin, dx, +1, +1, +1);
      sweep(tri, x, phi, closest_tri, origin, dx, -1, -1, -1);
      sweep(tri, x, phi, closest_tri, origin, dx, +1, +1, -1);
      sweep(tri, x, phi, closest_tri, origin, dx, -1, -1, +1);
      sweep(tri, x, phi, closest_tri, origin, dx, +1, -1, +1);
      sweep(tri, x, phi, closest_tri, origin, dx, -1, +1, -1);
      sweep(tri, x, phi, closest_tri, origin, dx, +1, -1, -1);
      sweep(tri, x, phi, closest_tri, origin, dx, -1, +1, +1);
   }
   // then figure out signs (inside/outside) from intersection counts
   for(int k=0; k<nk; ++k) for(int j=0; j<nj; ++j){
      int total_count=0;
      for(int i=0; i<ni; ++i){
         total_count+=intersection_count(i,j,k);
         if(total_count%2==1){ // if parity of intersections so far is odd,
            phi(i,j,k)=-phi(i,j,k); // we are inside the mesh
         }
      }
   }
}