示例#1
0
文件: testlr.c 项目: aar2163/GROMACS
static real phi_sr(FILE *log,int nj,rvec x[],real charge[],real rc,real r1,rvec box,
		   real phi[],t_block *excl,rvec f_sr[],bool bOld)
{
  int  i,j,k,m,ni,i1,i2;
  real pp,r2,R,R_1,R_2,rc2;
  real qi,qj,vsr,eps,fscal;
  rvec dx;
  
  vsr = 0.0;
  eps = ONE_4PI_EPS0;
  rc2 = rc*rc;
  ni=0;
  for(i=0; (i<nj-1); i++) {
    qi=charge[i];
    for(j=i+1; (j<nj); j++) {
      i1=excl->index[i];
      i2=excl->index[i+1];
      for(k=i1; (k<i2); k++)
	if (excl->a[k] == j)
	  break;
      if (k == i2) {
	r2=calc_dx2dx(x[i],x[j],box,dx);
	if (r2 < rc2) {
	  qj    = charge[j];
	  R_1   = invsqrt(r2);
	  R_2   = R_1*R_1;
	  R     = invsqrt(R_2);
	  if (bOld) {
	    fscal = old_f(R,rc,r1)*R_2;
	    pp    = old_phi(R,rc,r1);
	  }
	  else {
	    fscal = new_f(R,rc)*R_2;
	    pp    = new_phi(R,rc);
	  }
	  phi[i] += eps*qj*pp;
	  phi[j] += eps*qi*pp;
	  vsr    += eps*qj*qi*pp;
	  for(m=0; (m<DIM); m++) {
	    f_sr[i][m] += dx[m]*fscal;
	    f_sr[j][m] -= dx[m]*fscal;
	  }
	  ni++;
	}
      }
    }
  }
  fprintf(log,"There were %d short range interactions, vsr=%g\n",ni,vsr);
  
  return vsr;
}
示例#2
0
Real
StressDivergenceRZ::calculateJacobian( unsigned int ivar, unsigned int jvar )
{
  // B^T_i * C * B_j
  SymmTensor test, phi;
  if (ivar == 0)
  {
    test.xx() = _grad_test[_i][_qp](0);
    test.xy() = 0.5*_grad_test[_i][_qp](1);
    test.zz() = _test[_i][_qp] / _q_point[_qp](0);
  }
  else
  {
    test.xy() = 0.5*_grad_test[_i][_qp](0);
    test.yy() = _grad_test[_i][_qp](1);
  }
  if (jvar == 0)
  {
    phi.xx()  = _grad_phi[_j][_qp](0);
    phi.xy()  = 0.5*_grad_phi[_j][_qp](1);
    phi.zz()  = _phi[_j][_qp] / _q_point[_qp](0);
  }
  else
  {
    phi.xy()  = 0.5*_grad_phi[_j][_qp](0);
    phi.yy()  = _grad_phi[_j][_qp](1);
  }

  SymmTensor tmp( _Jacobian_mult[_qp] * phi );
  Real first_term( test.doubleContraction( tmp ) );
  Real val = 0.0;
  // volumetric locking correction
  // K = Bbar^T_i * C * Bbar^T_j where Bbar = B + Bvol
  // K = B^T_i * C * B_j + Bvol^T_i * C * Bvol_j + B^T_i * C * Bvol_j + Bvol^T_i * C * B_j
  if (_volumetric_locking_correction)
  {
    RealGradient new_test(2, 0.0);
    RealGradient new_phi(2, 0.0);

    new_test(0) = _grad_test[_i][_qp](0) + _test[_i][_qp] / _q_point[_qp](0);
    new_test(1) = _grad_test[_i][_qp](1);
    new_phi(0) = _grad_phi[_j][_qp](0) + _phi[_j][_qp] / _q_point[_qp](0);
    new_phi(1) = _grad_phi[_j][_qp](1);

    // Bvol^T_i * C * Bvol_j
    val += _Jacobian_mult[_qp].sum_3x3() * (_avg_grad_test[_i][ivar] - new_test(ivar)) * (_avg_grad_phi[_j][jvar] - new_phi(jvar)) / 3.0;

    // B^T_i * C * Bvol_j
    RealGradient sum_3x1 = _Jacobian_mult[_qp].sum_3x1();
    if (ivar == 0 && jvar == 0)
      val += (sum_3x1(0) * test.xx() +  sum_3x1(2) * test.zz()) * (_avg_grad_phi[_j][0] - new_phi(0));
    else if (ivar == 0 && jvar == 1)
      val += (sum_3x1(0) * test.xx() +  sum_3x1(2) * test.zz()) * (_avg_grad_phi[_j][1] - new_phi(1));
    else if (ivar == 1 && jvar == 0)
      val += sum_3x1(1) * test.yy() * (_avg_grad_phi[_j][0] - new_phi(0));
    else
      val += sum_3x1(1) * test.yy() * (_avg_grad_phi[_j][1] - new_phi(1));

    // Bvol^T_i * C * B_j
    // tmp = C * B_j from above
    if (ivar == 0)
      val += (tmp.xx() + tmp.yy() + tmp.zz()) * (_avg_grad_test[_i][0] - new_test(0));
    else
      val += (tmp.xx() + tmp.yy() + tmp.zz()) * (_avg_grad_test[_i][1] - new_test(1));
  }
  return val / 3.0 + first_term;
}
示例#3
0
Real
StressDivergenceRZTensors::calculateJacobian(unsigned int ivar, unsigned int jvar)
{
  // B^T_i * C * B_j
  RealGradient test, test_z, phi, phi_z;
  Real first_term = 0.0;
  if (ivar == 0) // Case grad_test for x, requires contributions from stress_xx, stress_xy, and
                 // stress_zz
  {
    test(0) = _grad_test[_i][_qp](0);
    test(1) = _grad_test[_i][_qp](1);
    test_z(2) = _test[_i][_qp] / _q_point[_qp](0);
  }
  else // Case grad_test for y
  {
    test(0) = _grad_test[_i][_qp](0);
    test(1) = _grad_test[_i][_qp](1);
  }

  if (jvar == 0)
  {
    phi(0) = _grad_phi[_j][_qp](0);
    phi(1) = _grad_phi[_j][_qp](1);
    phi_z(2) = _phi[_j][_qp] / _q_point[_qp](0);
  }
  else
  {
    phi(0) = _grad_phi[_j][_qp](0);
    phi(1) = _grad_phi[_j][_qp](1);
  }

  if (ivar == 0 &&
      jvar == 0) // Case when both phi and test are functions of x and z; requires four terms
  {
    const Real first_sum = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_x and phi_x
    const Real second_sum = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], 2, 2, test_z, phi_z); // test_z and phi_z
    const Real mixed_sum1 = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], ivar, 2, test, phi_z); // test_x and phi_z
    const Real mixed_sum2 = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], 2, jvar, test_z, phi); // test_z and phi_x

    first_term = first_sum + second_sum + mixed_sum1 + mixed_sum2;
  }
  else if (ivar == 0 && jvar == 1)
  {
    const Real first_sum = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_x and phi_y
    const Real mixed_sum2 = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], 2, jvar, test_z, phi); // test_z and phi_y

    first_term = first_sum + mixed_sum2;
  }
  else if (ivar == 1 && jvar == 0)
  {
    const Real second_sum = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_y and phi_x
    const Real mixed_sum1 = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], ivar, 2, test, phi_z); // test_y and phi_z

    first_term = second_sum + mixed_sum1;
  }
  else if (ivar == 1 && jvar == 1)
    first_term = ElasticityTensorTools::elasticJacobian(
        _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_y and phi_y
  else
    mooseError("Invalid component in Jacobian Calculation");

  Real val = 0.0;
  // volumetric locking correction
  // K = Bbar^T_i * C * Bbar^T_j where Bbar = B + Bvol
  // K = B^T_i * C * B_j + Bvol^T_i * C * Bvol_j + B^T_i * C * Bvol_j + Bvol^T_i * C * B_j
  if (_volumetric_locking_correction)
  {
    RealGradient new_test(2, 0.0);
    RealGradient new_phi(2, 0.0);

    new_test(0) = _grad_test[_i][_qp](0) + _test[_i][_qp] / _q_point[_qp](0);
    new_test(1) = _grad_test[_i][_qp](1);
    new_phi(0) = _grad_phi[_j][_qp](0) + _phi[_j][_qp] / _q_point[_qp](0);
    new_phi(1) = _grad_phi[_j][_qp](1);

    // Bvol^T_i * C * Bvol_j
    val += _Jacobian_mult[_qp].sum3x3() * (_avg_grad_test[_i][ivar] - new_test(ivar)) *
           (_avg_grad_phi[_j][jvar] - new_phi(jvar)) / 3.0;

    // B^T_i * C * Bvol_j
    RealGradient sum_3x1 = _Jacobian_mult[_qp].sum3x1();
    if (ivar == 0 && jvar == 0)
      val += (sum_3x1(0) * test(0) + sum_3x1(2) * test_z(2)) * (_avg_grad_phi[_j][0] - new_phi(0));
    else if (ivar == 0 && jvar == 1)
      val += (sum_3x1(0) * test(0) + sum_3x1(2) * test_z(2)) * (_avg_grad_phi[_j][1] - new_phi(1));
    else if (ivar == 1 && jvar == 0)
      val += sum_3x1(1) * test(1) * (_avg_grad_phi[_j][0] - new_phi(0));
    else
      val += sum_3x1(1) * test(1) * (_avg_grad_phi[_j][1] - new_phi(1));

    // Bvol^T_i * C * B_j
    // val = trace (C * B_j) *(avg_grad_test[_i][ivar] - new_test(ivar))
    if (jvar == 0)
      for (unsigned int i = 0; i < 3; ++i)
        val +=
            (_Jacobian_mult[_qp](i, i, 0, 0) * phi(0) + _Jacobian_mult[_qp](i, i, 0, 1) * phi(1) +
             _Jacobian_mult[_qp](i, i, 2, 2) * phi_z(2)) *
            (_avg_grad_test[_i][ivar] - new_test(ivar));
    else if (jvar == 1)
      for (unsigned int i = 0; i < 3; ++i)
        val +=
            (_Jacobian_mult[_qp](i, i, 0, 1) * phi(0) + _Jacobian_mult[_qp](i, i, 1, 1) * phi(1)) *
            (_avg_grad_test[_i][ivar] - new_test(ivar));
  }

  return val / 3.0 + first_term;
}