Ejemplo n.º 1
0
double power_1(int x, int n)
{
	if (n == 0) {
		return 1;
	} else if (n % 2 == 0) {
		return power_1(x * x, n / 2);
	} else {
		return x * power_1(x * x, n / 2);
	}
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
	printf("%f\n", power_0(4, 10));
	printf("%f\n", power_0(4, 11));

	printf("%f\n", power_1(4, 10));
	printf("%f\n", power_1(4, 11));

	printf("%f\n", power_2(4, 10, 1));
	printf("%f\n", power_2(4, 11, 1));

	printf("%f\n", power_3(4, 10);
	printf("%f\n", power_3(4, 11));

	return 0;
}
Ejemplo n.º 3
0
void csw2_value(double r, double *p, double *f)
{
  static double power;

  power_1(&power, &r, &p[3]);

  *f = (1. + p[0] * cos(p[1] * r + p[2])) / power;

  return;
}
Ejemplo n.º 4
0
void eopp_exp_value(double r, double *p, double *f)
{
  static double power;

  power_1(&power, &r, &p[3]);

  *f = p[0] * exp(-p[1] * r) + (p[2] / power) * cos(p[4] * r + p[5]);

  return;
}
Ejemplo n.º 5
0
void softshell_value(double r, double *p, double *f)
{
  static double x, y;

  x = p[0] / r;
  y = p[1];

  power_1(f, &x, &y);

  return;
}
Ejemplo n.º 6
0
void sheng_F_value(double r, double *p, double *f)
{
  static double x, y, power;

  x = r;
  y = p[1];
  power_1(&power, &x, &y);

  *f = p[0] * power + p[2] * r + p[3];

  return;
}
Ejemplo n.º 7
0
void bjs_value(double r, double *p, double *f)
{
  static double power;

  if (r == 0)
    *f = 0;
  else {
    power_1(&power, &r, &p[1]);
    *f = p[0] * (1. - p[1] * log(r)) * power + p[2] * r;
  }

  return;
}
Ejemplo n.º 8
0
void power_decay_value(double r, double *p, double *f)
{
  static double x, y, power;

  x = 1. / r;
  y = p[1];

  power_1(&power, &x, &y);

  *f = p[0] * power;

  return;
}
Ejemplo n.º 9
0
void mishin_value(double r, double *p, double *f)
{
  static double z;
  static double temp;
  static double power;

  z = r - p[3];
  temp = exp(-p[5] * r);

  power_1(&power, &z, &p[4]);

  *f = p[0] * power * temp * (1. + p[1] * temp) + p[2];

  return;
}
Ejemplo n.º 10
0
void vpair_value(double r, double *p, double *f)
{
  static double x[7], y, z;

  y = r;
  z = p[1];

  power_1(&x[0], &y, &z);
  x[1] = r * r;
  x[2] = x[1] * x[1];
  x[3] = p[2] * p[2];
  x[4] = p[3] * p[3];
  x[5] = p[4] * x[4] + p[5] * x[3];
  x[6] = exp(-r / p[6]);

  *f = 14.4 * (p[0] / x[0] - 0.5 * (x[5] / x[2]) * x[6]);

  return;
}
Ejemplo n.º 11
0
void RateMatrix::SetMatrix(
						   vector<double>& matrix, 
						   double len
						  )
{
	int i,j,k;
	double expt[numStates];
	vector<double>::iterator P;
	
	// P(t)ij = SUM Cijk * exp{Root*t}

	P=matrix.begin();

	if (len<1e-6) { 
		for (i=0; i<numStates; i++) {
			for (j=0; j<numStates; j++) {
				if (i==j) 
					(*P)=1.0;
				else 
					(*P)=0.0;
				P++;
			}
		}
		return; 
	}
	
	for (k=1; k<numStates; k++) {
		expt[k]=exp(len*Root[k]);
	}

	vector<unsigned int> squared (numStates, 0), power_1 (numStates, 0);
	for (i=0; i<numStates; i++) { squared[i]=i*numStates_squared; power_1[i]=i*numStates; }
	for (i=0; i<numStates; i++) {
		for (j=0; j<numStates; j++) {
			(*P)=Cijk.at(squared[i]+power_1[j]+0);
			for (k=1; k<numStates; k++) {
				(*P)+=Cijk.at(squared[i]+power_1[j]+k)*expt[k];
			}
			P++;
		}
	}
}
Ejemplo n.º 12
0
void sheng_rho_value(double r, double *p, double *f)
{
  static double sig_d_rad6, sig_d_rad12, x, y, power;
  static int h, k;

  h = (r > 1.45) ? 1 : 0;
  k = (r <= 1.45) ? 1 : 0;

  x = r;
  y = p[1];
  power_1(&power, &x, &y);

  sig_d_rad6 = (p[4] * p[4]) / (r * r);
  sig_d_rad6 = sig_d_rad6 * sig_d_rad6 * sig_d_rad6;
  sig_d_rad12 = dsquare(sig_d_rad6);

  *f = (p[0] * power + p[2]) * k + (4. * p[3] * (sig_d_rad12 - sig_d_rad6)) * h;

  return;
}
Ejemplo n.º 13
0
void RateMatrix::SetupMatrix(bool transition_probability_independent_sites_setup)
{
	unsigned int i,j,k;
	double mr;
	double sum;
	double U[numStates_squared+1], V[numStates_squared+1], T1[numStates_squared+1], T2[numStates_squared+1];
	double Qij2pass[numStates_squared+1];

	//////////
	/// transition_probability_independent_sites_setup:
	/// If we are calculating the transition probabilities as independent sites models, then we need
	/// to run the code in the if statements. However, if we are doing the pseudo-dependent sites
	/// calculations, we want to skip those code segments. 
	/// Segment #1: 
	///   * Sets the Qij entries to be the input substitution model. 
	///     -> For pseudo-dependent sites, we excise the Q matrix from the 4^N X 4^N sequence model.
	/// Segment #2:
	///	  * Sets Qij so that branch length corresponds to expected number of changes.
	///     -> pseudo-dependent sites branch lengths correspond not to 1 change per site, but whatever
	///        the dependent sites model constrains it to.
	//////////
	CheckFrequencies();
	k=0;
	if (transition_probability_independent_sites_setup) {
		for (i=0; i<numStates-1; i++) {
			for (j=i+1; j<numStates; j++) {
				Qij.at(i*numStates+j) = Qij.at(j*numStates+i) = Sij.at(k++);
			}
		}

		for (i=0; i<numStates; i++) {
			for (j=0; j<numStates; j++) { 
				Qij.at(i*numStates+j) *= pi.at(j);
			}
		}

		mr=0;		
		for (i=0; i<numStates; i++) {
			sum = 0;
			Qij.at(i*numStates+i)=0; 
			for (j=0; j<numStates; j++) { 
				sum += Qij.at(i*numStates+j);
			}
			Qij.at(i*numStates+i) = -sum; 
			mr += pi.at(i) * sum;
		}

		//////////
		/// Multiplies every element of Qij by 1.0/mr. This is abyx.
		//////////
		for (i=0; i<numStates_squared; Qij.at(i)*=1.0/mr,i++) ; 
	}

	// Testcode: Print Qij.
	//if (!transition_probability_independent_sites_setup) printQij();
	
	//Testcode: does sum = 1?
	sum = 0;
	double partial = 0;
	for (i = 0; i < numStates; i++) {
		partial = 0;
		for (j = 0; j < numStates; j++) {
			if (i != j)
				partial += Qij.at(i*numStates+j);
		}
		sum += pi.at(i) * partial;
	}
	//if (!transition_probability_independent_sites_setup) cerr << "Sum: " << sum << endl;

	for (i = 0; i < numStates_squared; i++) Qij2pass[i]=Qij.at(i);
	if ((k=eigen(1, Qij2pass, numStates, Root, T1, U, V, T2))!=0) {
		fprintf(stderr, "\ncomplex roots in SetupMatrix");
		exit(EXIT_FAILURE);
	}
	xtoy (U, V, numStates_squared);
	matinv (V, numStates, numStates, T1);
	vector<unsigned int> squared (numStates, 0), power_1 (numStates, 0);
	for (i=0; i<numStates; i++) { squared[i]=i*numStates_squared; power_1[i]=i*numStates; }
	for (i=0; i<numStates; i++) {
   		for (j=0; j<numStates; j++) {
   			for (k=0; k<numStates; k++) {
				Cijk.at(squared[i]+power_1[j]+k) = U[power_1[i]+k]*V[power_1[k]+j];
  			}
  		}
   	}
}
Ejemplo n.º 14
0
double calc_forces(double* xi_opt, double* forces, int flag)
{
  tersoff_t const* ters = &g_pot.apot_table.tersoff;

#if !defined(MPI)
  g_mpi.myconf = g_config.nconf;
#endif  // !MPI

  // This is the start of an infinite loop
  while (1) {
    // sum of squares of local process
    double error_sum = 0.0;

#if defined(MPI)
    MPI_Bcast(&flag, 1, MPI_INT, 0, MPI_COMM_WORLD);

    if (flag == 1)
      break; // Exception: flag 1 means clean up

    if (g_mpi.myid == 0)
      apot_check_params(xi_opt);
    MPI_Bcast(xi_opt, g_calc.ndimtot, MPI_DOUBLE, 0, MPI_COMM_WORLD);
#else
    apot_check_params(xi_opt);
#endif  // MPI

    update_tersoff_pointers(xi_opt);

    // loop over configurations
    for (int config_idx = g_mpi.firstconf; config_idx < g_mpi.firstconf + g_mpi.myconf; config_idx++) {
      int uf = g_config.conf_uf[config_idx - g_mpi.firstconf];

      // reset energies and stresses
      forces[g_calc.energy_p + config_idx] = 0.0;

#if defined(STRESS)
      int us = g_config.conf_us[config_idx - g_mpi.firstconf];
      int stress_idx = g_calc.stress_p + 6 * config_idx;
      memset(forces + stress_idx, 0, 6 * sizeof(double));
#endif  // STRESS

      // first loop over all atoms: reset forces
      for (int atom_idx = 0; atom_idx < g_config.inconf[config_idx]; atom_idx++) {
        int n_i = 3 * (g_config.cnfstart[config_idx] + atom_idx);
        if (uf) {
          forces[n_i + 0] = -g_config.force_0[n_i + 0];
          forces[n_i + 1] = -g_config.force_0[n_i + 1];
          forces[n_i + 2] = -g_config.force_0[n_i + 2];
        } else {
          memset(forces + n_i, 0, 3 * sizeof(double));
        }
      }

      // second loop: calculate cutoff function f_c for all neighbor
      for (int atom_idx = 0; atom_idx < g_config.inconf[config_idx]; atom_idx++) {
        atom_t* atom = g_config.conf_atoms + atom_idx + g_config.cnfstart[config_idx] - g_mpi.firstatom;
        int n_i = 3 * (g_config.cnfstart[config_idx] + atom_idx);

        // loop over neighbors
        for (int neigh_idx = 0; neigh_idx < atom->num_neigh; neigh_idx++) {
          neigh_t* neigh_j = atom->neigh + neigh_idx;
          int col_j = neigh_j->col[0];
          // check if we are within the cutoff range
          if (neigh_j->r < ters->S[col_j][0]) {
            int self = (neigh_j->nr == atom_idx + g_config.cnfstart[config_idx]) ? 1 : 0;

            // calculate cutoff function f_c and store it for every neighbor
            double cut_tmp = M_PI / (ters->S[col_j][0] - ters->R[col_j][0]);
            double cut_tmp_j = cut_tmp * (neigh_j->r - ters->R[col_j][0]);
            if (neigh_j->r < ters->R[col_j][0]) {
              neigh_j->f = 1.0;
              neigh_j->df = 0.0;
            } else {
              neigh_j->f = 0.5 * (1.0 + cos(cut_tmp_j));
              neigh_j->df = -0.5 * cut_tmp * sin(cut_tmp_j);
            }

            // calculate pair part f_c*A*exp(-lambda*r) and the derivative
            double tmp = exp(-ters->lambda[col_j][0] * neigh_j->r);
            double phi_val = neigh_j->f * ters->A[col_j][0] * tmp;
            double phi_grad = neigh_j->df - ters->lambda[col_j][0] * neigh_j->f;
            phi_grad *= ters->A[col_j][0] * tmp;

            // avoid double counting if atom is interacting with itself
            if (self) {
              phi_val *= 0.5;
              phi_grad *= 0.5;
            }

            // only half cohesive energy because we have a full neighbor list
            forces[g_calc.energy_p + config_idx] += 0.5 * phi_val;

            if (uf) {
              // calculate pair forces
              vector tmp_force;
              tmp_force.x = neigh_j->dist_r.x * phi_grad;
              tmp_force.y = neigh_j->dist_r.y * phi_grad;
              tmp_force.z = neigh_j->dist_r.z * phi_grad;
              forces[n_i + 0] += tmp_force.x;
              forces[n_i + 1] += tmp_force.y;
              forces[n_i + 2] += tmp_force.z;
#if defined(STRESS)
              // also calculate pair stresses
              if (us) {
                forces[stress_idx + 0] -= 0.5 * neigh_j->dist.x * tmp_force.x;
                forces[stress_idx + 1] -= 0.5 * neigh_j->dist.y * tmp_force.y;
                forces[stress_idx + 2] -= 0.5 * neigh_j->dist.z * tmp_force.z;
                forces[stress_idx + 3] -= 0.5 * neigh_j->dist.x * tmp_force.y;
                forces[stress_idx + 4] -= 0.5 * neigh_j->dist.y * tmp_force.z;
                forces[stress_idx + 5] -= 0.5 * neigh_j->dist.z * tmp_force.x;
              }
#endif  // STRESS
            }
          } else {
            neigh_j->f = 0.0;
            neigh_j->df = 0.0;
          }
        } // loop over neighbors

        // calculate threebody part
        for (int neigh_j_idx = 0; neigh_j_idx < atom->num_neigh; neigh_j_idx++) {
          neigh_t* neigh_j = atom->neigh + neigh_j_idx;
          int col_j = neigh_j->col[0];
          // check if we are within the cutoff range
          if (neigh_j->r < ters->S[col_j][0]) {
            int ijk = neigh_j->ijk_start;
            int n_j = 3 * neigh_j->nr;

            // skip neighbor if coefficient is zero
            if (ters->B[col_j][0] == 0.0)
              continue;

            // reset variables for each neighbor
            double zeta = 0.0;
            vector dzeta_i = {0.0, 0.0, 0.0};
            vector dzeta_j = {0.0, 0.0, 0.0};

            // inner loop over neighbors
            for (int neigh_k_idx = 0; neigh_k_idx < atom->num_neigh; neigh_k_idx++) {
              if (neigh_k_idx == neigh_j_idx)
                continue;
              neigh_t* neigh_k = atom->neigh + neigh_k_idx;
              int col_k = neigh_k->col[0];
              angle_t* angle = atom->angle_part + ijk++;
              if (neigh_k->r < ters->S[col_k][0]) {
                double tmp_jk = 1.0 / (neigh_j->r * neigh_k->r);

                double tmp_1 = ters->h[col_j][0] - angle->cos;
                double tmp_2 = 1.0 / (ters->d2[col_j] + tmp_1 * tmp_1);
                double g_theta = 1.0 + ters->c2[col_j] / ters->d2[col_j] -
                          ters->c2[col_j] * tmp_2;

                // zeta
                zeta += neigh_k->f * ters->omega[col_k][0] * g_theta;

                double tmp_j2 = angle->cos / (neigh_j->r * neigh_j->r);
                double tmp_k2 = angle->cos / (neigh_k->r * neigh_k->r);

                vector dcos_j;
                dcos_j.x = tmp_jk * neigh_k->dist.x - tmp_j2 * neigh_j->dist.x;
                dcos_j.y = tmp_jk * neigh_k->dist.y - tmp_j2 * neigh_j->dist.y;
                dcos_j.z = tmp_jk * neigh_k->dist.z - tmp_j2 * neigh_j->dist.z;

                vector dcos_k;
                dcos_k.x = tmp_jk * neigh_j->dist.x - tmp_k2 * neigh_k->dist.x;
                dcos_k.y = tmp_jk * neigh_j->dist.y - tmp_k2 * neigh_k->dist.y;
                dcos_k.z = tmp_jk * neigh_j->dist.z - tmp_k2 * neigh_k->dist.z;

                double tmp_3 = 2.0 * ters->c2[col_j] * tmp_1 * tmp_2 * tmp_2 * neigh_k->f * ters->omega[col_k][0];

                double tmp_grad = neigh_k->df / neigh_k->r * g_theta * ters->omega[col_k][0];

                neigh_k->dzeta.x = tmp_grad * neigh_k->dist.x - tmp_3 * dcos_k.x;
                neigh_k->dzeta.y = tmp_grad * neigh_k->dist.y - tmp_3 * dcos_k.y;
                neigh_k->dzeta.z = tmp_grad * neigh_k->dist.z - tmp_3 * dcos_k.z;

                dzeta_i.x -= neigh_k->dzeta.x;
                dzeta_i.y -= neigh_k->dzeta.y;
                dzeta_i.z -= neigh_k->dzeta.z;

                dzeta_j.x -= tmp_3 * dcos_j.x;
                dzeta_j.y -= tmp_3 * dcos_j.y;
                dzeta_j.z -= tmp_3 * dcos_j.z;
              }
            } // neigh_k_idx

            double phi_a = 0.5 * ters->B[col_j][0] * exp(-ters->mu[col_j][0] * neigh_j->r);

            double tmp_pow_1 = ters->gamma[col_j][0] * zeta;
            double tmp_4 = 0.0;
            power_1(&tmp_4, &tmp_pow_1, ters->n[col_j]);

            tmp_pow_1 = 1.0 + tmp_4;
            double tmp_pow_2 = -1.0 / (2.0 * ters->n[col_j][0]);
            double b_ij = 0.0;
            power_1(&b_ij, &tmp_pow_1, &tmp_pow_2);

            double phi_val = -b_ij * phi_a;

            forces[g_calc.energy_p + config_idx] += neigh_j->f * phi_val;

            double tmp_5 = 0.0;
            if (zeta != 0.0)
              tmp_5 = -b_ij * neigh_j->f * phi_a * tmp_4 / (2.0 * zeta * (1.0 + tmp_4));
            double tmp_6 = (neigh_j->f * phi_a * ters->mu[col_j][0] * b_ij + neigh_j->df * phi_val) / neigh_j->r;

            vector force_j;
            force_j.x = -tmp_6 * neigh_j->dist.x + tmp_5 * dzeta_j.x;
            force_j.y = -tmp_6 * neigh_j->dist.y + tmp_5 * dzeta_j.y;
            force_j.z = -tmp_6 * neigh_j->dist.z + tmp_5 * dzeta_j.z;

            for (int neigh_k_idx = 0; neigh_k_idx < atom->num_neigh; neigh_k_idx++) {
              if (neigh_k_idx != neigh_j_idx) {
                neigh_t* neigh_k = atom->neigh + neigh_k_idx;
                int col_k = neigh_k->col[0];
                if (neigh_k->r < ters->S[col_k][0]) {
                  int n_k = 3 * neigh_k->nr;
                  // update force on particle k
                  forces[n_k + 0] += tmp_5 * neigh_k->dzeta.x;
                  forces[n_k + 1] += tmp_5 * neigh_k->dzeta.y;
                  forces[n_k + 2] += tmp_5 * neigh_k->dzeta.z;

#if defined(STRESS)
                  if (us) {
                    // Distribute stress among atoms
                    forces[stress_idx + 0] += neigh_k->dist.x * tmp_5 * neigh_k->dzeta.x;
                    forces[stress_idx + 1] += neigh_k->dist.y * tmp_5 * neigh_k->dzeta.y;
                    forces[stress_idx + 2] += neigh_k->dist.z * tmp_5 * neigh_k->dzeta.z;
                    forces[stress_idx + 3] += 0.5 * tmp_5 * (neigh_k->dist.x * neigh_k->dzeta.y + neigh_k->dist.y * neigh_k->dzeta.x);
                    forces[stress_idx + 4] += 0.5 * tmp_5 * (neigh_k->dist.y * neigh_k->dzeta.z + neigh_k->dist.z * neigh_k->dzeta.y);
                    forces[stress_idx + 5] += 0.5 * tmp_5 * (neigh_k->dist.z * neigh_k->dzeta.x + neigh_k->dist.x * neigh_k->dzeta.z);
                  }
#endif  // STRESS
                }
              } // neigh_k_idx != neigh_j_idx
            }   // neigh_k_idx loop

            // update force on particle j
            forces[n_j + 0] += force_j.x;
            forces[n_j + 1] += force_j.y;
            forces[n_j + 2] += force_j.z;

            // update force on particle i
            forces[n_i + 0] += tmp_5 * dzeta_i.x - force_j.x;
            forces[n_i + 1] += tmp_5 * dzeta_i.y - force_j.y;
            forces[n_i + 2] += tmp_5 * dzeta_i.z - force_j.z;

#if defined(STRESS)
            if (us) {
              // Distribute stress among atoms
              forces[stress_idx + 0] += neigh_j->dist.x * force_j.x;
              forces[stress_idx + 1] += neigh_j->dist.y * force_j.y;
              forces[stress_idx + 2] += neigh_j->dist.z * force_j.z;
              forces[stress_idx + 3] += 0.5 * (neigh_j->dist.x * force_j.y + neigh_j->dist.y * force_j.x);
              forces[stress_idx + 4] += 0.5 * (neigh_j->dist.y * force_j.z + neigh_j->dist.z * force_j.y);
              forces[stress_idx + 5] += 0.5 * (neigh_j->dist.z * force_j.x + neigh_j->dist.x * force_j.z);
            }
#endif  // STRESS
          } // neigh_j_idx
        }
      } // end second loop over all atoms

      // third loop over all atoms, sum up forces
      if (uf) {
        for (int atom_idx = 0; atom_idx < g_config.inconf[config_idx]; atom_idx++) {
          atom_t* atom = g_config.conf_atoms + atom_idx + g_config.cnfstart[config_idx] - g_mpi.firstatom;
          int n_i = 3 * (g_config.cnfstart[config_idx] + atom_idx);
#if defined(FWEIGHT)
          // Weigh by absolute value of force
          forces[n_i + 0] /= FORCE_EPS + atom->absforce;
          forces[n_i + 1] /= FORCE_EPS + atom->absforce;
          forces[n_i + 2] /= FORCE_EPS + atom->absforce;
#endif  // FWEIGHT

// sum up forces
#if defined(CONTRIB)
          if (atom->contrib)
#endif  // CONTRIB
            error_sum += g_config.conf_weight[config_idx] * (dsquare(forces[n_i + 0]) + dsquare(forces[n_i + 1]) + dsquare(forces[n_i + 2]));
        }
      } // end third loop over all atoms

      // energy contributions
      forces[g_calc.energy_p + config_idx] /= (double)g_config.inconf[config_idx];
      forces[g_calc.energy_p + config_idx] -= g_config.force_0[g_calc.energy_p + config_idx];
      error_sum += g_config.conf_weight[config_idx] * g_param.eweight * dsquare(forces[g_calc.energy_p + config_idx]);

#if defined(STRESS)
      // stress contributions
      if (uf && us) {
        for (int i = 0; i < 6; i++) {
          forces[stress_idx + i] /= g_config.conf_vol[config_idx - g_mpi.firstconf];
          forces[stress_idx + i] -= g_config.force_0[stress_idx + i];
          error_sum += g_config.conf_weight[config_idx] * g_param.sweight * dsquare(forces[stress_idx + i]);
        }
      }
#endif  // STRESS
    } // loop over configurations

    // add punishment for out of bounds (mostly for powell_lsq)
    if (g_mpi.myid == 0)
      error_sum += apot_punish(xi_opt, forces);

    gather_forces(&error_sum, forces);

    // root process exits this function now
    if (g_mpi.myid == 0) {
      // Increase function call counter
      g_calc.fcalls++;
      if (isnan(error_sum)) {
#if defined(DEBUG)
        printf("\n--> Force is nan! <--\n\n");
#endif  // DEBUG
        return 10e10;
      } else
        return error_sum;
    }

  } // end of infinite loop

  // once a non-root process arrives here, all is done
  return -1.0;
}