Example #1
0
void ThrOMP::ev_tally_thr(Pair * const pair, const int i, const int j, const int nlocal,
                          const int newton_pair, const double evdwl, const double ecoul,
                          const double fpair, const double delx, const double dely,
                          const double delz, ThrData * const thr)
{

  if (pair->eflag_either)
    e_tally_thr(pair, i, j, nlocal, newton_pair, evdwl, ecoul, thr);

  if (pair->vflag_either) {
    double v[6];
    v[0] = delx*delx*fpair;
    v[1] = dely*dely*fpair;
    v[2] = delz*delz*fpair;
    v[3] = delx*dely*fpair;
    v[4] = delx*delz*fpair;
    v[5] = dely*delz*fpair;

    v_tally_thr(pair, i, j, nlocal, newton_pair, v, thr);
  }

  if (pair->num_tally_compute > 0) {
    // ev_tally callbacks are not thread safe and thus have to be protected
#if defined(_OPENMP)
#pragma omp critical
#endif
    for (int k=0; k < pair->num_tally_compute; ++k) {
      Compute *c = pair->list_tally_compute[k];
      c->pair_tally_callback(i, j, nlocal, newton_pair,
                             evdwl, ecoul, fpair, delx, dely, delz);
    }
  }
}
Example #2
0
int FixAveTime::column_length(int dynamic)
{
  int m,length,lengthone;

  // determine nrows for static values

  if (!dynamic) {
    length = 0;
    for (int i = 0; i < nvalues; i++) {
      if (varlen[i]) continue;
      if (which[i] == COMPUTE) {
        int icompute = modify->find_compute(ids[i]);
        if (argindex[i] == 0)
          lengthone = modify->compute[icompute]->size_vector;
        else lengthone = modify->compute[icompute]->size_array_rows;
      } else if (which[i] == FIX) {
        int ifix = modify->find_fix(ids[i]);
        if (argindex[i] == 0) lengthone = modify->fix[ifix]->size_vector;
        else lengthone = modify->fix[ifix]->size_array_rows;
      } else if (which[i] == VARIABLE) {
        // variables are always varlen = 1, so dynamic
      } 
      if (length == 0) length = lengthone;
      else if (lengthone != length)
        error->all(FLERR,"Fix ave/time columns are inconsistent lengths");
    }
  }

  // determine new nrows for dynamic values
  // either all must be the same
  // or must match other static values
  // don't need to check if not MODE = VECTOR, just invoke lock_length()

  if (dynamic) {
    length = 0;
    for (int i = 0; i < nvalues; i++) {
      if (varlen[i] == 0) continue;
      m = value2index[i];
      if (which[i] == COMPUTE) {
        Compute *compute = modify->compute[m];
        lengthone = compute->lock_length();
      } else if (which[i] == VARIABLE) {
        double *varvec;
        lengthone = input->variable->compute_vector(m,&varvec);
      }
      if (mode == SCALAR) continue;
      if (all_variable_length) {
        if (length == 0) length = lengthone;
        else if (lengthone != length)
          error->all(FLERR,"Fix ave/time columns are inconsistent lengths");
      } else {
        if (lengthone != nrows)
          error->all(FLERR,"Fix ave/time columns are inconsistent lengths");
      }
    }
  }

  return length;
}
int _tmain(int argc, _TCHAR* argv[])
{
	Compute *compute = new Compute("Zad10.txt");
	compute->GiveResult();
	delete compute;
	std::cin.get();
	return 0;
}
Example #4
0
void ComputeSlice::extract_one(int m, double *vec, int stride)
{
  int i,j;

  // invoke the appropriate compute if needed

  if (which[m] == COMPUTE) {
    Compute *compute = modify->compute[value2index[m]];

    if (argindex[m] == 0) {
      if (!(compute->invoked_flag & INVOKED_VECTOR)) {
	compute->compute_vector();
	compute->invoked_flag |= INVOKED_VECTOR;
      }
      double *cvector = compute->vector;
      j = 0;
      for (i = nstart; i < nstop; i += nskip) {
	vec[j] = cvector[i-1];
	j += stride;
      }
      
    } else {
      if (!(compute->invoked_flag & INVOKED_ARRAY)) {
	compute->compute_array();
	compute->invoked_flag |= INVOKED_ARRAY;
      }
      double **carray = compute->array;
      int icol = argindex[m]-1;
      j = 0;
      for (i = nstart; i < nstop; i += nskip) {
	vec[j] = carray[i-1][icol];
	j += stride;
      }
    }

  // access fix fields, check if fix frequency is a match
    
  } else if (which[m] == FIX) {
    if (update->ntimestep % modify->fix[value2index[m]]->global_freq)
      error->all(FLERR,"Fix used in compute slice not computed at compatible time");
    Fix *fix = modify->fix[value2index[m]];

    if (argindex[m] == 0) {
      j = 0;
      for (i = nstart; i < nstop; i += nskip) {
	vec[j] = fix->compute_vector(i-1);
	j += stride;
      }
    } else {
      int icol = argindex[m]-1;
      j = 0;
      for (i = nstart; i < nstop; i += nskip) {
	vec[j] = fix->compute_array(i-1,icol);
	j += stride;
      }
    }
  }
}
void ComputeAtomMolecule::compute_one(int m)
{
  int vidx = value2index[m];
  int aidx = argindex[m];

  // invoke compute if not previously invoked

  if (which[m] == COMPUTE) {
    Compute *compute = modify->compute[vidx];

    if (!(compute->invoked_flag & INVOKED_PERATOM)) {
      compute->compute_peratom();
      compute->invoked_flag |= INVOKED_PERATOM;
    }

    if (aidx == 0) {
      peratom = compute->vector_atom;
      nstride = 1;
    } else {
      if (compute->array_atom) peratom = &compute->array_atom[0][aidx-1];
      else peratom = NULL;
      nstride = compute->size_array_cols;
    }

  // access fix fields, check if fix frequency is a match

  } else if (which[m] == FIX) {
    if (update->ntimestep % modify->fix[vidx]->peratom_freq)
      error->all(FLERR,"Fix used in compute atom/molecule not computed "
                 "at compatible time");
    Fix *fix = modify->fix[vidx];

    if (aidx == 0) {
      peratom = fix->vector_atom;
      nstride = 1;
    } else {
      peratom = &fix->array_atom[0][aidx-1];
      nstride = fix->size_array_cols;
    }

  // evaluate atom-style variable

  } else if (which[m] == VARIABLE) {
    if (atom->nlocal > maxatom) {
      maxatom = atom->nmax;
      memory->destroy(scratch);
      memory->create(scratch,maxatom,"atom/molecule:scratch");
      peratom = scratch;
    }

    input->variable->compute_atom(vidx,igroup,peratom,1,0);
    nstride = 1;
  }
}
shared_ptr<LinkedActionList> ProgramHandler::runCompiler(const shared_ptr<LinkedTokenList>& tokenList, const bool printCompiledList)
{
	Compute compute;
	shared_ptr<LinkedActionList> compiledList = compute.computeCompile(tokenList);

	if (printCompiledList)
	{
		compiledList->printList();
	}

	return compiledList;
}
Example #7
0
void Compute::sendC() {
    int indexY = thisIndex.y;
    for(int j=0; j<num_chare_y; j++) {
        if(j != indexY) {
            // use a local pointer for chares on the same processor
            Compute *c = compute(thisIndex.x, j, thisIndex.z).ckLocal();
            if(c != NULL)
                c->receiveC(&C[j*subBlockDimXy*blockDimZ], subBlockDimXy * blockDimZ, 1);
            else
                compute(thisIndex.x, j, thisIndex.z).receiveC(&C[j*subBlockDimXy*blockDimZ], subBlockDimXy * blockDimZ, 1);
        }
    }
}
Example #8
0
void Compute::sendB() {
    int indexX = thisIndex.x;

    for(int i=0; i<num_chare_x; i++)
        if(i != indexX) {
            // use a local pointer for chares on the same processor
            Compute* c = compute(i, thisIndex.y, thisIndex.z).ckLocal();
            if(c != NULL)
                c->receiveB(indexX, &B[indexX*subBlockDimYx*blockDimZ], subBlockDimYx * blockDimZ);
            else
                compute(i, thisIndex.y, thisIndex.z).receiveB(indexX, &B[indexX*subBlockDimYx*blockDimZ], subBlockDimYx * blockDimZ);
        }
}
Example #9
0
void Compute::sendA() {
    int indexZ = thisIndex.z;

    for(int k=0; k<num_chare_z; k++)
        if(k != indexZ) {
            // use a local pointer for chares on the same processor
            Compute* c = compute(thisIndex.x, thisIndex.y, k).ckLocal();
            if(c != NULL)
                c->receiveA(indexZ, &A[indexZ*subBlockDimXz*blockDimY], subBlockDimXz * blockDimY);
            else
                compute(thisIndex.x, thisIndex.y, k).receiveA(indexZ, &A[indexZ*subBlockDimXz*blockDimY], subBlockDimXz * blockDimY);
        }
}
Example #10
0
void *lammps_extract_compute(void *ptr, char *id, int style, int type)
{
  LAMMPS *lmp = (LAMMPS *) ptr;

  int icompute = lmp->modify->find_compute(id);
  if (icompute < 0) return NULL;
  Compute *compute = lmp->modify->compute[icompute];

  if (style == 0) {
    if (type == 0) {
      if (!compute->scalar_flag) return NULL;
      if (compute->invoked_scalar != lmp->update->ntimestep)
	compute->compute_scalar();
      return (void *) &compute->scalar;
    }
    if (type == 1) {
      if (!compute->vector_flag) return NULL;
      if (compute->invoked_vector != lmp->update->ntimestep)
	compute->compute_vector();
      return (void *) compute->vector;
    }
    if (type == 2) {
      if (!compute->array_flag) return NULL;
      if (compute->invoked_array != lmp->update->ntimestep)
	compute->compute_array();
      return (void *) compute->array;
    }
  }

  if (style == 1) {
    if (!compute->peratom_flag) return NULL;
    if (type == 1) {
      if (compute->invoked_peratom != lmp->update->ntimestep)
	compute->compute_peratom();
      return (void *) compute->vector_atom;
    }
    if (type == 2) {
      if (compute->invoked_peratom != lmp->update->ntimestep)
	compute->compute_peratom();
      return (void *) compute->array_atom;
    }
  }

  if (style == 2) {
    if (!compute->local_flag) return NULL;
    if (type == 1) {
      if (compute->invoked_local != lmp->update->ntimestep)
	compute->compute_local();
      return (void *) compute->vector_local;
    }
    if (type == 2) {
      if (compute->invoked_local != lmp->update->ntimestep)
	compute->compute_local();
      return (void *) compute->array_local;
    }
  }

  return NULL;
}
Example #11
0
void Compute::sendA() {
  int indexZ = thisIndex.z;

  for(int k=0; k<num_chare_z; k++)
    if(k != indexZ) {
#if USE_CKDIRECT
      CkDirect_put(&sHandles[num_chare_x + num_chare_y + k]);
#else
      // use a local pointer for chares on the same processor
      Compute* c = compute(thisIndex.x, thisIndex.y, k).ckLocal();
      if(c != NULL)
	c->receiveA(indexZ, &A[indexZ*subBlockDimXz*blockDimY], subBlockDimXz * blockDimY);
      else
	compute(thisIndex.x, thisIndex.y, k).receiveA(indexZ, &A[indexZ*subBlockDimXz*blockDimY], subBlockDimXz * blockDimY);
#endif
    }
}
Example #12
0
void Compute::sendB() {
  int indexX = thisIndex.x;

  for(int i=0; i<num_chare_x; i++)
    if(i != indexX) {
#if USE_CKDIRECT
      CkDirect_put(&sHandles[i]);
#else
      // use a local pointer for chares on the same processor
      Compute* c = compute(i, thisIndex.y, thisIndex.z).ckLocal();
      if(c != NULL)
	c->receiveB(indexX, &B[indexX*subBlockDimYx*blockDimZ], subBlockDimYx * blockDimZ);
      else
	compute(i, thisIndex.y, thisIndex.z).receiveB(indexX, &B[indexX*subBlockDimYx*blockDimZ], subBlockDimYx * blockDimZ);
#endif
    }
}
Example #13
0
void Compute::sendC() {
  int indexY = thisIndex.y;
  for(int j=0; j<num_chare_y; j++) {
    if(j != indexY) {
#if USE_CKDIRECT
      CkDirect_put(&sHandles[num_chare_x + j]);
#else
      // use a local pointer for chares on the same processor
      Compute *c = compute(thisIndex.x, j, thisIndex.z).ckLocal();
      if(c != NULL)
	c->receiveC(&C[j*subBlockDimXy*blockDimZ], subBlockDimXy * blockDimZ, 1);
      else
	compute(thisIndex.x, j, thisIndex.z).receiveC(&C[j*subBlockDimXy*blockDimZ], subBlockDimXy * blockDimZ, 1);
#endif
    }
  }
}
Example #14
0
    EBTStatus ComputeTask::update(Agent* pAgent, EBTStatus childStatus) {
        BEHAVIAC_ASSERT(childStatus == BT_RUNNING);

        EBTStatus result = BT_SUCCESS;

        BEHAVIAC_ASSERT(Compute::DynamicCast(this->GetNode()));
        Compute* pComputeNode = (Compute*)(this->GetNode());

        //bool bValid = Compute::EvaluteCompute(pAgent, pComputeNode->m_typeName, pComputeNode->m_opl, pComputeNode->m_opr1, pComputeNode->m_opr1_m,
        //    pComputeNode->m_operator, pComputeNode->m_opr2, pComputeNode->m_opr2_m);
        if (pComputeNode->m_opl != NULL) {
            pComputeNode->m_opl->Compute(pAgent, pComputeNode->m_opr1, pComputeNode->m_opr2, pComputeNode->m_operator);
        } else {
            result = pComputeNode->update_impl(pAgent, childStatus);
        }

        return result;
    }
Example #15
0
AllResults compute(Compute& comp) {
  comp.compute();
  unsigned natoms = comp.get_natoms();
  AllResults res;
  res.energy = comp.get_energy();
  for (unsigned dim = 0; dim < 6; ++dim) {
    res.virial(dim) = comp.get_virial()(dim);
    res.virial_from_dEdr(dim) = comp.get_virial_from_dEdr()(dim);
  }
  for (unsigned i = 0; i < natoms; ++i) {
    res.particle_energy.push_back(comp.get_energy(i));
    for (unsigned dim = 0; dim < 3; ++dim) {
      res.force.push_back(comp.get_force(i, dim));
    }
    res.particle_virial.push_back(comp.get_virial(i));
  }
  return move(res);
}
Example #16
0
void FixAveTime::invoke_scalar(bigint ntimestep)
{
  int i,m;
  double scalar;

  // zero if first sample within single Nfreq epoch
  // NOTE: doc this
  // are not checking for returned length, just initialize it
  // check for exceeding length is done below

  if (irepeat == 0) {
    if (any_variable_length) {
      modify->clearstep_compute();
      column_length(1);
      modify->addstep_compute(ntimestep+nevery);
      modify->addstep_compute(ntimestep+nfreq);
    }
    for (i = 0; i < nvalues; i++) vector[i] = 0.0;
  }

  // accumulate results of computes,fixes,variables to local copy
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  for (i = 0; i < nvalues; i++) {
    m = value2index[i];

    // invoke compute if not previously invoked

    if (which[i] == COMPUTE) {
      Compute *compute = modify->compute[m];

      if (argindex[i] == 0) {
        if (!(compute->invoked_flag & INVOKED_SCALAR)) {
          compute->compute_scalar();
          compute->invoked_flag |= INVOKED_SCALAR;
        }
        scalar = compute->scalar;
      } else {
        if (!(compute->invoked_flag & INVOKED_VECTOR)) {
          compute->compute_vector();
          compute->invoked_flag |= INVOKED_VECTOR;
        }

        // insure no out-of-range access to variable-length compute vector

        if (varlen[i] && compute->size_vector < argindex[i]) scalar = 0.0;
        else scalar = compute->vector[argindex[i]-1];
      }

    // access fix fields, guaranteed to be ready

    } else if (which[i] == FIX) {
      if (argindex[i] == 0)
        scalar = modify->fix[m]->compute_scalar();
      else
        scalar = modify->fix[m]->compute_vector(argindex[i]-1);

    // evaluate equal-style variable

    } else if (which[i] == VARIABLE)
      scalar = input->variable->compute_equal(m);

    // add value to vector or just set directly if offcol is set

    if (offcol[i]) vector[i] = scalar;
    else vector[i] += scalar;
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep + nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // average the final result for the Nfreq timestep

  double repeat = nrepeat;
  for (i = 0; i < nvalues; i++)
    if (offcol[i] == 0) vector[i] /= repeat;

  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values

  if (ave == ONE) {
    for (i = 0; i < nvalues; i++) vector_total[i] = vector[i];
    norm = 1;

  } else if (ave == RUNNING) {
    for (i = 0; i < nvalues; i++) vector_total[i] += vector[i];
    norm++;

  } else if (ave == WINDOW) {
    for (i = 0; i < nvalues; i++) {
      vector_total[i] += vector[i];
      if (window_limit) vector_total[i] -= vector_list[iwindow][i];
      vector_list[iwindow][i] = vector[i];
    }

    iwindow++;
    if (iwindow == nwindow) {
      iwindow = 0;
      window_limit = 1;
    }
    if (window_limit) norm = nwindow;
    else norm = iwindow;
  }

  // insure any columns with offcol set are effectively set to last value

  for (i = 0; i < nvalues; i++)
    if (offcol[i]) vector_total[i] = norm*vector[i];

  // output result to file

  if (fp && me == 0) {
    clearerr(fp);
    if (overwrite) fseek(fp,filepos,SEEK_SET);
    fprintf(fp,BIGINT_FORMAT,ntimestep);
    for (i = 0; i < nvalues; i++) fprintf(fp,format,vector_total[i]/norm);
    fprintf(fp,"\n");
    if (ferror(fp))
      error->one(FLERR,"Error writing out time averaged data");

    fflush(fp);

    if (overwrite) {
      long fileend = ftell(fp);
      if (fileend > 0) ftruncate(fileno(fp),fileend);
    }
  }
}
void FixAveAtom::end_of_step()
{
  int i,j,m,n;

  // skip if not step which requires doing something

  bigint ntimestep = update->ntimestep;
  if (ntimestep != nvalid) return;

  // zero if first step

  int nlocal = atom->nlocal;

  if (irepeat == 0)
    for (i = 0; i < nlocal; i++)
      for (m = 0; m < nvalues; m++)
        array[i][m] = 0.0;

  // accumulate results of attributes,computes,fixes,variables to local copy
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  int *mask = atom->mask;

  for (m = 0; m < nvalues; m++) {
    n = value2index[m];
    j = argindex[m];

    if (which[m] == X) {
      double **x = atom->x;
      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit) array[i][m] += x[i][j];

    } else if (which[m] == V) {
      double **v = atom->v;
      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit) array[i][m] += v[i][j];

    } else if (which[m] == F) {
      double **f = atom->f;
      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit) array[i][m] += f[i][j];

    // invoke compute if not previously invoked

    } else if (which[m] == COMPUTE) {
      Compute *compute = modify->compute[n];
      if (!(compute->invoked_flag & INVOKED_PERATOM)) {
        compute->compute_peratom();
        compute->invoked_flag |= INVOKED_PERATOM;
      }

      if (j == 0) {
        double *compute_vector = compute->vector_atom;
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit) array[i][m] += compute_vector[i];
      } else {
        int jm1 = j - 1;
        double **compute_array = compute->array_atom;
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit) array[i][m] += compute_array[i][jm1];
      }

    // access fix fields, guaranteed to be ready

    } else if (which[m] == FIX) {
      if (j == 0) {
        double *fix_vector = modify->fix[n]->vector_atom;
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit) array[i][m] += fix_vector[i];
      } else {
        int jm1 = j - 1;
        double **fix_array = modify->fix[n]->array_atom;
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit) array[i][m] += fix_array[i][jm1];
      }

    // evaluate atom-style variable
    // final argument = 1 sums result to array

    } else if (which[m] == VARIABLE && array)
      input->variable->compute_atom(n,igroup,&array[0][m],nvalues,1);
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep+peratom_freq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // average the final result for the Nfreq timestep

  double repeat = nrepeat;
  for (i = 0; i < nlocal; i++)
    for (m = 0; m < nvalues; m++)
      array[i][m] /= repeat;
}
Example #18
0
void FixAveHisto::end_of_step()
{
  int i,j,m;

  // skip if not step which requires doing something
  // error check if timestep was reset in an invalid manner

  bigint ntimestep = update->ntimestep;
  if (ntimestep < nvalid_last || ntimestep > nvalid) 
    error->all(FLERR,"Invalid timestep reset for fix ave/histo");
  if (ntimestep != nvalid) return;
  nvalid_last = nvalid;

  // zero if first step

  if (irepeat == 0) {
    stats[0] = stats[1] = 0.0;
    stats[2] = BIG;
    stats[3] = -BIG;
    for (i = 0; i < nbins; i++) bin[i] = 0.0;
  }

  // accumulate results of computes,fixes,variables to local copy
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  for (i = 0; i < nvalues; i++) {
    m = value2index[i];
    j = argindex[i];

    // atom attributes

    if (which[i] == X)
      bin_atoms(&atom->x[0][j],3);
    else if (which[i] == V)
      bin_atoms(&atom->v[0][j],3);
    else if (which[i] == F)
      bin_atoms(&atom->f[0][j],3);

    // invoke compute if not previously invoked

    if (which[i] == COMPUTE) {
      Compute *compute = modify->compute[m];

      if (kind == GLOBAL && mode == SCALAR) {
        if (j == 0) {
          if (!(compute->invoked_flag & INVOKED_SCALAR)) {
            compute->compute_scalar();
            compute->invoked_flag |= INVOKED_SCALAR;
          }
          bin_one(compute->scalar);
        } else {
          if (!(compute->invoked_flag & INVOKED_VECTOR)) {
            compute->compute_vector();
            compute->invoked_flag |= INVOKED_VECTOR;
          }
          bin_one(compute->vector[j-1]);
        }
      } else if (kind == GLOBAL && mode == VECTOR) {
        if (j == 0) {
          if (!(compute->invoked_flag & INVOKED_VECTOR)) {
            compute->compute_vector();
            compute->invoked_flag |= INVOKED_VECTOR;
          }
          bin_vector(compute->size_vector,compute->vector,1);
        } else {
          if (!(compute->invoked_flag & INVOKED_ARRAY)) {
            compute->compute_array();
            compute->invoked_flag |= INVOKED_ARRAY;
          }
          if (compute->array)
            bin_vector(compute->size_array_rows,&compute->array[0][j-1],
                       compute->size_array_cols);
        }

      } else if (kind == PERATOM) {
        if (!(compute->invoked_flag & INVOKED_PERATOM)) {
          compute->compute_peratom();
          compute->invoked_flag |= INVOKED_PERATOM;
        }
        if (j == 0)
          bin_atoms(compute->vector_atom,1);
        else if (compute->array_atom)
          bin_atoms(&compute->array_atom[0][j-1],compute->size_peratom_cols);

      } else if (kind == LOCAL) {
        if (!(compute->invoked_flag & INVOKED_LOCAL)) {
          compute->compute_local();
          compute->invoked_flag |= INVOKED_LOCAL;
        }
        if (j == 0)
          bin_vector(compute->size_local_rows,compute->vector_local,1);
        else if (compute->array_local)
          bin_vector(compute->size_local_rows,&compute->array_local[0][j-1],
                     compute->size_local_cols);
      }

      // access fix fields, guaranteed to be ready

    } else if (which[i] == FIX) {

      Fix *fix = modify->fix[m];

      if (kind == GLOBAL && mode == SCALAR) {
        if (j == 0) bin_one(fix->compute_scalar());
        else bin_one(fix->compute_vector(j-1));

      } else if (kind == GLOBAL && mode == VECTOR) {
        if (j == 0) {
          int n = fix->size_vector;
          for (i = 0; i < n; i++) bin_one(fix->compute_vector(i));
        } else {
          int n = fix->size_vector;
          for (i = 0; i < n; i++) bin_one(fix->compute_array(i,j-1));
        }

      } else if (kind == PERATOM) {
        if (j == 0) bin_atoms(fix->vector_atom,1);
        else if (fix->array_atom)
          bin_atoms(fix->array_atom[j-1],fix->size_peratom_cols);

      } else if (kind == LOCAL) {
        if (j == 0) bin_vector(fix->size_local_rows,fix->vector_local,1);
        else if (fix->array_local)
          bin_vector(fix->size_local_rows,&fix->array_local[0][j-1],
                     fix->size_local_cols);
      }

      // evaluate equal-style variable

    } else if (which[i] == VARIABLE && kind == GLOBAL) {
      bin_one(input->variable->compute_equal(m));

    } else if (which[i] == VARIABLE && kind == PERATOM) {
      if (atom->nlocal > maxatom) {
        memory->destroy(vector);
        maxatom = atom->nmax;
        memory->create(vector,maxatom,"ave/histo:vector");
      }
      input->variable->compute_atom(m,igroup,vector,1,0);
      bin_atoms(vector,1);
    }
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep + nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // merge histogram stats across procs if necessary

  if (kind == PERATOM || kind == LOCAL) {
    MPI_Allreduce(stats,stats_all,2,MPI_DOUBLE,MPI_SUM,world);
    MPI_Allreduce(&stats[2],&stats_all[2],1,MPI_DOUBLE,MPI_MIN,world);
    MPI_Allreduce(&stats[3],&stats_all[3],1,MPI_DOUBLE,MPI_MAX,world);
    MPI_Allreduce(bin,bin_all,nbins,MPI_DOUBLE,MPI_SUM,world);

    stats[0] = stats_all[0];
    stats[1] = stats_all[1];
    stats[2] = stats_all[2];
    stats[3] = stats_all[3];
    for (i = 0; i < nbins; i++) bin[i] = bin_all[i];
  }

  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values

  if (ave == ONE) {
    stats_total[0] = stats[0];
    stats_total[1] = stats[1];
    stats_total[2] = stats[2];
    stats_total[3] = stats[3];
    for (i = 0; i < nbins; i++) bin_total[i] = bin[i];

  } else if (ave == RUNNING) {
    stats_total[0] += stats[0];
    stats_total[1] += stats[1];
    stats_total[2] = MIN(stats_total[2],stats[2]);
    stats_total[3] = MAX(stats_total[3],stats[3]);
    for (i = 0; i < nbins; i++) bin_total[i] += bin[i];

  } else if (ave == WINDOW) {
    stats_total[0] += stats[0];
    if (window_limit) stats_total[0] -= stats_list[iwindow][0];
    stats_list[iwindow][0] = stats[0];
    stats_total[1] += stats[1];
    if (window_limit) stats_total[1] -= stats_list[iwindow][1];
    stats_list[iwindow][1] = stats[1];

    if (window_limit) m = nwindow;
    else m = iwindow+1;

    stats_list[iwindow][2] = stats[2];
    stats_total[2] = stats_list[0][2];
    for (i = 1; i < m; i++)
      stats_total[2] = MIN(stats_total[2],stats_list[i][2]);
    stats_list[iwindow][3] = stats[3];
    stats_total[3] = stats_list[0][3];
    for (i = 1; i < m; i++)
      stats_total[3] = MAX(stats_total[3],stats_list[i][3]);

    for (i = 0; i < nbins; i++) {
      bin_total[i] += bin[i];
      if (window_limit) bin_total[i] -= bin_list[iwindow][i];
      bin_list[iwindow][i] = bin[i];
    }

    iwindow++;
    if (iwindow == nwindow) {
      iwindow = 0;
      window_limit = 1;
    }
  }

  // output result to file

  if (fp && me == 0) {
    if (overwrite) fseek(fp,filepos,SEEK_SET);
    fprintf(fp,BIGINT_FORMAT " %d %g %g %g %g\n",ntimestep,nbins,
            stats_total[0],stats_total[1],stats_total[2],stats_total[3]);
    if (stats_total[0] != 0.0)
      for (i = 0; i < nbins; i++)
        fprintf(fp,"%d %g %g %g\n",
                i+1,coord[i],bin_total[i],bin_total[i]/stats_total[0]);
    else
      for (i = 0; i < nbins; i++)
        fprintf(fp,"%d %g %g %g\n",i+1,coord[i],0.0,0.0);
    fflush(fp);
    if (overwrite) {
      long fileend = ftell(fp);
      ftruncate(fileno(fp),fileend);
    }
  }
}
Example #19
0
void Compute::callBackRcvdC(void *arg) {
  Compute *obj = (Compute *)arg;
  obj->countC++;
  if(obj->countC == num_chare_y)
    obj->thisProxy(obj->thisIndex.x, obj->thisIndex.y, obj->thisIndex.z).receiveC();
}
Example #20
0
void Compute::callBackRcvdB(void *arg) {
  Compute *obj = (Compute *)arg;
  obj->countB++;
  if(obj->countA == num_chare_z-1 && obj->countB == num_chare_x-1)
    obj->thisProxy(obj->thisIndex.x, obj->thisIndex.y, obj->thisIndex.z).doWork();
}
Example #21
0
void FixAveSpatial::end_of_step()
{
  int i,j,m,n,ilayer;
  double lo,hi;

  // skip if not step which requires doing something

  int ntimestep = update->ntimestep;
  if (ntimestep != nvalid) return;

  // if computing the first sample, setup layers
  // compute current origin = boundary for some layer
  // lo = layer boundary immediately below boxlo
  // hi = layer boundary immediately above boxhi
  // allocate and initialize arrays based on new layer count

  if (irepeat == 0) {
    double *boxlo,*boxhi,*prd;
    if (scaleflag == REDUCED) {
      boxlo = domain->boxlo_lamda;
      boxhi = domain->boxhi_lamda;
      prd = domain->prd_lamda;
    } else {
      boxlo = domain->boxlo;
      boxhi = domain->boxhi;
      prd = domain->prd;
    }

    if (originflag == LOWER) origin = boxlo[dim];
    else if (originflag == UPPER) origin = boxhi[dim];
    else if (originflag == CENTER) origin = 0.5 * (boxlo[dim] + boxhi[dim]);

    if (origin < boxlo[dim]) {
      m = static_cast<int> ((boxlo[dim] - origin) * invdelta);
      lo = origin + m*delta;
    } else {
      m = static_cast<int> ((origin - boxlo[dim]) * invdelta);
      lo = origin - m*delta;
      if (lo > boxlo[dim]) lo -= delta;
    }
    if (origin < boxhi[dim]) {
      m = static_cast<int> ((boxhi[dim] - origin) * invdelta);
      hi = origin + m*delta;
      if (hi < boxhi[dim]) hi += delta;
    } else {
      m = static_cast<int> ((origin - boxhi[dim]) * invdelta);
      hi = origin - m*delta;
    }

    offset = lo;
    nlayers = static_cast<int> ((hi-lo) * invdelta + 0.5);
    double volume = domain->xprd * domain->yprd * domain->zprd;
    layer_volume = delta * volume/prd[dim];

    if (nlayers > maxlayer) {
      maxlayer = nlayers;
      coord = (double *) memory->srealloc(coord,nlayers*sizeof(double),
					  "ave/spatial:coord");
      count_one = (double *) 
	memory->srealloc(count_one,nlayers*sizeof(double),
			 "ave/spatial:count_one");
      count_many = (double *) 
	memory->srealloc(count_many,nlayers*sizeof(double),
			 "ave/spatial:count_many");
      count_sum = (double *) 
	memory->srealloc(count_sum,nlayers*sizeof(double),
			 "ave/spatial:count_sum");
      count_total = (double *) 
	memory->srealloc(count_total,nlayers*sizeof(double),
			 "ave/spatial:count_total");

      values_one = memory->grow_2d_double_array(values_one,nlayers,nvalues,
						"ave/spatial:values_one");
      values_many = memory->grow_2d_double_array(values_many,nlayers,nvalues,
						 "ave/spatial:values_many");
      values_sum = memory->grow_2d_double_array(values_sum,nlayers,nvalues,
						"ave/spatial:values_sum");
      values_total = memory->grow_2d_double_array(values_total,nlayers,nvalues,
						  "ave/spatial:values_total");

      // initialize count and values total to zero since they accumulate

      for (m = 0; m < nlayers; m++) {
	for (i = 0; i < nvalues; i++) values_total[m][i] = 0.0;
	count_total[m] = 0.0;
      }

      // only allocate count and values list for ave = WINDOW
      // only happens once since nlayers never changes for these ave settings
      
      if (ave == WINDOW) {
	count_list =
	  memory->create_2d_double_array(nwindow,nlayers,
					 "ave/spatial:count_list");
	values_list =
	  memory->create_3d_double_array(nwindow,nlayers,nvalues,
					 "ave/spatial:values_list");
      }
    }

    for (m = 0; m < nlayers; m++) {
      coord[m] = offset + (m+0.5)*delta;
      count_many[m] = count_sum[m] = 0.0;
      for (i = 0; i < nvalues; i++) values_many[m][i] = 0.0;
    }
  }
  
  // zero out arrays for one sample

  for (m = 0; m < nlayers; m++) {
    count_one[m] = 0.0;
    for (i = 0; i < nvalues; i++) values_one[m][i] = 0.0;
  }

  // assign each atom to a layer
  // remap each atom's relevant coord back into box via PBC if necessary
  // if scaleflag = REDUCED, box coords -> lamda coords

  double **x = atom->x;
  int *mask = atom->mask;
  int nlocal = atom->nlocal;

  if (nlocal > maxatomlayer) {
    maxatomlayer = atom->nmax;
    memory->sfree(layer);
    layer = (int *) 
      memory->smalloc(maxatomlayer*sizeof(int),"ave/spatial:layer");
  }

  double *boxlo,*boxhi,*prd;
  double xremap;
  int periodicity = domain->periodicity[dim];

  if (periodicity) {
    if (scaleflag == REDUCED) {
      boxlo = domain->boxlo_lamda;
      boxhi = domain->boxhi_lamda;
      prd = domain->prd_lamda;
    } else {
      boxlo = domain->boxlo;
      boxhi = domain->boxhi;
      prd = domain->prd;
    }
  }

  if (scaleflag == REDUCED) domain->x2lamda(nlocal);
  
  for (i = 0; i < nlocal; i++)
    if (mask[i] & groupbit) {
      xremap = x[i][dim];
      if (periodicity) {
	if (xremap < boxlo[dim]) xremap += prd[dim];
	if (xremap >= boxhi[dim]) xremap -= prd[dim];
      }
      ilayer = static_cast<int> ((xremap - offset) * invdelta);
      if (ilayer < 0) ilayer = 0;
      if (ilayer >= nlayers) ilayer = nlayers-1;
      layer[i] = ilayer;
      count_one[ilayer] += 1.0;
    }

  if (scaleflag == REDUCED) domain->lamda2x(nlocal);

  // perform the computation for one sample
  // accumulate results of attributes,computes,fixes,variables to local copy
  // sum within each layer, only include atoms in fix group
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  for (m = 0; m < nvalues; m++) {
    n = value2index[m];
    j = argindex[m];

    // X,V,F adds coords,velocities,forces to values

    if (which[m] == X || which[m] == V || which[m] == F) {
      double **attribute;
      if (which[m] == X) attribute = x;
      else if (which[m] == V) attribute = atom->v;
      else attribute = atom->f;

      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit)
	  values_one[layer[i]][m] += attribute[i][j];

    // DENSITY_NUMBER adds 1 to values

    } else if (which[m] == DENSITY_NUMBER) {

      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit)
	  values_one[layer[i]][m] += 1.0;

    // DENSITY_MASS adds mass to values

    } else if (which[m] == DENSITY_MASS) {
      int *type = atom->type;
      double *mass = atom->mass;
      double *rmass = atom->rmass;

      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit)
	  if (rmass) values_one[layer[i]][m] += rmass[i];
	  else values_one[layer[i]][m] += mass[type[i]];

    // COMPUTE adds its scalar or vector component to values
    // invoke compute if not previously invoked

    } else if (which[m] == COMPUTE) {
      Compute *compute = modify->compute[n];
      if (!(compute->invoked_flag & INVOKED_PERATOM)) {
	compute->compute_peratom();
	compute->invoked_flag |= INVOKED_PERATOM;
      }
      double *vector = compute->vector_atom;
      double **array = compute->array_atom;
      int jm1 = j - 1;

      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit)
	  if (j == 0) values_one[layer[i]][m] += vector[i];
	  else values_one[layer[i]][m] += array[i][jm1];
      
    // FIX adds its scalar or vector component to values
    // access fix fields, guaranteed to be ready

    } else if (which[m] == FIX) {
      double *vector = modify->fix[n]->vector_atom;
      double **array = modify->fix[n]->array_atom;
      int jm1 = j - 1;

      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit) {
	  if (j == 0) values_one[layer[i]][m] += vector[i];
	  else values_one[layer[i]][m] += array[i][jm1];
	}

    // VARIABLE adds its per-atom quantities to values
    // evaluate atom-style variable

    } else if (which[m] == VARIABLE) {
      if (nlocal > maxatomvar) {
	maxatomvar = atom->nmax;
	memory->sfree(varatom);
	varatom = (double *) 
	  memory->smalloc(maxatomvar*sizeof(double),"ave/spatial:varatom");
      }

      input->variable->compute_atom(n,igroup,varatom,1,0);

      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit)
	  values_one[layer[i]][m] += varatom[i];
    }
  }

  // process a single sample
  // if normflag = ALL, accumulate values,count separately to many
  // if normflag = SAMPLE, one = value/count, accumulate one to many
  // exception is SAMPLE density: no normalization by atom count

  if (normflag == ALL) {
    for (m = 0; m < nlayers; m++) {
      count_many[m] += count_one[m];
      for (j = 0; j < nvalues; j++)
	values_many[m][j] += values_one[m][j];
    }
  } else {
    MPI_Allreduce(count_one,count_many,nlayers,MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nlayers; m++) {
      if (count_many[m] > 0.0)
	for (j = 0; j < nvalues; j++) {
	  if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
	    values_many[m][j] += values_one[m][j];
	  else values_many[m][j] += values_one[m][j]/count_many[m];
	}
      count_sum[m] += count_many[m];
    }
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // time average across samples
  // if normflag = ALL, final is total value / total count
  // if normflag = SAMPLE, final is sum of ave / repeat
  // exception is ALL density: normalized by repeat, not total count

  double repeat = nrepeat;

  if (normflag == ALL) {
    MPI_Allreduce(count_many,count_sum,nlayers,MPI_DOUBLE,MPI_SUM,world);
    MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nlayers*nvalues,
		  MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nlayers; m++) {
      if (count_sum[m] > 0.0)
	for (j = 0; j < nvalues; j++)
	  if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
	    values_sum[m][j] /= repeat;
	  else values_sum[m][j] /= count_sum[m];
      count_sum[m] /= repeat;
    }
  } else {
    MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nlayers*nvalues,
		  MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nlayers; m++) {
      for (j = 0; j < nvalues; j++)
	values_sum[m][j] /= repeat;
      count_sum[m] /= repeat;
    }
  }

  // density is additionally normalized by layer volume

  for (j = 0; j < nvalues; j++)
    if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
      for (m = 0; m < nlayers; m++)
	values_sum[m][j] /= layer_volume;

  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, comine with nwindow most recent Nfreq timestep values

  if (ave == ONE) {
    for (m = 0; m < nlayers; m++) {
      for (i = 0; i < nvalues; i++) 
	values_total[m][i] = values_sum[m][i];
      count_total[m] = count_sum[m];
    }
    norm = 1;

  } else if (ave == RUNNING) {
    for (m = 0; m < nlayers; m++) {
      for (i = 0; i < nvalues; i++)
	values_total[m][i] += values_sum[m][i];
      count_total[m] += count_sum[m];
    }
    norm++;

  } else if (ave == WINDOW) {
    for (m = 0; m < nlayers; m++) {
      for (i = 0; i < nvalues; i++) {
	values_total[m][i] += values_sum[m][i];
	if (window_limit) values_total[m][i] -= values_list[iwindow][m][i];
	values_list[iwindow][m][i] = values_sum[m][i];
      }
      count_total[m] += count_sum[m];
      if (window_limit) count_total[m] -= count_list[iwindow][m];
      count_list[iwindow][m] = count_sum[m];
    }

    iwindow++;
    if (iwindow == nwindow) {
      iwindow = 0;
      window_limit = 1;
    }
    if (window_limit) norm = nwindow;
    else norm = iwindow;
  }

  // output result to file
  
  if (fp && me == 0) {
    fprintf(fp,"%d %d\n",ntimestep,nlayers);
    for (m = 0; m < nlayers; m++) {
      fprintf(fp,"  %d %g %g",m+1,coord[m],count_total[m]/norm);
      for (i = 0; i < nvalues; i++) fprintf(fp," %g",values_total[m][i]/norm);
      fprintf(fp,"\n");
    }
    fflush(fp);
  }
}
Example #22
0
void FixAveCorrelate::end_of_step()
{
  int i,j,m;
  double scalar;

  // skip if not step which requires doing something
  // error check if timestep was reset in an invalid manner

  bigint ntimestep = update->ntimestep;
  if (ntimestep < nvalid_last || ntimestep > nvalid) 
    error->all(FLERR,"Invalid timestep reset for fix ave/correlate");
  if (ntimestep != nvalid) return;
  nvalid_last = nvalid;

  // accumulate results of computes,fixes,variables to origin
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  // lastindex = index in values ring of latest time sample

  lastindex++;
  if (lastindex == nrepeat) lastindex = 0;

  for (i = 0; i < nvalues; i++) {
    m = value2index[i];

    // invoke compute if not previously invoked

    if (which[i] == COMPUTE) {
      Compute *compute = modify->compute[m];

      if (argindex[i] == 0) {
        if (!(compute->invoked_flag & INVOKED_SCALAR)) {
          compute->compute_scalar();
          compute->invoked_flag |= INVOKED_SCALAR;
        }
        scalar = compute->scalar;
      } else {
        if (!(compute->invoked_flag & INVOKED_VECTOR)) {
          compute->compute_vector();
          compute->invoked_flag |= INVOKED_VECTOR;
        }
        scalar = compute->vector[argindex[i]-1];
      }

    // access fix fields, guaranteed to be ready

    } else if (which[i] == FIX) {
      if (argindex[i] == 0)
        scalar = modify->fix[m]->compute_scalar();
      else
        scalar = modify->fix[m]->compute_vector(argindex[i]-1);

    // evaluate equal-style variable

    } else if (which[i] == VARIABLE)
      scalar = input->variable->compute_equal(m);

    values[lastindex][i] = scalar;
  }

  // fistindex = index in values ring of earliest time sample
  // nsample = number of time samples in values ring

  if (nsample < nrepeat) nsample++;
  else {
    firstindex++;
    if (firstindex == nrepeat) firstindex = 0;
  }

  nvalid += nevery;
  modify->addstep_compute(nvalid);

  // calculate all Cij() enabled by latest values

  accumulate();
  if (ntimestep % nfreq) return;

  // save results in save_count and save_corr

  for (i = 0; i < nrepeat; i++) {
    save_count[i] = count[i];
    if (count[i])
      for (j = 0; j < npair; j++)
        save_corr[i][j] = prefactor*corr[i][j]/count[i];
    else
      for (j = 0; j < npair; j++)
        save_corr[i][j] = 0.0;
  }

  // output result to file

  if (fp && me == 0) {
    if (overwrite) fseek(fp,filepos,SEEK_SET);
    fprintf(fp,BIGINT_FORMAT " %d\n",ntimestep,nrepeat);
    for (i = 0; i < nrepeat; i++) {
      fprintf(fp,"%d %d %d",i+1,i*nevery,count[i]);
      if (count[i])
        for (j = 0; j < npair; j++)
          fprintf(fp," %g",prefactor*corr[i][j]/count[i]);
      else
        for (j = 0; j < npair; j++)
          fprintf(fp," 0.0");
      fprintf(fp,"\n");
    }
    fflush(fp);
    if (overwrite) {
      long fileend = ftell(fp);
      ftruncate(fileno(fp),fileend);
    }
  }

  // zero accumulation if requested
  // recalculate Cij(0)

  if (ave == ONE) {
    for (i = 0; i < nrepeat; i++) {
      count[i] = 0;
      for (j = 0; j < npair; j++)
        corr[i][j] = 0.0;
    }
    nsample = 1;
    accumulate();
  }
}
Example #23
0
void FixAveTime::invoke_vector(bigint ntimestep)
{
  int i,j,m;
  
  // zero if first step

  if (irepeat == 0)
    for (i = 0; i < nrows; i++)
      for (j = 0; j < nvalues; j++) array[i][j] = 0.0;
  
  // accumulate results of computes,fixes,variables to local copy
  // compute/fix/variable may invoke computes so wrap with clear/add
  
  modify->clearstep_compute();
  
  for (j = 0; j < nvalues; j++) {
    m = value2index[j];
    
    // invoke compute if not previously invoked
    
    if (which[j] == COMPUTE) {
      Compute *compute = modify->compute[m];
      
      if (argindex[j] == 0) {
	if (!(compute->invoked_flag & INVOKED_VECTOR)) {
	  compute->compute_vector();
	  compute->invoked_flag |= INVOKED_VECTOR;
	}
	double *cvector = compute->vector;
	for (i = 0; i < nrows; i++)
	  column[i] = cvector[i];
	
      } else {
	if (!(compute->invoked_flag & INVOKED_ARRAY)) {
	  compute->compute_array();
	  compute->invoked_flag |= INVOKED_ARRAY;
	}
	double **carray = compute->array;
	int icol = argindex[j]-1;
	for (i = 0; i < nrows; i++)
	  column[i] = carray[i][icol];
      }
      
    // access fix fields, guaranteed to be ready
      
    } else if (which[j] == FIX) {
      Fix *fix = modify->fix[m];
      if (argindex[j] == 0)
	for (i = 0; i < nrows; i++)
	  column[i] = fix->compute_vector(i);
      else {
	int icol = argindex[j]-1;
	for (i = 0; i < nrows; i++)
	  column[i] = fix->compute_array(i,icol);
      }
    }
    
    // add columns of values to array or just set directly if offcol is set
    
    if (offcol[j]) {
      for (i = 0; i < nrows; i++)
	array[i][j] = column[i];
    } else {
      for (i = 0; i < nrows; i++)
	array[i][j] += column[i];
    }
  }
  
  // done if irepeat < nrepeat
  // else reset irepeat and nvalid
  
  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }
  
  irepeat = 0;
  nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);
  
  // average the final result for the Nfreq timestep
  
  double repeat = nrepeat;
  for (i = 0; i < nrows; i++)
    for (j = 0; j < nvalues; j++)
      if (offcol[j] == 0) array[i][j] /= repeat;
  
  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values
  
  if (ntimestep >= startstep) {
    if (ave == ONE) {
      for (i = 0; i < nrows; i++)
	for (j = 0; j < nvalues; j++) array_total[i][j] = array[i][j];
      norm = 1;
      
    } else if (ave == RUNNING) {
      for (i = 0; i < nrows; i++)
	for (j = 0; j < nvalues; j++) array_total[i][j] += array[i][j];
      norm++;
      
    } else if (ave == WINDOW) {
      for (i = 0; i < nrows; i++)
	for (j = 0; j < nvalues; j++) {
	  array_total[i][j] += array[i][j];
	  if (window_limit) array_total[i][j] -= array_list[iwindow][i][j];
	  array_list[iwindow][i][j] = array[i][j];
	}
      
      iwindow++;
      if (iwindow == nwindow) {
	iwindow = 0;
	window_limit = 1;
      }
      if (window_limit) norm = nwindow;
      else norm = iwindow;
    }
  }
  
  // insure any columns with offcol set are effectively set to last value
  
  for (i = 0; i < nrows; i++)
    for (j = 0; j < nvalues; j++)
      if (offcol[j]) array_total[i][j] = norm*array[i][j];
  
  // output result to file
      
  if (fp && me == 0) {
    fprintf(fp,BIGINT_FORMAT " %d\n",ntimestep,nrows);
    for (i = 0; i < nrows; i++) {
      fprintf(fp,"%d",i+1);
      for (j = 0; j < nvalues; j++) fprintf(fp," %g",array_total[i][j]/norm);
      fprintf(fp,"\n");
    }
    fflush(fp);
  }
}
Example #24
0
void FixAveTime::invoke_scalar(bigint ntimestep)
{
  int i,m;
  double scalar;

  // zero if first step

  if (irepeat == 0)
    for (i = 0; i < nvalues; i++) vector[i] = 0.0;

  // accumulate results of computes,fixes,variables to local copy
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  for (i = 0; i < nvalues; i++) {
    m = value2index[i];
    
    // invoke compute if not previously invoked
    
    if (which[i] == COMPUTE) {
      Compute *compute = modify->compute[m];
      
      if (argindex[i] == 0) {
	if (!(compute->invoked_flag & INVOKED_SCALAR)) {
	  compute->compute_scalar();
	  compute->invoked_flag |= INVOKED_SCALAR;
	}
	scalar = compute->scalar;
      } else {
	if (!(compute->invoked_flag & INVOKED_VECTOR)) {
	  compute->compute_vector();
	  compute->invoked_flag |= INVOKED_VECTOR;
	}
	scalar = compute->vector[argindex[i]-1];
      }
      
    // access fix fields, guaranteed to be ready
      
    } else if (which[i] == FIX) {
      if (argindex[i] == 0) 
	scalar = modify->fix[m]->compute_scalar();
      else
	scalar = modify->fix[m]->compute_vector(argindex[i]-1);
      
    // evaluate equal-style variable
      
    } else if (which[i] == VARIABLE)
      scalar = input->variable->compute_equal(m);
    
    // add value to vector or just set directly if offcol is set
    
    if (offcol[i]) vector[i] = scalar;
    else vector[i] += scalar;
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep + nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // average the final result for the Nfreq timestep

  double repeat = nrepeat;
  for (i = 0; i < nvalues; i++)
    if (offcol[i] == 0) vector[i] /= repeat;

  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values

  if (ntimestep >= startstep) {
    if (ave == ONE) {
      for (i = 0; i < nvalues; i++) vector_total[i] = vector[i];
      norm = 1;

    } else if (ave == RUNNING) {
      for (i = 0; i < nvalues; i++) vector_total[i] += vector[i];
      norm++;
      
    } else if (ave == WINDOW) {
      for (i = 0; i < nvalues; i++) {
	vector_total[i] += vector[i];
	if (window_limit) vector_total[i] -= vector_list[iwindow][i];
	vector_list[iwindow][i] = vector[i];
      }
      
      iwindow++;
      if (iwindow == nwindow) {
	iwindow = 0;
	window_limit = 1;
      }
      if (window_limit) norm = nwindow;
      else norm = iwindow;
    }
  }

  // insure any columns with offcol set are effectively set to last value

  for (i = 0; i < nvalues; i++)
    if (offcol[i]) vector_total[i] = norm*vector[i];

  // output result to file

  if (fp && me == 0) {
    fprintf(fp,BIGINT_FORMAT,ntimestep);
    for (i = 0; i < nvalues; i++) fprintf(fp," %g",vector_total[i]/norm);
    fprintf(fp,"\n");
    fflush(fp);
  }
}
void ComputeChunkSpreadAtom::compute_peratom()
{
  invoked_peratom = update->ntimestep;

  // grow local vector_atom or array_atom if necessary

  if (atom->nmax > nmax) {
    if (nvalues == 1) {
      memory->destroy(vector_atom);
      nmax = atom->nmax;
      memory->create(vector_atom,nmax,"chunk/spread/atom:vector_atom");
    } else {
      memory->destroy(array_atom);
      nmax = atom->nmax;
      memory->create(array_atom,nmax,nvalues,"chunk/spread/atom:array_atom");
    }
  }

  // compute chunk/atom assigns atoms to chunk IDs
  // extract ichunk index vector from compute
  // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms

  int nchunk = cchunk->setup_chunks();
  cchunk->compute_ichunk();
  int *ichunk = cchunk->ichunk;

  // loop over values, access compute or fix
  // loop over atoms, use chunk ID of each atom to store value from compute/fix

  int *mask = atom->mask;
  int nlocal = atom->nlocal;

  int i,m,n,index,nstride;
  double *ptr;

  for (m = 0; m < nvalues; m++) {
    n = value2index[m];

    // copy compute/fix values into vector_atom or array_atom
    // nstride between values for each atom

    if (nvalues == 1) {
      ptr = vector_atom;
      nstride = 1;
    } else {
      ptr = &array_atom[0][m];
      nstride = nvalues;
    }

    // invoke compute if not previously invoked

    if (which[m] == COMPUTE) {
      Compute *compute = modify->compute[n];

      if (argindex[m] == 0) {
        if (!(compute->invoked_flag & INVOKED_VECTOR)) {
          compute->compute_vector();
          compute->invoked_flag |= INVOKED_VECTOR;
        }
	double *cvector = compute->vector;
	for (i = 0; i < nlocal; i++, ptr += nstride) {
	  *ptr = 0.0;
	  if (!(mask[i] & groupbit)) continue;
	  index = ichunk[i]-1;
	  if (index < 0 || index >= nchunk) continue;
	  *ptr = cvector[index];
	}

      } else {
        if (!(compute->invoked_flag & INVOKED_ARRAY)) {
          compute->compute_array();
          compute->invoked_flag |= INVOKED_ARRAY;
        }
        int icol = argindex[m]-1;
        double **carray = compute->array;
	for (i = 0; i < nlocal; i++, ptr += nstride) {
	  *ptr = 0.0;
	  if (!(mask[i] & groupbit)) continue;
	  index = ichunk[i]-1;
	  if (index < 0 || index >= nchunk) continue;
	  *ptr = carray[index][icol];
	}
      }

    // access fix data, check if fix frequency is a match
    // are assuming the fix global vector/array is per-chunk data
    // check if index exceeds fix output length/rows

    } else if (which[m] == FIX) {
      Fix *fix = modify->fix[n];
      if (update->ntimestep % fix->global_freq)
        error->all(FLERR,"Fix used in compute chunk/spread/atom not "
                   "computed at compatible time");

      if (argindex[m] == 0) {
        int nfix = fix->size_vector;
        for (i = 0; i < nlocal; i++, ptr += nstride) {
          *ptr = 0.0;
          if (!(mask[i] & groupbit)) continue;
          index = ichunk[i]-1;
          if (index < 0 || index >= nchunk || index >= nfix) continue;
          *ptr = fix->compute_vector(index);
        }

      } else {
        int icol = argindex[m]-1;
        int nfix = fix->size_array_rows;
        for (i = 0; i < nlocal; i++, ptr += nstride) {
          *ptr = 0.0;
          if (!(mask[i] & groupbit)) continue;
          index = ichunk[i]-1;
          if (index < 0 || index >= nchunk || index >= nfix) continue;
          *ptr = fix->compute_array(index,icol);
        }
      }
    }
  }
}
Example #26
0
void FixAveChunk::end_of_step()
{
  int i,j,m,n,index;

  // skip if not step which requires doing something
  // error check if timestep was reset in an invalid manner

  bigint ntimestep = update->ntimestep;
  if (ntimestep < nvalid_last || ntimestep > nvalid) 
    error->all(FLERR,"Invalid timestep reset for fix ave/chunk");
  if (ntimestep != nvalid) return;
  nvalid_last = nvalid;

  // first sample within single Nfreq epoch
  // zero out arrays that accumulate over many samples, but not across epochs
  // invoke setup_chunks() to determine current nchunk
  //   re-allocate per-chunk arrays if needed
  // invoke lock() in two cases:
  //   if nrepeat > 1: so nchunk cannot change until Nfreq epoch is over,
  //     will be unlocked on last repeat of this Nfreq
  //   if ave = RUNNING/WINDOW and not yet locked:
  //     set forever, will be unlocked in fix destructor
  // wrap setup_chunks in clearstep/addstep b/c it may invoke computes
  //   both nevery and nfreq are future steps, 
  //   since call below to cchunk->ichunk() 
  //     does not re-invoke internal cchunk compute on this same step

  if (irepeat == 0) {
    if (cchunk->computeflag) modify->clearstep_compute();
    nchunk = cchunk->setup_chunks();
    if (cchunk->computeflag) {
      modify->addstep_compute(ntimestep+nevery);
      modify->addstep_compute(ntimestep+nfreq);
    }
    allocate();
    if (nrepeat > 1 && ave == ONE)
      cchunk->lock(this,ntimestep,ntimestep+(nrepeat-1)*nevery);
    else if ((ave == RUNNING || ave == WINDOW) && !lockforever) {
      cchunk->lock(this,update->ntimestep,-1);
      lockforever = 1;
    }
    for (m = 0; m < nchunk; m++) {
      count_many[m] = count_sum[m] = 0.0;
      for (i = 0; i < nvalues; i++) values_many[m][i] = 0.0;
    }
  }

  // zero out arrays for one sample

  for (m = 0; m < nchunk; m++) {
    count_one[m] = 0.0;
    for (i = 0; i < nvalues; i++) values_one[m][i] = 0.0;
  }

  // compute chunk/atom assigns atoms to chunk IDs
  // extract ichunk index vector from compute
  // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms
  // wrap compute_ichunk in clearstep/addstep b/c it may invoke computes

  if (cchunk->computeflag) modify->clearstep_compute();

  cchunk->compute_ichunk();
  int *ichunk = cchunk->ichunk;

  if (cchunk->computeflag) modify->addstep_compute(ntimestep+nevery);

  // perform the computation for one sample
  // count # of atoms in each bin
  // accumulate results of attributes,computes,fixes,variables to local copy
  // sum within each chunk, only include atoms in fix group
  // compute/fix/variable may invoke computes so wrap with clear/add

  int *mask = atom->mask;
  int nlocal = atom->nlocal;

  for (i = 0; i < nlocal; i++)
    if (mask[i] & groupbit && ichunk[i] > 0)
      count_one[ichunk[i]-1]++;

  modify->clearstep_compute();

  for (m = 0; m < nvalues; m++) {
    n = value2index[m];
    j = argindex[m];

    // V,F adds velocities,forces to values

    if (which[m] == V || which[m] == F) {
      double **attribute;
      if (which[m] == V) attribute = atom->v;
      else attribute = atom->f;

      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && ichunk[i] > 0) {
          index = ichunk[i]-1;
          values_one[index][m] += attribute[i][j];
        }

    // DENSITY_NUMBER adds 1 to values

    } else if (which[m] == DENSITY_NUMBER) {

      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && ichunk[i] > 0) {
          index = ichunk[i]-1;
          values_one[index][m] += 1.0;
        }

    // DENSITY_MASS or MASS adds mass to values

    } else if (which[m] == DENSITY_MASS || which[m] == MASS) {
      int *type = atom->type;
      double *mass = atom->mass;
      double *rmass = atom->rmass;

      if (rmass) {
	for (i = 0; i < nlocal; i++)
	  if (mask[i] & groupbit && ichunk[i] > 0) {
	    index = ichunk[i]-1;
	    values_one[index][m] += rmass[i];
          }
      } else {
        for (i = 0; i < nlocal; i++)
	  if (mask[i] & groupbit && ichunk[i] > 0) {
	    index = ichunk[i]-1;
	    values_one[index][m] += mass[type[i]];
          }
      }

    // TEMPERATURE adds KE to values
    // subtract and restore velocity bias if requested

    } else if (which[m] == TEMPERATURE) {

      if (biasflag) {
        if (tbias->invoked_scalar != ntimestep) tbias->compute_scalar();
        tbias->remove_bias_all();
      }

      double **v = atom->v;
      int *type = atom->type;
      double *mass = atom->mass;
      double *rmass = atom->rmass;

      if (rmass) {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && ichunk[i] > 0) {
            index = ichunk[i]-1;
            values_one[index][m] += 
              (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * rmass[i];
          }
      } else {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && ichunk[i] > 0) {
            index = ichunk[i]-1;
            values_one[index][m] += 
              (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * 
              mass[type[i]];
          }
      }

      if (biasflag) tbias->restore_bias_all();

    // COMPUTE adds its scalar or vector component to values
    // invoke compute if not previously invoked

    } else if (which[m] == COMPUTE) {
      Compute *compute = modify->compute[n];
      if (!(compute->invoked_flag & INVOKED_PERATOM)) {
        compute->compute_peratom();
        compute->invoked_flag |= INVOKED_PERATOM;
      }
      double *vector = compute->vector_atom;
      double **array = compute->array_atom;
      int jm1 = j - 1;

      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && ichunk[i] > 0) {
          index = ichunk[i]-1;
          if (j == 0) values_one[index][m] += vector[i];
          else values_one[index][m] += array[i][jm1];
        }

    // FIX adds its scalar or vector component to values
    // access fix fields, guaranteed to be ready

    } else if (which[m] == FIX) {
      double *vector = modify->fix[n]->vector_atom;
      double **array = modify->fix[n]->array_atom;
      int jm1 = j - 1;

      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && ichunk[i] > 0) {
          index = ichunk[i]-1;
          if (j == 0) values_one[index][m] += vector[i];
          else values_one[index][m] += array[i][jm1];
        }

    // VARIABLE adds its per-atom quantities to values
    // evaluate atom-style variable

    } else if (which[m] == VARIABLE) {
      if (nlocal > maxvar) {
        maxvar = atom->nmax;
        memory->destroy(varatom);
        memory->create(varatom,maxvar,"ave/chunk:varatom");
      }

      input->variable->compute_atom(n,igroup,varatom,1,0);

      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && ichunk[i] > 0) {
          index = ichunk[i]-1;
          values_one[index][m] += varatom[i];
        }
    }
  }

  // process the current sample
  // if normflag = ALL, accumulate values,count separately to many
  // if normflag = SAMPLE, one = value/count, accumulate one to many
  //   count is MPI summed here, value is MPI summed below across samples
  //   exception is TEMPERATURE: normalize by DOF
  //   exception is DENSITYs: no normalize by atom count
  //   exception is scaleflag = NOSCALE : no normalize by atom count
  //     check last so other options can take precedence

  double mvv2e = force->mvv2e;
  double boltz = force->boltz;

  if (normflag == ALL) {
    for (m = 0; m < nchunk; m++) {
      count_many[m] += count_one[m];
      for (j = 0; j < nvalues; j++)
        values_many[m][j] += values_one[m][j];
    }
  } else if (normflag == SAMPLE) {
    MPI_Allreduce(count_one,count_many,nchunk,MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nchunk; m++) {
      if (count_many[m] > 0.0)
        for (j = 0; j < nvalues; j++) {
          if (which[j] == TEMPERATURE)
            values_many[m][j] += mvv2e*values_one[m][j] / 
              ((cdof + adof*count_many[m]) * boltz);
          else if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS ||
                   scaleflag == NOSCALE)
            values_many[m][j] += values_one[m][j];
          else
            values_many[m][j] += values_one[m][j]/count_many[m];
        }
      count_sum[m] += count_many[m];
    }
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // unlock compute chunk/atom at end of Nfreq epoch
  // do not unlock if ave = RUNNING or WINDOW

  if (nrepeat > 1 && ave == ONE) cchunk->unlock(this);

  // time average across samples
  // if normflag = ALL, final is total value / total count
  //   exception is TEMPERATURE: normalize by DOF for total count
  //   exception is DENSITYs: normalize by repeat, not total count
  //   exception is scaleflag == NOSCALE: normalize by repeat, not total count
  //     check last so other options can take precedence
  // if normflag = SAMPLE, final is sum of ave / repeat

  double repeat = nrepeat;
  double mv2d = force->mv2d;

  if (normflag == ALL) {
    MPI_Allreduce(count_many,count_sum,nchunk,MPI_DOUBLE,MPI_SUM,world);
    MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nchunk*nvalues,
                  MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nchunk; m++) {
      if (count_sum[m] > 0.0)
        for (j = 0; j < nvalues; j++) {
          if (which[j] == TEMPERATURE)
            values_sum[m][j] *= mvv2e / ((cdof + adof*count_sum[m]) * boltz);
          else if (which[j] == DENSITY_MASS)
            values_sum[m][j] *= mv2d/repeat;
          else if (which[j] == DENSITY_NUMBER || scaleflag == NOSCALE)
            values_sum[m][j] /= repeat;
          else values_sum[m][j] /= count_sum[m];
        }
      count_sum[m] /= repeat;
    }
  } else if (normflag == SAMPLE) {
    MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nchunk*nvalues,
                  MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nchunk; m++) {
      for (j = 0; j < nvalues; j++) values_sum[m][j] /= repeat;
      count_sum[m] /= repeat;
    }
  }

  // DENSITYs are additionally normalized by chunk volume
  // only relevant if chunks are spatial bins

  for (j = 0; j < nvalues; j++)
    if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS) {
      double chunk_volume = cchunk->chunk_volume_scalar;
      for (m = 0; m < nchunk; m++)
        values_sum[m][j] /= chunk_volume;
    }

  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, comine with nwindow most recent Nfreq timestep values

  if (ave == ONE) {
    for (m = 0; m < nchunk; m++) {
      for (i = 0; i < nvalues; i++)
        values_total[m][i] = values_sum[m][i];
      count_total[m] = count_sum[m];
    }
    normcount = 1;

  } else if (ave == RUNNING) {
    for (m = 0; m < nchunk; m++) {
      for (i = 0; i < nvalues; i++)
        values_total[m][i] += values_sum[m][i];
      count_total[m] += count_sum[m];
    }
    normcount++;

  } else if (ave == WINDOW) {
    for (m = 0; m < nchunk; m++) {
      for (i = 0; i < nvalues; i++) {
        values_total[m][i] += values_sum[m][i];
        if (window_limit) values_total[m][i] -= values_list[iwindow][m][i];
        values_list[iwindow][m][i] = values_sum[m][i];
      }
      count_total[m] += count_sum[m];
      if (window_limit) count_total[m] -= count_list[iwindow][m];
      count_list[iwindow][m] = count_sum[m];
    }

    iwindow++;
    if (iwindow == nwindow) {
      iwindow = 0;
      window_limit = 1;
    }
    if (window_limit) normcount = nwindow;
    else normcount = iwindow;
  }

  // output result to file

  if (fp && me == 0) {
    if (overwrite) fseek(fp,filepos,SEEK_SET);
    double count = 0.0;
    for (m = 0; m < nchunk; m++) count += count_total[m];
    fprintf(fp,BIGINT_FORMAT " %d %g\n",ntimestep,nchunk,count);

    int compress = cchunk->compress;
    int *chunkID = cchunk->chunkID;
    int ncoord = cchunk->ncoord;
    double **coord = cchunk->coord;

    if (!compress) {
      if (ncoord == 0) {
        for (m = 0; m < nchunk; m++) {
          fprintf(fp,"  %d %g",m+1,count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      } else if (ncoord == 1) {
        for (m = 0; m < nchunk; m++) {
          fprintf(fp,"  %d %g %g",m+1,coord[m][0],
                  count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      } else if (ncoord == 2) {
        for (m = 0; m < nchunk; m++) {
          fprintf(fp,"  %d %g %g %g",m+1,coord[m][0],coord[m][1],
                  count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      } else if (ncoord == 3) {
        for (m = 0; m < nchunk; m++) {
          fprintf(fp,"  %d %g %g %g %g",m+1,
                  coord[m][0],coord[m][1],coord[m][2],count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      }
    } else {
      int j;
      if (ncoord == 0) {
        for (m = 0; m < nchunk; m++) {
          fprintf(fp,"  %d %d %g",m+1,chunkID[m],count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      } else if (ncoord == 1) {
        for (m = 0; m < nchunk; m++) {
          j = chunkID[m];
          fprintf(fp,"  %d %d %g %g",m+1,j,coord[j-1][0],
                  count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      } else if (ncoord == 2) {
        for (m = 0; m < nchunk; m++) {
          j = chunkID[m];
          fprintf(fp,"  %d %d %g %g %g",m+1,j,coord[j-1][0],coord[j-1][1],
                  count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      } else if (ncoord == 3) {
        for (m = 0; m < nchunk; m++) {
          j = chunkID[m];
          fprintf(fp,"  %d %d %g %g %g %g",m+1,j,coord[j-1][0],
                  coord[j-1][1],coord[j-1][2],count_total[m]/normcount);
          for (i = 0; i < nvalues; i++)
            fprintf(fp," %g",values_total[m][i]/normcount);
          fprintf(fp,"\n");
        }
      }
    }

    fflush(fp);
    if (overwrite) {
      long fileend = ftell(fp);
      ftruncate(fileno(fp),fileend);
    }
  }
}
Example #27
0
void FixAveSpatial::end_of_step()
{
  int i,j,m,n;

  // skip if not step which requires doing something

  bigint ntimestep = update->ntimestep;
  if (ntimestep != nvalid) return;

  // zero out arrays that accumulate over many samples
  // if box changes, first re-setup bins

  if (irepeat == 0) {
    if (domain->box_change) setup_bins();
    for (m = 0; m < nbins; m++) {
      count_many[m] = count_sum[m] = 0.0;
      for (i = 0; i < nvalues; i++) values_many[m][i] = 0.0;
    }
  }

  // zero out arrays for one sample

  for (m = 0; m < nbins; m++) {
    count_one[m] = 0.0;
    for (i = 0; i < nvalues; i++) values_one[m][i] = 0.0;
  }

  // assign each atom to a bin

  double **x = atom->x;
  int *mask = atom->mask;
  int nlocal = atom->nlocal;

  if (nlocal > maxatom) {
    maxatom = atom->nmax;
    memory->destroy(bin);
    memory->create(bin,maxatom,"ave/spatial:bin");
  }

  if (ndim == 1) atom2bin1d();
  else if (ndim == 2) atom2bin2d();
  else atom2bin3d();

  // perform the computation for one sample
  // accumulate results of attributes,computes,fixes,variables to local copy
  // sum within each bin, only include atoms in fix group
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  for (m = 0; m < nvalues; m++) {
    n = value2index[m];
    j = argindex[m];

    // V,F adds velocities,forces to values

    if (which[m] == V || which[m] == F) {
      double **attribute;
      if (which[m] == V) attribute = atom->v;
      else attribute = atom->f;

      if (regionflag == 0) {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit)
            values_one[bin[i]][m] += attribute[i][j];
      } else {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
            values_one[bin[i]][m] += attribute[i][j];
      }

    // DENSITY_NUMBER adds 1 to values

    } else if (which[m] == DENSITY_NUMBER) {

      if (regionflag == 0) {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit)
            values_one[bin[i]][m] += 1.0;
      } else {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
            values_one[bin[i]][m] += 1.0;
      }

    // DENSITY_MASS adds mass to values

    } else if (which[m] == DENSITY_MASS) {
      int *type = atom->type;
      double *mass = atom->mass;
      double *rmass = atom->rmass;

      if (regionflag == 0) {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit) {
            if (rmass) values_one[bin[i]][m] += rmass[i];
            else values_one[bin[i]][m] += mass[type[i]];
          }
      } else {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
            if (rmass) values_one[bin[i]][m] += rmass[i];
            else values_one[bin[i]][m] += mass[type[i]];
          }
      }

    // COMPUTE adds its scalar or vector component to values
    // invoke compute if not previously invoked

    } else if (which[m] == COMPUTE) {
      Compute *compute = modify->compute[n];
      if (!(compute->invoked_flag & INVOKED_PERATOM)) {
        compute->compute_peratom();
        compute->invoked_flag |= INVOKED_PERATOM;
      }
      double *vector = compute->vector_atom;
      double **array = compute->array_atom;
      int jm1 = j - 1;

      if (regionflag == 0) {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit) {
            if (j == 0) values_one[bin[i]][m] += vector[i];
            else values_one[bin[i]][m] += array[i][jm1];
          }
      } else {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
            if (j == 0) values_one[bin[i]][m] += vector[i];
            else values_one[bin[i]][m] += array[i][jm1];
          }
      }

    // FIX adds its scalar or vector component to values
    // access fix fields, guaranteed to be ready

    } else if (which[m] == FIX) {
      double *vector = modify->fix[n]->vector_atom;
      double **array = modify->fix[n]->array_atom;
      int jm1 = j - 1;

      if (regionflag == 0) {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit) {
            if (j == 0) values_one[bin[i]][m] += vector[i];
            else values_one[bin[i]][m] += array[i][jm1];
          }
      } else {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
            if (j == 0) values_one[bin[i]][m] += vector[i];
            else values_one[bin[i]][m] += array[i][jm1];
          }
      }

    // VARIABLE adds its per-atom quantities to values
    // evaluate atom-style variable

    } else if (which[m] == VARIABLE) {
      if (nlocal > maxvar) {
        maxvar = atom->nmax;
        memory->destroy(varatom);
        memory->create(varatom,maxvar,"ave/spatial:varatom");
      }

      input->variable->compute_atom(n,igroup,varatom,1,0);

      if (regionflag == 0) {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit)
            values_one[bin[i]][m] += varatom[i];
      } else {
        for (i = 0; i < nlocal; i++)
          if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
            values_one[bin[i]][m] += varatom[i];
      }
    }
  }

  // process a single sample
  // if normflag = ALL, accumulate values,count separately to many
  // if normflag = SAMPLE, one = value/count, accumulate one to many
  // exception is SAMPLE density: no normalization by atom count

  if (normflag == ALL) {
    for (m = 0; m < nbins; m++) {
      count_many[m] += count_one[m];
      for (j = 0; j < nvalues; j++)
        values_many[m][j] += values_one[m][j];
    }
  } else {
    MPI_Allreduce(count_one,count_many,nbins,MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nbins; m++) {
      if (count_many[m] > 0.0)
        for (j = 0; j < nvalues; j++) {
          if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
            values_many[m][j] += values_one[m][j];
          else values_many[m][j] += values_one[m][j]/count_many[m];
        }
      count_sum[m] += count_many[m];
    }
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // time average across samples
  // if normflag = ALL, final is total value / total count
  // if normflag = SAMPLE, final is sum of ave / repeat
  // exception is densities: normalized by repeat, not total count

  double repeat = nrepeat;
  double mv2d = force->mv2d;

  if (normflag == ALL) {
    MPI_Allreduce(count_many,count_sum,nbins,MPI_DOUBLE,MPI_SUM,world);
    MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nbins*nvalues,
                  MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nbins; m++) {
      if (count_sum[m] > 0.0)
        for (j = 0; j < nvalues; j++)
          if (which[j] == DENSITY_NUMBER) values_sum[m][j] /= repeat;
          else if (which[j] == DENSITY_MASS) values_sum[m][j] *= mv2d/repeat;
          else values_sum[m][j] /= count_sum[m];
      count_sum[m] /= repeat;
    }
  } else {
    MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nbins*nvalues,
                  MPI_DOUBLE,MPI_SUM,world);
    for (m = 0; m < nbins; m++) {
      for (j = 0; j < nvalues; j++)
        values_sum[m][j] /= repeat;
      count_sum[m] /= repeat;
    }
  }

  // density is additionally normalized by bin volume

  for (j = 0; j < nvalues; j++)
    if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
      for (m = 0; m < nbins; m++)
        values_sum[m][j] /= bin_volume;

  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, comine with nwindow most recent Nfreq timestep values

  if (ave == ONE) {
    for (m = 0; m < nbins; m++) {
      for (i = 0; i < nvalues; i++)
        values_total[m][i] = values_sum[m][i];
      count_total[m] = count_sum[m];
    }
    norm = 1;

  } else if (ave == RUNNING) {
    for (m = 0; m < nbins; m++) {
      for (i = 0; i < nvalues; i++)
        values_total[m][i] += values_sum[m][i];
      count_total[m] += count_sum[m];
    }
    norm++;

  } else if (ave == WINDOW) {
    for (m = 0; m < nbins; m++) {
      for (i = 0; i < nvalues; i++) {
        values_total[m][i] += values_sum[m][i];
        if (window_limit) values_total[m][i] -= values_list[iwindow][m][i];
        values_list[iwindow][m][i] = values_sum[m][i];
      }
      count_total[m] += count_sum[m];
      if (window_limit) count_total[m] -= count_list[iwindow][m];
      count_list[iwindow][m] = count_sum[m];
    }

    iwindow++;
    if (iwindow == nwindow) {
      iwindow = 0;
      window_limit = 1;
    }
    if (window_limit) norm = nwindow;
    else norm = iwindow;
  }

  // output result to file

  if (fp && me == 0) {
    if (overwrite) fseek(fp,filepos,SEEK_SET);
    if(write_ts_) fprintf(fp,BIGINT_FORMAT " %d\n",ntimestep,nbins);
    if (ndim == 1)
      for (m = 0; m < nbins; m++) {
        fprintf(fp,"  %d %g %g",m+1,coord[m][0],
                count_total[m]/norm);
        for (i = 0; i < nvalues; i++)
          fprintf(fp," %g",values_total[m][i]/norm);
        fprintf(fp,"\n");
      }
    else if (ndim == 2)
      for (m = 0; m < nbins; m++) {
        fprintf(fp,"  %d %g %g %g",m+1,coord[m][0],coord[m][1],
                count_total[m]/norm);
        for (i = 0; i < nvalues; i++)
          fprintf(fp," %g",values_total[m][i]/norm);
        fprintf(fp,"\n");
      }
    else
      for (m = 0; m < nbins; m++) {
        fprintf(fp,"  %d %g %g %g %g",m+1,coord[m][0],coord[m][1],coord[m][2],
                count_total[m]/norm);
        for (i = 0; i < nvalues; i++)
          fprintf(fp," %g",values_total[m][i]/norm);
        fprintf(fp,"\n");
      }

    fflush(fp);
    if (overwrite) {
      long fileend = ftell(fp);
      ftruncate(fileno(fp),fileend);
    }
  }

  // calculate mean and standard deviation
  
  if (calcStd != 0) {
    int n_samples = 0;
    int n_empty = 0;
    int n_lower = 0;
    int n_higher = 0;
    double *true_mean, *samples_mean, *std;
    double diff, count_sum, count_samples, samples_average, count_max;

    memory->create(true_mean,nvalues,"ave/spatial:true_mean");
    memory->create(samples_mean,nvalues,"ave/spatial:samples_mean");
    memory->create(std,nvalues,"ave/spatial:std");

    count_sum = 0;
    count_samples = 0;
    samples_average = 0;
    count_max = 0;

    for (i = 0; i < nvalues; i++) {
      true_mean[i] = 0;

      for (m = 0; m < nbins; m++) {
        true_mean[i] += values_total[m][i] * count_total[m];
        if (i == 0) count_sum += count_total[m];
      }

      if (count_sum != 0) true_mean[i] /= count_sum;

      samples_mean[i] = 0;
      std[i] = 0;
    }

    for (m = 0; m < nbins; m++) {
      if (count_total[m] > count_max) count_max = count_total[m];
      if (count_total[m] == 0) n_empty += 1;
      else if (count_total[m] < lowerLimit) n_lower += 1;
      else if (count_total[m] > upperLimit) n_higher += 1;
      else {
        n_samples += 1;
        count_samples += count_total[m];
        for (i = 0; i < nvalues; i++) {
          samples_mean[i] += values_total[m][i];
          diff = values_total[m][i] - true_mean[i];
          std[i] += diff * diff;
        }
      }
    }

    if (n_samples != 0) {
      for (i = 0; i < nvalues; i++) {
        samples_average = count_samples / n_samples; // average # particles per sample
        samples_mean[i] /= n_samples;
        std[i] /= n_samples; // not(n_sample-1) since true_mean is the true Average
        std[i] = sqrt(std[i]);
        samples_mean[i] /= norm;
        std[i] /= norm;
      }
    }

    // output to file
    if (fp2 && me == 0) {
      fprintf(fp2,BIGINT_FORMAT " %g %d %g %d %d %d %d %g",
        ntimestep,count_sum,nbins,count_max,n_empty,n_lower,n_higher,n_samples,samples_average);
      for (i = 0; i < nvalues; i++) {
        fprintf(fp2," %g %g %g",true_mean[i],samples_mean[i],std[i]); //;
      }
      fprintf(fp2,"\n");
      fflush(fp2);
    }

    memory->destroy(true_mean);
    memory->destroy(samples_mean);
    memory->destroy(std);
  }
}
Example #28
0
double ComputeReduce::compute_one(int m, int flag)
{
  int i;

  // invoke the appropriate attribute,compute,fix,variable
  // for flag = -1, compute scalar quantity by scanning over atom properties
  // only include atoms in group for atom properties and per-atom quantities

  index = -1;
  int vidx = value2index[m];
  int aidx = argindex[m];

  int *mask = atom->mask;
  int nlocal = atom->nlocal;

  double one;
  if (mode == SUM) one = 0.0;
  else if (mode == MINN) one = BIG;
  else if (mode == MAXX) one = -BIG;
  else if (mode == AVE) one = 0.0;

  if (which[m] == X) {
    double **x = atom->x;
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit) combine(one,x[i][aidx],i);
    } else one = x[flag][aidx];
  } else if (which[m] == V) {
    double **v = atom->v;
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit) combine(one,v[i][aidx],i);
    } else one = v[flag][aidx];
  } else if (which[m] == F) {
    double **f = atom->f;
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit) combine(one,f[i][aidx],i);
    } else one = f[flag][aidx];
    
  // invoke compute if not previously invoked

  } else if (which[m] == COMPUTE) {
    Compute *compute = modify->compute[vidx];
    
    if (flavor[m] == PERATOM) {
      if (!(compute->invoked_flag & INVOKED_PERATOM)) {
	compute->compute_peratom();
	compute->invoked_flag |= INVOKED_PERATOM;
      }

      if (aidx == 0) {
	double *comp_vec = compute->vector_atom;
	int n = nlocal;
	if (flag < 0) {
	  for (i = 0; i < n; i++)
	    if (mask[i] & groupbit) combine(one,comp_vec[i],i);
	} else one = comp_vec[flag];
      } else {
	double **carray_atom = compute->array_atom;
	int n = nlocal;
	int aidxm1 = aidx - 1;
	if (flag < 0) {
	  for (i = 0; i < n; i++)
	    if (mask[i] & groupbit) combine(one,carray_atom[i][aidxm1],i);
	} else one = carray_atom[flag][aidxm1];
      }

    } else if (flavor[m] == LOCAL) {
      if (!(compute->invoked_flag & INVOKED_LOCAL)) {
	compute->compute_local();
	compute->invoked_flag |= INVOKED_LOCAL;
      }

      if (aidx == 0) {
	double *comp_vec = compute->vector_local;
	int n = compute->size_local_rows;
	if (flag < 0)
	  for (i = 0; i < n; i++)
	    combine(one,comp_vec[i],i);
	else one = comp_vec[flag];
      } else {
	double **carray_local = compute->array_local;
	int n = compute->size_local_rows;
	int aidxm1 = aidx - 1;
	if (flag < 0)
	  for (i = 0; i < n; i++)
	    combine(one,carray_local[i][aidxm1],i);
	else one = carray_local[flag][aidxm1];
      }
    }

  // access fix fields, check if fix frequency is a match

  } else if (which[m] == FIX) {
    if (update->ntimestep % modify->fix[vidx]->peratom_freq)
      error->all("Fix used in compute reduce not computed at compatible time");
    Fix *fix = modify->fix[vidx];

    if (flavor[m] == PERATOM) {
      if (aidx == 0) {
	double *fix_vector = fix->vector_atom;
	int n = nlocal;
	if (flag < 0) {
	  for (i = 0; i < n; i++)
	    if (mask[i] & groupbit) combine(one,fix_vector[i],i);
	} else one = fix_vector[flag];
      } else {
	double **fix_array = fix->array_atom;
	int aidxm1 = aidx - 1;
	if (flag < 0) {
	  for (i = 0; i < nlocal; i++)
	    if (mask[i] & groupbit) combine(one,fix_array[i][aidxm1],i);
	} else one = fix_array[flag][aidxm1];
      }

    } else if (flavor[m] == LOCAL) {
      if (aidx == 0) {
	double *fix_vector = fix->vector_local;
	int n = fix->size_local_rows;
	if (flag < 0)
	  for (i = 0; i < n; i++)
	    combine(one,fix_vector[i],i);
	else one = fix_vector[flag];
      } else {
	double **fix_array = fix->array_local;
	int n = fix->size_local_rows;
	int aidxm1 = aidx - 1;
	if (flag < 0)
	  for (i = 0; i < n; i++)
	    combine(one,fix_array[i][aidxm1],i);
	else one = fix_array[flag][aidxm1];
      }
    }
    
  // evaluate atom-style variable

  } else if (which[m] == VARIABLE) {
    if (nlocal > maxatom) {
      maxatom = atom->nmax;
      memory->destroy(varatom);
      memory->create(varatom,maxatom,"reduce:varatom");
    }

    input->variable->compute_atom(vidx,igroup,varatom,1,0);
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
	if (mask[i] & groupbit) combine(one,varatom[i],i);
    } else one = varatom[flag];
  }

  return one;
}
double ComputeReduceRegion::compute_one(int m, int flag)
{
  int i;

  Region *region = domain->regions[iregion];
  region->prematch();

  // invoke the appropriate attribute,compute,fix,variable
  // compute scalar quantity by summing over atom scalars
  // only include atoms in group

  index = -1;
  double **x = atom->x;
  int *mask = atom->mask;
  int nlocal = atom->nlocal;

  int n = value2index[m];
  int j = argindex[m];

  double one;
  if (mode == SUM) one = 0.0;
  else if (mode == MINN) one = BIG;
  else if (mode == MAXX) one = -BIG;
  else if (mode == AVE) one = 0.0;

  if (which[m] == X) {
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
          combine(one,x[i][j],i);
    } else one = x[flag][j];
  } else if (which[m] == V) {
    double **v = atom->v;
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
          combine(one,v[i][j],i);
    } else one = v[flag][j];
  } else if (which[m] == F) {
    double **f = atom->f;
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
          combine(one,f[i][j],i);
    } else one = f[flag][j];

  // invoke compute if not previously invoked

  } else if (which[m] == COMPUTE) {
    Compute *compute = modify->compute[n];

    if (flavor[m] == PERATOM) {
      if (!(compute->invoked_flag & INVOKED_PERATOM)) {
        compute->compute_peratom();
        compute->invoked_flag |= INVOKED_PERATOM;
      }

      if (j == 0) {
        double *compute_vector = compute->vector_atom;
        int n = nlocal;
        if (flag < 0) {
          for (i = 0; i < n; i++)
            if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
              combine(one,compute_vector[i],i);
        } else one = compute_vector[flag];
      } else {
        double **compute_array = compute->array_atom;
        int n = nlocal;
        int jm1 = j - 1;
        if (flag < 0) {
          for (i = 0; i < n; i++)
            if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
              combine(one,compute_array[i][jm1],i);
        } else one = compute_array[flag][jm1];
      }

    } else if (flavor[m] == LOCAL) {
      if (!(compute->invoked_flag & INVOKED_LOCAL)) {
        compute->compute_local();
        compute->invoked_flag |= INVOKED_LOCAL;
      }

      if (j == 0) {
        double *compute_vector = compute->vector_local;
        int n = compute->size_local_rows;
        if (flag < 0)
          for (i = 0; i < n; i++)
            combine(one,compute_vector[i],i);
        else one = compute_vector[flag];
      } else {
        double **compute_array = compute->array_local;
        int n = compute->size_local_rows;
        int jm1 = j - 1;
        if (flag < 0)
          for (i = 0; i < n; i++)
            combine(one,compute_array[i][jm1],i);
        else one = compute_array[flag][jm1];
      }
    }

  // check if fix frequency is a match

  } else if (which[m] == FIX) {
    if (update->ntimestep % modify->fix[n]->peratom_freq)
      error->all(FLERR,"Fix used in compute reduce not computed at "
                 "compatible time");
    Fix *fix = modify->fix[n];

    if (flavor[m] == PERATOM) {
      if (j == 0) {
        double *fix_vector = fix->vector_atom;
        int n = nlocal;
        if (flag < 0) {
          for (i = 0; i < n; i++)
            if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
              combine(one,fix_vector[i],i);
        } else one = fix_vector[flag];
      } else {
        double **fix_array = fix->array_atom;
        int jm1 = j - 1;
        if (flag < 0) {
          for (i = 0; i < nlocal; i++)
            if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
              combine(one,fix_array[i][jm1],i);
        } else one = fix_array[flag][jm1];
      }

    } else if (flavor[m] == LOCAL) {
      if (j == 0) {
        double *fix_vector = fix->vector_local;
        int n = fix->size_local_rows;
        if (flag < 0)
          for (i = 0; i < n; i++)
            combine(one,fix_vector[i],i);
        else one = fix_vector[flag];
      } else {
        double **fix_array = fix->array_local;
        int n = fix->size_local_rows;
        int jm1 = j - 1;
        if (flag < 0)
          for (i = 0; i < n; i++)
            combine(one,fix_array[i][jm1],i);
        else one = fix_array[flag][jm1];
      }
    }

  // evaluate atom-style variable

  } else if (which[m] == VARIABLE) {
    if (nlocal > maxatom) {
      maxatom = atom->nmax;
      memory->destroy(varatom);
      memory->create(varatom,maxatom,"reduce/region:varatom");
    }

    input->variable->compute_atom(n,igroup,varatom,1,0);
    if (flag < 0) {
      for (i = 0; i < nlocal; i++)
        if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
          combine(one,varatom[i],i);
    } else one = varatom[flag];
  }

  return one;
}
Example #30
0
void FixAveTime::invoke_vector(bigint ntimestep)
{
  int i,j,m;

  // first sample within single Nfreq epoch
  // zero out arrays that accumulate over many samples, but not across epochs
  // invoke setup_chunks() to determine current nchunk
  //   re-allocate per-chunk arrays if needed
  // invoke lock() in two cases:
  //   if nrepeat > 1: so nchunk cannot change until Nfreq epoch is over,
  //     will be unlocked on last repeat of this Nfreq
  //   if ave = RUNNING/WINDOW and not yet locked:
  //     set forever, will be unlocked in fix destructor
  // wrap setup_chunks in clearstep/addstep b/c it may invoke computes
  //   both nevery and nfreq are future steps,
  //   since call below to cchunk->ichunk()
  //     does not re-invoke internal cchunk compute on this same step

  if (irepeat == 0) {
    if (any_variable_length) {
      modify->clearstep_compute();
      int nrows_new = column_length(1);
      modify->addstep_compute(ntimestep+nevery);
      modify->addstep_compute(ntimestep+nfreq);

      if (all_variable_length && nrows_new != nrows) {
        nrows = nrows_new;
        memory->destroy(column);
        memory->create(column,nrows,"ave/time:column");
        allocate_arrays();
      }

      bigint ntimestep = update->ntimestep;
      int lockforever_flag = 0;
      for (i = 0; i < nvalues; i++) {
        if (!varlen[i]) continue;
        if (nrepeat > 1 && ave == ONE) {
          Compute *compute = modify->compute[value2index[i]];
          compute->lock(this,ntimestep,ntimestep+(nrepeat-1)*nevery);
        } else if ((ave == RUNNING || ave == WINDOW) && !lockforever) {
          Compute *compute = modify->compute[value2index[i]];
          compute->lock(this,update->ntimestep,-1);
          lockforever_flag = 1;
        }
      }
      if (lockforever_flag) lockforever = 1;
    }

    for (i = 0; i < nrows; i++)
      for (j = 0; j < nvalues; j++) array[i][j] = 0.0;
  }

  // accumulate results of computes,fixes,variables to local copy
  // compute/fix/variable may invoke computes so wrap with clear/add

  modify->clearstep_compute();

  for (j = 0; j < nvalues; j++) {
    m = value2index[j];

    // invoke compute if not previously invoked

    if (which[j] == COMPUTE) {
      Compute *compute = modify->compute[m];

      if (argindex[j] == 0) {
        if (!(compute->invoked_flag & INVOKED_VECTOR)) {
          compute->compute_vector();
          compute->invoked_flag |= INVOKED_VECTOR;
        }
        double *cvector = compute->vector;
        for (i = 0; i < nrows; i++)
          column[i] = cvector[i];

      } else {
        if (!(compute->invoked_flag & INVOKED_ARRAY)) {
          compute->compute_array();
          compute->invoked_flag |= INVOKED_ARRAY;
        }
        double **carray = compute->array;
        int icol = argindex[j]-1;
        for (i = 0; i < nrows; i++)
          column[i] = carray[i][icol];
      }

    // access fix fields, guaranteed to be ready

    } else if (which[j] == FIX) {
      Fix *fix = modify->fix[m];
      if (argindex[j] == 0)
        for (i = 0; i < nrows; i++)
          column[i] = fix->compute_vector(i);
      else {
        int icol = argindex[j]-1;
        for (i = 0; i < nrows; i++)
          column[i] = fix->compute_array(i,icol);
      }
    }

    // add columns of values to array or just set directly if offcol is set

    if (offcol[j]) {
      for (i = 0; i < nrows; i++)
        array[i][j] = column[i];
    } else {
      for (i = 0; i < nrows; i++)
        array[i][j] += column[i];
    }
  }

  // done if irepeat < nrepeat
  // else reset irepeat and nvalid

  irepeat++;
  if (irepeat < nrepeat) {
    nvalid += nevery;
    modify->addstep_compute(nvalid);
    return;
  }

  irepeat = 0;
  nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
  modify->addstep_compute(nvalid);

  // unlock any variable length computes at end of Nfreq epoch
  // do not unlock if ave = RUNNING or WINDOW

  if (any_variable_length && nrepeat > 1 && ave == ONE) {
    for (i = 0; i < nvalues; i++) {
      if (!varlen[i]) continue;
      Compute *compute = modify->compute[value2index[i]];
      compute->unlock(this);
    }
  }

  // average the final result for the Nfreq timestep

  double repeat = nrepeat;
  for (i = 0; i < nrows; i++)
    for (j = 0; j < nvalues; j++)
      if (offcol[j] == 0) array[i][j] /= repeat;

  // if ave = ONE, only single Nfreq timestep value is needed
  // if ave = RUNNING, combine with all previous Nfreq timestep values
  // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values

  if (ave == ONE) {
    for (i = 0; i < nrows; i++)
      for (j = 0; j < nvalues; j++) array_total[i][j] = array[i][j];
    norm = 1;

  } else if (ave == RUNNING) {
    for (i = 0; i < nrows; i++)
      for (j = 0; j < nvalues; j++) array_total[i][j] += array[i][j];
    norm++;

  } else if (ave == WINDOW) {
    for (i = 0; i < nrows; i++)
      for (j = 0; j < nvalues; j++) {
        array_total[i][j] += array[i][j];
        if (window_limit) array_total[i][j] -= array_list[iwindow][i][j];
        array_list[iwindow][i][j] = array[i][j];
      }

    iwindow++;
    if (iwindow == nwindow) {
      iwindow = 0;
      window_limit = 1;
    }
    if (window_limit) norm = nwindow;
    else norm = iwindow;
  }

  // insure any columns with offcol set are effectively set to last value

  for (i = 0; i < nrows; i++)
    for (j = 0; j < nvalues; j++)
      if (offcol[j]) array_total[i][j] = norm*array[i][j];

  // output result to file

  if (fp && me == 0) {
    if (overwrite) fseek(fp,filepos,SEEK_SET);
    fprintf(fp,BIGINT_FORMAT " %d\n",ntimestep,nrows);
    for (i = 0; i < nrows; i++) {
      fprintf(fp,"%d",i+1);
      for (j = 0; j < nvalues; j++) fprintf(fp,format,array_total[i][j]/norm);
      fprintf(fp,"\n");
    }
    fflush(fp);
    if (overwrite) {
      long fileend = ftell(fp);
      if (fileend > 0) ftruncate(fileno(fp),fileend);
    }
  }
}