Ejemplo n.º 1
0
//------------------------------------------------------------------------------
double PD_OSP::calculateDilationTerm(const std::pair<int, int> &idCol)
{
    const int pId = idCol.first;
    const int col_i = idCol.second;
    const double d_i = m_data(col_i, m_indexD);

    vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

    double r_i[3];
    double r0_i[3];
    for(int d=0; d<m_dim; d++)
    {
        r_i[d] = m_r(d, col_i);
        r0_i[d] = m_r0(d, col_i);
    }

    const int nConnections = PDconnections.size();
    double dr_ij[3];

    double theta_i = 0;
    for(int l_j=0; l_j<nConnections; l_j++)
    {
        auto &con = PDconnections[l_j];
        if(con.second[m_indexConnected] <= 0.5)
            continue;

        const int id_j = con.first;
        const int j = m_pIds[id_j];

        const double d_j = m_data(j, m_indexD);
        const double vol_j = m_data(j, m_indexVolume);
        const double dr0 = con.second[m_indexDr0];
        const double volumeScaling = con.second[m_indexVolumeScaling];
        const double d_ij = 0.5*(d_i + d_j);

        double dr2 = 0;
        double A_ij = 0; // The lambda-factor

        for(int d=0; d<m_dim; d++)
        {
            dr_ij[d] = m_r(d, j) - r_i[d];
            dr2 += dr_ij[d]*dr_ij[d];
            A_ij += dr_ij[d]*(m_r0(d, j) - r0_i[d]);
        }

        const double dr = sqrt(dr2);
        A_ij /= (dr0*dr);
        double ds = dr - dr0;

        // To avoid roundoff errors
        if (fabs(ds) < THRESHOLD)
            ds = 0.0;

        const double s = ds/dr0;
        theta_i += d_ij*s*A_ij*vol_j*volumeScaling;
    }

    return m_delta*theta_i;
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------------
double PD_LPS::calculatePotentialEnergyDensity(const std::pair<int, int> &idCol)
{
    const int pId = idCol.first;
    const int i = idCol.second;
    const double m_i = m_data(i, m_iMass);

    vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

    double r_i[m_dim];
    double r0_i[m_dim];
    for(int d=0; d<m_dim; d++)
    {
        r_i[d] = m_r(d, i);
        r0_i[d] = m_r0(d, i);
    }

    const int nConnections = PDconnections.size();
    double dr_ij[m_dim];

    double alpha = 0;
    if(m_dim == 3)
        alpha = 15*m_mu/m_i;
    else
        alpha = 8*m_mu/m_i;

    double theta_i = this->computeDilation(idCol);

    double W_i = 0;
    for(int l_j=0; l_j<nConnections; l_j++) {
        auto &con = PDconnections[l_j];
        if(con.second[m_iConnected] <= 0.5)
            continue;

        const int id_j = con.first;
        const int j = m_pIds[id_j];

        const double vol_j = m_data(j, m_iVolume);
        const double dr0 = con.second[m_iDr0];
        const double volumeScaling = con.second[m_iVolumeScaling];
        double dr2 = 0;

        for(int d=0; d<m_dim; d++)
        {
            dr_ij[d] = m_r(d, j) - r_i[d];
            dr2 += dr_ij[d]*dr_ij[d];
        }

        const double dr = sqrt(dr2);
        double ds = dr - dr0;
        const double extension_term =  alpha*(pow(ds - theta_i*dr0/m_dim, 2));

        W_i += (extension_term)*vol_j*volumeScaling;
    }
    W_i += m_k*(pow(theta_i, 2));

    return 0.5* W_i;
}
Ejemplo n.º 3
0
//------------------------------------------------------------------------------
void PD_OSP::calculateForces(const std::pair<int, int> &idCol)
{
    const int pId = idCol.first;
    const int col_i = idCol.second;
    const double a_i = m_data(col_i, m_indexA);
    const double b_i = m_data(col_i, m_indexB);
    const double d_i = m_data(col_i, m_indexD);
    const double theta_i = m_data(col_i, m_indexTheta);

    vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

    double r_i[3];
    double r0_i[3];
    double f_i[3];
    for(int d=0; d<m_dim; d++)
    {
        f_i[d] = 0;
        r_i[d] = m_r(d, col_i);
        r0_i[d] = m_r0(d, col_i);
    }

    const int nConnections = PDconnections.size();
    double dr_ij[3];

    double thetaNew = 0;
    for(int l_j=0; l_j<nConnections; l_j++)
    {
        auto &con = PDconnections[l_j];
        if(con.second[m_indexConnected] <= 0.5)
            continue;

        const int id_j = con.first;
        const int j = m_pIds[id_j];

        const double a_j = m_data(j, m_indexA);
        const double b_j = m_data(j, m_indexB);
        const double d_j = m_data(j, m_indexD);
        const double theta_j = m_data(j, m_indexTheta);
        const double vol_j = m_data(j, m_indexVolume);
        const double dr0 = con.second[m_indexDr0];
        const double volumeScaling = con.second[m_indexVolumeScaling];
        const double a_ij = 0.5*(a_i + a_j);
        const double b_ij = 0.5*(b_i + b_j);
        const double d_ij = 0.5*(d_i + d_j);
        const double Gd_ij = con.second[m_indexForceScalingDilation];
        const double Gb_ij = con.second[m_indexForceScalingBond];

        double dr2 = 0;
        double A_ij = 0; // The lambda-factor

        for(int d=0; d<m_dim; d++)
        {
            dr_ij[d] = m_r(d, j) - r_i[d];
            dr2 += dr_ij[d]*dr_ij[d];
            A_ij += dr_ij[d]*(m_r0(d, j) - r0_i[d]);
        }

        const double dr = sqrt(dr2);
        A_ij /= (dr0*dr);
        double ds = dr - dr0;

        // To avoid roundoff errors
        if (fabs(ds) < THRESHOLD)
            ds = 0.0;

        const double s = ds/dr0;
        const double fbond = (a_ij*d_ij*Gd_ij*A_ij/dr0*(theta_i + theta_j) + b_ij*Gb_ij*s)
                *vol_j*volumeScaling/dr;
        for(int d=0; d<m_dim; d++)
        {
            f_i[d] += dr_ij[d]*fbond;
        }

        thetaNew += d_ij*s*A_ij*vol_j*volumeScaling;
        con.second[m_indexStretch] = s;
    }

    for(int d=0; d<m_dim; d++)
    {
        m_F(d, col_i) += m_delta*f_i[d];
    }

    m_data(col_i, m_indexThetaNew) = m_delta*thetaNew;
}
Ejemplo n.º 4
0
//------------------------------------------------------------------------------
void PD_LPS_porosity_adrmc::calculateForces(const int id, const int i) {
  const double theta_i = m_data(i, m_iTheta);
  const double m_i = m_data(i, m_iMass);
  const double a_i = m_data(i, m_iA);
  const double b_i = m_data(i, m_iA);

  vector<pair<int, vector<double>>> &PDconnections =
      m_particles.pdConnections(id);

  const int nConnections = PDconnections.size();
  double dr0_ij[m_dim];
  double dr_ij[m_dim];
  _F.zeros();

  double thetaNew = 0;
  int nConnected = 0;

  //----------------------------------
  // TMP - standard stress calc from
  //    m_data(i, m_indexStress[0]) = 0;
  //    m_data(i, m_indexStress[1]) = 0;
  //    m_data(i, m_indexStress[2]) = 0;
  //----------------------------------

  for (int l_j = 0; l_j < nConnections; l_j++) {
    auto &con = PDconnections[l_j];

    if (con.second[m_iConnected] <= 0.5)
      continue;

    const int id_j = con.first;
    const int j = m_idToCol_v[id_j];

    const double m_j = m_data(j, m_iMass);
    const double theta_j = m_data(j, m_iTheta);
    const double vol_j = m_data(j, m_iVolume);
    const double dr0 = con.second[m_iDr0];
    const double volumeScaling = con.second[m_iVolumeScaling];
    const double vol = vol_j * volumeScaling;
    const double w = weightFunction(dr0);
    const double a_j = m_data(j, m_iA);
    const double b_j = m_data(j, m_iB);

    double dr2 = 0;

    for (int d = 0; d < m_dim; d++) {
      dr0_ij[d] = m_r0(j, d) - m_r0(i, d);
      dr_ij[d] = m_r(j, d) - m_r(i, d);
      dr2 += dr_ij[d] * dr_ij[d];
    }

    const double dr = sqrt(dr2);
    const double ds = dr - dr0;
    double bond = (b_i * theta_i / m_i + b_j * theta_j / m_j) * dr0;
    bond += (a_i / m_i + a_j / m_j) * ds;
    bond *= w * vol / dr;
    thetaNew += w * dr0 * ds * vol;

    for (int d = 0; d < m_dim; d++) {
      m_F(i, d) += dr_ij[d] * bond;

      for (int d2 = 0; d2 < m_dim; d2++) {
        _F(d, d2) += w * dr_ij[d] * dr0_ij[d2] * vol;
      }
    }

    con.second[m_iStretch] = ds / dr0;
    //----------------------------------
    // TMP - standard stres calc from
    //        m_data(i, m_indexStress[0]) += 0.5*dr_ij[0]*dr_ij[0]*bond;
    //        m_data(i, m_indexStress[1]) += 0.5*dr_ij[1]*dr_ij[1]*bond;
    //        m_data(i, m_indexStress[2]) += 0.5*dr_ij[0]*dr_ij[1]*bond;
    //----------------------------------
    nConnected++;
  }

  if (nConnections <= 3) {
    m_data(i, m_iThetaNew) = 0;
  } else {
    m_data(i, m_iThetaNew) = m_dim / m_i * thetaNew;
  }

  //----------------------------------
  // TMP - standard stres calc from
  //----------------------------------
  //    if(nConnected > 5) {
  //        computeStress(id, i, nConnected);
  //    }
  computeStress(id, i, nConnected);
  //--------------------
  m_continueState = false;
}
Ejemplo n.º 5
0
//------------------------------------------------------------------------------
void PD_LPS::applySurfaceCorrection(double strain)
{
    arma::vec3 strainFactor;
    arma::mat gd = arma::zeros(m_particles.nParticles(), m_dim); // Dilation correction
    arma::mat gb = arma::zeros(m_particles.nParticles(), m_dim); // Bond correction

    //--------------------------------------------------------------------------
    // Apllying correction to the dilation term
    //--------------------------------------------------------------------------
    // Stretching all particle in the x, y and z-direction
    strainFactor(0) = strain;
    strainFactor(1) = 0;
    strainFactor(2) = 0;

    for(int a=0; a<m_dim; a++)
    {
        if(a == 1)
            strainFactor.swap_rows(0,1);
        else if(a == 2)
            strainFactor.swap_rows(1,2);

#ifdef USE_OPENMP
# pragma omp parallel for
#endif
        // Applying uniaxial stretch
        for(int i=0; i<m_particles.nParticles(); i++)
        {
            pair<int, int> idCol(i, i);
            const int col_i = idCol.second;

            for(int d=0; d<m_dim; d++)
            {
                m_r(d, col_i) = (1 + strainFactor(d))*m_r(d, col_i);
            }
        }

        double W_d = strain;
#ifdef USE_OPENMP
# pragma omp parallel for
#endif
        // Calculating the elastic energy density
        for(int i=0; i<m_particles.nParticles(); i++)
        {
            pair<int, int> idCol(i, i);
            const int col_i = idCol.second;
            const double theta_i = computeDilation(idCol);
            const double factor =  W_d/theta_i;
            gd(col_i, a) = factor;
        }

#ifdef USE_OPENMP
# pragma omp parallel for
#endif
        // Resetting the positions
        for(int i=0; i<m_particles.nParticles(); i++)
        {
            pair<int, int> idCol(i, i);
            int col_i = idCol.second;

            for(int d=0; d<m_dim; d++)
            {
//                m_r(d, col_i) = m_r(d, col_i)/(1 + strainFactor(d));
                m_r(d, col_i) = m_r0(d, col_i);
            }
        }
    }

    //--------------------------------------------------------------------------
    // Applying correction to the bond term
    //--------------------------------------------------------------------------
    // Performing a simple shear of all particle in the x, y and z-direction
    arma::ivec3 axis;
    strainFactor(0) = strain;
    strainFactor(1) = 0.*strain;
    strainFactor(2) = 0;
    axis(0) = 1;
    axis(1) = 0;
    axis(2) = 0;

    for(int a=0; a<m_dim; a++)
    {
        if(a == 1)
        {
            strainFactor.swap_rows(1,2);
            strainFactor.swap_rows(0,1);
            axis(0) = 2;
            axis(1) = 0;
            axis(2) = 1;
        }
        else if(a == 2)
        {
            strainFactor.swap_rows(2,0);
            strainFactor.swap_rows(1,2);
            axis(0) = 2;
            axis(1) = 0;
            axis(2) = 0;
        }
//#ifdef USE_OPENMP
//# pragma omp parallel for
//#endif
        // Applying uniaxial stretch
        for(int i=0; i<m_particles.nParticles(); i++)
        {
            pair<int, int> idCol(i, i);
            int col_i = idCol.second;

            for(int d=0; d<m_dim; d++)
            {
                double shear = strainFactor(d)*m_r(axis(d), col_i);
                m_r(d, col_i) = m_r(d, col_i) + shear;
            }
        }

        double W_s = 0.5*m_mu*strain*strain;
//#ifdef USE_OPENMP
        //# pragma omp parallel for
        //#endif
        // Calculating the elastic energy density
        for(int i=0; i<m_particles.nParticles(); i++)
        {
            pair<int, int> idCol(i, i);
            const int col_i = idCol.second;
            const double bond_i = calculatePotentialEnergyDensity(idCol);
            const double factor =  W_s/bond_i;
            gb(col_i, a) = factor;
        }

        //#ifdef USE_OPENMP
//# pragma omp parallel for
//#endif
        // Resetting the positions
        for(int i=0; i<m_particles.nParticles(); i++)
        {
            pair<int, int> idCol(i, i);
            int col_i = idCol.second;

            for(int d=0; d<m_dim; d++)
            {
//                m_r(d, col_i) = m_r(d, col_i) - strainFactor(d)*m_r(axis(d), col_i);
                m_r(d, col_i) = m_r0(d, col_i);
            }
        }
    }

    //--------------------------------------------------------------------------
    // Calculating the scaling
    //--------------------------------------------------------------------------
//#ifdef USE_OPENMP
//# pragma omp parallel for
//#endif
    for(int i=0; i<m_particles.nParticles(); i++)
    {
        pair<int, int> idCol(i, i);
        int pId = idCol.first;
        int col_i = idCol.second;

        vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

        for(auto &con:PDconnections)
        {
            int id_j = con.first;
            int col_j = m_pIds[id_j];

            double dr0Len = con.second[m_iDr0];
            arma::vec3 n = (m_r.col(col_i) - m_r.col(col_j))/dr0Len;

            arma::vec3 gd_mean;
            arma::vec3 gb_mean;
            double Gd = 0;
            double Gb = 0;
            for(int d=0; d<m_dim; d++)
            {
                const double gd_i = gd(col_i, d);
                const double gd_j = gd(col_j, d);
                const double gb_i = gb(col_i, d);
                const double gb_j = gb(col_j, d);
                gd_mean(d) = 0.5*(gd_i + gd_j);
                gb_mean(d) = 0.5*(gb_i + gb_j);
                Gb += pow(n(d)/gb_mean(d), 2);
                Gd += pow(n(d)/gd_mean(d), 2);
            }

            Gd = pow(Gd, -0.5);
            Gb = pow(Gb, -0.5);
            con.second[m_iForceScalingDilation] *= Gd;
            con.second[m_iForceScalingBond] *= Gb;
        }
    }
}
Ejemplo n.º 6
0
//------------------------------------------------------------------------------
void PD_LPS::calculateForces(const std::pair<int, int> &idCol)
{
    const int pId = idCol.first;
    const int i = idCol.second;
    const double theta_i = m_data(i, m_iTheta);
    const double m_i = m_data(i, m_iMass);

    double alpha;
    if(m_dim == 3)
        alpha = 15*m_mu;
    else
        alpha = 8*m_mu;

    const double c = (3*m_k - 5*m_mu);

    vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

    double r_i[m_dim];
    double r0_i[m_dim];
    double f_i[m_dim];

    for(int d=0; d<m_dim; d++)
    {
        f_i[d] = 0;
        r_i[d] = m_r(d, i);
        r0_i[d] = m_r0(d, i);
    }

    const int nConnections = PDconnections.size();
    double dr_ij[m_dim];

    double thetaNew = 0;
    for(int l_j=0; l_j<nConnections; l_j++)
    {
        auto &con = PDconnections[l_j];

        if(con.second[m_iConnected] <= 0.5)
            continue;

        const int id_j = con.first;
        const int j = m_pIds[id_j];

        const double m_j = m_data(j, m_iMass);
        const double theta_j = m_data(j, m_iTheta);
        const double vol_j = m_data(j, m_iVolume);
        const double dr0 = con.second[m_iDr0];
        const double volumeScaling = con.second[m_iVolumeScaling];
        const double gb_ij = con.second[m_iForceScalingBond];
        const double gd_ij = con.second[m_iForceScalingDilation];

        double dr2 = 0;

        for(int d=0; d<m_dim; d++)
        {
            dr_ij[d] = m_r(d, j) - r_i[d];
            dr2 += dr_ij[d]*dr_ij[d];
        }

        const double dr = sqrt(dr2);
        const double ds = dr - dr0;
        double bond = gd_ij*c*(theta_i/m_i + theta_j/m_j)*dr0;
        bond += gb_ij*alpha*(1./m_i + 1./m_j)*ds;
        bond *= vol_j*volumeScaling/dr;
        thetaNew += dr0*ds*vol_j*volumeScaling;

        for(int d=0; d<m_dim; d++)
        {
            m_F(d, i) += dr_ij[d]*bond;
        }

        con.second[m_iStretch] = ds/dr0;
    }

    m_data(i, m_iThetaNew) = m_dim/m_i*thetaNew;
}
Ejemplo n.º 7
0
//------------------------------------------------------------------------------
void PD_LPS::calculateStress(const std::pair<int, int> &idCol, const int (&indexStress)[6])
{
    const int pId = idCol.first;
    const int i = idCol.second;
    const double theta_i = m_data(i, m_iTheta);
    const double m_i = m_data(i, m_iMass);

    double beta = 0;
    if(m_dim == 3)
        beta = 15*m_mu;
    else
        beta = 8*m_mu;

    const double alpha_i = beta/m_i;

    vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

    double r_i[3];
    double r0_i[3];
    for(int d=0; d<m_dim; d++)
    {
        r_i[d] = m_r(d, i);
        r0_i[d] = m_r0(d, i);
    }

    const int nConnections = PDconnections.size();
    double dr_ij[m_dim];

    for(int l_j=0; l_j<nConnections; l_j++)
    {
        auto &con = PDconnections[l_j];
        if(con.second[m_iConnected] <= 0.5)
            continue;

        const int id_j = con.first;
        const int j = m_pIds[id_j];

        const double m_j = m_data(j, m_iMass);
        const double theta_j = m_data(j, m_iTheta);
        const double vol_j = m_data(j, m_iVolume);
        const double dr0 = con.second[m_iDr0];
        const double volumeScaling = con.second[m_iVolumeScaling];
        const double alpha_j = beta/m_j;
        const double gb_ij = con.second[m_iForceScalingBond];
        const double gd_ij = con.second[m_iForceScalingDilation];

        double dr2 = 0;

        for(int d=0; d<m_dim; d++)
        {
            dr_ij[d] = m_r(d, j) - r_i[d];
            dr2 += dr_ij[d]*dr_ij[d];
        }

        const double dr = sqrt(dr2);
        const double ds = dr - dr0;

        double bond_ij = gd_ij*(3*m_k - 5*m_mu)*(theta_i/m_i + theta_j/m_j)*dr0;
        bond_ij += gb_ij*(alpha_i + alpha_j)*ds;
        bond_ij *= vol_j*volumeScaling/dr;

        m_data(i, indexStress[0]) += 0.5*bond_ij*dr_ij[X]*dr_ij[X];
        m_data(i, indexStress[1]) += 0.5*bond_ij*dr_ij[Y]*dr_ij[Y];
        m_data(i, indexStress[3]) += 0.5*bond_ij*dr_ij[X]*dr_ij[Y];

        if(m_dim == 3)
        {
            m_data(i, indexStress[2]) += 0.5*bond_ij*dr_ij[Z]*dr_ij[Z];
            m_data(i, indexStress[4]) += 0.5*bond_ij*dr_ij[X]*dr_ij[Z];
            m_data(i, indexStress[5]) += 0.5*bond_ij*dr_ij[Y]*dr_ij[Z];
        }
    }
}