//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(); }
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; }
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]; } } }
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); } }
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]; } //} } }