void PointExp::v_GetCoords(Array<OneD,NekDouble> &coords_0, Array<OneD, NekDouble> &coords_1, Array<OneD, NekDouble> &coords_2) { ASSERTL1(coords_0.num_elements() > 0, "Coords_0 is of insufficient size."); ASSERTL1(GetCoordim() < 2 || coords_1.num_elements() > 0, "Coords_1 is of insufficient size."); ASSERTL1(GetCoordim() < 3 || coords_2.num_elements() > 0, "Coords_2 is of insufficient size."); SpatialDomains::PointGeomSharedPtr v = boost::dynamic_pointer_cast<SpatialDomains::PointGeom>(m_geom); NekDouble tmp; switch(GetCoordim()) { case 1: v->GetCoords(coords_0[0], tmp, tmp); break; case 2: v->GetCoords(coords_0[0], coords_1[0], tmp); break; case 3: v->GetCoords(coords_0[0], coords_1[0], coords_2[0]); break; } }
/// \brief BLAS level 1: y = alpha \a x plus \a y static inline void Daxpy (const int& n, const double& alpha, const Nektar::Array <Nektar::OneD,const double> &x, const int& incx, Nektar::Array<Nektar::OneD,double> &y, const int& incy) { ASSERTL1(static_cast<unsigned int>(n*incx) <= x.num_elements()+x.GetOffset(),"Array out of bounds"); ASSERTL1(static_cast<unsigned int>(n*incy) <= y.num_elements()+y.GetOffset(),"Array out of bounds"); F77NAME(daxpy)(n,alpha,&x[0],incx,&y[0],incy); }
GlobalLinSysSharedPtr ContField1D::GenGlobalLinSys( const GlobalLinSysKey &mkey) { ASSERTL1(mkey.LocToGloMapIsDefined(), "To use method must have a AssemblyMap " "attached to key"); return ExpList::GenGlobalLinSys(mkey, m_locToGloMap); }
void SubtractEqualNegatedLhs(NekMatrix<DataType, StandardMatrixTag>& result, const NekMatrix<RhsDataType, RhsMatrixType>& rhs) { ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") + boost::lexical_cast<std::string>(result.GetRows()) + std::string(" and ") + boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be subtracted.")); ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") + boost::lexical_cast<std::string>(result.GetColumns()) + std::string(" and ") + boost::lexical_cast<std::string>(rhs.GetColumns()) + std::string(" can't be subtracted.")); for(unsigned int i = 0; i < rhs.GetRows(); ++i) { for(unsigned int j = 0; j < rhs.GetColumns(); ++j) { result(i,j) = -result(i,j) - rhs(i,j); } } }
void Add(NekMatrix<DataType, StandardMatrixTag>& result, const NekMatrix<LhsDataType, LhsMatrixType>& lhs, const NekMatrix<RhsDataType, RhsMatrixType>& rhs) { ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") + boost::lexical_cast<std::string>(lhs.GetRows()) + std::string(" and ") + boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be added.")); ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") + boost::lexical_cast<std::string>(lhs.GetColumns()) + std::string(" and ") + boost::lexical_cast<std::string>(rhs.GetColumns()) + std::string(" can't be added.")); for(unsigned int i = 0; i < lhs.GetRows(); ++i) { for(unsigned int j = 0; j < lhs.GetColumns(); ++j) { result(i,j) = lhs(i,j) + rhs(i,j); } } }
void Multiply(NekVector<DataType>& result, const NekMatrix<LhsDataType, MatrixType>& lhs, const NekVector<DataType>& rhs) { ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") + boost::lexical_cast<std::string>(lhs.GetColumns()) + std::string(" and a right side vector with row count ") + boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be multiplied.")); Multiply(result.GetRawPtr(), lhs, rhs.GetRawPtr()); }
void IncNavierStokes::v_GetFluxVector(const int i, Array<OneD, Array<OneD, NekDouble> > &physfield, Array<OneD, Array<OneD, NekDouble> > &flux) { ASSERTL1(flux.num_elements() == m_velocity.num_elements(),"Dimension of flux array and velocity array do not match"); for(int j = 0; j < flux.num_elements(); ++j) { Vmath::Vmul(GetNpoints(), physfield[i], 1, m_fields[m_velocity[j]]->GetPhys(), 1, flux[j], 1); } }
void EigenValuesAdvection::v_GetFluxVector(const int i, Array<OneD, Array<OneD, NekDouble> > &physfield, Array<OneD, Array<OneD, NekDouble> > &flux) { ASSERTL1(flux.num_elements() == m_velocity.num_elements(),"Dimension of flux array and velocity array do not match"); for(int j = 0; j < flux.num_elements(); ++j) { Vmath::Vmul(GetNpoints(),physfield[i],1, m_velocity[j],1,flux[j],1); } }
/** * @brief Upwind Riemann solver * * @param pL Perturbation pressure left state * @param rhoL Perturbation density left state * @param pR Perturbation pressure right state * @param rhoR Perturbation density right state * @param uL x perturbation velocity component left state * @param uR x perturbation velocity component right state * @param vL y perturbation velocity component left state * @param vR y perturbation velocity component right state * @param wL z perturbation velocity component left state * @param wR z perturbation velocity component right state * @param p0 Base pressure * @param rho0 Base density * @param u0 Base x velocity component * @param v0 Base y velocity component * @param w0 Base z velocity component * @param pF Computed Riemann flux for perturbation pressure * @param rhoF Computed Riemann flux for perturbation density * @param uF Computed Riemann flux for x perturbation velocity component * @param vF Computed Riemann flux for y perturbation velocity component * @param wF Computed Riemann flux for z perturbation velocity component */ void UpwindSolver::v_PointSolve( NekDouble pL, NekDouble rhoL, NekDouble uL, NekDouble vL, NekDouble wL, NekDouble pR, NekDouble rhoR, NekDouble uR, NekDouble vR, NekDouble wR, NekDouble p0, NekDouble rho0, NekDouble u0, NekDouble v0, NekDouble w0, NekDouble &pF, NekDouble &rhoF, NekDouble &uF, NekDouble &vF, NekDouble &wF) { // fetch params ASSERTL1(CheckParams("Gamma"), "Gamma not defined."); const NekDouble &gamma = m_params["Gamma"](); // Speed of sound NekDouble c = sqrt(gamma * p0 / rho0); Array<OneD, NekDouble> characteristic(4); Array<OneD, NekDouble> W(2); Array<OneD, NekDouble> lambda(2); // compute the wave speeds lambda[0] = u0 + c; lambda[1] = u0 - c; // calculate the caracteristic variables //left characteristics characteristic[0] = pL/2 + uL*c*rho0/2; characteristic[1] = pL/2 - uL*c*rho0/2; //right characteristics characteristic[2] = pR/2 + uR*c*rho0/2; characteristic[3] = pR/2 - uR*c*rho0/2; //take left or right value of characteristic variable for (int j = 0; j < 2; j++) { if (lambda[j] >= 0) { W[j] = characteristic[j]; } if (lambda[j] < 0) { W[j] = characteristic[j+2]; } } //calculate conservative variables from characteristics NekDouble p = W[0] + W[1]; NekDouble u = (W[0] - W[1])/(c*rho0); // assemble the fluxes pF = rho0*u + u0*p/(c*c); uF = p/rho0 + u0*u + v0*vL + w0*wL; vF = 0.0; wF = 0.0; }
void DriverArnoldi::WriteFld(std::string file, std::vector<Array<OneD, NekDouble> > coeffs) { std::vector<std::string> variables(m_nfields); ASSERTL1(coeffs.size() >= m_nfields, "coeffs is not of the correct length"); for(int i = 0; i < m_nfields; ++i) { variables[i] = m_equ[0]->GetVariable(i); } m_equ[0]->WriteFld(file,m_equ[0]->UpdateFields()[0], coeffs, variables); }
/** * Riemann solver for upwinding at an interface between two * elements. Uses the characteristic variables for calculating * the upwinded state \f$(A_u,u_u)\f$ from the left * \f$(A_L,u_L)\f$ and right state \f$(A_R,u_R)\f$. Returns the * upwinded flux $\mathbf{F}^u$ needed for the weak formulation * (1). Details can be found in "Pulse wave propagation in the * human vascular system", section 3.3 * */ void PulseWavePropagation::RiemannSolverUpwind(NekDouble AL,NekDouble uL, NekDouble AR,NekDouble uR, NekDouble &Aflux, NekDouble &uflux, NekDouble A_0, NekDouble beta, NekDouble n) { Array<OneD, NekDouble> W(2); Array<OneD, NekDouble> upwindedphysfield(2); NekDouble cL = 0.0; NekDouble cR = 0.0; NekDouble rho = m_rho; NekDouble pext = m_pext; NekDouble p = 0.0; NekDouble p_t = 0.0; // Compute the wave speeds. The use of the normal here allows // for the definition of the characteristics to be inverted // (and hence the left and right state) if n is in the -ve // x-direction. This means we end up with the positive // defintion of the flux which has to therefore be multiplied // by the normal at the end of the methods This is a bit of a // mind twister but is efficient from a coding perspective. cL = sqrt(beta*sqrt(AL)/(2*rho))*n; cR = sqrt(beta*sqrt(AR)/(2*rho))*n; ASSERTL1(fabs(cL+cR) > fabs(uL+uR),"Conditions are not sub-sonic"); // If upwinding from left and right for subsonic domain // then know characteristics immediately W[0] = uL + 4*cL; W[1] = uR - 4*cR; // Calculate conservative variables from characteristics NekDouble w0mw1 = 0.25*(W[0]-W[1]); NekDouble fac = rho/(2*beta); w0mw1 *= w0mw1; // squared w0mw1 *= w0mw1; // fourth power fac *= fac; // squared upwindedphysfield[0]= w0mw1*fac; upwindedphysfield[1]= 0.5*(W[0] + W[1]); // Compute the fluxes multipled by the normal. Aflux = upwindedphysfield[0] * upwindedphysfield[1]*n; p = pext + beta*(sqrt(upwindedphysfield[0]) - sqrt(A_0)); p_t = 0.5*(upwindedphysfield[1]*upwindedphysfield[1]) + p/rho; uflux = p_t*n; }
void DriverArnoldi::WriteFld(std::string file, Array<OneD, NekDouble> coeffs) { std::vector<std::string> variables(m_nfields); std::vector<Array<OneD, NekDouble> > fieldcoeffs(m_nfields); int ncoeffs = m_equ[0]->UpdateFields()[0]->GetNcoeffs(); ASSERTL1(coeffs.num_elements() >= ncoeffs*m_nfields,"coeffs is not of sufficient size"); for(int i = 0; i < m_nfields; ++i) { variables[i] = m_equ[0]->GetVariable(i); fieldcoeffs[i] = coeffs + i*ncoeffs; } m_equ[0]->WriteFld(file,m_equ[0]->UpdateFields()[0], fieldcoeffs, variables); }
/** * @brief Implementation of the upwind solver. * * The upwind solver assumes that a scalar field Vn is defined, which * corresponds with the dot product \f$\mathbf{V}\cdot\mathbf{n}\f$, * where \f$\mathbf{V}\f$ is the advection velocity and \f$\mathbf{n}\f$ * defines the normal of a vertex, edge or face at each quadrature point * of the trace space. * * @param Fwd Forwards trace space. * @param Bwd Backwards trace space. * @param flux Resulting flux. */ void UpwindSolver::v_Solve( const Array<OneD, const Array<OneD, NekDouble> > &Fwd, const Array<OneD, const Array<OneD, NekDouble> > &Bwd, Array<OneD, Array<OneD, NekDouble> > &flux) { ASSERTL1(CheckScalars("Vn"), "Vn not defined."); const Array<OneD, NekDouble> &traceVel = m_scalars["Vn"](); for (int j = 0; j < traceVel.num_elements(); ++j) { const Array<OneD, const Array<OneD, NekDouble> > &tmp = traceVel[j] >= 0 ? Fwd : Bwd; for (int i = 0; i < Fwd.num_elements(); ++i) { flux[i][j] = traceVel[j]*tmp[i][j]; } } }
/** * @brief Return the flux vector for the linear advection equation. * * @param i Component of the flux vector to calculate. * @param physfield Fields. * @param flux Resulting flux. */ void UnsteadyAdvection::GetFluxVector( const Array<OneD, Array<OneD, NekDouble> > &physfield, Array<OneD, Array<OneD, Array<OneD, NekDouble> > > &flux) { ASSERTL1(flux[0].num_elements() == m_velocity.num_elements(), "Dimension of flux array and velocity array do not match"); int i , j; int nq = physfield[0].num_elements(); for (i = 0; i < flux.num_elements(); ++i) { for (j = 0; j < flux[0].num_elements(); ++j) { Vmath::Vmul(nq, physfield[i], 1, m_velocity[j], 1, flux[i][j], 1); } } }
void Multiply(NekMatrix<DataType, StandardMatrixTag>& result, const NekMatrix<LhsDataType, LhsMatrixType>& lhs, const NekMatrix<RhsDataType, RhsMatrixType>& rhs) { ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") + boost::lexical_cast<std::string>(lhs.GetColumns()) + std::string(" and a right side matrix with row count ") + boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be multiplied.")); result.SetSize(lhs.GetRows(), rhs.GetColumns()); if( lhs.GetType() == eFULL && rhs.GetType() == eFULL) { NekMultiplyFullMatrixFullMatrix(result, lhs, rhs); } else { NekMultiplyDefaultImpl(result, lhs, rhs); } }
void NekMultiplyDefaultImpl(NekMatrix<ResultType, StandardMatrixTag>& result, const NekMatrix<LhsDataType, LhsMatrixType>& lhs, const NekMatrix<RhsDataType, RhsMatrixType>& rhs) { ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") + boost::lexical_cast<std::string>(lhs.GetColumns()) + std::string(" and a right side matrix with row count ") + boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be multiplied.")); for(unsigned int i = 0; i < result.GetRows(); ++i) { for(unsigned int j = 0; j < result.GetColumns(); ++j) { ResultType t = ResultType(0); // Set the result(i,j) element. for(unsigned int k = 0; k < lhs.GetColumns(); ++k) { t += lhs(i,k)*rhs(k,j); } result(i,j) = t; } } }
/** * Allocates a new DNekSparseMat object from the given specification. * @param rows Number of rows in matrix. * @param columns Number of columns in matrix. * @param cooMat ? */ GlobalMatrix::GlobalMatrix( const LibUtilities::SessionReaderSharedPtr& pSession, unsigned int rows, unsigned int columns, const COOMatType &cooMat, const MatrixStorage& matStorage): m_smvbsrmatrix(), m_rows(rows), m_mulCallsCounter(0) { MatrixStorageType storageType = pSession-> GetSolverInfoAsEnum<MatrixStorageType>("GlobalMatrixStorageType"); unsigned int brows, bcols; // Size of dense matrix sub-blocks int block_size = 1; BCOMatType bcoMat; // assuming current sparse format allows // block-sparse data representation if(pSession->DefinesParameter("SparseBlockSize")) { pSession->LoadParameter("SparseBlockSize", block_size); ASSERTL1(block_size > 0,"SparseBlockSize parameter must to be positive"); } brows = rows / block_size + (rows % block_size > 0); bcols = columns / block_size + (columns % block_size > 0); if (rows % block_size > 0) m_copyOp = true; if (m_copyOp) { m_tmpin = Array<OneD, NekDouble> (brows*block_size, 0.0); m_tmpout = Array<OneD, NekDouble> (brows*block_size, 0.0); } convertCooToBco(brows, bcols, block_size, cooMat, bcoMat); size_t matBytes; switch(storageType) { case eSmvBSR: { // Create zero-based Smv-multiply BSR sparse storage holder DNekSmvBsrMat::SparseStorageSharedPtr sparseStorage = MemoryManager<DNekSmvBsrMat::StorageType>:: AllocateSharedPtr( brows, bcols, block_size, bcoMat, matStorage ); // Create sparse matrix m_smvbsrmatrix = MemoryManager<DNekSmvBsrMat>:: AllocateSharedPtr( sparseStorage ); matBytes = m_smvbsrmatrix->GetMemoryFootprint(); } break; default: NEKERROR(ErrorUtil::efatal,"Unsupported sparse storage type chosen"); } cout << "Global matrix storage type: " << MatrixStorageTypeMap[storageType] << endl; std::cout << "Global matrix memory, bytes = " << matBytes; if (matBytes/(1024*1024) > 0) { std::cout << " ("<< matBytes/(1024*1024) <<" MB)" << std::endl; } else { std::cout << " ("<< matBytes/1024 <<" KB)" << std::endl; } std::cout << "Sparse storage block size = " << block_size << std::endl; }
static DataType& reference(const boost::shared_ptr<DataType>& o) { ASSERTL1(o, "Can't dereference null pointer."); return *o; }
/** * @brief Return the flux vector for the APE equations. * * @param physfield Fields. * @param flux Resulting flux. flux[eq][dir][pt] */ void APE::GetFluxVector( const Array<OneD, Array<OneD, NekDouble> > &physfield, Array<OneD, Array<OneD, Array<OneD, NekDouble> > > &flux) { UpdateBasefield(); int nq = physfield[0].num_elements(); Array<OneD, NekDouble> tmp1(nq); Array<OneD, NekDouble> tmp2(nq); ASSERTL1(flux[0].num_elements() == m_spacedim, "Dimension of flux array and velocity array do not match"); // F_{adv,p',j} = \rho_0 u'_j + p' \bar{u}_j / c^2 for (int j = 0; j < m_spacedim; ++j) { Vmath::Zero(nq, flux[0][j], 1); // construct rho_0 u'_j term Vmath::Vmul(nq, m_basefield[1], 1, physfield[j + 1], 1, flux[0][j], 1); // construct p' \bar{u}_j / c^2 term // c^2 Vmath::Vdiv(nq, m_basefield[0], 1, m_basefield[1], 1, tmp1, 1); Vmath::Smul(nq, m_gamma, tmp1, 1, tmp1, 1); // p' \bar{u}_j / c^2 term Vmath::Vmul(nq, physfield[0], 1, m_basefield[j + 2], 1, tmp2, 1); Vmath::Vdiv(nq, tmp2, 1, tmp1, 1, tmp2, 1); // \rho_0 u'_j + p' \bar{u}_j / c^2 Vmath::Vadd(nq, flux[0][j], 1, tmp2, 1, flux[0][j], 1); } for (int i = 1; i < flux.num_elements(); ++i) { ASSERTL1(flux[i].num_elements() == m_spacedim, "Dimension of flux array and velocity array do not match"); // F_{adv,u'_i,j} = (p'/ \bar{rho} + \bar{u}_k u'_k) \delta_{ij} for (int j = 0; j < m_spacedim; ++j) { Vmath::Zero(nq, flux[i][j], 1); if (i - 1 == j) { // contruct p'/ \bar{rho} term Vmath::Vdiv(nq, physfield[0], 1, m_basefield[1], 1, flux[i][j], 1); // construct \bar{u}_k u'_k term Vmath::Zero(nq, tmp1, 1); for (int k = 0; k < m_spacedim; ++k) { Vmath::Vvtvp(nq, physfield[k + 1], 1, m_basefield[k + 2], 1, tmp1, 1, tmp1, 1); } // add terms Vmath::Vadd(nq, flux[i][j], 1, tmp1, 1, flux[i][j], 1); } } } }
/** * @brief Return the flux vector for the linear advection equation using * the dealiasing technique. * * @param i Component of the flux vector to calculate. * @param physfield Fields. * @param flux Resulting flux. */ void UnsteadyAdvection::GetFluxVectorDeAlias( const Array<OneD, Array<OneD, NekDouble> > &physfield, Array<OneD, Array<OneD, Array<OneD, NekDouble> > > &flux) { ASSERTL1(flux[0].num_elements() == m_velocity.num_elements(), "Dimension of flux array and velocity array do not match"); int i, j; int nq = physfield[0].num_elements(); int nVariables = physfield.num_elements(); // Factor to rescale 1d points in dealiasing NekDouble OneDptscale = 2; Array<OneD, Array<OneD, NekDouble> > advVel_plane(m_velocity.num_elements()); // Get number of points to dealias a cubic non-linearity nq = m_fields[0]->Get1DScaledTotPoints(OneDptscale); // Initialisation of higher-space variables Array<OneD, Array<OneD, NekDouble> >physfieldInterp(nVariables); Array<OneD, Array<OneD, NekDouble> >velocityInterp(m_expdim); Array<OneD, Array<OneD, Array<OneD, NekDouble> > >fluxInterp(nVariables); // Interpolation to higher space of physfield for (i = 0; i < nVariables; ++i) { physfieldInterp[i] = Array<OneD, NekDouble>(nq); fluxInterp[i] = Array<OneD, Array<OneD, NekDouble> >(m_expdim); for (j = 0; j < m_expdim; ++j) { fluxInterp[i][j] = Array<OneD, NekDouble>(nq); } m_fields[0]->PhysInterp1DScaled( OneDptscale, physfield[i], physfieldInterp[i]); } // Interpolation to higher space of velocity for (j = 0; j < m_expdim; ++j) { velocityInterp[j] = Array<OneD, NekDouble>(nq); m_fields[0]->PhysInterp1DScaled( OneDptscale, m_velocity[j], velocityInterp[j]); } // Evaluation of flux vector in the higher space for (i = 0; i < flux.num_elements(); ++i) { for (j = 0; j < flux[0].num_elements(); ++j) { Vmath::Vmul(nq, physfieldInterp[i], 1, velocityInterp[j], 1, fluxInterp[i][j], 1); } } // Galerkin project solution back to original space for (i = 0; i < nVariables; ++i) { for (j = 0; j < m_spacedim; ++j) { m_fields[0]->PhysGalerkinProjection1DScaled( OneDptscale, fluxInterp[i][j], flux[i][j]); } } }
void PreconditionerLinear::v_DoPreconditionerWithNonVertOutput( const Array<OneD, NekDouble>& pInput, Array<OneD, NekDouble>& pOutput, const Array<OneD, NekDouble>& pNonVertOutput, Array<OneD, NekDouble>& pVertForce) { GlobalSysSolnType solvertype=m_locToGloMap->GetGlobalSysSolnType(); switch(solvertype) { case MultiRegions::eIterativeStaticCond: { int i,val; int nloc = m_vertLocToGloMap->GetNumLocalCoeffs(); int nglo = m_vertLocToGloMap->GetNumGlobalCoeffs(); // mapping from full space to vertices Array<OneD, int> LocToGloBnd = m_vertLocToGloMap->GetLocalToGlobalBndMap(); // Global to local for linear solver (different from above) Array<OneD, int> LocToGlo = m_vertLocToGloMap->GetLocalToGlobalMap(); // number of Dir coeffs in from full problem int nDirFull = m_locToGloMap->GetNumGlobalDirBndCoeffs(); Array<OneD,NekDouble> In(nglo,0.0); Array<OneD,NekDouble> Out(nglo,0.0); // Gather rhs for(i = 0; i < nloc; ++i) { val = LocToGloBnd[i]; if(val >= nDirFull) { In[LocToGlo[i]] = pInput[val-nDirFull]; } } // Do solve without enforcing any boundary conditions. m_vertLinsys->SolveLinearSystem( m_vertLocToGloMap->GetNumGlobalCoeffs(), In,Out,m_vertLocToGloMap, m_vertLocToGloMap->GetNumGlobalDirBndCoeffs()); if(pNonVertOutput != NullNekDouble1DArray) { ASSERTL1(pNonVertOutput.num_elements() >= pOutput.num_elements(),"Non Vert output is not of sufficient length"); Vmath::Vcopy(pOutput.num_elements(),pNonVertOutput,1,pOutput,1); } else { //Copy input to output as a unit preconditioner on //any other value Vmath::Vcopy(pInput.num_elements(),pInput,1,pOutput,1); } if(pVertForce != NullNekDouble1DArray) { Vmath::Zero(pVertForce.num_elements(),pVertForce,1); // Scatter back soln from linear solve for(i = 0; i < nloc; ++i) { val = LocToGloBnd[i]; if(val >= nDirFull) { pOutput[val-nDirFull] = Out[LocToGlo[i]]; // copy vertex forcing into this vector pVertForce[val-nDirFull] = In[LocToGlo[i]]; } } } else { // Scatter back soln from linear solve for(i = 0; i < nloc; ++i) { val = LocToGloBnd[i]; if(val >= nDirFull) { pOutput[val-nDirFull] = Out[LocToGlo[i]]; } } } } break; default: ASSERTL0(0,"Unsupported solver type"); break; } }
static DataType& reference(DataType* o) { ASSERTL1(o != 0, "Can't dereference null pointer."); return *o; }