Пример #1
0
    void OStream::writeArchiveMetadata()
    {
        if (mRuntimeVersion >= 6)
        {
            // Max possible size.
            const std::size_t BufferLen = 1+5+5+1;

            char buffer[BufferLen] = {0};
            buffer[0] = BeginArchiveMetadata;

            RCF::ByteBuffer byteBuffer(&buffer[0], BufferLen);
            std::size_t pos = 1;
            encodeInt(mRuntimeVersion, byteBuffer, pos);
            encodeInt(mArchiveVersion, byteBuffer, pos);

            if (mRuntimeVersion >= 10)
            {
                encodeBool(getTrackingContext().getEnabled(), byteBuffer, pos);
            }

            writeRaw(&buffer[0], static_cast<UInt32>(pos));
        }
    }
Пример #2
0
 bool OStream::getEnablePointerTracking() const
 {
     return getTrackingContext().getEnabled();
 }
Пример #3
0
 void OStream::setEnablePointerTracking(bool enable)
 {
     getTrackingContext().setEnabled(enable); 
 }
Пример #4
0
    void OStream::clearState() 
    { 
        getTrackingContext().clear(); 

        mArchiveMetadataWritten = false;
    }
Пример #5
0
    bool IStream::begin(Node &node)
    {
        while (true)
        {
            Byte8 byte = 0;
            read_byte(byte);

            switch (byte)
            {
            case Blank: 
                {
                    Byte8 count = 0;
                    read_byte(count);
                    std::vector<Byte8> buffer(count);
                    UInt32 bytesRead = read( &(buffer[0]), count);
                    if (bytesRead != static_cast<UInt32>(count))
                    {
                        RCF::Exception e(RCF::_SfError_DataFormat());
                        RCF_THROW(e)(bytesRead)(count);
                    }
                    continue;
                }

            case BeginArchiveMetadata:
                {
                    int runtimeVersion = 0;
                    int archiveVersion = 0;
                    bool pointerTrackingEnabled = false;
                    bool * pPointerTrackingEnabled = NULL;

                    const size_t BufferLen = 11;
                    char buffer[BufferLen] = {0};
                    RCF::ByteBuffer byteBuffer( &buffer[0], BufferLen);
                    std::size_t pos0 = static_cast<std::size_t>(mpIs->tellg());

#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4996 )  // warning C4996: 'std::basic_istream<_Elem,_Traits>::readsome': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
#endif
                    std::size_t bytesRead = static_cast<std::size_t>(mpIs->readsome(buffer, BufferLen));

#ifdef _MSC_VER
#pragma warning( pop )
#endif
                    byteBuffer = RCF::ByteBuffer(byteBuffer, 0, bytesRead);
                    std::size_t pos1 = 0;
                    decodeInt(runtimeVersion, byteBuffer, pos1);
                    decodeInt(archiveVersion, byteBuffer, pos1);

                    if (runtimeVersion >= 10)
                    {
                        decodeBool(pointerTrackingEnabled, byteBuffer, pos1);
                        pPointerTrackingEnabled = &pointerTrackingEnabled;
                    }

                    mpIs->seekg(
                        static_cast<std::istream::off_type>(pos0 + pos1), 
                        std::ios_base::beg);

                    if (!mIgnoreVersionStamp)
                    {
                        if (runtimeVersion)
                        {
                            mRuntimeVersion = runtimeVersion;
                        }
                        if (archiveVersion)
                        {
                            mArchiveVersion = archiveVersion;
                        }
                    }

                    if (pPointerTrackingEnabled && !*pPointerTrackingEnabled)
                    {
                        getTrackingContext().setEnabled(false);
                    }

                    continue;
                }

            case Begin:
                {
                    read_byte( byte );
                    Byte8 attrSpec = byte;

                    // id
                    if (attrSpec & 1)
                    {
                        read_int(node.id);
                    }

                    // ref
                    attrSpec = attrSpec >> 1;
                    if (attrSpec & 1)
                    {
                        node.ref = 1;
                    }

                    // type
                    attrSpec = attrSpec >> 1;
                    if (attrSpec & 1)
                    {
                        UInt32 length = 0;
                        read_int(length);
                        node.type.allocate(length);
                        read(node.type.get(), length );
                    }

                    // label
                    attrSpec = attrSpec >> 1;
                    if (attrSpec & 1)
                    {
                        UInt32 length = 0;
                        read_int(length);
                        node.label.allocate(length);
                        read(node.label.get(), length);
                    }

                    return true;
                }

            default:
                {
                    RCF::Exception e(RCF::_SfError_DataFormat());
                    RCF_THROW(e)(byte);
                }
            }
        }

    }
Пример #6
0
 void IStream::clearState() 
 { 
     getTrackingContext().clear();
 }
Пример #7
0
void optimizeBinSettingsForImpedance(double timeSpan, double freq, double Q,
                                     double *binSize, long *nBins, long maxBins)
{
  long n_bins, maxBins2;
  double bin_size, factor;
  TRACKING_CONTEXT tcontext;
  
  n_bins = *nBins;
  bin_size = *binSize;
  getTrackingContext(&tcontext);

  if (maxBins<=0)
    maxBins2 = pow(2, 20);
  else
    maxBins2 = pow(2, (long)(log(maxBins)/log(2)+1));
  if (maxBins>0 && maxBins!=maxBins2)
    fprintf(stdout, "Adjusted maximum number of bins for %s %s to %ld\n",
            entity_name[tcontext.elementType],
            tcontext.elementName, maxBins2);
  
  if (1/(2*freq*bin_size)<10) {
    /* want maximum frequency in Z > 10*fResonance */
    fprintf(stdout, "%s %s has excessive bin size for given resonance frequency\n",
            entity_name[tcontext.elementType],
            tcontext.elementName);
    bin_size = 1./freq/20;
    fprintf(stdout, "  Bin size adjusted to %e\n", bin_size);
    fflush(stdout);
  }
  if (2*timeSpan>bin_size*n_bins) {
    fprintf(stdout, "%s %s has insufficient time span for initial bunch\n",
            entity_name[tcontext.elementType],
            tcontext.elementName);
    n_bins = pow(2,
                 (long)(log(2*timeSpan*1.05/bin_size)/log(2)+1));
    if (maxBins2<n_bins) {
      fprintf(stderr, "  Maximum number of bins does not allow sufficient time span!\n");
      exitElegant(1);
    }
    fprintf(stdout, "  Number of bins adjusted to %ld\n",
            n_bins);
    fflush(stdout);
  }
  if (Q<1) 
    /* Ideally, want frequency resolution < fResonance/200 and < fResonanceWidth/200 */
    factor = 200/(n_bins*bin_size*freq/Q);
  else
    factor = 200/(n_bins*bin_size*freq);
  if (factor>1) {
    fprintf(stdout, "%s %s has too few bins or excessively small bin size for given frequency\n",
            entity_name[tcontext.elementType],
            tcontext.elementName);
    if (n_bins*factor>maxBins2) {
      if ((n_bins*factor)/maxBins2>50) {
        if (Q<1)
          fprintf(stdout, " With %ld bins, the frequency resolution is only %.1g times the resonant frequency\n",
                  maxBins2, freq*maxBins2*bin_size);
        else
          fprintf(stdout, " With %ld bins, the frequency resolution is only %.1g times the resonance width\n",
                  maxBins2, freq/Q*maxBins2*bin_size);
        fprintf(stdout, " It isn't possible to model this situation accurately with %ld bins.  Consider the RFMODE or TRFMODE element.\n",
                maxBins2);
        fprintf(stdout, " Alternatively, consider increasing your bin size or maximum number of bins\n");
        exitElegant(1);
      }
      n_bins = maxBins2;
      fprintf(stdout, "  Number of bins adjusted to %ld\n", n_bins);
      
    } else {
      n_bins = pow(2, (long)(log(n_bins*factor)/log(2)+1));
      fprintf(stdout, "  Number of bins adjusted to %ld\n",
              n_bins);
    }
    fflush(stdout);
  }
  
  *nBins = n_bins;
  *binSize = bin_size;
}
Пример #8
0
void track_through_ztransverse(double **part, long np, ZTRANSVERSE *ztransverse, double Po,
                               RUN *run, long i_pass, CHARGE *charge
                               )
{
  static double *posItime[2] = {NULL, NULL};     /* array for particle density times x, y*/
  static double *posIfreq;                       /* array for FFT of particle density times x or y*/
  static double *Vtime = NULL;           /* array for voltage acting on each bin */
  static long max_n_bins = 0;
  static long *pbin = NULL;              /* array to record which bin each particle is in */
  static double *time = NULL;            /* array to record arrival time of each particle */
  static double *pz = NULL;
  static long max_np = 0;
  double *Vfreq, *iZ;
#if USE_MPI
  long i;
#endif
  long ib, nb, n_binned, nfreq, iReal, iImag, plane, first;
  double factor, tmin, tmax, tmean, dt, userFactor[2], rampFactor=1;
  static long not_first_call = -1;
  long ip, ip1, ip2, bunches, bunch, npb, i_pass0;
  long bucketEnd[MAX_BUCKETS];
#if USE_MPI
  float *buffer_send, *buffer_recv;
#endif
#if defined(DEBUG)
  FILE *fp;
#endif
  i_pass0 = i_pass;
  if ((i_pass -= ztransverse->startOnPass)<0)
    return;
  
  if (i_pass>=(ztransverse->rampPasses-1))
    rampFactor = 1;
  else
    rampFactor = (i_pass+1.0)/ztransverse->rampPasses;
  
  not_first_call += 1;

#if (!USE_MPI)
  if (np>max_np) {
    pbin = trealloc(pbin, sizeof(*pbin)*(max_np=np));
    time = trealloc(time, sizeof(*time)*max_np);
    pz = trealloc(pz, sizeof(*pz)*max_np);
  }
#else
    if (USE_MPI) {
      long np_total;
      if (isSlave) {
	MPI_Allreduce(&np, &np_total, 1, MPI_LONG, MPI_SUM, workers);
	if (np_total>max_np) { 
	  /* if the total number of particles is increased, we do reallocation for every CPU */
	  pbin = trealloc(pbin, sizeof(*pbin)*(max_np=np));
	  time = trealloc(time, sizeof(*time)*max_np);
	  pz = trealloc(pz, sizeof(*pz)*max_np);
	  max_np = np_total; /* max_np should be the sum across all the processors */
	}
      }
    } 
#endif
  
  if ((part[0][6]-floor(part[0][6]))!=0) {
    /* This is a kludgey way to determine that particles have been assigned to buckets */
    printf("Bunched beam detected\n"); fflush(stdout);
#if USE_MPI
    if (n_processors!=1) {
      printf("Error (ZTRANSVERSE): must have bunch_frequency=0 for parallel mode.\n");
      MPI_Barrier(MPI_COMM_WORLD); /* Make sure the information can be printed before aborting */
      MPI_Abort(MPI_COMM_WORLD, 2);
    }
#endif
    /* Start by sorting in bucket order */
    qsort(part[0], np, COORDINATES_PER_PARTICLE*sizeof(double), comp_BucketNumbers);
    /* Find the end of the buckets in the particle list */
    bunches = 0;
    for (ip=1; ip<np; ip++) {
      if ((part[ip-1][6]-floor(part[ip-1][6]))!=(part[ip][6]-floor(part[ip][6]))) {
        /* printf("Bucket %ld ends with ip=%ld\n", bunches, ip-1); fflush(stdout); */
        bucketEnd[bunches++] = ip-1;
        if (bunches>=MAX_BUCKETS) {
            bombElegant("Error (wake): maximum number of buckets was exceeded", NULL);
          }
      }
    }
    bucketEnd[bunches++] = np-1;
  } else {
    bunches = 1;
    bucketEnd[0] = np-1;
  }
  /* printf("Bucket %ld ends with ip=%ld\n", bunches, bucketEnd[bunches-1]); fflush(stdout); */

  ip2 = -1;
  for (bunch=0; bunch<bunches; bunch++) {
    ip1 = ip2+1;
    ip2 = bucketEnd[bunch];
    npb = ip2-ip1+1;
    /* printf("Processing bunch %ld with %ld particles\n", bunch, npb); fflush(stdout); */
    /* Compute time coordinate of each particle */
    tmean = computeTimeCoordinates(time+ip1, Po, part+ip1, npb);
    find_min_max(&tmin, &tmax, time+ip1, npb);
#if USE_MPI
    find_global_min_max(&tmin, &tmax, np, workers);      
#endif
    if (bunch==0) {
      /* use np here since we need to compute the macroparticle charge */
      set_up_ztransverse(ztransverse, run, i_pass, np, charge, tmax-tmin);
    }
    nb = ztransverse->n_bins;
    dt = ztransverse->bin_size;
    tmin -= dt;
    tmax -= dt;
    if ((tmax-tmin)*2>nb*dt) {
      TRACKING_CONTEXT tcontext;
      getTrackingContext(&tcontext);
      fprintf(stderr, "%s %s: Time span of bunch (%le s) is more than half the total time span (%le s).\n",
              entity_name[tcontext.elementType],
              tcontext.elementName,
              tmax-tmin, nb*dt);
      fprintf(stderr, "If using broad-band impedance, you should increase the number of bins and rerun.\n");
      fprintf(stderr, "If using file-based impedance, you should increase the number of data points or decrease the frequency resolution.\n");
      exitElegant(1);
    }

    if (nb>max_n_bins) {
      posItime[0] = trealloc(posItime[0], 2*sizeof(**posItime)*(max_n_bins=nb));
      posItime[1] = trealloc(posItime[1], 2*sizeof(**posItime)*(max_n_bins=nb));
      posIfreq = trealloc(posIfreq, 2*sizeof(*posIfreq)*(max_n_bins=nb));
      Vtime = trealloc(Vtime, 2*sizeof(*Vtime)*(max_n_bins+1));
    }

    for (ib=0; ib<nb; ib++)
      posItime[0][2*ib] = posItime[0][2*ib+1] = 
        posItime[1][2*ib] = posItime[1][2*ib+1] = 0;

    /* make arrays of I(t)*x and I(t)*y */
    n_binned = binTransverseTimeDistribution(posItime, pz, pbin, tmin, dt, nb, 
                                             time+ip1, part+ip1, Po, npb,
                                             ztransverse->dx, ztransverse->dy,
                                             ztransverse->xDriveExponent, ztransverse->yDriveExponent);
#if (!USE_MPI)
    if (n_binned!=npb) {
      fprintf(stdout, "Warning: only %ld of %ld particles were binned (ZTRANSVERSE)!\n", n_binned, npb);
      if (!not_first_call) {
        fprintf(stdout, "*** This may produce unphysical results.  Your wake needs smaller frequency\n");
        fprintf(stdout, "    spacing to cover a longer time span.\n");
      }
      fflush(stdout);
    }  
#else
    if (USE_MPI) {
      int all_binned, result = 1;
      if (isSlave)
        result = ((n_binned==np) ? 1 : 0);
      
      MPI_Allreduce(&result, &all_binned, 1, MPI_INT, MPI_LAND, workers);
      if (!all_binned) {
	if (myid==1) {  
	  /* This warning will be given only if the flag MPI_DEBUG is defined for the Pelegant */ 
	  fprintf(stdout, "warning: Not all of %ld particles were binned (WAKE)\n", np);
	  fprintf(stdout, "consider setting n_bins=0 in WAKE definition to invoke autoscaling\n");
	  fflush(stdout); 
	}
      }
    }
#endif

    userFactor[0] = ztransverse->factor*ztransverse->xfactor*rampFactor;
    userFactor[1] = ztransverse->factor*ztransverse->yfactor*rampFactor;

    first = 1;
    for (plane=0; plane<2; plane++) {
#if USE_MPI
      /* This could be good for some advanced network structures */
      /*
        if (isSlave) {
        double buffer[nb];
        MPI_Allreduce(posItime[plane], buffer, nb, MPI_DOUBLE, MPI_SUM, workers);
        memcpy(posItime[plane], buffer, sizeof(double)*nb);
        }
        */
      if (isSlave) {
        buffer_send = malloc(sizeof(float) * nb);
        buffer_recv = malloc(sizeof(float) * nb);
        for (i=0; i<nb; i++)
          buffer_send[i] = posItime[plane][i];
        MPI_Reduce(buffer_send, buffer_recv, nb, MPI_FLOAT, MPI_SUM, 1, workers);
        MPI_Bcast(buffer_recv, nb, MPI_FLOAT, 1, workers);
        for (i=0; i<nb; i++)
          posItime[plane][i] = buffer_recv[i];
        free(buffer_send);
        free(buffer_recv);
      }

#endif
      if (userFactor[plane]==0) {
        for (ib=0; ib<nb; ib++)
          Vtime[ib] = 0;
      } else {
        if (ztransverse->smoothing)
          SavitzyGolaySmooth(posItime[plane], nb, ztransverse->SGOrder,
                             ztransverse->SGHalfWidth, ztransverse->SGHalfWidth, 0);
        
        /* Take the FFT of (x*I)(t) to get (x*I)(f) */
        memcpy(posIfreq, posItime[plane], 2*nb*sizeof(*posIfreq));
        realFFT(posIfreq, nb, 0);
        
        /* Compute V(f) = i*Z(f)*(x*I)(f), putting in a factor 
         * to normalize the current waveform
         */
        Vfreq = Vtime;
        factor = ztransverse->macroParticleCharge*particleRelSign/dt*userFactor[plane];
        iZ = ztransverse->iZ[plane];
        Vfreq[0] = posIfreq[0]*iZ[0]*factor;
        nfreq = nb/2 + 1;
        if (nb%2==0)
          /* Nyquist term */
          Vfreq[nb-1] = posIfreq[nb-1]*iZ[nb-1]*factor;
        for (ib=1; ib<nfreq-1; ib++) {
          iImag = (iReal = 2*ib-1)+1;
          /* The signs are chosen here to get agreement with TRFMODE.
             In particular, test particles following closely behind the 
             drive particle get defocused.
             */
          Vfreq[iReal] =  (posIfreq[iReal]*iZ[iImag] + posIfreq[iImag]*iZ[iReal])*factor; 
          Vfreq[iImag] = -(posIfreq[iReal]*iZ[iReal] - posIfreq[iImag]*iZ[iImag])*factor;
        }
        
        /* Compute inverse FFT of V(f) to get V(t) */
        realFFT(Vfreq, nb, INVERSE_FFT);
        Vtime = Vfreq;
        
        /* change particle transverse momenta to reflect voltage in relevant bin */
        applyTransverseWakeKicks(part+ip1, time+ip1, pz, pbin, npb, 
                                 Po, plane, 
                                 Vtime, nb, tmin, dt, ztransverse->interpolate,
                                 plane==0?ztransverse->xProbeExponent:ztransverse->yProbeExponent);
      }

      if (ztransverse->SDDS_wake_initialized && ztransverse->wakes) {
        /* wake potential output */
        factor = ztransverse->macroParticleCharge*particleRelSign/dt;
        if ((ztransverse->wake_interval<=0 || ((i_pass0-ztransverse->wake_start)%ztransverse->wake_interval)==0) &&
            i_pass0>=ztransverse->wake_start && i_pass0<=ztransverse->wake_end) {
          if (first && !SDDS_StartTable(&ztransverse->SDDS_wake, nb)) {
            SDDS_SetError("Problem starting SDDS table for wake output (track_through_ztransverse)");
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          }
          for (ib=0; ib<nb; ib++) {
            if (!SDDS_SetRowValues(&ztransverse->SDDS_wake, SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE, ib,
                                   0, ib*dt, 
                                   1+plane*2, posItime[plane][ib]*factor,  
                                   2+plane*2, Vtime[ib], -1)) {
              SDDS_SetError("Problem setting rows of SDDS table for wake output (track_through_ztransverse)");
              SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            }
          }
          if (!SDDS_SetParameters(&ztransverse->SDDS_wake, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,
                                  "Pass", i_pass0, "q", ztransverse->macroParticleCharge*particleRelSign*np, NULL)) {
            SDDS_SetError("Problem setting parameters of SDDS table for wake output (track_through_ztransverse)");
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          }
          if (ztransverse->broad_band) {
            if (!SDDS_SetParameters(&ztransverse->SDDS_wake, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,
                                    "Rs", ztransverse->Rs, "fo", ztransverse->freq, 
                                    "Deltaf", ztransverse->bin_size, NULL)) {
              SDDS_SetError("Problem setting parameters of SDDS table for wake output (track_through_ztransverse)");
              SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            }
          }
          if (!first) {
            if (!SDDS_WriteTable(&ztransverse->SDDS_wake)) {
              SDDS_SetError("Problem writing SDDS table for wake output (track_through_ztransverse)");
              SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            }
            if (!inhibitFileSync)
              SDDS_DoFSync(&ztransverse->SDDS_wake);
          }
        }
      }
      first = 0;
    }
  }
  
#if defined(MIMIMIZE_MEMORY)
  free(posItime[0]);
  free(posItime[1]);
  free(posIfreq);
  free(Vtime);
  free(pbin);
  free(time);
  free(pz);
  posItime[0] = posItime[1] = Vtime = time = pz = posIfreq = NULL;
  pbin = NULL;
  max_n_bins = max_np = 0 ;
#endif

}