Nektar++
Advection.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: Advection.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Abstract base class for advection.
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <boost/core/ignore_unused.hpp>
36 
38 
39 namespace Nektar
40 {
41 namespace SolverUtils
42 {
43 
44 /**
45  * @returns The advection factory.
46  */
48 {
49  static AdvectionFactory instance;
50  return instance;
51 }
52 
53 
54 /**
55  * @param pSession Session configuration data.
56  * @param pFields Array of ExpList objects.
57  */
61 {
62  v_InitObject(pSession, pFields);
63 }
64 
65 
66 /**
67  * @param nConvectiveFields Number of velocity components.
68  * @param pFields Expansion lists for scalar fields.
69  * @param pAdvVel Advection velocity.
70  * @param pInarray Scalar data to advect.
71  * @param pOutarray Advected scalar data.
72  * @param pTime Simulation time.
73  */
75  const int nConvectiveFields,
77  const Array<OneD, Array<OneD, NekDouble> > &pAdvVel,
78  const Array<OneD, Array<OneD, NekDouble> > &pInarray,
79  Array<OneD, Array<OneD, NekDouble> > &pOutarray,
80  const NekDouble &pTime,
81  const Array<OneD, Array<OneD, NekDouble> > &pFwd,
82  const Array<OneD, Array<OneD, NekDouble> > &pBwd)
83 {
84  v_Advect(nConvectiveFields, pFields, pAdvVel, pInarray,
85  pOutarray, pTime, pFwd, pBwd);
86 }
87 
88 template<typename DataType, typename TypeNekBlkMatSharedPtr>
90  const int nConvectiveFields,
91  const int nSpaceDim,
93  const Array<OneD, TypeNekBlkMatSharedPtr> &TracePntJacCons,
95  const Array<OneD, TypeNekBlkMatSharedPtr> &TracePntJacGrad,
96  const Array<OneD, Array<OneD, DataType> > &TracePntJacGradSign)
97 {
98  MultiRegions::ExpListSharedPtr tracelist = pFields[0]->GetTrace();
99  std::shared_ptr<LocalRegions::ExpansionVector> traceExp
100  = tracelist->GetExp();
101  int ntotTrac = (*traceExp).size();
102  int nTracePnts = tracelist->GetTotPoints();
103  int nTracPnt,nTracCoef;
104 
105  DNekMatSharedPtr tmp2Add;
106  Array<OneD, DataType> MatData0;
107  Array<OneD, NekDouble> MatData1;
108  Array<OneD, NekDouble> MatData2;
109 
110  Array<OneD, DNekMatSharedPtr> TraceJacFwd(ntotTrac);
111  Array<OneD, DNekMatSharedPtr> TraceJacBwd(ntotTrac);
112 
113  for(int nelmt = 0; nelmt < ntotTrac; nelmt++)
114  {
115  nTracCoef = (*traceExp)[nelmt]->GetNcoeffs();
116  nTracPnt = (*traceExp)[nelmt]->GetTotPoints();
117  TraceJacFwd[nelmt] =MemoryManager<DNekMat>
118  ::AllocateSharedPtr(nTracCoef, nTracPnt,0.0);
119  TraceJacBwd[nelmt] =MemoryManager<DNekMat>
120  ::AllocateSharedPtr(nTracCoef, nTracPnt,0.0);
121  }
122 
123  std::shared_ptr<LocalRegions::ExpansionVector> fieldExp
124  = pFields[0]->GetExp();
125  int nTotElmt = (*fieldExp).size();
126  int nElmtPnt,nElmtCoef;
127 
128  Array<OneD, DNekMatSharedPtr> ElmtJacQuad(nTotElmt);
129  Array<OneD, DNekMatSharedPtr> ElmtJacCoef(nTotElmt);
130 
131  Array<OneD, NekDouble> SymmMatData;
132 
133  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
134  {
135  nElmtCoef = (*fieldExp)[nelmt]->GetNcoeffs();
136  nElmtPnt = (*fieldExp)[nelmt]->GetTotPoints();
137 
138  ElmtJacQuad[nelmt] =MemoryManager<DNekMat>
139  ::AllocateSharedPtr(nElmtCoef, nElmtPnt,0.0);
140  ElmtJacCoef[nelmt] =MemoryManager<DNekMat>
141  ::AllocateSharedPtr(nElmtCoef, nElmtCoef,0.0);
142  }
143 
144  bool TracePntJacGradflag = true;
145 
146  Array<OneD, Array<OneD, DataType> > TraceJacConsSign(2);
147  for(int i = 0; i < 2; i++)
148  {
149  TraceJacConsSign[i] = Array<OneD, DataType>(nTracePnts,1.0);
150  }
151 
152  if(0==TracePntJacGrad.size())
153  {
154  TracePntJacGradflag = false;
155  }
156 
157  for(int m = 0; m < nConvectiveFields; m++)
158  {
159  for(int n = 0; n < nConvectiveFields; n++)
160  {
161  // ElmtJacCons to set 0
162  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
163  {
164  (*ElmtJacCoef[nelmt]) = 0.0;
165  (*ElmtJacQuad[nelmt]) = 0.0;
166  }
167 
168  if(TracePntJacGradflag)
169  {
170  //only BJac is stored here because BJac = - FJac
171  for(int ndir = 0; ndir < nSpaceDim; ndir++)
172  {
173  // ElmtJacGrad to set 0
174  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
175  {
176  (*ElmtJacQuad[nelmt]) = 0.0;
177  }
178  int ngrad = n*nSpaceDim+ndir;
179 
180  CalcJacobTraceInteg(pFields, m,ngrad, TracePntJacGrad,
181  TracePntJacGradSign, TraceJacFwd, TraceJacBwd);
182  pFields[0]->AddTraceJacToElmtJac(TraceJacFwd, TraceJacBwd,
183  ElmtJacQuad);
184  // cost can be lower down by doing 3 directions together
185  pFields[0]->AddRightIPTPhysDerivBase(ndir, ElmtJacQuad,
186  ElmtJacCoef);
187  }
188  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
189  {
190  nElmtCoef = (*fieldExp)[nelmt]->GetNcoeffs();
191  if(SymmMatData.size()<nElmtCoef)
192  {
193  SymmMatData =
194  Array<OneD, NekDouble> (nElmtCoef*nElmtCoef);
195  }
196  MatData1 = ElmtJacCoef[nelmt]->GetPtr();
197  for(int i=0;i<nElmtCoef;i++)
198  {
199  Vmath::Vcopy(nElmtCoef, &MatData1[i*nElmtCoef], 1,
200  &SymmMatData[i], nElmtCoef);
201  }
202  Vmath::Vadd(nElmtCoef*nElmtCoef, SymmMatData, 1,
203  MatData1, 1, MatData1, 1);
204  }
205  }
206 
207  CalcJacobTraceInteg(pFields, m, n, TracePntJacCons,
208  TraceJacConsSign, TraceJacFwd, TraceJacBwd);
209 
210  pFields[0]->AddTraceJacToElmtJac(TraceJacFwd, TraceJacBwd,
211  ElmtJacQuad);
212  //Memory can be save to explore reusing ElmtJacQuad as output
213  pFields[0]->AddRightIPTBaseMatrix(ElmtJacQuad, ElmtJacCoef);
214 
215  // add ElmtJacCons to gmtxarray[m][n]
216  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
217  {
218  tmp2Add = ElmtJacCoef[nelmt];
219  MatData0 = gmtxarray[m][n]->GetBlock(nelmt,nelmt)->GetPtr();
220  MatData1 = tmp2Add->GetPtr();
221  for(int i=0;i<MatData0.size();i++)
222  {
223  MatData0[i] += DataType(MatData1[i]);
224  }
225  }
226  }
227  }
228 }
229 
231  const int nConvectiveFields,
232  const int nSpaceDim,
234  const Array<OneD, DNekBlkMatSharedPtr> &TracePntJacCons,
236  const Array<OneD, DNekBlkMatSharedPtr> &TracePntJacGrad,
237  const Array<OneD, Array<OneD, NekDouble> > &TracePntJacGradSign);
239  const int nConvectiveFields,
240  const int nSpaceDim,
242  const Array<OneD, SNekBlkMatSharedPtr> &TracePntJacCons,
244  const Array<OneD, SNekBlkMatSharedPtr> &TracePntJacGrad,
245  const Array<OneD, Array<OneD, NekSingle> > &TracePntJacGradSign);
246 
247 
248 // TODO: To change it into one by one
249 template<typename DataType, typename TypeNekBlkMatSharedPtr>
252  const int m,
253  const int n,
255  const Array<OneD, const Array<OneD, DataType> > & PntJacSign,
256  Array<OneD, DNekMatSharedPtr> & TraceJacFwd,
257  Array<OneD, DNekMatSharedPtr> & TraceJacBwd)
258 {
259  MultiRegions::ExpListSharedPtr tracelist = pFields[0]->GetTrace();
260  std::shared_ptr<LocalRegions::ExpansionVector> traceExp =
261  tracelist->GetExp();
262  int ntotTrac = (*traceExp).size();
263  int nTracPnt,noffset,pntoffset;
264 
265  Array<OneD, int > tracepnts(ntotTrac);
266  Array<OneD, Array<OneD, NekDouble> > JacFwd(ntotTrac);
267  Array<OneD, Array<OneD, NekDouble> > JacBwd(ntotTrac);
268 
269  for(int nelmt = 0; nelmt < ntotTrac; nelmt++)
270  {
271  nTracPnt = (*traceExp)[nelmt]->GetTotPoints();
272  tracepnts[nelmt] = nTracPnt;
273 
274  JacFwd[nelmt] =Array<OneD, NekDouble>(nTracPnt,0.0);
275  JacBwd[nelmt] =Array<OneD, NekDouble>(nTracPnt,0.0);
276  }
277 
278  // DNekMatSharedPtr FtmpMat,BtmpMat;
279  DataType ftmp,btmp;
280  for(int nelmt = 0; nelmt < ntotTrac; nelmt++)
281  {
282  nTracPnt = tracepnts[nelmt];
283  noffset = tracelist->GetPhys_Offset(nelmt);
284  for(int npnt = 0; npnt < nTracPnt; npnt++)
285  {
286  pntoffset = noffset+npnt;
287  ftmp = (*PntJac[0]->GetBlock(pntoffset,pntoffset))(m,n);
288  JacFwd[nelmt][npnt] = NekDouble(PntJacSign[0][pntoffset]*ftmp);
289 
290  btmp = (*PntJac[1]->GetBlock(pntoffset,pntoffset))(m,n);
291  JacBwd[nelmt][npnt] = NekDouble(PntJacSign[1][pntoffset]*btmp);
292  }
293  }
294  tracelist->GetDiagMatIpwrtBase(JacFwd,TraceJacFwd);
295  tracelist->GetDiagMatIpwrtBase(JacBwd,TraceJacBwd);
296 }
297 
298 
300  const int nConvectiveFields,
302  const Array<OneD, Array<OneD, NekDouble>> &pAdvVel,
303  const Array<OneD, Array<OneD, NekDouble>> &pInarray,
304  TensorOfArray3D<NekDouble> &pVolumeFlux,
305  const NekDouble &pTime)
306 {
307  boost::ignore_unused(nConvectiveFields, pFields, pAdvVel, pInarray,
308  pVolumeFlux, pTime);
309  ASSERTL0(false, "Not defined for AdvectVolumeFlux.");
310 }
311 
312 /**
313  * @brief calculate the advection flux in the cell the trace integration
314  */
316  const int nConvectiveFields,
318  const Array<OneD, Array<OneD, NekDouble>> &pAdvVel,
319  const Array<OneD, Array<OneD, NekDouble>> &pInarray,
320  Array<OneD, Array<OneD, NekDouble>> &pTraceFlux,
321  const NekDouble &pTime,
322  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
323  const Array<OneD, Array<OneD, NekDouble>> &pBwd)
324 {
325  boost::ignore_unused(nConvectiveFields, pFields, pAdvVel, pInarray,
326  pTraceFlux, pTime, pFwd, pBwd);
327  ASSERTL0(false, "Not defined for AdvectTraceFlux.");
328 }
329 
330 /**
331  * @brief Similar with Advection::Advect(): calculate the advection flux
332  * The difference is in the outarray:
333  * it is the coefficients of basis for AdvectCoeffs()
334  * it is the physics on quadrature points for Advect()
335  *
336  * @param nConvectiveFields Number of velocity components.
337  * @param pFields Expansion lists for scalar fields.
338  * @param pAdvVel Advection velocity.
339  * @param pInarray Scalar data to advect.
340  * @param pOutarray Advected scalar data.
341  * @param pTime Simulation time.
342  */
344  const int nConvectiveFields,
346  const Array<OneD, Array<OneD, NekDouble> > &pAdvVel,
347  const Array<OneD, Array<OneD, NekDouble> > &pInarray,
348  Array<OneD, Array<OneD, NekDouble> > &pOutarray,
349  const NekDouble &pTime,
350  const Array<OneD, Array<OneD, NekDouble> > &pFwd,
351  const Array<OneD, Array<OneD, NekDouble> > &pBwd)
352 {
353  v_AdvectCoeffs(nConvectiveFields, pFields, pAdvVel, pInarray,
354  pOutarray, pTime, pFwd, pBwd);
355 }
356 
357 /**
358  * This function should be overridden in derived classes to initialise the
359  * specific advection data members. However, this base class function should
360  * be called as the first statement of the overridden function to ensure the
361  * base class is correctly initialised in order.
362  *
363  * @param pSession Session information.
364  * @param pFields Expansion lists for scalar fields.
365  */
369 {
370  m_spaceDim = pFields[0]->GetCoordim(0);
371 
372  if (pSession->DefinesSolverInfo("HOMOGENEOUS"))
373  {
374  std::string HomoStr = pSession->GetSolverInfo("HOMOGENEOUS");
375  if (HomoStr == "HOMOGENEOUS1D" || HomoStr == "Homogeneous1D" ||
376  HomoStr == "1D" || HomoStr == "Homo1D" ||
377  HomoStr == "HOMOGENEOUS2D" || HomoStr == "Homogeneous2D" ||
378  HomoStr == "2D" || HomoStr == "Homo2D")
379  {
380  m_spaceDim++;
381  }
382  else
383  {
385  "Only 1D homogeneous dimension supported.");
386  }
387  }
388 }
389 
390 
391 /**
392  *
393  */
395  const Array<OneD, Array<OneD, NekDouble> > &inarray,
397 {
398  boost::ignore_unused(inarray, fields);
400  "A baseflow is not appropriate for this advection type.");
401 }
402 
404  const int nConvectiveFields,
406  const Array<OneD, Array<OneD, NekDouble> > &advVel,
407  const Array<OneD, Array<OneD, NekDouble> > &inarray,
408  Array<OneD, Array<OneD, NekDouble> > &outarray,
409  const NekDouble &time,
410  const Array<OneD, Array<OneD, NekDouble> > &pFwd,
411  const Array<OneD, Array<OneD, NekDouble> > &pBwd)
412 {
413  boost::ignore_unused(nConvectiveFields, fields, advVel, inarray, outarray,
414  time, pFwd, pBwd);
415  ASSERTL0(false, "v_AdvectCoeffs not defined");
416 }
417 
420  const int &nConvectiveFields,
421  const TensorOfArray5D<NekDouble> &ElmtJacArray,
423  {
424  boost::ignore_unused(pFields,nConvectiveFields,ElmtJacArray,gmtxarray);
425  ASSERTL0(false,"v_AddVolumJacToMat NOT SPECIFIED");
426  return;
427  }
428 
429 }
430 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
#define SOLVER_UTILS_EXPORT
size_type size() const
Returns the array's size.
Provides a generic Factory class.
Definition: NekFactory.hpp:105
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
int m_spaceDim
Storage for space dimension. Used for homogeneous extension.
Definition: Advection.h:225
virtual SOLVER_UTILS_EXPORT void v_AddVolumJacToMat(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const int &nConvectiveFields, const TensorOfArray5D< NekDouble > &ElmtJacArray, Array< OneD, Array< OneD, SNekBlkMatSharedPtr >> &gmtxarray)
Definition: Advection.cpp:418
virtual SOLVER_UTILS_EXPORT void v_AdvectCoeffs(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &advVel, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble &time, const Array< OneD, Array< OneD, NekDouble > > &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble > > &pBwd=NullNekDoubleArrayOfArray)
Definition: Advection.cpp:403
virtual SOLVER_UTILS_EXPORT void v_InitObject(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Initialises the advection object.
Definition: Advection.cpp:366
void CalcJacobTraceInteg(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const int m, const int n, const Array< OneD, const TypeNekBlkMatSharedPtr > &PntJac, const Array< OneD, const Array< OneD, DataType > > &PntJacSign, Array< OneD, DNekMatSharedPtr > &TraceJacFwd, Array< OneD, DNekMatSharedPtr > &TraceJacBwd)
Definition: Advection.cpp:250
virtual SOLVER_UTILS_EXPORT void v_Advect(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &advVel, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble &time, const Array< OneD, Array< OneD, NekDouble > > &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble > > &pBwd=NullNekDoubleArrayOfArray)=0
Advects a vector field.
SOLVER_UTILS_EXPORT void InitObject(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Interface function to initialise the advection object.
Definition: Advection.cpp:58
virtual SOLVER_UTILS_EXPORT void v_SetBaseFlow(const Array< OneD, Array< OneD, NekDouble > > &inarray, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields)
Overrides the base flow used during linearised advection.
Definition: Advection.cpp:394
SOLVER_UTILS_EXPORT void AddTraceJacToMat(const int nConvectiveFields, const int nSpaceDim, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const Array< OneD, TypeNekBlkMatSharedPtr > &TracePntJacCons, Array< OneD, Array< OneD, TypeNekBlkMatSharedPtr > > &gmtxarray, const Array< OneD, TypeNekBlkMatSharedPtr > &TracePntJacGrad, const Array< OneD, Array< OneD, DataType > > &TracePntJacGradSign)
virtual SOLVER_UTILS_EXPORT void v_AdvectTraceFlux(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &advVel, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble >> &pTraceFlux, const NekDouble &time, const Array< OneD, Array< OneD, NekDouble > > &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble > > &pBwd=NullNekDoubleArrayOfArray)
Advects Trace Flux.
Definition: Advection.cpp:315
SOLVER_UTILS_EXPORT void Advect(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &advVel, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble &time, const Array< OneD, Array< OneD, NekDouble > > &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble > > &pBwd=NullNekDoubleArrayOfArray)
Interface function to advect the vector field.
Definition: Advection.cpp:74
virtual SOLVER_UTILS_EXPORT void v_AdvectVolumeFlux(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &advVel, const Array< OneD, Array< OneD, NekDouble > > &inarray, TensorOfArray3D< NekDouble > &pVolumeFlux, const NekDouble &time)
Advects Volume Flux.
Definition: Advection.cpp:299
SOLVER_UTILS_EXPORT void AdvectCoeffs(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &advVel, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble &time, const Array< OneD, Array< OneD, NekDouble > > &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble > > &pBwd=NullNekDoubleArrayOfArray)
Similar with Advection::Advect(): calculate the advection flux The difference is in the outarray: it ...
Definition: Advection.cpp:343
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:47
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
double NekDouble
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:322
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199