Nektar++
SubSteppingExtrapolate.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: SubSteppingExtrapolate.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 SubSteppingExtrapolate.
32//
33///////////////////////////////////////////////////////////////////////////////
34
36
38
39namespace Nektar
40{
41using namespace LibUtilities;
42
43/**
44 * Registers the class with the Factory.
45 */
48 "SubStepping", SubSteppingExtrapolate::create, "SubStepping");
49
54 const SolverUtils::AdvectionSharedPtr advObject)
55 : Extrapolate(pSession, pFields, pPressure, pVel, advObject)
56{
57 m_session->LoadParameter("IO_InfoSteps", m_infosteps, 0);
58 m_session->LoadParameter("SubStepCFL", m_cflSafetyFactor, 0.5);
59 m_session->LoadParameter("MinSubSteps", m_minsubsteps, 1);
60 m_session->LoadParameter("MaxSubSteps", m_maxsubsteps, 100);
61
62 size_t dim = m_fields[0]->GetCoordim(0);
64
65 size_t nTracePts = m_fields[0]->GetTrace()->GetNpoints();
66 for (size_t i = 0; i < dim; ++i)
67 {
69 }
70 m_fields[0]->GetTrace()->GetNormals(m_traceNormals);
71}
72
74{
75}
76
78 const Array<OneD, const Array<OneD, NekDouble>> &fields,
79 const Array<OneD, const Array<OneD, NekDouble>> &N, NekDouble kinvis)
80{
81 boost::ignore_unused(fields, N, kinvis);
82 ASSERTL0(false, "This method should not be called by Substepping routine");
83}
84
86 const LibUtilities::TimeIntegrationSchemeSharedPtr &IntegrationScheme)
87{
88 m_intScheme = IntegrationScheme;
89
90 size_t order = IntegrationScheme->GetOrder();
91
92 // Set to 1 for first step and it will then be increased in
93 // time advance routines
94 if ((IntegrationScheme->GetName() == "Euler" &&
95 IntegrationScheme->GetVariant() == "Backward") ||
96
97 (IntegrationScheme->GetName() == "BDFImplicit" &&
98 (order == 1 || order == 2)))
99 {
100 // Note RK first order SSP is just Forward Euler.
101 std::string vSubStepIntScheme = "RungeKutta";
102 std::string vSubStepIntSchemeVariant = "SSP";
103 int vSubStepIntSchemeOrder = order;
104
105 if (m_session->DefinesSolverInfo("SubStepIntScheme"))
106 {
107 vSubStepIntScheme = m_session->GetSolverInfo("SubStepIntScheme");
108 vSubStepIntSchemeVariant = "";
109 vSubStepIntSchemeOrder = order;
110 }
111
114 vSubStepIntScheme, vSubStepIntSchemeVariant,
115 vSubStepIntSchemeOrder, std::vector<NekDouble>());
116
117 size_t nvel = m_velocity.size();
118 size_t ndim = order + 1;
119
120 // Fields for linear/quadratic interpolation
122 int ntotpts = m_fields[0]->GetTotPoints();
123 m_previousVelFields[0] = Array<OneD, NekDouble>(ndim * nvel * ntotpts);
124
125 for (size_t i = 1; i < ndim * nvel; ++i)
126 {
127 m_previousVelFields[i] = m_previousVelFields[i - 1] + ntotpts;
128 }
129 }
130 else
131 {
132 ASSERTL0(0, "Integration method not suitable: Options include "
133 "BackwardEuler or BDFImplicitOrder{1,2}");
134 }
135
136 m_intSteps = IntegrationScheme->GetNumIntegrationPhases();
137
138 // set explicit time-integration class operators
143}
144
145/**
146 * Explicit Advection terms used by SubStepAdvance time integration
147 */
149 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
150 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
151{
152 size_t i;
153 size_t nVariables = inarray.size();
154 size_t nQuadraturePts = inarray[0].size();
155
156 /// Get the number of coefficients
157 size_t ncoeffs = m_fields[0]->GetNcoeffs();
158
159 /// Define an auxiliary variable to compute the RHS
160 Array<OneD, Array<OneD, NekDouble>> WeakAdv(nVariables);
161 WeakAdv[0] = Array<OneD, NekDouble>(ncoeffs * nVariables);
162 for (i = 1; i < nVariables; ++i)
163 {
164 WeakAdv[i] = WeakAdv[i - 1] + ncoeffs;
165 }
166
168
169 Velfields[0] = Array<OneD, NekDouble>(nQuadraturePts * m_velocity.size());
170
171 for (i = 1; i < m_velocity.size(); ++i)
172 {
173 Velfields[i] = Velfields[i - 1] + nQuadraturePts;
174 }
175
176 SubStepExtrapolateField(fmod(time, m_timestep), Velfields);
177
178 for (auto &x : m_forcing)
179 {
180 x->PreApply(m_fields, Velfields, Velfields, time);
181 }
182 m_advObject->Advect(m_velocity.size(), m_fields, Velfields, inarray,
183 outarray, time);
184 for (auto &x : m_forcing)
185 {
186 x->Apply(m_fields, outarray, outarray, time);
187 }
188
189 for (i = 0; i < nVariables; ++i)
190 {
191 m_fields[i]->IProductWRTBase(outarray[i], WeakAdv[i]);
192 // negation requried due to sign of DoAdvection term to be consistent
193 Vmath::Neg(ncoeffs, WeakAdv[i], 1);
194 }
195
196 AddAdvectionPenaltyFlux(Velfields, inarray, WeakAdv);
197
198 /// Operations to compute the RHS
199 for (i = 0; i < nVariables; ++i)
200 {
201 // Negate the RHS
202 Vmath::Neg(ncoeffs, WeakAdv[i], 1);
203
204 /// Multiply the flux by the inverse of the mass matrix
205 m_fields[i]->MultiplyByElmtInvMass(WeakAdv[i], WeakAdv[i]);
206
207 /// Store in outarray the physical values of the RHS
208 m_fields[i]->BwdTrans(WeakAdv[i], outarray[i]);
209 }
210}
211
212/**
213 * Projection used by SubStepAdvance time integration
214 */
216 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
217 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
218{
219 boost::ignore_unused(time);
220 ASSERTL1(inarray.size() == outarray.size(),
221 "Inarray and outarray of different sizes ");
222
223 for (size_t i = 0; i < inarray.size(); ++i)
224 {
225 Vmath::Vcopy(inarray[i].size(), inarray[i], 1, outarray[i], 1);
226 }
227}
228
229/**
230 *
231 */
233 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
234 const NekDouble Aii_Dt, NekDouble kinvis)
235{
236 boost::ignore_unused(Aii_Dt);
237
238 // int nConvectiveFields =m_fields.size()-1;
240
242
243 // Calculate non-linear and viscous BCs at current level and
244 // put in m_pressureHBCs[0]
245 CalcNeumannPressureBCs(inarray, nullvelfields, kinvis);
246
247 // Extrapolate to m_pressureHBCs to n+1
249
250 // Add (phi,Du/Dt) term to m_presureHBC
251 AddDuDt();
252
253 // Copy m_pressureHBCs to m_PbndExp
255
256 // Evaluate High order outflow conditiosn if required.
257 CalcOutflowBCs(inarray, kinvis);
258}
259
260/**
261 *
262 */
264{
265 size_t i, n;
266 size_t nvel = m_velocity.size();
267 size_t npts = m_fields[0]->GetTotPoints();
268
269 // rotate fields
270 size_t nblocks = m_previousVelFields.size() / nvel;
272
273 // rotate storage space
274 for (n = 0; n < nvel; ++n)
275 {
276 save = m_previousVelFields[(nblocks - 1) * nvel + n];
277
278 for (i = nblocks - 1; i > 0; --i)
279 {
280 m_previousVelFields[i * nvel + n] =
281 m_previousVelFields[(i - 1) * nvel + n];
282 }
283
284 m_previousVelFields[n] = save;
285 }
286
287 // Put previous field
288 for (i = 0; i < nvel; ++i)
289 {
290 m_fields[m_velocity[i]]->BwdTrans(
291 m_fields[m_velocity[i]]->GetCoeffs(),
292 m_fields[m_velocity[i]]->UpdatePhys());
293 Vmath::Vcopy(npts, m_fields[m_velocity[i]]->GetPhys(), 1,
294 m_previousVelFields[i], 1);
295 }
296
297 if (nstep == 0) // initialise all levels with first field
298 {
299 for (n = 0; n < nvel; ++n)
300 {
301 for (i = 1; i < nblocks; ++i)
302 {
303 Vmath::Vcopy(npts, m_fields[m_velocity[n]]->GetPhys(), 1,
304 m_previousVelFields[i * nvel + n], 1);
305 }
306 }
307 }
308}
309
310/**
311 *
312 */
314{
315 int n;
316 int nsubsteps;
317
318 NekDouble dt;
319
321
322 static int ncalls = 1;
323 size_t nint = std::min(ncalls++, m_intSteps);
324
325 // this needs to change
326 m_comm = m_fields[0]->GetComm()->GetRowComm();
327
328 // Get the proper time step with CFL control
329 dt = GetSubstepTimeStep();
330
331 nsubsteps = (m_timestep > dt) ? ((int)(m_timestep / dt) + 1) : 1;
332 nsubsteps = std::max(m_minsubsteps, nsubsteps);
333
334 ASSERTL0(nsubsteps < m_maxsubsteps,
335 "Number of substeps has exceeded maximum");
336
337 dt = m_timestep / nsubsteps;
338
339 if (m_infosteps && !((nstep + 1) % m_infosteps) && m_comm->GetRank() == 0)
340 {
341 std::cout << "Sub-integrating using " << nsubsteps
342 << " steps over Dt = " << m_timestep
343 << " (SubStep CFL=" << m_cflSafetyFactor << ")" << std::endl;
344 }
345
346 const TripleArray &solutionVector = m_intScheme->GetSolutionVector();
347
348 for (size_t m = 0; m < nint; ++m)
349 {
350 // We need to update the fields held by the m_intScheme
351 fields = solutionVector[m];
352
353 // Initialise NS solver which is set up to use a GLM method
354 // with calls to EvaluateAdvection_SetPressureBCs and
355 // SolveUnsteadyStokesSystem
356 m_subStepIntegrationScheme->InitializeScheme(dt, fields, time,
358
359 for (n = 0; n < nsubsteps; ++n)
360 {
361 fields = m_subStepIntegrationScheme->TimeIntegrate(n, dt);
362 }
363
364 // set up HBC m_acceleration field for Pressure BCs
366
367 // Reset time integrated solution in m_intScheme
368 m_intScheme->SetSolutionVector(m, fields);
369 }
370}
371
372/**
373 *
374 */
376{
377 size_t n_element = m_fields[0]->GetExpSize();
378
379 const Array<OneD, int> ExpOrder = m_fields[0]->EvalBasisNumModesMaxPerExp();
380
381 const NekDouble cLambda = 0.2; // Spencer book pag. 317
382
383 Array<OneD, NekDouble> tstep(n_element, 0.0);
384 Array<OneD, NekDouble> stdVelocity(n_element, 0.0);
386
387 for (size_t i = 0; i < m_velocity.size(); ++i)
388 {
389 velfields[i] = m_fields[m_velocity[i]]->UpdatePhys();
390 }
391 stdVelocity = GetMaxStdVelocity(velfields);
392
393 for (size_t el = 0; el < n_element; ++el)
394 {
395 tstep[el] =
396 m_cflSafetyFactor / (stdVelocity[el] * cLambda *
397 (ExpOrder[el] - 1) * (ExpOrder[el] - 1));
398 }
399
400 NekDouble TimeStep = Vmath::Vmin(n_element, tstep, 1);
401 m_comm->AllReduce(TimeStep, LibUtilities::ReduceMin);
402
403 return TimeStep;
404}
405
407 const Array<OneD, const Array<OneD, NekDouble>> &velfield,
408 const Array<OneD, const Array<OneD, NekDouble>> &physfield,
410{
411 ASSERTL1(physfield.size() == Outarray.size(),
412 "Physfield and outarray are of different dimensions");
413
414 size_t i;
415
416 /// Number of trace points
417 size_t nTracePts = m_fields[0]->GetTrace()->GetNpoints();
418
419 /// Number of spatial dimensions
420 size_t nDimensions = m_bnd_dim;
421
422 /// Forward state array
423 Array<OneD, NekDouble> Fwd(3 * nTracePts);
424
425 /// Backward state array
426 Array<OneD, NekDouble> Bwd = Fwd + nTracePts;
427
428 /// upwind numerical flux state array
429 Array<OneD, NekDouble> numflux = Bwd + nTracePts;
430
431 /// Normal velocity array
432 Array<OneD, NekDouble> Vn(nTracePts, 0.0);
433
434 // Extract velocity field along the trace space and multiply by trace
435 // normals
436 for (i = 0; i < nDimensions; ++i)
437 {
438 m_fields[0]->ExtractTracePhys(velfield[i], Fwd);
439 Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, Fwd, 1, Vn, 1, Vn, 1);
440 }
441
442 for (i = 0; i < physfield.size(); ++i)
443 {
444 /// Extract forwards/backwards trace spaces
445 /// Note: Needs to have correct i value to get boundary conditions
446 m_fields[i]->GetFwdBwdTracePhys(physfield[i], Fwd, Bwd);
447
448 /// Upwind between elements
449 m_fields[0]->GetTrace()->Upwind(Vn, Fwd, Bwd, numflux);
450
451 /// Construct difference between numflux and Fwd,Bwd
452 Vmath::Vsub(nTracePts, numflux, 1, Fwd, 1, Fwd, 1);
453 Vmath::Vsub(nTracePts, numflux, 1, Bwd, 1, Bwd, 1);
454
455 /// Calculate the numerical fluxes multipling Fwd, Bwd and
456 /// numflux by the normal advection velocity
457 Vmath::Vmul(nTracePts, Fwd, 1, Vn, 1, Fwd, 1);
458 Vmath::Vmul(nTracePts, Bwd, 1, Vn, 1, Bwd, 1);
459
460 m_fields[0]->AddFwdBwdTraceIntegral(Fwd, Bwd, Outarray[i]);
461 }
462}
463
464/**
465 * Extrapolate field using equally time spaced field un,un-1,un-2, (at
466 * dt intervals) to time n+t at order Ord
467 */
470{
471 size_t npts = m_fields[0]->GetTotPoints();
472 size_t nvel = m_velocity.size();
473 size_t i, j;
475
476 size_t ord = m_intSteps;
477
478 // calculate Lagrange interpolants
479 Vmath::Fill(4, 1.0, l, 1);
480
481 for (i = 0; i <= ord; ++i)
482 {
483 for (j = 0; j <= ord; ++j)
484 {
485 if (i != j)
486 {
487 l[i] *= (j * m_timestep + toff);
488 l[i] /= (j * m_timestep - i * m_timestep);
489 }
490 }
491 }
492
493 for (i = 0; i < nvel; ++i)
494 {
495 Vmath::Smul(npts, l[0], m_previousVelFields[i], 1, ExtVel[i], 1);
496
497 for (j = 1; j <= ord; ++j)
498 {
499 Blas::Daxpy(npts, l[j], m_previousVelFields[j * nvel + i], 1,
500 ExtVel[i], 1);
501 }
502 }
503}
504
505/**
506 *
507 */
509 int HBCdata, NekDouble kinvis, Array<OneD, NekDouble> &Q,
511{
512 boost::ignore_unused(Advection);
513
514 Vmath::Smul(HBCdata, -kinvis, Q, 1, Q, 1);
515}
516
518{
519 return m_subStepIntegrationScheme->GetName();
520}
521
522} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
Array< OneD, Array< OneD, NekDouble > > m_pressureHBCs
Storage for current and previous levels of high order pressure boundary conditions.
Definition: Extrapolate.h:242
int m_bnd_dim
bounday dimensionality
Definition: Extrapolate.h:218
void CopyPressureHBCsToPbndExp(void)
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Velocity fields.
Definition: Extrapolate.h:199
Array< OneD, Array< OneD, NekDouble > > m_iprodnormvel
Storage for current and previous levels of the inner product of normal velocity.
Definition: Extrapolate.h:246
Array< OneD, NekDouble > GetMaxStdVelocity(const Array< OneD, Array< OneD, NekDouble > > inarray)
int m_intSteps
Maximum points used in pressure BC evaluation.
Definition: Extrapolate.h:236
void CalcNeumannPressureBCs(const Array< OneD, const Array< OneD, NekDouble > > &fields, const Array< OneD, const Array< OneD, NekDouble > > &N, NekDouble kinvis)
Definition: Extrapolate.h:170
void IProductNormVelocityOnHBC(const Array< OneD, const Array< OneD, NekDouble > > &Vel, Array< OneD, NekDouble > &IprodVn)
NekDouble m_timestep
Definition: Extrapolate.h:238
void ExtrapolateArray(Array< OneD, Array< OneD, NekDouble > > &array)
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Definition: Extrapolate.h:210
SolverUtils::AdvectionSharedPtr m_advObject
Definition: Extrapolate.h:208
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
Definition: Extrapolate.h:206
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Definition: Extrapolate.h:248
int m_pressureCalls
number of times the high-order pressure BCs have been called
Definition: Extrapolate.h:227
LibUtilities::SessionReaderSharedPtr m_session
Definition: Extrapolate.h:191
void CalcOutflowBCs(const Array< OneD, const Array< OneD, NekDouble > > &fields, NekDouble kinvis)
LibUtilities::CommSharedPtr m_comm
Definition: Extrapolate.h:193
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
An abstract base class encapsulating the concept of advection of a vector field.
Definition: Advection.h:83
LibUtilities::TimeIntegrationSchemeOperators m_subStepIntegrationOps
virtual void v_MountHOPBCs(int HBCdata, NekDouble kinvis, Array< OneD, NekDouble > &Q, Array< OneD, const NekDouble > &Advection) override
LibUtilities::TimeIntegrationSchemeSharedPtr m_subStepIntegrationScheme
void SubStepExtrapolateField(NekDouble toff, Array< OneD, Array< OneD, NekDouble > > &ExtVel)
static std::string className
Name of class.
virtual void v_SubStepSaveFields(int nstep) override
static ExtrapolateSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, MultiRegions::ExpListSharedPtr &pPressure, const Array< OneD, int > &pVel, const SolverUtils::AdvectionSharedPtr &advObject)
Creates an instance of this class.
void SubStepAdvection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
void SubStepProjection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
LibUtilities::TimeIntegrationSchemeSharedPtr m_intScheme
virtual void v_SubSteppingTimeIntegration(const LibUtilities::TimeIntegrationSchemeSharedPtr &IntegrationScheme) override
virtual void v_SubStepAdvance(int nstep, NekDouble time) override
virtual std::string v_GetSubStepName(void) override
void AddAdvectionPenaltyFlux(const Array< OneD, const Array< OneD, NekDouble > > &velfield, const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &outarray)
virtual void v_SubStepSetPressureBCs(const Array< OneD, const Array< OneD, NekDouble > > &inarray, NekDouble Aii_Dt, NekDouble kinvis) override
SubSteppingExtrapolate(const LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields, MultiRegions::ExpListSharedPtr pPressure, const Array< OneD, int > pVel, const SolverUtils::AdvectionSharedPtr advObject)
Array< OneD, Array< OneD, NekDouble > > m_previousVelFields
virtual void v_EvaluatePressureBCs(const Array< OneD, const Array< OneD, NekDouble > > &fields, const Array< OneD, const Array< OneD, NekDouble > > &N, NekDouble kinvis) override
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
Definition: Blas.hpp:137
TimeIntegrationSchemeFactory & GetTimeIntegrationSchemeFactory()
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< TimeIntegrationScheme > TimeIntegrationSchemeSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< Advection > AdvectionSharedPtr
A shared pointer to an Advection object.
Definition: Advection.h:56
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
ExtrapolateFactory & GetExtrapolateFactory()
Definition: Extrapolate.cpp:48
double NekDouble
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.
Definition: Vmath.cpp:207
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:513
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
Definition: Vmath.cpp:1045
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
Definition: Vmath.cpp:569
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.cpp:245
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:43
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.cpp:414