Ejemplo n.º 1
0
//second argument unused
//rectract with step size
//first used to avoid computation repetition
arma::mat fixRank::retract(double stepSize, std::string method,
                bool first){
  arma::mat S,Us,Vs;
  arma::vec Sigma_s;
  bool conv;
  Yt=Y;
  if(first){
    conv=arma::qr_econ(Qu,Ru,Up_desc);
    if(!conv) return Y;
    conv=arma::qr_econ(Qv,Rv,Vp_desc);
    if(!conv) return Y;
  }
  S=arma::mat(2*r,2*r,arma::fill::zeros);
  S(arma::span(0,r-1),arma::span(0,r-1))=arma::diagmat(Sigma)+M_desc*stepSize;
  S(arma::span(r,2*r-1),arma::span(0,r-1))=Ru*stepSize;
  S(arma::span(0,r-1),arma::span(r,2*r-1))=Rv.t()*stepSize; 
  conv=arma::svd_econ(Us,Sigma_s,Vs,S);
  if(!conv) return Y;
  Sigma_t=Sigma_s(arma::span(0,r-1));
  Ut=U*Us(arma::span(0,r-1),arma::span(0,r-1))+Qu*Us(arma::span(r,2*r-1),arma::span(0,r-1));
  Vt=V*Vs(arma::span(0,r-1),arma::span(0,r-1))+Qv*Vs(arma::span(r,2*r-1),arma::span(0,r-1));
  
  Yt=Ut*arma::diagmat(Sigma_t)*Vt.t();
  return Yt;
}
Foam::syringePressureFvPatchScalarField::syringePressureFvPatchScalarField
(
    const fvPatch& p,
    const DimensionedField<scalar, volMesh>& iF,
    const dictionary& dict
)
:
    fixedValueFvPatchScalarField(p, iF),
    Ap_(readScalar(dict.lookup("Ap"))),
    Sp_(readScalar(dict.lookup("Sp"))),
    VsI_(readScalar(dict.lookup("VsI"))),
    tas_(readScalar(dict.lookup("tas"))),
    tae_(readScalar(dict.lookup("tae"))),
    tds_(readScalar(dict.lookup("tds"))),
    tde_(readScalar(dict.lookup("tde"))),
    psI_(readScalar(dict.lookup("psI"))),
    psi_(readScalar(dict.lookup("psi"))),
    ams_(readScalar(dict.lookup("ams"))),
    ams0_(ams_),
    phiName_(dict.lookupOrDefault<word>("phi", "phi")),
    curTimeIndex_(-1)
{
    scalar ps = (psI_*VsI_ + ams_/psi_)/Vs(db().time().value());
    fvPatchField<scalar>::operator=(ps);
}
void syringePressureFvPatchScalarField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    if (curTimeIndex_ != db().time().timeIndex())
    {
        ams0_ = ams_;
        curTimeIndex_ = db().time().timeIndex();
    }

    scalar t = db().time().value();
    scalar deltaT = db().time().deltaT().value();

    const surfaceScalarField& phi = db().lookupObject<surfaceScalarField>
    (
        "phi"
    );

    const fvsPatchField<scalar>& phip =
        patch().patchField<surfaceScalarField, scalar>(phi);

    if (phi.dimensions() == dimVelocity*dimArea)
    {
        ams_ = ams0_ + deltaT*sum((*this*psi_)*phip);
    }
    else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
    {
        ams_ = ams0_ + deltaT*sum(phip);
    }
    else
    {
        FatalErrorIn("syringePressureFvPatchScalarField::updateCoeffs()")
            << "dimensions of phi are not correct"
            << "\n    on patch " << this->patch().name()
            << " of field " << this->dimensionedInternalField().name()
            << " in file " << this->dimensionedInternalField().objectPath()
            << exit(FatalError);
    }

    scalar ps = (psI_*VsI_ + ams_/psi_)/Vs(t);

    operator==(ps);

    fixedValueFvPatchScalarField::updateCoeffs();
}
void BeetstraDrag::setForce() const
{
    scale_=cg();
    Info << "BeetstraDrag using scale from liggghts cg = " << scale_ << endl;

    // get viscosity field
    #ifdef comp
        const volScalarField nufField = particleCloud_.turbulence().mu()/rho_;
    #else
        const volScalarField& nufField = particleCloud_.turbulence().nu();
    #endif

    vector position(0,0,0);
    scalar voidfraction(1);
    vector Ufluid(0,0,0);
    vector drag(0,0,0);
    label cellI=0;
    scalar beta(0);

    vector Us(0,0,0);
    vector Ur(0,0,0);
    scalar ds(0);
    scalar nuf(0);
    scalar rho(0);
    scalar magUr(0);
    scalar Rep(0);
	scalar Vs(0);
	scalar localPhiP(0);
	scalar filterDragPrefactor(1.0);
	scalar cCorrParcelSize_(1.0) ;
	scalar vCell(0);
	scalar FfFilterPrime(1);
	
    scalar F0=0.;
    scalar G0=0.;

    interpolationCellPoint<scalar> voidfractionInterpolator_(voidfraction_);
    interpolationCellPoint<vector> UInterpolator_(U_);

    #include "setupProbeModel.H"

    for(int index = 0;index <  particleCloud_.numberOfParticles(); index++)
    {
        //if(mask[index][0])
        //{
            cellI = particleCloud_.cellIDs()[index][0];
            drag = vector(0,0,0);
            Ufluid= vector(0,0,0);
            
            if (cellI > -1) // particle Found
            {
                if(interpolation_)
                {
	                position     = particleCloud_.position(index);
                    voidfraction = voidfractionInterpolator_.interpolate(position,cellI);
                    Ufluid       = UInterpolator_.interpolate(position,cellI);
                    //Ensure interpolated void fraction to be meaningful
                    // Info << " --> voidfraction: " << voidfraction << endl;
                    if(voidfraction>1.00) voidfraction = 1.00;
                    if(voidfraction<0.10) voidfraction = 0.10;
                }
                else
                {
					voidfraction = voidfraction_[cellI];
                    Ufluid = U_[cellI];
                }
           
                Us = particleCloud_.velocity(index);
                Ur = Ufluid-Us;
                ds = 2*particleCloud_.radius(index);
                dPrim_ = ds/scale_;
                nuf = nufField[cellI];
                rho = rho_[cellI];

                magUr = mag(Ur);
				Rep = 0;
                Vs = ds*ds*ds*M_PI/6;
                localPhiP = 1-voidfraction+SMALL;
                vCell = U_.mesh().V()[cellI];
                
                 if (magUr > 0)
                {
                    // calc particle Re Nr
                    Rep = dPrim_*voidfraction*magUr/(nuf+SMALL);


// 3 - C - 1 - In this section we could insert parameters
//             or functions
//             that come from a database

                    // calc model coefficient F0
                    F0 = 10.f * localPhiP / voidfraction / voidfraction
                       + voidfraction * voidfraction * ( 1.0+1.5*sqrt(localPhiP) );

                    // calc model coefficient G0
                    G0 =  0.01720833 * Rep / voidfraction / voidfraction  //0.0172083 = 0.413/24
                              *  ( 1.0 / voidfraction + 3.0 * localPhiP  * voidfraction + 8.4 
                                                            * powf(Rep,-0.343) ) 
                              /  ( 1.0 + powf( 10., 3.0* localPhiP ) 
                                       * powf( Rep,-(1.0+4.0*localPhiP)/2.0 ) );

                    // calc model coefficient beta
                    beta =  18.*nuf*rho/(dPrim_*dPrim_)
                              *voidfraction
                              *(F0 + G0);

                    //Apply filtered drag correction
                    if(useFilteredDragModel_)
                    {
                        FfFilterPrime =  FfFilterFunc(
                                                    filtDragParamsLChar2_,
                                                    vCell,
                                                    0
                                                   );
                 
                        filterDragPrefactor = 1 - fFuncFilteredDrag(FfFilterPrime, localPhiP)
                                                * hFuncFilteredDrag(localPhiP);
                                           
                        beta *= filterDragPrefactor;
                    }
                    if(useParcelSizeDependentFilteredDrag_) //Apply filtered drag correction
                    {
                        scalar dParceldPrim = scale_;
                        cCorrParcelSize_ = 
                               cCorrFunctionFilteredDrag(
                                          filtDragParamsK_, 
                                          filtDragParamsALimit_,
                                          filtDragParamsAExponent_,
                                          localPhiP,
                                          dParceldPrim
                                       );                                          
                        beta *= cCorrParcelSize_;
                    }

                    // calc particle's drag
                    drag = Vs * beta * Ur;

                    if (modelType_=="B")
                        drag /= voidfraction;
                }

// 3 - C - 2 - This is a standardized debug and report section

                if( verbose_ ) //&& index>100 && index < 105)
                {
                    Info << "index / cellI = " << index << tab << cellI << endl;
                    Info << "position = " << particleCloud_.position(index) << endl;
                    Info << "Us = " << Us << endl;
                    Info << "Ur = " << Ur << endl;
                    Info << "ds = " << ds << endl;
                    Info << "rho = " << rho << endl;
                    Info << "nuf = " << nuf << endl;
                    Info << "voidfraction = " << voidfraction << endl;
                    Info << "voidfraction_[cellI]: " << voidfraction_[cellI] << endl;
                    Info << "Rep = " << Rep << endl;
                    Info << "filterDragPrefactor = " << filterDragPrefactor << endl;
                    Info << "fFuncFilteredDrag: " << fFuncFilteredDrag(FfFilterPrime, localPhiP) << endl;
                    Info << "hFuncFilteredDrag: " << hFuncFilteredDrag(localPhiP) << endl;
                    Info << "cCorrParcelSize:   " << cCorrParcelSize_ << endl;
                    Info << "F0 / G0: " << F0 << tab << G0 << endl;
                    Info << "beta:   " << beta << endl;
                    Info << "drag = " << drag << endl;

                    Info << "\nBeetstra drag model settings: treatExplicit " << treatExplicit_ << tab
                                    << "verbose: " << verbose_ << tab
                                    << "dPrim: " << dPrim_  << tab
                                    << "interpolation: " << interpolation_  << tab
                                    << "filteredDragM: " << useFilteredDragModel_   << tab
                                    << "parcelSizeDepDrag: " << useParcelSizeDependentFilteredDrag_
                                    << endl << endl;
                }

                //Set value fields and write the probe
                if(probeIt_)
                {
                    #include "setupProbeModelfields.H"
                    vValues.append(drag);           //first entry must the be the force
                    vValues.append(Ur);                
                    sValues.append(Rep);
                    sValues.append(beta);
                    sValues.append(voidfraction);
                    sValues.append(filterDragPrefactor);
                    particleCloud_.probeM().writeProbe(index, sValues, vValues);
                }
            }

            // set force on particle
            if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j];
            else  for(int j=0;j<3;j++) impForces()[index][j] += drag[j];

            // set Cd
            if(implDEM_)
            {
                for(int j=0;j<3;j++) fluidVel()[index][j]=Ufluid[j];

                if (modelType_=="B")
                    Cds()[index][0] = Vs*beta/voidfraction;
                else
                    Cds()[index][0] = Vs*beta;

            }else{
                for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j];
            }
        //}
    }
}
inline
void
GenEigsSolver<eT, SelectionRule, OpType>::factorise_from(uword from_k, uword to_m, const Col<eT>& fk)
  {
  arma_extra_debug_sigprint();
  
  if(to_m <= from_k) { return; }

  fac_f = fk;

  Col<eT> w(dim_n);
  eT beta = norm(fac_f);
  // Keep the upperleft k x k submatrix of H and set other elements to 0
  fac_H.tail_cols(ncv - from_k).zeros();
  fac_H.submat(span(from_k, ncv - 1), span(0, from_k - 1)).zeros();
  for(uword i = from_k; i <= to_m - 1; i++)
    {
    bool restart = false;
    // If beta = 0, then the next V is not full rank
    // We need to generate a new residual vector that is orthogonal
    // to the current V, which we call a restart
    if(beta < eps)
      {
      // Generate new random vector for fac_f
      blas_int idist = 2;
      blas_int iseed[4] = {1, 3, 5, 7};
      iseed[0] = (i + 100) % 4095;
      blas_int n = dim_n;
      lapack::larnv(&idist, iseed, &n, fac_f.memptr());
      // f <- f - V * V' * f, so that f is orthogonal to V
      Mat<eT> Vs(fac_V.memptr(), dim_n, i, false); // First i columns
      Col<eT> Vf = Vs.t() * fac_f;
      fac_f -= Vs * Vf;
      // beta <- ||f||
      beta = norm(fac_f);

      restart = true;
      }

    // v <- f / ||f||
    fac_V.col(i) = fac_f / beta; // The (i+1)-th column

    // Note that H[i+1, i] equals to the unrestarted beta
    if(restart) { fac_H(i, i - 1) = 0.0; } else { fac_H(i, i - 1) = beta; }

    // w <- A * v, v = fac_V.col(i)
    op.perform_op(fac_V.colptr(i), w.memptr());
    nmatop++;

    // First i+1 columns of V
    Mat<eT> Vs(fac_V.memptr(), dim_n, i + 1, false);
    // h = fac_H(0:i, i)
    Col<eT> h(fac_H.colptr(i), i + 1, false);
    // h <- V' * w
    h = Vs.t() * w;

    // f <- w - V * h
    fac_f = w - Vs * h;
    beta = norm(fac_f);

    if(beta > 0.717 * norm(h)) { continue; }

    // f/||f|| is going to be the next column of V, so we need to test
    // whether V' * (f/||f||) ~= 0
    Col<eT> Vf = Vs.t() * fac_f;
    // If not, iteratively correct the residual
    uword count = 0;
    while(count < 5 && abs(Vf).max() > approx0 * beta)
      {
      // f <- f - V * Vf
      fac_f -= Vs * Vf;
      // h <- h + Vf
      h += Vf;
      // beta <- ||f||
      beta = norm(fac_f);

      Vf = Vs.t() * fac_f;
      count++;
      }
    }
  }
inline
void
GenEigsSolver<eT, SelectionRule, OpType>::restart(uword k)
  {
  arma_extra_debug_sigprint();
  
  if(k >= ncv) { return; }

  DoubleShiftQR<eT>     decomp_ds(ncv);
  UpperHessenbergQR<eT> decomp;
  
  Mat<eT> Q(ncv, ncv, fill::eye);

  for(uword i = k; i < ncv; i++)
    {
    if(cx_attrib::is_complex(ritz_val(i), eps) && cx_attrib::is_conj(ritz_val(i), ritz_val(i + 1), eps))
      {
      // H - mu * I = Q1 * R1
      // H <- R1 * Q1 + mu * I = Q1' * H * Q1
      // H - conj(mu) * I = Q2 * R2
      // H <- R2 * Q2 + conj(mu) * I = Q2' * H * Q2
      //
      // (H - mu * I) * (H - conj(mu) * I) = Q1 * Q2 * R2 * R1 = Q * R
      eT s = 2 * ritz_val(i).real();
      eT t = std::norm(ritz_val(i));
      decomp_ds.compute(fac_H, s, t);

      // Q -> Q * Qi
      decomp_ds.apply_YQ(Q);
      // H -> Q'HQ
      fac_H = decomp_ds.matrix_QtHQ();

      i++;
      }
    else
      {
      // QR decomposition of H - mu * I, mu is real
      fac_H.diag() -= ritz_val(i).real();
      decomp.compute(fac_H);

      // Q -> Q * Qi
      decomp.apply_YQ(Q);
      // H -> Q'HQ = RQ + mu * I
      fac_H = decomp.matrix_RQ();
      fac_H.diag() += ritz_val(i).real();
      }
    }
  // V -> VQ
  // Q has some elements being zero
  // The first (ncv - k + i) elements of the i-th column of Q are non-zero
  Mat<eT> Vs(dim_n, k + 1);
  uword nnz;
  for(uword i = 0; i < k; i++)
    {
    nnz = ncv - k + i + 1;
    Mat<eT> V(fac_V.memptr(), dim_n, nnz, false);
    Col<eT> q(Q.colptr(i), nnz, false);
    Col<eT> v(Vs.colptr(i), dim_n, false);
    v = V * q;
    }
  Vs.col(k) = fac_V * Q.col(k);
  fac_V.head_cols(k + 1) = Vs;

  Col<eT> fk = fac_f * Q(ncv - 1, k - 1) + fac_V.col(k) * fac_H(k, k - 1);
  factorise_from(k, ncv, fk);
  retrieve_ritzpair();
}
Ejemplo n.º 7
0
IGL_INLINE bool igl::copyleft::boolean::mesh_boolean(
    const Eigen::PlainObjectBase<DerivedVA> & VA,
    const Eigen::PlainObjectBase<DerivedFA> & FA,
    const Eigen::PlainObjectBase<DerivedVB> & VB,
    const Eigen::PlainObjectBase<DerivedFB> & FB,
    const WindingNumberOp& wind_num_op,
    const KeepFunc& keep,
    const ResolveFunc& resolve_fun,
    Eigen::PlainObjectBase<DerivedVC > & VC,
    Eigen::PlainObjectBase<DerivedFC > & FC,
    Eigen::PlainObjectBase<DerivedJ > & J) 
{

#ifdef MESH_BOOLEAN_TIMING
  const auto & tictoc = []() -> double
  {
    static double t_start = igl::get_seconds();
    double diff = igl::get_seconds()-t_start;
    t_start += diff;
    return diff;
  };
  const auto log_time = [&](const std::string& label) -> void {
    std::cout << "mesh_boolean." << label << ": "
      << tictoc() << std::endl;
  };
  tictoc();
#endif

  typedef typename DerivedVC::Scalar Scalar;
  //typedef typename DerivedFC::Scalar Index;
  typedef CGAL::Epeck Kernel;
  typedef Kernel::FT ExactScalar;
  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3> MatrixX3S;
  //typedef Eigen::Matrix<Index,Eigen::Dynamic,Eigen::Dynamic> MatrixXI;
  typedef Eigen::Matrix<typename DerivedJ::Scalar,Eigen::Dynamic,1> VectorXJ;

  // Generate combined mesh.
  typedef Eigen::Matrix<
    ExactScalar,
    Eigen::Dynamic,
    Eigen::Dynamic,
    DerivedVC::IsRowMajor> MatrixXES;
  MatrixXES V;
  DerivedFC F;
  VectorXJ  CJ;
  {
      DerivedVA VV(VA.rows() + VB.rows(), 3);
      DerivedFC FF(FA.rows() + FB.rows(), 3);
      VV << VA, VB;
      FF << FA, FB.array() + VA.rows();
      //// Handle annoying empty cases
      //if(VA.size()>0)
      //{
      //  VV<<VA;
      //}
      //if(VB.size()>0)
      //{
      //  VV<<VB;
      //}
      //if(FA.size()>0)
      //{
      //  FF<<FA;
      //}
      //if(FB.size()>0)
      //{
      //  FF<<FB.array()+VA.rows();
      //}
      resolve_fun(VV, FF, V, F, CJ);
  }
#ifdef MESH_BOOLEAN_TIMING
  log_time("resolve_self_intersection");
#endif

  // Compute winding numbers on each side of each facet.
  const size_t num_faces = F.rows();
  Eigen::MatrixXi W;
  Eigen::VectorXi labels(num_faces);
  std::transform(CJ.data(), CJ.data()+CJ.size(), labels.data(),
      [&](int i) { return i<FA.rows() ? 0:1; });
  bool valid = true;
  if (num_faces > 0) 
  {
    valid = valid & 
      igl::copyleft::cgal::propagate_winding_numbers(V, F, labels, W);
  } else 
  {
    W.resize(0, 4);
  }
  assert((size_t)W.rows() == num_faces);
  if (W.cols() == 2) 
  {
    assert(FB.rows() == 0);
    Eigen::MatrixXi W_tmp(num_faces, 4);
    W_tmp << W, Eigen::MatrixXi::Zero(num_faces, 2);
    W = W_tmp;
  } else {
    assert(W.cols() == 4);
  }
#ifdef MESH_BOOLEAN_TIMING
  log_time("propagate_input_winding_number");
#endif

  // Compute resulting winding number.
  Eigen::MatrixXi Wr(num_faces, 2);
  for (size_t i=0; i<num_faces; i++) 
  {
    Eigen::MatrixXi w_out(1,2), w_in(1,2);
    w_out << W(i,0), W(i,2);
    w_in  << W(i,1), W(i,3);
    Wr(i,0) = wind_num_op(w_out);
    Wr(i,1) = wind_num_op(w_in);
  }
#ifdef MESH_BOOLEAN_TIMING
  log_time("compute_output_winding_number");
#endif

  // Extract boundary separating inside from outside.
  auto index_to_signed_index = [&](size_t i, bool ori) -> int
  {
    return (i+1)*(ori?1:-1);
  };
  //auto signed_index_to_index = [&](int i) -> size_t {
  //    return abs(i) - 1;
  //};
  std::vector<int> selected;
  for(size_t i=0; i<num_faces; i++) 
  {
    auto should_keep = keep(Wr(i,0), Wr(i,1));
    if (should_keep > 0) 
    {
      selected.push_back(index_to_signed_index(i, true));
    } else if (should_keep < 0) 
    {
      selected.push_back(index_to_signed_index(i, false));
    }
  }

  const size_t num_selected = selected.size();
  DerivedFC kept_faces(num_selected, 3);
  DerivedJ  kept_face_indices(num_selected, 1);
  for (size_t i=0; i<num_selected; i++) 
  {
    size_t idx = abs(selected[i]) - 1;
    if (selected[i] > 0) 
    {
      kept_faces.row(i) = F.row(idx);
    } else 
    {
      kept_faces.row(i) = F.row(idx).reverse();
    }
    kept_face_indices(i, 0) = CJ[idx];
  }
#ifdef MESH_BOOLEAN_TIMING
  log_time("extract_output");
#endif

  // Finally, remove duplicated faces and unreferenced vertices.
  {
    DerivedFC G;
    DerivedJ JJ;
    igl::resolve_duplicated_faces(kept_faces, G, JJ);
    igl::slice(kept_face_indices, JJ, 1, J);

#ifdef DOUBLE_CHECK_EXACT_OUTPUT
    {
      // Sanity check on exact output.
      igl::copyleft::cgal::RemeshSelfIntersectionsParam params;
      params.detect_only = true;
      params.first_only = true;
      MatrixXES dummy_VV;
      DerivedFC dummy_FF, dummy_IF;
      Eigen::VectorXi dummy_J, dummy_IM;
      igl::copyleft::cgal::SelfIntersectMesh<
        Kernel,
        MatrixXES, DerivedFC,
        MatrixXES, DerivedFC,
        DerivedFC,
        Eigen::VectorXi,
        Eigen::VectorXi
      > checker(V, G, params,
          dummy_VV, dummy_FF, dummy_IF, dummy_J, dummy_IM);
      if (checker.count != 0) 
      {
        throw "Self-intersection not fully resolved.";
      }
    }
#endif

    MatrixX3S Vs(V.rows(), V.cols());
    for (size_t i=0; i<(size_t)V.rows(); i++)
    {
      for (size_t j=0; j<(size_t)V.cols(); j++)
      {
        igl::copyleft::cgal::assign_scalar(V(i,j), Vs(i,j));
      }
    }
    Eigen::VectorXi newIM;
    igl::remove_unreferenced(Vs,G,VC,FC,newIM);
  }
#ifdef MESH_BOOLEAN_TIMING
  log_time("clean_up");
#endif
  return valid;
}
Ejemplo n.º 8
0
void GidaspowDrag::setForce() const
{
    if (scaleDia_ > 1)
        Info << "Gidaspow using scale = " << scaleDia_ << endl;
    else if (particleCloud_.cg() > 1){
        scaleDia_=particleCloud_.cg();
        Info << "Gidaspow using scale from liggghts cg = " << scaleDia_ << endl;
    }

    // get viscosity field
    #ifdef comp
        const volScalarField nufField = particleCloud_.turbulence().mu() / rho_;
    #else
        const volScalarField& nufField = particleCloud_.turbulence().nu();
    #endif

    vector position(0,0,0);
    scalar voidfraction(1);
    vector Ufluid(0,0,0);
    vector drag(0,0,0);
    label cellI=0;

    vector Us(0,0,0);
    vector Uturb(0,0,0);
    vector Ur(0,0,0);
    scalar ds(0);
    scalar nuf(0);
    scalar rho(0);
    scalar magUr(0);
    scalar Rep(0);
    scalar Vs(0);
    scalar localPhiP(0);

    scalar CdMagUrLag(0);       //Cd of the very particle
    scalar KslLag(0);           //momentum exchange of the very particle (per unit volume)
    scalar betaP(0);             //momentum exchange of the very particle

    interpolationCellPoint<scalar> voidfractionInterpolator_(voidfraction_);
    interpolationCellPoint<vector> UInterpolator_(U_);

    #include "setupProbeModel.H"

    for(int index = 0;index <  particleCloud_.numberOfParticles(); ++index)
    {
        //if(mask[index][0])
        //{
            cellI = particleCloud_.cellIDs()[index][0];
            drag = vector(0,0,0);
            betaP = 0;
            Vs = 0;
            Ufluid =vector(0,0,0);
            voidfraction=0;

            if (cellI > -1) // particle Found
            {
                position     = particleCloud_.position(index);
                if(interpolation_)
                {
	            	//position     = particleCloud_.position(index);
                    voidfraction = voidfractionInterpolator_.interpolate(position,cellI);
                    Ufluid       = UInterpolator_.interpolate(position,cellI);
                    //Ensure interpolated void fraction to be meaningful
                    // Info << " --> voidfraction: " << voidfraction << endl;
                    if(voidfraction>1.00) voidfraction = 1.0;
                    if(voidfraction<0.10) voidfraction = 0.10;
                }
                else
                {
                    voidfraction = voidfraction_[cellI];
                    Ufluid = U_[cellI];                    
                }

                Us = particleCloud_.velocity(index);                    
                Ur = Ufluid-Us;
                
                //accounting for turbulent dispersion
                if(particleCloud_.dispersionM().isActive())
                {
                    Uturb=particleCloud_.fluidTurbVel(index);
                    Ur=(Ufluid+Uturb)-Us;                                        
                }
                                        
                magUr = mag(Ur);
                ds = 2*particleCloud_.radius(index)*phi_;
                rho = rho_[cellI];
                nuf = nufField[cellI];

                Rep=0.0;
                localPhiP = 1.0f-voidfraction+SMALL;
                Vs = ds*ds*ds*M_PI/6;

                //Compute specific drag coefficient (i.e., Force per unit slip velocity and per m³ SUSPENSION)
                //Wen and Yu, 1966
                if(voidfraction > 0.8) //dilute
                {
                    Rep=ds/scaleDia_*voidfraction*magUr/nuf;
                    CdMagUrLag = (24.0*nuf/(ds/scaleDia_*voidfraction)) //1/magUr missing here, but compensated in expression for KslLag!
                                 *(scalar(1)+0.15*Foam::pow(Rep, 0.687));

                    KslLag = 0.75*(
                                            rho*localPhiP*voidfraction*CdMagUrLag
                                          /
                                            (ds/scaleDia_*Foam::pow(voidfraction,2.65))
                                          );
                }
                //Ergun, 1952
                else  //dense
                {
                    KslLag = (150*Foam::pow(localPhiP,2)*nuf*rho)/
                             (voidfraction*ds/scaleDia_*ds/scaleDia_+SMALL)
                            +
                             (1.75*(localPhiP) * magUr * rho)/
                             ((ds/scaleDia_));
                }

                // calc particle's drag coefficient (i.e., Force per unit slip velocity and per m³ PARTICLE)
                betaP = KslLag / localPhiP;

                // calc particle's drag
                drag = Vs * betaP * Ur * scaleDrag_;

                if (modelType_=="B")
                    drag /= voidfraction;

                if(verbose_ && index >=0 && index <1)
                {
                    Pout << " "<< endl;
                    Pout << "Gidaspow drag force verbose: "  << endl;
                    
                    
                    Pout << "magUr = " << magUr << endl;
                    Pout << "localPhiP = " << localPhiP << endl;
                    Pout << "CdMagUrLag = " << CdMagUrLag << endl;
                    
                    Pout << "treatExplicit_ = " << treatExplicit_ << endl;
                    Pout << "implDEM_ = " << implDEM_ << endl;
                    Pout << "modelType_ = " << modelType_ << endl;                    
                    
                    Pout << "KslLag = " << KslLag << endl;                    
                                        
                    Pout << "cellI = " << cellI << endl;
                    Pout << "index = " << index << endl;                    
                    
                    Pout << "Ufluid = " << Ufluid << endl; 
                    Pout << "Uturb = " << Uturb << endl; 
                    Pout << "Us = " << Us << endl; 
                    
                    Pout << "Ur = " << Ur << endl;
                    Pout << "Vs = " << Vs << endl;                    
                    Pout << "ds = " << ds << endl;
                    Pout << "ds/scale = " << ds/scaleDia_ << endl;
                    Pout << "phi = " << phi_ << endl;
                    Pout << "rho = " << rho << endl;
                    Pout << "nuf = " << nuf << endl;
                    Pout << "voidfraction = " << voidfraction << endl;
                    Pout << "Rep = " << Rep << endl;
                    
                    Pout << "localPhiP = " << localPhiP << endl;
                    Pout << "betaP = " << betaP << endl;
                    
                    Pout << "drag = " << drag << endl;                    
                    Pout << "position = " << position << endl;
                    Pout << " "<< endl;
                }

                //Set value fields and write the probe
                if(probeIt_)
                {
                    #include "setupProbeModelfields.H"
                    vValues.append(drag);   //first entry must the be the force
                    vValues.append(Ur);
                    sValues.append(Rep);
                    sValues.append(betaP);
                    sValues.append(voidfraction);
                    particleCloud_.probeM().writeProbe(index, sValues, vValues);
                }
            }

            // set force on particle
            //treatExplicit_ = false by default
            if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j];
            else  for(int j=0;j<3;j++) impForces()[index][j] += drag[j];

            // set Cd
            //implDEM_ = false by default
            if(implDEM_)
            {
                for(int j=0;j<3;j++) fluidVel()[index][j]=Ufluid[j];

                if (modelType_=="B" && cellI > -1)
                    Cds()[index][0] = Vs*betaP/voidfraction*scaleDrag_;
                else
                    Cds()[index][0] = Vs*betaP*scaleDrag_;

            }else{
                for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j];
            }

        //}// end if mask
    }// end loop particles
}
void KochHillDrag::setForce() const
{
    const volScalarField& nufField = forceSubM(0).nuField();
    const volScalarField& rhoField = forceSubM(0).rhoField();


    //update force submodels to prepare for loop
    for (int iFSub=0;iFSub<nrForceSubModels();iFSub++)
        forceSubM(iFSub).preParticleLoop(forceSubM(iFSub).verbose());


    vector position(0,0,0);
    scalar voidfraction(1);
    vector Ufluid(0,0,0);
    vector drag(0,0,0);
    vector dragExplicit(0,0,0);
    scalar dragCoefficient(0);
    label cellI=0;

    vector Us(0,0,0);
    vector Ur(0,0,0);
    scalar ds(0);
    scalar dParcel(0);
    scalar nuf(0);
    scalar rho(0);
    scalar magUr(0);
    scalar Rep(0);
	scalar Vs(0);
	scalar volumefraction(0);
    scalar betaP(0);

    scalar piBySix(M_PI/6);


    int couplingInterval(particleCloud_.dataExchangeM().couplingInterval());

    #include "resetVoidfractionInterpolator.H"
    #include "resetUInterpolator.H"
    #include "setupProbeModel.H"

    for(int index = 0;index <  particleCloud_.numberOfParticles(); index++)
    {
            cellI = particleCloud_.cellIDs()[index][0];
            drag = vector(0,0,0);
            dragExplicit = vector(0,0,0);
            dragCoefficient=0;
            betaP = 0;
            Vs = 0;
            Ufluid =vector(0,0,0);
            voidfraction=0;

            if (cellI > -1) // particle Found
            {
                if(forceSubM(0).interpolation())
                {
	                position = particleCloud_.position(index);
                    voidfraction = voidfractionInterpolator_().interpolate(position,cellI);
                    Ufluid = UInterpolator_().interpolate(position,cellI);

                    //Ensure interpolated void fraction to be meaningful
                    // Info << " --> voidfraction: " << voidfraction << endl;
                    if(voidfraction>1.00) voidfraction = 1.00;
                    if(voidfraction<0.40) voidfraction = 0.40;
                }else
                {
					voidfraction = voidfraction_[cellI];
                    Ufluid = U_[cellI];
                }

                ds = particleCloud_.d(index);
                dParcel = ds;
                forceSubM(0).scaleDia(ds); //caution: this fct will scale ds!
                nuf = nufField[cellI];
                rho = rhoField[cellI];

                Us = particleCloud_.velocity(index);

                //Update any scalar or vector quantity
                for (int iFSub=0;iFSub<nrForceSubModels();iFSub++)
                      forceSubM(iFSub).update(  index,
                                                cellI,
                                                ds,
                                                Ufluid, 
                                                Us, 
                                                nuf,
                                                rho,
                                                forceSubM(0).verbose()
                                             );

                Ur = Ufluid-Us;
                magUr = mag(Ur);
				Rep = 0;

                Vs = ds*ds*ds*piBySix;

                volumefraction = max(SMALL,min(1-SMALL,1-voidfraction));

                if (magUr > 0)
                {
                    // calc particle Re Nr
                    Rep = ds*voidfraction*magUr/(nuf+SMALL);

                    // calc model coefficient F0
                    scalar F0=0.;
                    if(volumefraction < 0.4)
                    {
                        F0 = (1. + 3.*sqrt((volumefraction)/2.) + (135./64.)*volumefraction*log(volumefraction)
                              + 16.14*volumefraction
                             )/
                             (1+0.681*volumefraction-8.48*sqr(volumefraction)
                              +8.16*volumefraction*volumefraction*volumefraction
                             );
                    } else {
                        F0 = 10*volumefraction/(voidfraction*voidfraction*voidfraction);
                    }

                    // calc model coefficient F3
                    scalar F3 = 0.0673+0.212*volumefraction+0.0232/pow(voidfraction,5);

                    //Calculate F (the factor 0.5 is introduced, since Koch and Hill, ARFM 33:619–47, use the radius
                    //to define Rep, and we use the particle diameter, see vanBuijtenen et al., CES 66:2368–2376.
                    scalar F = voidfraction * (F0 + 0.5*F3*Rep);

                    // calc drag model coefficient betaP
                    betaP = 18.*nuf*rho/(ds*ds)*voidfraction*F;

                    // calc particle's drag
                    dragCoefficient = Vs*betaP;
                    if (modelType_=="B")
                        dragCoefficient /= voidfraction;

                    forceSubM(0).scaleCoeff(dragCoefficient,dParcel);

                    if(forceSubM(0).switches()[7]) // implForceDEMaccumulated=true
                    {
		                //get drag from the particle itself
		                for (int j=0 ; j<3 ; j++) drag[j] = particleCloud_.fAccs()[index][j]/couplingInterval;
                    }else
                    {
                        drag = dragCoefficient * Ur;

                        // explicitCorr
                        for (int iFSub=0;iFSub<nrForceSubModels();iFSub++)
                            forceSubM(iFSub).explicitCorr( drag, 
                                                           dragExplicit,
                                                           dragCoefficient,
                                                           Ufluid, U_[cellI], Us, UsField_[cellI],
                                                           forceSubM(iFSub).verbose()
                                                         );
                    }
                }

                if(forceSubM(0).verbose() && index >=0 && index <2)
                {
                    Pout << "cellI = " << cellI << endl;
                    Pout << "index = " << index << endl;
                    Pout << "Us = " << Us << endl;
                    Pout << "Ur = " << Ur << endl;
                    Pout << "dprim = " << ds << endl;
                    Pout << "rho = " << rho << endl;
                    Pout << "nuf = " << nuf << endl;
                    Pout << "voidfraction = " << voidfraction << endl;
                    Pout << "Rep = " << Rep << endl;
                    Pout << "betaP = " << betaP << endl;
                    Pout << "drag = " << drag << endl;
                }

                //Set value fields and write the probe
                if(probeIt_)
                {
                    #include "setupProbeModelfields.H"
                    // Note: for other than ext one could use vValues.append(x)
                    // instead of setSize
                    vValues.setSize(vValues.size()+1, drag);           //first entry must the be the force
                    vValues.setSize(vValues.size()+1, Ur);
                    sValues.setSize(sValues.size()+1, Rep); 
                    sValues.setSize(sValues.size()+1, betaP);
                    sValues.setSize(sValues.size()+1, voidfraction);
                    particleCloud_.probeM().writeProbe(index, sValues, vValues);
                }    
            }

            // write particle based data to global array
            forceSubM(0).partToArray(index,drag,dragExplicit,Ufluid,dragCoefficient);
    }
}
void KochHillDrag::setForce
(
    double** const& mask,
    double**& impForces,
    double**& expForces,
    double**& DEMForces
) const
{
    // get viscosity field
    #ifdef comp
        const volScalarField nufField = particleCloud_.turbulence().mu()/rho_;
    #else
        const volScalarField& nufField = particleCloud_.turbulence().nu();
    #endif

    vector position(0,0,0);
    scalar voidfraction(1);
    vector Ufluid(0,0,0);
    vector drag(0,0,0);
    label cellI=0;

    vector Us(0,0,0);
    vector Ur(0,0,0);
    scalar ds(0);
    scalar nuf(0);
    scalar rho(0);
    scalar magUr(0);
    scalar Rep(0);
	scalar Vs(0);
	scalar volumefraction(0);

    interpolationCellPoint<scalar> voidfractionInterpolator_(voidfraction_);
    interpolationCellPoint<vector> UInterpolator_(U_);

    for(int index = 0;index <  particleCloud_.numberOfParticles(); index++)
    {
        if(mask[index][0])
        {

            cellI = particleCloud_.cellIDs()[index][0];
            drag = vector(0,0,0);

            if (cellI > -1) // particle Found
            {
                if(interpolation_)
                {
	                position = particleCloud_.position(index);
                    voidfraction = voidfractionInterpolator_.interpolate(position,cellI);
                    Ufluid = UInterpolator_.interpolate(position,cellI);
                }else
                {
					voidfraction = particleCloud_.voidfraction(index);
                    Ufluid = U_[cellI];
                }

                Us = particleCloud_.velocity(index);
                Ur = Ufluid-Us;
                ds = 2*particleCloud_.radius(index);
                nuf = nufField[cellI];
                rho = rho_[cellI];
                magUr = mag(Ur);
				Rep = 0;
                Vs = ds*ds*ds*M_PI/6;
                volumefraction = 1-voidfraction+SMALL;

                if (magUr > 0)
                {
                    // calc particle Re Nr
                    Rep = ds/scale_*voidfraction*magUr/(nuf+SMALL);

                    // calc model coefficient F0
                    scalar F0=0.;
                    if(volumefraction < 0.4)
                    {
                        F0 = (1+3*sqrt((volumefraction)/2)+135/64*volumefraction*log(volumefraction)+16.14*volumefraction)/
                             (1+0.681*volumefraction-8.48*sqr(volumefraction)+8.16*volumefraction*volumefraction*volumefraction);
                    } else {
                        F0 = 10*volumefraction/(voidfraction*voidfraction*voidfraction);
                    }

                    // calc model coefficient F3
                    scalar F3 = 0.0673+0.212*volumefraction+0.0232/pow(voidfraction,5);

                    // calc model coefficient beta
                    scalar beta = 18*nuf*rho*voidfraction*voidfraction*volumefraction/(ds/scale_*ds/scale_)*
                                  (F0 + 0.5*F3*Rep);

                    // calc particle's drag
                    drag = Vs*beta/volumefraction*Ur;

                    if (modelType_=="B")
                        drag /= voidfraction;
                }

                if(verbose_ && index >=0 && index <2)
                {
                    Info << "index = " << index << endl;
                    Info << "Us = " << Us << endl;
                    Info << "Ur = " << Ur << endl;
                    Info << "ds = " << ds << endl;
                    Info << "ds/scale = " << ds/scale_ << endl;
                    Info << "rho = " << rho << endl;
                    Info << "nuf = " << nuf << endl;
                    Info << "voidfraction = " << voidfraction << endl;
                    Info << "Rep = " << Rep << endl;
                    Info << "drag = " << drag << endl;
                }
            }
            // set force on particle
            if(treatExplicit_) for(int j=0;j<3;j++) expForces[index][j] += drag[j];
            else  for(int j=0;j<3;j++) impForces[index][j] += drag[j];
        }
    }
}
Ejemplo n.º 11
0
IGL_INLINE void igl::copyleft::boolean::mesh_boolean(
    const Eigen::PlainObjectBase<DerivedVA> & VA,
    const Eigen::PlainObjectBase<DerivedFA> & FA,
    const Eigen::PlainObjectBase<DerivedVB> & VB,
    const Eigen::PlainObjectBase<DerivedFB> & FB,
    const WindingNumberOp& wind_num_op,
    const KeepFunc& keep,
    const ResolveFunc& resolve_fun,
    Eigen::PlainObjectBase<DerivedVC > & VC,
    Eigen::PlainObjectBase<DerivedFC > & FC,
    Eigen::PlainObjectBase<DerivedJ > & J) {

  typedef typename DerivedVC::Scalar Scalar;
  //typedef typename DerivedFC::Scalar Index;
  typedef CGAL::Epeck Kernel;
  typedef Kernel::FT ExactScalar;
  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3> MatrixX3S;
  //typedef Eigen::Matrix<Index,Eigen::Dynamic,Eigen::Dynamic> MatrixXI;
  typedef Eigen::Matrix<typename DerivedJ::Scalar,Eigen::Dynamic,1> VectorXJ;

  // Generate combined mesh.
  typedef Eigen::Matrix<
    ExactScalar,
    Eigen::Dynamic,
    Eigen::Dynamic,
    DerivedVC::IsRowMajor> MatrixXES;
  MatrixXES V;
  DerivedFC F;
  VectorXJ  CJ;
  {
      DerivedVA VV(VA.rows() + VB.rows(), 3);
      DerivedFC FF(FA.rows() + FB.rows(), 3);
      VV << VA, VB;
      FF << FA, FB.array() + VA.rows();
      //// Handle annoying empty cases
      //if(VA.size()>0)
      //{
      //  VV<<VA;
      //}
      //if(VB.size()>0)
      //{
      //  VV<<VB;
      //}
      //if(FA.size()>0)
      //{
      //  FF<<FA;
      //}
      //if(FB.size()>0)
      //{
      //  FF<<FB.array()+VA.rows();
      //}
      resolve_fun(VV, FF, V, F, CJ);
  }

  // Compute winding numbers on each side of each facet.
  const size_t num_faces = F.rows();
  Eigen::MatrixXi W;
  Eigen::VectorXi labels(num_faces);
  std::transform(CJ.data(), CJ.data()+CJ.size(), labels.data(),
      [&](int i) { return i<FA.rows() ? 0:1; });
  igl::copyleft::cgal::propagate_winding_numbers(V, F, labels, W);
  assert((size_t)W.rows() == num_faces);
  if (W.cols() == 2) {
    assert(FB.rows() == 0);
    Eigen::MatrixXi W_tmp(num_faces, 4);
    W_tmp << W, Eigen::MatrixXi::Zero(num_faces, 2);
    W = W_tmp;
  } else {
    assert(W.cols() == 4);
  }

  // Compute resulting winding number.
  Eigen::MatrixXi Wr(num_faces, 2);
  for (size_t i=0; i<num_faces; i++) {
    Eigen::MatrixXi w_out(1,2), w_in(1,2);
    w_out << W(i,0), W(i,2);
    w_in  << W(i,1), W(i,3);
    Wr(i,0) = wind_num_op(w_out);
    Wr(i,1) = wind_num_op(w_in);
  }

  // Extract boundary separating inside from outside.
  auto index_to_signed_index = [&](size_t i, bool ori) -> int{
    return (i+1)*(ori?1:-1);
  };
  //auto signed_index_to_index = [&](int i) -> size_t {
  //    return abs(i) - 1;
  //};
  std::vector<int> selected;
  for(size_t i=0; i<num_faces; i++) {
    auto should_keep = keep(Wr(i,0), Wr(i,1));
    if (should_keep > 0) {
      selected.push_back(index_to_signed_index(i, true));
    } else if (should_keep < 0) {
      selected.push_back(index_to_signed_index(i, false));
    }
  }

  const size_t num_selected = selected.size();
  DerivedFC kept_faces(num_selected, 3);
  DerivedJ  kept_face_indices(num_selected, 1);
  for (size_t i=0; i<num_selected; i++) {
    size_t idx = abs(selected[i]) - 1;
    if (selected[i] > 0) {
      kept_faces.row(i) = F.row(idx);
    } else {
      kept_faces.row(i) = F.row(idx).reverse();
    }
    kept_face_indices(i, 0) = CJ[idx];
  }

  // Finally, remove duplicated faces and unreferenced vertices.
  {
    DerivedFC G;
    DerivedJ JJ;
    igl::resolve_duplicated_faces(kept_faces, G, JJ);
    igl::slice(kept_face_indices, JJ, 1, J);

    MatrixX3S Vs(V.rows(), V.cols());
    for (size_t i=0; i<(size_t)V.rows(); i++)
    {
      for (size_t j=0; j<(size_t)V.cols(); j++)
      {
        igl::copyleft::cgal::assign_scalar(V(i,j), Vs(i,j));
      }
    }
    Eigen::VectorXi newIM;
    igl::remove_unreferenced(Vs,G,VC,FC,newIM);
  }
}
Ejemplo n.º 12
0
void KochHillDrag::setForce() const
{
    if (scaleDia_ > 1)
        Info << "KochHill using scale = " << scaleDia_ << endl;
    else if (particleCloud_.cg() > 1){
        scaleDia_=particleCloud_.cg();
        Info << "KochHill using scale from liggghts cg = " << scaleDia_ << endl;
    }

    // get viscosity field
    #ifdef comp
        const volScalarField nufField = particleCloud_.turbulence().mu()/rho_;
    #else
        const volScalarField& nufField = particleCloud_.turbulence().nu();
    #endif

    vector position(0,0,0);
    scalar voidfraction(1);
    vector Ufluid(0,0,0);
    vector drag(0,0,0);
    label cellI=0;

    vector Us(0,0,0);
    vector Ur(0,0,0);
    scalar ds(0);
    scalar nuf(0);
    scalar rho(0);
    scalar magUr(0);
    scalar Rep(0);
	scalar Vs(0);
	scalar volumefraction(0);
    scalar betaP(0);

    interpolationCellPoint<scalar> voidfractionInterpolator_(voidfraction_);
    interpolationCellPoint<vector> UInterpolator_(U_);

    #include "setupProbeModel.H"

    for(int index = 0;index <  particleCloud_.numberOfParticles(); index++)
    {
        //if(mask[index][0])
        //{
            cellI = particleCloud_.cellIDs()[index][0];
            drag = vector(0,0,0);
            betaP = 0;
            Vs = 0;
            Ufluid =vector(0,0,0);
            voidfraction=0;

            if (cellI > -1) // particle Found
            {
                if(interpolation_)
                {
	                position = particleCloud_.position(index);
                    voidfraction = voidfractionInterpolator_.interpolate(position,cellI);
                    Ufluid = UInterpolator_.interpolate(position,cellI);
                    //Ensure interpolated void fraction to be meaningful
                    // Info << " --> voidfraction: " << voidfraction << endl;
                    if(voidfraction>1.00) voidfraction = 1.00;
                    if(voidfraction<0.40) voidfraction = 0.40;
                }else
                {
					voidfraction = voidfraction_[cellI];
                    Ufluid = U_[cellI];
                }

                Us = particleCloud_.velocity(index);
                Ur = Ufluid-Us;
                ds = particleCloud_.d(index);
                nuf = nufField[cellI];
                rho = rho_[cellI];
                magUr = mag(Ur);
				Rep = 0;
                Vs = ds*ds*ds*M_PI/6;
                volumefraction = 1-voidfraction+SMALL;

                if (magUr > 0)
                {
                    // calc particle Re Nr
                    Rep = ds/scaleDia_*voidfraction*magUr/(nuf+SMALL);

                    // calc model coefficient F0
                    scalar F0=0.;
                    if(volumefraction < 0.4)
                    {
                        F0 = (1+3*sqrt((volumefraction)/2)+135/64*volumefraction*log(volumefraction)
                              +16.14*volumefraction
                             )/
                             (1+0.681*volumefraction-8.48*sqr(volumefraction)
                              +8.16*volumefraction*volumefraction*volumefraction
                             );
                    } else {
                        F0 = 10*volumefraction/(voidfraction*voidfraction*voidfraction);
                    }

                    // calc model coefficient F3
                    scalar F3 = 0.0673+0.212*volumefraction+0.0232/pow(voidfraction,5);

                    //Calculate F
                    scalar F = voidfraction * (F0 + 0.5*F3*Rep);

                    // calc drag model coefficient betaP
                    betaP = 18.*nuf*rho/(ds/scaleDia_*ds/scaleDia_)*voidfraction*F;

                    // calc particle's drag
                    drag = Vs*betaP*Ur*scaleDrag_;

                    if (modelType_=="B")
                        drag /= voidfraction;
                }

                if(verbose_ && index >=0 && index <2)
                {
                    Pout << "cellI = " << cellI << endl;
                    Pout << "index = " << index << endl;
                    Pout << "Us = " << Us << endl;
                    Pout << "Ur = " << Ur << endl;
                    Pout << "ds = " << ds << endl;
                    Pout << "ds/scale = " << ds/scaleDia_ << endl;
                    Pout << "rho = " << rho << endl;
                    Pout << "nuf = " << nuf << endl;
                    Pout << "voidfraction = " << voidfraction << endl;
                    Pout << "Rep = " << Rep << endl;
                    Pout << "betaP = " << betaP << endl;
                    Pout << "drag = " << drag << endl;
                }

                //Set value fields and write the probe
                if(probeIt_)
                {
                    #include "setupProbeModelfields.H"
                    vValues.append(drag);           //first entry must the be the force
                    vValues.append(Ur);
                    sValues.append(Rep);
                    sValues.append(betaP);
                    sValues.append(voidfraction);
                    particleCloud_.probeM().writeProbe(index, sValues, vValues);
                }    
            }
            // set force on particle
            if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j];
            else  for(int j=0;j<3;j++) impForces()[index][j] += drag[j];

            // set Cd
            if(implDEM_)
            {
                for(int j=0;j<3;j++) fluidVel()[index][j]=Ufluid[j];

                if (modelType_=="B" && cellI > -1)
                    Cds()[index][0] = Vs*betaP/voidfraction*scaleDrag_;
                else
                    Cds()[index][0] = Vs*betaP*scaleDrag_;

            }else{
                for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j];
            }

        //}
    }
}