46 namespace MultiRegions
51 m_lhom(1), m_homogeneous1DBlockMat(
60 const bool useFFT,
const bool dealiasing)
61 :
ExpList(type), m_useFFT(useFFT), m_lhom(lhom),
62 m_homogeneous1DBlockMat(
64 m_dealiasing(dealiasing)
67 m_comm = pSession->GetComm();
70 "Homogeneous Basis is a null basis");
75 ?
m_comm->GetColumnComm()->GetColumnComm()
79 "HomModesZ should be a multiple of npz.");
90 "HomModesZ/npz should be an even integer.");
118 ASSERTL0(
false,
"Dealiasing available just in combination "
128 :
ExpList(In, false), m_transposition(In.m_transposition),
129 m_StripZcomm(In.m_StripZcomm), m_useFFT(In.m_useFFT), m_FFT(In.m_FFT),
130 m_tmpIN(In.m_tmpIN), m_tmpOUT(In.m_tmpOUT),
131 m_homogeneousBasis(In.m_homogeneousBasis), m_lhom(In.m_lhom),
132 m_homogeneous1DBlockMat(In.m_homogeneous1DBlockMat),
133 m_dealiasing(In.m_dealiasing), m_padsize(In.m_padsize)
141 :
ExpList(In, eIDs, false, ImpType), m_transposition(In.m_transposition),
142 m_useFFT(In.m_useFFT), m_FFT(In.m_FFT), m_tmpIN(In.m_tmpIN),
143 m_tmpOUT(In.m_tmpOUT), m_homogeneousBasis(In.m_homogeneousBasis),
145 m_homogeneous1DBlockMat(
147 m_dealiasing(In.m_dealiasing), m_padsize(In.m_padsize)
204 int num_points_per_plane = num_dofs /
m_planes.size();
206 if (!
m_session->DefinesSolverInfo(
"HomoStrip"))
208 num_proc =
m_comm->GetColumnComm()->GetSize();
214 int num_dfts_per_proc =
215 num_points_per_plane / num_proc + (num_points_per_plane % num_proc > 0);
235 for (
int i = 0; i < num_dfts_per_proc; i++)
239 Vmath::Vcopy(N, &(ShufV1[i * N]), 1, &(ShufV1_PAD_coef[0]), 1);
240 Vmath::Vcopy(N, &(ShufV2[i * N]), 1, &(ShufV2_PAD_coef[0]), 1);
243 m_FFT_deal->FFTBwdTrans(ShufV1_PAD_coef, ShufV1_PAD_phys);
244 m_FFT_deal->FFTBwdTrans(ShufV2_PAD_coef, ShufV2_PAD_phys);
249 ShufV1V2_PAD_phys, 1);
253 m_FFT_deal->FFTFwdTrans(ShufV1V2_PAD_phys, ShufV1V2_PAD_coef);
257 Vmath::Vcopy(N, &(ShufV1V2_PAD_coef[0]), 1, &(ShufV1V2[i * N]), 1);
288 int ndim = inarray1.size();
289 ASSERTL1(inarray2.size() % ndim == 0,
290 "Wrong dimensions for DealiasedDotProd.");
291 int nvec = inarray2.size() / ndim;
296 int num_points_per_plane = num_dofs /
m_planes.size();
298 if (!
m_session->DefinesSolverInfo(
"HomoStrip"))
300 num_proc =
m_comm->GetColumnComm()->GetSize();
306 int num_dfts_per_proc =
307 num_points_per_plane / num_proc + (num_points_per_plane % num_proc > 0);
314 for (
int i = 0; i < ndim; i++)
318 for (
int i = 0; i < ndim * nvec; i++)
325 for (
int i = 0; i < ndim; i++)
330 for (
int i = 0; i < ndim * nvec; i++)
341 for (
int i = 0; i < ndim; i++)
350 for (
int i = 0; i < ndim * nvec; i++)
359 for (
int i = 0; i < nvec; i++)
364 for (
int i = 0; i < ndim; i++)
369 for (
int i = 0; i < ndim * nvec; i++)
376 for (
int i = 0; i < num_dfts_per_proc; i++)
378 for (
int j = 0; j < ndim; j++)
382 Vmath::Vcopy(N, &(ShufV1[j][i * N]), 1, &(ShufV1_PAD_coef[0]), 1);
384 m_FFT_deal->FFTBwdTrans(ShufV1_PAD_coef, ShufV1_PAD_phys[j]);
386 for (
int j = 0; j < ndim * nvec; j++)
388 Vmath::Vcopy(N, &(ShufV2[j][i * N]), 1, &(ShufV2_PAD_coef[0]), 1);
389 m_FFT_deal->FFTBwdTrans(ShufV2_PAD_coef, ShufV2_PAD_phys[j]);
394 for (
int j = 0; j < nvec; j++)
397 for (
int k = 0; k < ndim; k++)
400 ShufV2_PAD_phys[j * ndim + k], 1,
401 ShufV1V2_PAD_phys, 1, ShufV1V2_PAD_phys, 1);
405 m_FFT_deal->FFTFwdTrans(ShufV1V2_PAD_phys, ShufV1V2_PAD_coef);
408 Vmath::Vcopy(N, &(ShufV1V2_PAD_coef[0]), 1, &(ShufV1V2[j][i * N]),
416 for (
int j = 0; j < nvec; j++)
425 for (
int j = 0; j < nvec; j++)
441 int cnt = 0, cnt1 = 0;
444 for (
int n = 0; n <
m_planes.size(); ++n)
446 m_planes[n]->FwdTrans(inarray + cnt, tmparray = outarray + cnt1);
464 int cnt = 0, cnt1 = 0;
468 for (
int n = 0; n <
m_planes.size(); ++n)
470 m_planes[n]->FwdTransLocalElmt(inarray + cnt,
471 tmparray = outarray + cnt1);
488 int cnt = 0, cnt1 = 0;
492 for (
int n = 0; n <
m_planes.size(); ++n)
494 m_planes[n]->FwdTransBndConstrained(inarray + cnt,
495 tmparray = outarray + cnt1);
512 int cnt = 0, cnt1 = 0;
515 for (
int n = 0; n <
m_planes.size(); ++n)
517 m_planes[n]->BwdTrans(inarray + cnt, tmparray = outarray + cnt1);
519 cnt1 +=
m_planes[n]->GetTotPoints();
535 "Inarray is not of sufficient length");
536 int cnt = 0, cnt1 = 0;
549 for (
int n = 0; n <
m_planes.size(); ++n)
551 m_planes[n]->IProductWRTBase(tmpIn + cnt, tmparray = outarray + cnt1);
568 int num_points_per_plane = num_dofs /
m_planes.size();
569 int num_dfts_per_proc;
570 if (!
m_session->DefinesSolverInfo(
"HomoStrip"))
572 int nP =
m_comm->GetColumnComm()->GetSize();
574 num_points_per_plane / nP + (num_points_per_plane % nP > 0);
580 num_points_per_plane / nP + (num_points_per_plane % nP > 0);
596 inarray, 1, fft_in, 1);
601 for (
int i = 0; i < num_dfts_per_proc; i++)
611 for (
int i = 0; i < num_dfts_per_proc; i++)
628 fft_out, 1, outarray, 1);
658 int nrows = blkmat->GetRows();
659 int ncols = blkmat->GetColumns();
679 out = (*blkmat) * in;
705 return matrixIter->second;
715 int num_trans_per_proc = 0;
724 n_exp =
m_planes[0]->GetTotPoints();
727 num_trans_per_proc = n_exp /
m_comm->GetColumnComm()->GetSize() +
728 (n_exp %
m_comm->GetColumnComm()->GetSize() > 0);
798 for (
int i = 0; i < num_trans_per_proc; ++i)
800 BlkMatrix->SetBlock(i, i, loc_mat);
809 std::vector<LibUtilities::FieldDefinitionsSharedPtr> returnval;
814 std::vector<NekDouble> HomoLen;
815 HomoLen.push_back(
m_lhom);
817 std::vector<unsigned int> StripsIDs;
820 m_session->MatchSolverInfo(
"HomoStrip",
"True", strips,
false);
826 std::vector<unsigned int> PlanesIDs;
836 for (
int i = 0; i <
m_planes.size(); i++)
841 m_planes[0]->GeneralGetFieldDefinitions(returnval, 1, HomoBasis, HomoLen,
842 strips, StripsIDs, PlanesIDs);
847 std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef)
852 std::vector<NekDouble> HomoLen;
853 HomoLen.push_back(
m_lhom);
855 std::vector<unsigned int> StripsIDs;
858 m_session->MatchSolverInfo(
"HomoStrip",
"True", strips,
false);
864 std::vector<unsigned int> PlanesIDs;
872 for (
int i = 0; i <
m_planes.size(); i++)
878 m_planes[0]->GeneralGetFieldDefinitions(fielddef, 1, HomoBasis, HomoLen,
879 strips, StripsIDs, PlanesIDs);
893 int ncoeffs_per_plane =
m_planes[0]->GetNcoeffs();
899 for (i = 0; i <
m_planes[0]->GetExpSize(); ++i)
905 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
908 int datalen = (*m_exp)[eid]->GetNcoeffs();
910 for (n = 0; n <
m_planes.size(); ++n)
922 std::vector<NekDouble> &fielddata)
930 std::vector<NekDouble> &fielddata, std::string &field,
936 int datalen = fielddata.size() / fielddef->m_fields.size();
937 std::vector<unsigned int> fieldDefHomoZids;
940 for (i = 0; i < fielddef->m_fields.size(); ++i)
942 if (fielddef->m_fields[i] == field)
949 if (i == fielddef->m_fields.size())
951 cout <<
"Field " << field <<
"not found in data file. " << endl;
956 int modes_offset = 0;
957 int planes_offset = 0;
962 if (zIdToPlane.size() == 0)
968 for (i = 0; i <
m_planes.size(); ++i)
976 for (i = 0; i <
m_planes[0]->GetExpSize(); ++i)
982 if (fielddef->m_numHomogeneousDir)
984 nzmodes = fielddef->m_homogeneousZIDs.size();
985 fieldDefHomoZids = fielddef->m_homogeneousZIDs;
990 fieldDefHomoZids.push_back(0);
994 int ncoeffs_per_plane =
m_planes[0]->GetNcoeffs();
996 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
998 if (fielddef->m_uniOrder ==
true)
1004 fielddef->m_shapeType, fielddef->m_numModes, modes_offset);
1012 offset += datalen * nzmodes;
1014 (*m_exp)[0]->GetNumBases() + fielddef->m_numHomogeneousDir;
1018 int eid = it->second;
1019 bool sameBasis =
true;
1020 for (
int j = 0; j < fielddef->m_basis.size() - 1; ++j)
1022 if (fielddef->m_basis[j] != (*
m_exp)[eid]->GetBasisType(j))
1029 for (n = 0; n < nzmodes; ++n, offset += datalen)
1032 it = zIdToPlane.find(fieldDefHomoZids[n]);
1035 if (it == zIdToPlane.end())
1040 planes_offset = it->second;
1045 planes_offset * ncoeffs_per_plane],
1050 (*m_exp)[eid]->ExtractDataToCoeffs(
1051 &fielddata[offset], fielddef->m_numModes, modes_offset,
1053 planes_offset * ncoeffs_per_plane],
1058 (*m_exp)[0]->GetNumBases() + fielddef->m_numHomogeneousDir;
1065 const std::shared_ptr<ExpList> &fromExpList,
1070 int fromNcoeffs_per_plane = fromExpList->GetPlane(0)->GetNcoeffs();
1071 int toNcoeffs_per_plane =
m_planes[0]->GetNcoeffs();
1074 for (i = 0; i <
m_planes.size(); ++i)
1076 m_planes[i]->ExtractCoeffsToCoeffs(
1077 fromExpList->GetPlane(i),
1078 fromcoeffs_tmp = fromCoeffs + fromNcoeffs_per_plane * i,
1079 tocoeffs_tmp = toCoeffs + toNcoeffs_per_plane * i);
1084 int expansion, std::string var)
1089 m_planes[0]->WriteVtkPieceData(outfile, expansion, var);
1094 int nq = (*m_exp)[expansion]->GetTotPoints();
1095 int npoints_per_plane =
m_planes[0]->GetTotPoints();
1098 int outputExtraPlane = 0;
1104 outputExtraPlane = 1;
1115 int fromRank = (rank + 1) % size;
1116 int toRank = (rank == 0) ? size - 1 : rank - 1;
1121 m_StripZcomm->SendRecv(toRank, send, fromRank, extraPlane);
1126 outfile <<
" <DataArray type=\"Float64\" Name=\"" << var <<
"\">"
1129 for (
int n = 0; n <
m_planes.size(); ++n)
1134 for (i = 0; i < nq; ++i)
1140 if (outputExtraPlane)
1142 for (i = 0; i < nq; ++i)
1151 outfile <<
" </DataArray>" << endl;
1161 cnt1 =
m_planes[0]->Get1DScaledTotPoints(scale);
1164 "size of outarray does not match internal estimage");
1166 for (
int i = 0; i <
m_planes.size(); i++)
1169 m_planes[i]->PhysInterp1DScaled(scale, inarray + i * cnt,
1170 tmparray = outarray + i * cnt1);
1180 cnt =
m_planes[0]->Get1DScaledTotPoints(scale);
1181 cnt1 =
m_planes[0]->GetTotPoints();
1183 "size of outarray does not match internal estimage");
1185 for (
int i = 0; i <
m_planes.size(); i++)
1187 m_planes[i]->PhysGalerkinProjection1DScaled(
1188 scale, inarray + i * cnt, tmparray = outarray + i * cnt1);
1207 for (
int i = 0; i <
m_planes.size(); i++)
1209 m_planes[i]->PhysDeriv(inarray + i * nP_pts, tmp2 = out_d0 + i * nP_pts,
1210 tmp3 = out_d1 + i * nP_pts);
1225 temparray = inarray;
1254 for (
int i = 0; i <
m_planes.size(); i++)
1260 tmp2 = outarray + (i -
int(
sign)) * nP_pts, 1);
1277 if (!
m_session->DefinesSolverInfo(
"HomoStrip"))
1280 "Parallelisation in the homogeneous direction "
1281 "implemented just for Fourier basis");
1286 "Parallelisation in the homogeneous direction "
1287 "implemented just for Fourier basis");
1292 ASSERTL0(
false,
"Semi-phyisical time-stepping not "
1293 "implemented yet for non-Fourier "
1303 for (
int i = 0; i < nP_pts; i++)
1306 tmp2 = outarray + i *
m_planes.size());
1329 int dir = (int)edir;
1338 for (
int i = 0; i <
m_planes.size(); i++)
1340 m_planes[i]->PhysDeriv(edir, inarray + i * nP_pts,
1341 tmp2 = out_d + i * nP_pts);
1356 temparray = inarray;
1384 for (
int i = 0; i <
m_planes.size(); i++)
1390 tmp2 = outarray + (i -
int(
sign)) * nP_pts, 1);
1406 if (!
m_session->DefinesSolverInfo(
"HomoStrip"))
1409 "Parallelisation in the homogeneous direction "
1410 "implemented just for Fourier basis");
1415 "Parallelisation in the homogeneous direction "
1416 "implemented just for Fourier basis");
1421 ASSERTL0(
false,
"Semi-phyisical time-stepping not implemented "
1422 "yet for non-Fourier basis");
1431 for (
int i = 0; i < nP_pts; i++)
1434 tmp2 = outarray + i *
m_planes.size());
1488 for (i = 0; i < (*m_exp).size(); ++i)
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
#define sign(a, b)
return the sign(b)*a
Describes the specification for a Basis.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2)
virtual std::vector< LibUtilities::FieldDefinitionsSharedPtr > v_GetFieldDefinitions(void) override
virtual void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Array< OneD, NekDouble > m_tmpIN
virtual LibUtilities::TranspositionSharedPtr v_GetTransposition(void) override
NekDouble m_lhom
Width of homogeneous direction.
LibUtilities::TranspositionSharedPtr m_transposition
virtual void v_ExtractDataToCoeffs(LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata, std::string &field, Array< OneD, NekDouble > &coeffs, std::unordered_map< int, int > zIdToPlane) override
Extract data from raw field data into expansion list.
virtual void v_WriteVtkPieceData(std::ostream &outfile, int expansion, std::string var) override
virtual void v_FwdTransLocalElmt(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Array< OneD, ExpListSharedPtr > m_planes
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
LibUtilities::CommSharedPtr m_StripZcomm
Homo1DBlockMatrixMapShPtr m_homogeneous1DBlockMat
virtual void v_AppendFieldData(LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata) override
virtual void v_FwdTransBndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
LibUtilities::BasisSharedPtr m_homogeneousBasis
Definition of the total number of degrees of freedom and quadrature points. Sets up the storage for m...
virtual void v_PhysGalerkinProjection1DScaled(const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
LibUtilities::NektarFFTSharedPtr m_FFT_deal
virtual void v_HomogeneousFwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true) override
virtual void v_ExtractCoeffsToCoeffs(const std::shared_ptr< ExpList > &fromExpList, const Array< OneD, const NekDouble > &fromCoeffs, Array< OneD, NekDouble > &toCoeffs) override
Array< OneD, NekDouble > m_tmpOUT
virtual NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray) override
virtual void v_PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2) override
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
LibUtilities::NektarFFTSharedPtr m_FFT
virtual ~ExpListHomogeneous1D()
Destructor.
virtual NekDouble v_GetHomoLen(void) override
void Homogeneous1DTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool IsForwards, bool Shuff=true, bool UnShuff=true)
virtual void v_HomogeneousBwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true) override
virtual void v_SetHomoLen(const NekDouble lhom) override
DNekBlkMatSharedPtr GenHomogeneous1DBlockMatrix(Homogeneous1DMatType mattype) const
DNekBlkMatSharedPtr GetHomogeneous1DBlockMatrix(Homogeneous1DMatType mattype) const
virtual Array< OneD, const unsigned int > v_GetZIDs(void) override
virtual void v_DealiasedProd(const int num_dofs, const Array< OneD, NekDouble > &inarray1, const Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray) override
bool m_useFFT
FFT variables.
virtual void v_PhysInterp1DScaled(const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
ExpListHomogeneous1D(const ExpansionType type)
Default constructor.
virtual void v_DealiasedDotProd(const int num_dofs, const Array< OneD, Array< OneD, NekDouble >> &inarray1, const Array< OneD, Array< OneD, NekDouble >> &inarray2, Array< OneD, Array< OneD, NekDouble >> &outarray) override
Base class for all multi-elemental spectral/hp expansions.
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
int GetNcoeffs(void) const
Returns the total number of local degrees of freedom .
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
LibUtilities::CommSharedPtr m_comm
Communicator.
std::shared_ptr< LocalRegions::ExpansionVector > m_exp
The list of local expansions.
void HomogeneousBwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
std::unordered_map< int, int > m_elmtToExpId
Mapping from geometry ID of element to index inside m_exp.
LibUtilities::SessionReaderSharedPtr m_session
Session.
Array< OneD, int > m_phys_offset
Offset of elemental data into the array m_phys.
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
void HomogeneousFwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
Class representing a segment element in reference space All interface of this class sits in StdExpans...
static BasisSharedPtr NullBasisSharedPtr
BasisManagerT & BasisManager(void)
NektarFFTFactory & GetNektarFFTFactory()
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
int GetNumberOfCoefficients(ShapeType shape, std::vector< unsigned int > &modes, int offset=0)
std::shared_ptr< Transposition > TranspositionSharedPtr
@ beta
Gauss Radau pinned at x=-1,.
@ eFourierEvenlySpaced
1D Evenly-spaced points using Fourier Fit
@ eFourierSingleMode
Fourier ModifiedExpansion with just the first mode .
@ eFourierHalfModeIm
Fourier Modified expansions with just the imaginary part of the first mode .
@ eFourierHalfModeRe
Fourier Modified expansions with just the real part of the first mode .
@ eFourier
Fourier Expansion .
std::map< Homogeneous1DMatType, DNekBlkMatSharedPtr > Homo1DBlockMatrixMap
A map between homo matrix keys and their associated block matrices.
static const NekDouble kNekZeroTol
The above copyright notice and this permission notice shall be included.
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< DNekMat > DNekMatSharedPtr
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Zero(int n, T *x, const int incx)
Zero vector.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)