Doxygen 1.15.0
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.2
Loading...
Searching...
No Matches
tsgGridLocalPolynomial.hpp
1/*
2 * Copyright (c) 2017, Miroslav Stoyanov
3 *
4 * This file is part of
5 * Toolkit for Adaptive Stochastic Modeling And Non-Intrusive ApproximatioN: TASMANIAN
6 *
7 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
12 * and the following disclaimer in the documentation and/or other materials provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * UT-BATTELLE, LLC AND THE UNITED STATES GOVERNMENT MAKE NO REPRESENTATIONS AND DISCLAIM ALL WARRANTIES, BOTH EXPRESSED AND IMPLIED.
25 * THERE ARE NO EXPRESS OR IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY PATENT,
26 * COPYRIGHT, TRADEMARK, OR OTHER PROPRIETARY RIGHTS, OR THAT THE SOFTWARE WILL ACCOMPLISH THE INTENDED RESULTS OR THAT THE SOFTWARE OR ITS USE WILL NOT RESULT IN INJURY OR DAMAGE.
27 * THE USER ASSUMES RESPONSIBILITY FOR ALL LIABILITIES, PENALTIES, FINES, CLAIMS, CAUSES OF ACTION, AND COSTS AND EXPENSES, CAUSED BY, RESULTING FROM OR ARISING OUT OF,
28 * IN WHOLE OR IN PART THE USE, STORAGE OR DISPOSAL OF THE SOFTWARE.
29 */
30
31#ifndef __TASMANIAN_SPARSE_GRID_LPOLY_HPP
32#define __TASMANIAN_SPARSE_GRID_LPOLY_HPP
33
34#include "tsgGridCore.hpp"
35
36namespace TasGrid{
37
38#ifndef __TASMANIAN_DOXYGEN_SKIP
39class GridLocalPolynomial : public BaseCanonicalGrid{
40public:
41 GridLocalPolynomial(AccelerationContext const *acc) : BaseCanonicalGrid(acc), order(1), top_level(0){}
42 friend struct GridReaderVersion5<GridLocalPolynomial>;
43 GridLocalPolynomial(AccelerationContext const *acc, const GridLocalPolynomial *pwpoly, int ibegin, int iend);
44 GridLocalPolynomial(AccelerationContext const *acc, int cnum_dimensions, int cnum_outputs, int depth, int corder, TypeOneDRule crule, const std::vector<int> &level_limits);
45 ~GridLocalPolynomial() = default;
46
47 bool isLocalPolynomial() const override{ return true; }
48
49 void write(std::ostream &os, bool iomode) const override{ if (iomode == mode_ascii) write<mode_ascii>(os); else write<mode_binary>(os); }
50
51 template<bool iomode> void write(std::ostream &os) const;
52
53 TypeOneDRule getRule() const override{ return RuleLocal::getRule(effective_rule); }
54 int getOrder() const{ return order; }
55
56 template<RuleLocal::erule, typename points_mode>
57 void getPoints(double *x) const;
58 void getLoadedPoints(double *x) const override;
59 void getNeededPoints(double *x) const override;
60 void getPoints(double *x) const override; // returns the loaded points unless no points are loaded, then returns the needed points
61
62 template<RuleLocal::erule effrule>
63 void getQuadratureWeights(double weights[]) const;
64 void getQuadratureWeights(double weights[]) const override;
65 void getInterpolationWeights(const double x[], double weights[]) const override;
66 void getDifferentiationWeights(const double x[], double weights[]) const override;
67
68 void loadNeededValues(const double *vals) override;
69
70 void evaluate(const double x[], double y[]) const override;
71 void integrate(double q[], double *conformal_correction) const override;
72 void differentiate(const double x[], double jacobian[]) const override;
73
74 void evaluateBatchOpenMP(const double x[], int num_x, double y[]) const;
75 void evaluateBatch(const double x[], int num_x, double y[]) const override;
76
77 void loadNeededValuesGPU(const double *vals);
78 void evaluateGpuMixed(const double x[], int num_x, double y[]) const;
79 void evaluateBatchGPU(const double gpu_x[], int cpu_num_x, double gpu_y[]) const override;
80 void evaluateBatchGPU(const float gpu_x[], int cpu_num_x, float gpu_y[]) const override;
81 template<typename T> void evaluateBatchGPUtempl(const T gpu_x[], int cpu_num_x, T gpu_y[]) const;
82 void evaluateHierarchicalFunctionsGPU(const double gpu_x[], int cpu_num_x, double *gpu_y) const override;
83 void buildSparseBasisMatrixGPU(const double gpu_x[], int cpu_num_x, GpuVector<int> &gpu_spntr, GpuVector<int> &gpu_sindx, GpuVector<double> &gpu_svals) const;
84 void evaluateHierarchicalFunctionsGPU(const float gpu_x[], int cpu_num_x, float *gpu_y) const override;
85 void buildSparseBasisMatrixGPU(const float gpu_x[], int cpu_num_x, GpuVector<int> &gpu_spntr, GpuVector<int> &gpu_sindx, GpuVector<float> &gpu_svals) const;
86
87 void setSurplusRefinement(double tolerance, TypeRefinement criteria, int output, const std::vector<int> &level_limits, const double *scale_correction);
88 void clearRefinement() override;
89 void mergeRefinement() override;
96 std::vector<double> getScaledCoefficients(int output, const double *scale_correction);
97 int removePointsByHierarchicalCoefficient(double tolerance, int output, const double *scale_correction); // returns the number of points kept
98 void removePointsByHierarchicalCoefficient(int new_num_points, int output, const double *scale_correction);
104 int removeMappedPoints(std::vector<bool> const &pmap);
105
106 void beginConstruction() override;
107 void writeConstructionData(std::ostream &os, bool) const override;
108 void readConstructionData(std::istream &is, bool) override;
109 template<RuleLocal::erule effrule>
110 std::vector<double> getCandidateConstructionPoints(double tolerance, TypeRefinement criteria, int output, std::vector<int> const &level_limits, double const *scale_correction);
111 std::vector<double> getCandidateConstructionPoints(double tolerance, TypeRefinement criteria, int output, std::vector<int> const &level_limits, double const *scale_correction);
112 template<RuleLocal::erule effrule>
113 void loadConstructedPoint(const double x[], const std::vector<double> &y);
114 void loadConstructedPoint(const double x[], const std::vector<double> &y) override;
115 template<RuleLocal::erule effrule>
116 void loadConstructedPoint(const double x[], int numx, const double y[]);
117 void loadConstructedPoint(const double x[], int numx, const double y[]) override;
118 void finishConstruction() override;
119
120 void evaluateHierarchicalFunctions(const double x[], int num_x, double y[]) const override;
121 std::vector<double> getSupport() const override final;
122 void setHierarchicalCoefficients(const double c[]) override;
123 void integrateHierarchicalFunctions(double integrals[]) const override;
124
125 void updateAccelerationData(AccelerationContext::ChangeType change) const override;
126
127 const double* getSurpluses() const;
128 const int* getNeededIndexes() const;
129
130 void buildSpareBasisMatrix(const double x[], int num_x, int num_chunk, std::vector<int> &spntr, std::vector<int> &sindx, std::vector<double> &svals) const;
131 void buildSpareBasisMatrixStatic(const double x[], int num_x, int num_chunk, int *spntr, int *sindx, double *svals) const;
132 int getSpareBasisMatrixNZ(const double x[], int num_x) const;
133
134protected:
136 GridLocalPolynomial(AccelerationContext const *acc, int cnum_dimensions, int cnum_outputs, int corder, TypeOneDRule crule, std::vector<int> &&pnts, std::vector<double> &&vals, std::vector<double> &&surps);
137
139 void updateValues(double const *vals);
140
141 void buildTree();
142
144 template<RuleLocal::erule effrule>
145 std::vector<int> getSubGraph(std::vector<int> const &point) const;
146
148 template<RuleLocal::erule effrule>
149 void expandGrid(std::vector<int> const &point, std::vector<double> const &value);
150
152 template<RuleLocal::erule effrule>
153 std::vector<int> getMultiIndex(const double x[]);
154
156 template<RuleLocal::erule effrule>
157 void loadConstructedPoints();
158
160 template<RuleLocal::erule effrule>
161 void recomputeSurpluses();
162
163 void recomputeSurpluses();
164
180 template<RuleLocal::erule effrule>
181 void updateSurpluses(MultiIndexSet const &work, int max_level, std::vector<int> const &level, Data2D<int> const &dagUp);
182
183 // Same idea as in GridSequence::applyTransformationTransposed().
184 template<int mode>
185 void applyTransformationTransposed(double weights[], const MultiIndexSet &work, const std::vector<int> &active_points) const;
186 template<int mode, RuleLocal::erule effrule>
187 void applyTransformationTransposed(double weights[], const MultiIndexSet &work, const std::vector<int> &active_points) const;
188
189 void buildSparseMatrixBlockForm(const double x[], int num_x, int num_chunk, std::vector<int> &numnz,
190 std::vector<std::vector<int>> &tindx, std::vector<std::vector<double>> &tvals) const;
191
192 template<RuleLocal::erule eff_rule>
193 double evalBasisSupported(const int point[], const double x[], bool &isSupported) const{
194 double f = RuleLocal::evalSupport<eff_rule>(order, point[0], x[0], isSupported);
195 if (!isSupported) return 0.0;
196 for(int j=1; j<num_dimensions; j++){
197 f *= RuleLocal::evalSupport<eff_rule>(order, point[j], x[j], isSupported);
198 if (!isSupported) return 0.0;
199 }
200 return f;
201 }
202 template<RuleLocal::erule effrule>
203 void diffBasisSupported(const int point[], const double x[], double diff_values[], bool &isSupported) const{
204 isSupported = false;
205 for(int i=0; i<num_dimensions; i++) diff_values[i] = 1.0;
206 bool isDimSupported = false;
207 for(int k=0; k<num_dimensions; k++) {
208 double fval = RuleLocal::evalSupport<effrule>(order, point[k], x[k], isDimSupported);
209 isSupported = isDimSupported or isSupported;
210 for(int j=0; j<k; j++) diff_values[j] *= fval;
211 for(int j=k+1; j<num_dimensions; j++) diff_values[j] *= fval;
212 }
213 for (int k=0; k<num_dimensions; k++) {
214 diff_values[k] *= RuleLocal::diffSupport<effrule>(order, point[k], x[k], isDimSupported);
215 isSupported = isDimSupported or isSupported;
216 }
217 }
218
234 template<int mode, RuleLocal::erule effrule>
235 void walkTree(const MultiIndexSet &work, const double x[], std::vector<int> &sindx, std::vector<double> &svals, double *y) const{
236 std::vector<int> monkey_count(top_level+1); // traverse the tree, counts the branches of the current node
237 std::vector<int> monkey_tail(top_level+1); // traverse the tree, keeps track of the previous node (history)
238
239 bool isSupported;
240 double basis_value;
241 std::vector<double> basis_derivative(num_dimensions);
242
243 for(const auto &r : roots){
244 if (mode == 3 or mode == 4) {
245 diffBasisSupported<effrule>(work.getIndex(r), x, basis_derivative.data(), isSupported);
246 } else {
247 basis_value = evalBasisSupported<effrule>(work.getIndex(r), x, isSupported);
248 }
249
250 if (isSupported){
251 if (mode == 0){
252 double const *s = surpluses.getStrip(r);
253 for(int k=0; k<num_outputs; k++)
254 y[k] += basis_value * s[k];
255 }else if (mode == 1 or mode == 2){
256 sindx.push_back(r);
257 svals.push_back(basis_value);
258 }else if (mode == 3){
259 double const *s = surpluses.getStrip(r);
260 for(int k=0; k<num_outputs; k++)
261 for (int d=0; d<num_dimensions; d++)
262 y[k * num_dimensions + d] += basis_derivative[d] * s[k];
263 }else{
264 sindx.push_back(r);
265 for (auto dx : basis_derivative)
266 svals.push_back(dx);
267 }
268
269 int current = 0;
270 monkey_tail[0] = r;
271 monkey_count[0] = pntr[r];
272
273 while(monkey_count[0] < pntr[monkey_tail[0]+1]){
274 if (monkey_count[current] < pntr[monkey_tail[current]+1]){
275 int p = indx[monkey_count[current]];
276 if (mode == 3 or mode == 4){
277 diffBasisSupported<effrule>(work.getIndex(p), x, basis_derivative.data(), isSupported);
278 }else{
279 basis_value = evalBasisSupported<effrule>(work.getIndex(p), x, isSupported);
280 }
281 if (isSupported){
282 if (mode == 0){
283 double const *s = surpluses.getStrip(p);
284 for(int k=0; k<num_outputs; k++)
285 y[k] += basis_value * s[k];
286 }else if (mode == 1 or mode == 2){
287 sindx.push_back(p);
288 svals.push_back(basis_value);
289 }else if (mode == 3){
290 double const *s = surpluses.getStrip(p);
291 for(int k=0; k<num_outputs; k++)
292 for (int d=0; d<num_dimensions; d++)
293 y[k * num_dimensions + d] += basis_derivative[d] * s[k];
294 }else{
295 sindx.push_back(p);
296 for (auto dx : basis_derivative)
297 svals.push_back(dx);
298 }
299 monkey_tail[++current] = p;
300 monkey_count[current] = pntr[p];
301 }else{
302 monkey_count[current]++;
303 }
304 }else{
305 monkey_count[--current]++;
306 }
307 }
308 }
309 }
310
311 // according to https://docs.nvidia.com/cuda/cusparse/index.html#sparse-format
312 // "... it is assumed that the indices are provided in increasing order and that each index appears only once."
313 // This may not be a requirement for cusparseDgemvi(), but it may be that I have not tested it sufficiently
314 // Also, see AccelerationDataGPUFull::cusparseMatveci() for inaccuracies in Nvidia documentation
315 if (mode == 2){
316 std::vector<int> map(sindx);
317 std::iota(map.begin(), map.end(), 0);
318 std::sort(map.begin(), map.end(), [&](int a, int b)->bool{ return (sindx[a] < sindx[b]); });
319
320 std::vector<int> idx = sindx;
321 std::vector<double> vls = svals;
322 std::transform(map.begin(), map.end(), sindx.begin(), [&](int i)->int{ return idx[i]; });
323 std::transform(map.begin(), map.end(), svals.begin(), [&](int i)->double{ return vls[i]; });
324 }
325 }
326 // Explicitly instantiates based on the effective_rule
327 template<int mode>
328 void walkTree(const MultiIndexSet &work, const double x[], std::vector<int> &sindx, std::vector<double> &svals, double *y) const{
329 switch(effective_rule) {
330 case RuleLocal::erule::pwc:
331 walkTree<mode, RuleLocal::erule::pwc>(work,x, sindx, svals, y);
332 break;
333 case RuleLocal::erule::localp:
334 walkTree<mode, RuleLocal::erule::localp>(work,x, sindx, svals, y);
335 break;
336 case RuleLocal::erule::semilocalp:
337 walkTree<mode, RuleLocal::erule::semilocalp>(work,x, sindx, svals, y);
338 break;
339 case RuleLocal::erule::localp0:
340 walkTree<mode, RuleLocal::erule::localp0>(work,x, sindx, svals, y);
341 break;
342 default: // case RuleLocal::erule::localpb:
343 walkTree<mode, RuleLocal::erule::localpb>(work,x, sindx, svals, y);
344 break;
345 };
346 }
347
348 template<RuleLocal::erule effrule>
349 double evalBasisRaw(const int point[], const double x[]) const {
350 double f = RuleLocal::evalRaw<effrule>(order, point[0], x[0]);
351 for(int j=1; j<num_dimensions; j++) f *= RuleLocal::evalRaw<effrule>(order, point[j], x[j]);
352 return f;
353 }
354
355 std::vector<double> getNormalization() const;
356
357 template<RuleLocal::erule effrule>
358 Data2D<int> buildUpdateMap(double tolerance, TypeRefinement criteria, int output, const double *scale_correction) const;
359 template<RuleLocal::erule effrule>
360 MultiIndexSet getRefinementCanidates(double tolerance, TypeRefinement criteria, int output, const std::vector<int> &level_limits, const double *scale_correction) const;
361
362 template<RuleLocal::erule effrule>
363 bool addParent(const int point[], int direction, const MultiIndexSet &exclude, Data2D<int> &destination) const;
364 template<RuleLocal::erule effrule>
365 void addChild(const int point[], int direction, const MultiIndexSet &exclude, Data2D<int> &destination) const;
366 template<RuleLocal::erule effrule>
367 void addChildLimited(const int point[], int direction, const MultiIndexSet &exclude, const std::vector<int> &level_limits, Data2D<int> &destination) const;
368
369 void clearGpuSurpluses();
370 void clearGpuBasisHierarchy();
371
372private:
373 int order, top_level;
374
375 Data2D<double> surpluses;
376
377 Data2D<int> parents;
378
379 // tree for evaluation
380 std::vector<int> roots;
381 std::vector<int> pntr;
382 std::vector<int> indx;
383
384 RuleLocal::erule effective_rule;
385
386 std::unique_ptr<SimpleConstructData> dynamic_values;
387
388 // synchronize with tasgpu_devalpwpoly_feval
389 template<int ord, TypeOneDRule crule, typename T>
390 Data2D<T> encodeSupportForGPU(const MultiIndexSet &work) const{
391 Data2D<T> cpu_support(num_dimensions, work.getNumIndexes());
392 for(int i=0; i<work.getNumIndexes(); i++){
393 const int* p = work.getIndex(i);
394 T *s = cpu_support.getStrip(i);
395 for(int j=0; j<num_dimensions; j++){
396 if (ord == 0){
397 s[j] = static_cast<T>(RuleLocal::getSupport<RuleLocal::erule::pwc>(p[j]));
398 } else {
399 switch(crule) {
400 case rule_localp:
401 s[j] = static_cast<T>(RuleLocal::getSupport<RuleLocal::erule::localp>(p[j]));
402 break;
403 case rule_semilocalp:
404 s[j] = static_cast<T>(RuleLocal::getSupport<RuleLocal::erule::semilocalp>(p[j]));
405 break;
406 case rule_localp0:
407 s[j] = static_cast<T>(RuleLocal::getSupport<RuleLocal::erule::localp0>(p[j]));
408 break;
409 case rule_localpb:
410 s[j] = static_cast<T>(RuleLocal::getSupport<RuleLocal::erule::localpb>(p[j]));
411 break;
412 };
413 if (ord == 2) s[j] *= s[j];
414 if ((crule == rule_localp) || (crule == rule_semilocalp)) if (p[j] == 0) s[j] = static_cast<T>(-1.0); // constant function
415 if ((crule == rule_localp) && (ord == 2)){
416 if (p[j] == 1) s[j] = static_cast<T>(-2.0);
417 else if (p[j] == 2) s[j] = static_cast<T>(-3.0);
418 }
419 if ((crule == rule_semilocalp) && (ord == 2)){
420 if (p[j] == 1) s[j] = static_cast<T>(-4.0);
421 else if (p[j] == 2) s[j] = static_cast<T>(-5.0);
422 }
423 if ((crule == rule_localpb) && (ord == 2)){
424 if (p[j] < 2) s[j] = static_cast<T>(-2.0); // linear functions on level 0
425 }
426 }
427 }
428 }
429 return cpu_support;
430 }
431 std::unique_ptr<CudaLocalPolynomialData<double>>& getGpuCacheOverload(double) const{ return gpu_cache; }
432 std::unique_ptr<CudaLocalPolynomialData<float>>& getGpuCacheOverload(float) const{ return gpu_cachef; }
433 template<typename T> std::unique_ptr<CudaLocalPolynomialData<T>>& getGpuCache() const{
434 return getGpuCacheOverload(static_cast<T>(0.0));
435 }
436 template<typename T> void loadGpuBasis() const;
437 template<typename T> void loadGpuHierarchy() const;
438 template<typename T> void loadGpuSurpluses() const;
439 mutable std::unique_ptr<CudaLocalPolynomialData<double>> gpu_cache;
440 mutable std::unique_ptr<CudaLocalPolynomialData<float>> gpu_cachef;
441};
442
443// Old version reader
444template<> struct GridReaderVersion5<GridLocalPolynomial>{
445 template<typename iomode> static std::unique_ptr<GridLocalPolynomial> read(AccelerationContext const *acc, std::istream &is){
446 std::unique_ptr<GridLocalPolynomial> grid = Utils::make_unique<GridLocalPolynomial>(acc);
447
448 grid->num_dimensions = IO::readNumber<iomode, int>(is);
449 grid->num_outputs = IO::readNumber<iomode, int>(is);
450 grid->order = IO::readNumber<iomode, int>(is);
451 grid->top_level = IO::readNumber<iomode, int>(is);
452 TypeOneDRule rule = IO::readRule<iomode>(is);
453 grid->effective_rule = RuleLocal::getEffectiveRule(grid->order, rule);
454
455 if (IO::readFlag<iomode>(is)) grid->points = MultiIndexSet(is, iomode());
456 if (std::is_same<iomode, IO::mode_ascii_type>::value){ // backwards compatible: surpluses and needed, or needed and surpluses
457 if (IO::readFlag<iomode>(is))
458 grid->surpluses = IO::readData2D<iomode, double>(is, grid->num_outputs, grid->points.getNumIndexes());
459 if (IO::readFlag<iomode>(is)) grid->needed = MultiIndexSet(is, iomode());
460 }else{
461 if (IO::readFlag<iomode>(is)) grid->needed = MultiIndexSet(is, iomode());
462 if (IO::readFlag<iomode>(is))
463 grid->surpluses = IO::readData2D<iomode, double>(is, grid->num_outputs, grid->points.getNumIndexes());
464 }
465 int max_parents = [&]()->int {
466 switch(grid->effective_rule) {
467 case RuleLocal::erule::pwc: return RuleLocal::getMaxNumParents<RuleLocal::erule::pwc>();
468 case RuleLocal::erule::localp: return RuleLocal::getMaxNumParents<RuleLocal::erule::localp>();
469 case RuleLocal::erule::semilocalp: return RuleLocal::getMaxNumParents<RuleLocal::erule::semilocalp>();
470 case RuleLocal::erule::localp0: return RuleLocal::getMaxNumParents<RuleLocal::erule::localp0>();
471 default: // case RuleLocal::erule::localpb:
472 return RuleLocal::getMaxNumParents<RuleLocal::erule::localpb>();
473 };
474 }();
475
476 if (IO::readFlag<iomode>(is))
477 grid->parents = IO::readData2D<iomode, int>(is, max_parents * grid->num_dimensions, grid->points.getNumIndexes());
478
479 size_t num_points = (size_t) ((grid->points.empty()) ? grid->needed.getNumIndexes() : grid->points.getNumIndexes());
480 grid->roots = std::vector<int>((size_t) IO::readNumber<iomode, int>(is));
481 if (grid->roots.size() > 0){
482 IO::readVector<iomode>(is, grid->roots);
483 grid->pntr = IO::readVector<iomode, int>(is, num_points + 1);
484 if (grid->pntr[num_points] > 0){
485 grid->indx = IO::readVector<iomode, int>(is, grid->pntr[num_points]);
486 }else{
487 grid->indx = IO::readVector<iomode, int>(is, 1);
488 }
489 }
490
491 if (grid->num_outputs > 0) grid->values = StorageSet(is, iomode());
492
493 return grid;
494 }
495};
496#endif // __TASMANIAN_DOXYGEN_SKIP
497}
498
499#endif
TypeOneDRule
Used to specify the one dimensional family of rules that induces the sparse grid.
Definition tsgEnumerates.hpp:285
@ rule_localp
Nested rule with a hierarchy of uniformly distributed nodes and functions with compact support.
Definition tsgEnumerates.hpp:362
@ rule_localpb
Variation of rule_localp focusing nodes on the boundary instead of the interior.
Definition tsgEnumerates.hpp:368
@ rule_localp0
Variation of rule_localp assuming the model is zero at the domain boundary.
Definition tsgEnumerates.hpp:364
@ rule_semilocalp
Variation of rule_localp using increased support in exchange for higher order basis (better for smoot...
Definition tsgEnumerates.hpp:366
void loadNeededValues(std::function< void(double const x[], double y[], size_t thread_id)> model, TasmanianSparseGrid &grid, size_t num_threads)
Loads the current grid with model values, does not perform any refinement.
Definition tsgLoadNeededValues.hpp:104
Encapsulates the Tasmanian Sparse Grid module.
Definition TasmanianSparseGrid.hpp:68