Loading...
Searching...
No Matches
stencil_solver.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#include "stencil_solver.hpp"
26
27#include <cmath>
28
29namespace bitpit {
30
38
46
53template<typename stencil_t, typename stencil_container_t>
55 : DiscretizationStencilStorageInterface<stencil_t>(),
56 m_stencils(stencils), m_stride(stride)
57{
58}
59
65template<typename stencil_t, typename stencil_container_t>
67 : DiscretizationStencilProxyBaseStorage<stencil_t, stencil_container_t>(stencils, 1)
68{
69}
70
74 * \result The size of the container.
75 */
76template<typename stencil_t, typename stencil_container_t>
79 return this->m_stencils->size();
80}
82/*!
83 * Get the stencil associated with the specified row.
84 *
85 * \param rowIndex is the index of the row in the storage
86 * \result The stencil associated with the specified row.
87 */
88template<typename stencil_t, typename stencil_container_t>
90{
91 return (*(this->m_stencils))[rowIndex];
92}
93
100template<typename stencil_t, typename stencil_container_t>
102{
103 return (*(this->m_stencils))[rowRawIndex];
104}
105
113template<typename stencil_t, typename stencil_container_t>
114const stencil_t & DiscretizationStencilProxyStorage<stencil_t, stencil_container_t>::at(long blockIndex, int componentIdx) const
115{
116 return (*(this->m_stencils))[blockIndex * this->m_stride + componentIdx];
117}
118
122 * \param blockRawIndex is the raw index of the block
123 * \param componentIdx is the index of the component inside the block
124 * \result The stencil associated with the specified row.
125 */
126template<typename stencil_t, typename stencil_container_t>
127const stencil_t & DiscretizationStencilProxyStorage<stencil_t, stencil_container_t>::rawAt(std::size_t blockRawIndex, int componentIdx) const
128{
129 return (*(this->m_stencils))[blockRawIndex * this->m_stride + componentIdx];
131
132/*!
133 * Constructor.
134 *
135 * \param stencils are the stencils
136 */
137template<typename stencil_t>
139 : DiscretizationStencilProxyBaseStorage<stencil_t, PiercedStorage<stencil_t>>(stencils, stencils->getFieldCount())
141}
143/*!
144 * Get the size of the container.
146 * \result The size of the container.
147 */
148template<typename stencil_t>
151 return this->m_stencils->getKernel()->size() * this->m_stride;
154/*!
155 * Get the stencil associated with the specified row.
157 * \param rowIndex is the index of the row in the storage
158 * \result The stencil associated with the specified row.
159 */
160template<typename stencil_t>
162{
163 return this->m_stencils->at(rowIndex);
164}
165
172template<typename stencil_t>
174{
175 return this->m_stencils->rawAt(rowRawIndex);
176}
177
181 * \param blockIndex is the index of the block
182 * \param componentIdx is the index of the component inside the block
183 * \result The stencil associated with the specified row.
184 */
185template<typename stencil_t>
186const stencil_t & DiscretizationStencilProxyStorage<stencil_t, PiercedStorage<stencil_t>>::at(long blockIndex, int componentIdx) const
187{
188 return this->m_stencils->at(blockIndex, componentIdx);
189}
194 * \param blockRawIndex is the raw index of the block
195 * \param componentIdx is the index of the component inside the block
196 * \result The stencil associated with the specified row.
197 */
198template<typename stencil_t>
199const stencil_t & DiscretizationStencilProxyStorage<stencil_t, PiercedStorage<stencil_t>>::rawAt(std::size_t blockRawIndex, int componentIdx) const
201 return this->m_stencils->rawAt(blockRawIndex, componentIdx);
203
205 * \class DiscretizationStencilSolverAssembler
206 * \ingroup discretization
208 * \brief The DiscretizationStencilSolverAssembler class defines an assembler
209 * for building the stencil solver.
210 */
211
212#if BITPIT_ENABLE_MPI==1
216 * \param stencils are the stencils
217 * \param assemblerKernelArgs are the arguments that will be passed to the constructor of the
218 * assembler of the solver kernel
219 */
220template<typename stencil_t, typename solver_kernel_t>
221template<typename stencil_container_t, typename... AssemblerKernelArgs>
223 AssemblerKernelArgs&&... assemblerKernelArgs)
224 : DiscretizationStencilSolverAssembler(MPI_COMM_SELF, false, stencils, std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
225{
226}
227
237template<typename stencil_t, typename solver_kernel_t>
238template<typename stencil_container_t, typename... AssemblerKernelArgs>
240 const stencil_container_t *stencils,
241 AssemblerKernelArgs&&... assemblerKernelArgs)
242 : DiscretizationStencilSolverAssembler(communicator, partitioned,
243 std::unique_ptr<DiscretizationStencilStorageInterface<stencil_t>>(new DiscretizationStencilProxyStorage<stencil_t, stencil_container_t>(stencils)),
244 std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
246}
247#else
248/*!
249 * Constructor.
251 * \param stencils are the stencils
252 * \param assemblerKernelArgs are the arguments that will be passed to the constructor of the
253 * assembler of the solver kernel
254 */
255template<typename stencil_t, typename solver_kernel_t>
256template<typename stencil_container_t, typename... AssemblerKernelArgs>
258 AssemblerKernelArgs&&... assemblerKernelArgs)
259 : DiscretizationStencilSolverAssembler(std::unique_ptr<DiscretizationStencilStorageInterface<stencil_t>>(new DiscretizationStencilProxyStorage<stencil_t, stencil_container_t>(stencils)),
260 std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
261{
263#endif
264
265#if BITPIT_ENABLE_MPI==1
271 * assembler of the solver kernel
272 */
273template<typename stencil_t, typename solver_kernel_t>
274template<typename... AssemblerKernelArgs>
276 AssemblerKernelArgs&&... assemblerKernelArgs)
277 : DiscretizationStencilSolverAssembler(MPI_COMM_SELF, false, std::move(stencils), std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
278{
279}
280
290template<typename stencil_t, typename solver_kernel_t>
291template<typename... AssemblerKernelArgs>
293 std::unique_ptr<DiscretizationStencilStorageInterface<stencil_t>> &&stencils,
294 AssemblerKernelArgs&&... assemblerKernelArgs)
295 : DiscretizationStencilSolverAssembler(communicator, partitioned, std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
296#else
304template<typename stencil_t, typename solver_kernel_t>
305template<typename... AssemblerKernelArgs>
306DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::DiscretizationStencilSolverAssembler(std::unique_ptr<DiscretizationStencilStorageInterface<stencil_t>> &&stencils,
307 AssemblerKernelArgs&&... assemblerKernelArgs)
308 : DiscretizationStencilSolverAssembler(std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
309#endif
310{
311 setStencils(std::move(stencils));
313 setBlockSize();
315}
316
317#if BITPIT_ENABLE_MPI==1
324template<typename stencil_t, typename solver_kernel_t>
325template<typename... AssemblerKernelArgs>
327 : DiscretizationStencilSolverAssembler(MPI_COMM_SELF, false, std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
328{
329}
330
339template<typename stencil_t, typename solver_kernel_t>
340template<typename... AssemblerKernelArgs>
342 AssemblerKernelArgs&&... assemblerKernelArgs)
343 : solver_kernel_type::Assembler(std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...),
344 m_partitioned(partitioned), m_communicator(communicator)
345{
346}
347#else
354template<typename stencil_t, typename solver_kernel_t>
355template<typename... AssemblerKernelArgs>
357 : solver_kernel_type::Assembler(std::forward<AssemblerKernelArgs>(assemblerKernelArgs)...)
358{
359}
360#endif
361
362#if BITPIT_ENABLE_MPI==1
368template<typename stencil_t, typename solver_kernel_t>
373
379template<typename stencil_t, typename solver_kernel_t>
381{
382 return m_communicator;
383}
384#endif
385
391template<typename stencil_t, typename solver_kernel_t>
392typename DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::assembly_options_type DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getOptions() const
393{
394 assembly_options_type options;
395 options.full = true;
396 options.sorted = false;
397
398 return options;
399}
400
404template<typename stencil_t, typename solver_kernel_t>
405template<typename W, typename V, typename std::enable_if<std::is_fundamental<W>::value>::type *>
410
414template<typename stencil_t, typename solver_kernel_t>
415template<typename W, typename V, std::size_t D, typename std::enable_if<std::is_same<std::array<V, D>, W>::value>::type *>
417{
418 setBlockSize(sizeof(typename StencilVector::weight_type) / sizeof(typename StencilVector::weight_type::value_type));
419}
420
432template<typename stencil_t, typename solver_kernel_t>
433template<typename W, typename V, typename std::enable_if<std::is_same<std::vector<V>, W>::value>::type *>
435{
436 // Get block size
437 //
438 // Block size is evaluated from the constant of the first stencil.
439 //
440 // The block size is set equal to the square root of the weight size; if the square
441 // root of the weight type is not an integer number, an exception is throw.
442 if (getRowCount() == 0) {
443 throw std::runtime_error("Unable to evaluate the block size.");
444 }
445
446 const StencilBlock &stencil = getRowStencil(0);
447 std::size_t stencilConstantSize = stencil.getConstant().size();
448 int blockSize = static_cast<int>(std::round(std::sqrt(stencilConstantSize)));
449 if (static_cast<std::size_t>(blockSize * blockSize) != stencilConstantSize) {
450 throw std::runtime_error("Weights size should be a square.");
451 }
452 setBlockSize(blockSize);
453
454#ifdef DEBUG
455 // Validate block size
456 //
457 // All weight sizes should match
458 for (long i = 0; i < getRowCount(); ++i) {
459 const StencilBlock &stencil = getRowStencil(i);
460 const StencilBlock::weight_type *weightData = stencil.weightData();
461 std::size_t stencilSize = stencil.size();
462
463 for (std::size_t k = 0; k < stencilSize; ++k) {
464 if (weightData[k].size() != m_blockSize * m_blockSize)) {
465 throw std::runtime_error("All stencils weights should have the same size.");
466 }
467 }
468
469 if (stencil.getConstant().size() != m_blockSize * m_blockSize) {
470 throw std::runtime_error("The stencils constant should have the same size of the stencil weights.");
471 }
472 }
473#endif
474}
475
481template<typename stencil_t, typename solver_kernel_t>
483{
484 m_blockSize = blockSize;
485}
486
492template<typename stencil_t, typename solver_kernel_t>
497
501template<typename stencil_t, typename solver_kernel_t>
506
513template<typename stencil_t, typename solver_kernel_t>
515{
516 // Set system sizes
517 m_nRows = nRows;
518 m_nCols = nCols;
519
520#if BITPIT_ENABLE_MPI==1
521 // Global system sizes
522 m_nGlobalRows = nRows;
523 m_nGlobalCols = nCols;
524 if (m_partitioned) {
525 MPI_Allreduce(MPI_IN_PLACE, &m_nGlobalRows, 1, MPI_LONG, MPI_SUM, m_communicator);
526 MPI_Allreduce(MPI_IN_PLACE, &m_nGlobalCols, 1, MPI_LONG, MPI_SUM, m_communicator);
527 }
528
529 // Global offsets
530 m_globalRowOffset = 0;
531 m_globalColOffset = 0;
532 if (m_partitioned) {
533 int nProcessors;
534 MPI_Comm_size(m_communicator, &nProcessors);
535
536 std::vector<long> nRankRows(nProcessors);
537 MPI_Allgather(&m_nRows, 1, MPI_LONG, nRankRows.data(), 1, MPI_LONG, m_communicator);
538
539 std::vector<long> nRankCols(nProcessors);
540 MPI_Allgather(&m_nCols, 1, MPI_LONG, nRankCols.data(), 1, MPI_LONG, m_communicator);
541
542 int rank;
543 MPI_Comm_rank(m_communicator, &rank);
544 for (int i = 0; i < rank; ++i) {
545 m_globalRowOffset += nRankRows[i];
546 m_globalColOffset += nRankCols[i];
547 }
548 }
549#endif
550}
551
555template<typename stencil_t, typename solver_kernel_t>
557{
558 long maxRowNZ = 0;
559 for (long n = 0; n < getRowCount(); ++n) {
560 maxRowNZ = std::max(getRowNZCount(n), maxRowNZ);
561 }
562
563 setMaximumRowNZ(maxRowNZ);
564}
565
571template<typename stencil_t, typename solver_kernel_t>
573{
574 m_maxRowNZ = maxRowNZ;
575}
576
582template<typename stencil_t, typename solver_kernel_t>
587
597template<typename stencil_t, typename solver_kernel_t>
602
612template<typename stencil_t, typename solver_kernel_t>
617
626template<typename stencil_t, typename solver_kernel_t>
628{
629 long nRowElements = getBlockSize() * getRowCount();
630
631 return nRowElements;
632}
633
642template<typename stencil_t, typename solver_kernel_t>
644{
645 long nColElements = getBlockSize() * getColCount();
646
647 return nColElements;
648}
649
650#if BITPIT_ENABLE_MPI==1
660template<typename stencil_t, typename solver_kernel_t>
665
675template<typename stencil_t, typename solver_kernel_t>
680
689template<typename stencil_t, typename solver_kernel_t>
696
705template<typename stencil_t, typename solver_kernel_t>
712
718template<typename stencil_t, typename solver_kernel_t>
723
729template<typename stencil_t, typename solver_kernel_t>
734
743template<typename stencil_t, typename solver_kernel_t>
750
759template<typename stencil_t, typename solver_kernel_t>
766#endif
767
774template<typename stencil_t, typename solver_kernel_t>
776{
777 const stencil_t &stencil = getRowStencil(rowIndex);
778 std::size_t stencilSize = stencil.size();
779
780 return stencilSize;
781}
782
788template<typename stencil_t, typename solver_kernel_t>
793
805template<typename stencil_t, typename solver_kernel_t>
806void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getRowPattern(long rowIndex, ConstProxyVector<long> *pattern) const
807{
808 // Get stencil information
809 const stencil_t &stencil = getRowStencil(rowIndex);
810
811 // Get pattern
812 getPattern(stencil, pattern);
813}
814
821template<typename stencil_t, typename solver_kernel_t>
822void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getPattern(const stencil_t &stencil, ConstProxyVector<long> *pattern) const
823{
824 std::size_t stencilSize = stencil.size();
825
826 const long *patternData = stencil.patternData();
827 pattern->set(patternData, stencilSize);
828}
829
843template<typename stencil_t, typename solver_kernel_t>
844void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getRowValues(long rowIndex, ConstProxyVector<double> *values) const
845{
846 // Get stencil information
847 const stencil_t &stencil = getRowStencil(rowIndex);
848
849 // Get values
850 getValues(stencil, values);
851}
852
861template<typename stencil_t, typename solver_kernel_t>
862template<typename U, typename std::enable_if<std::is_fundamental<U>::value>::type *>
863void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getValues(const stencil_t &stencil, ConstProxyVector<double> *values) const
864{
865 values->set(stencil.weightData(), m_blockSize * stencil.size());
866}
867
876template<typename stencil_t, typename solver_kernel_t>
877template<typename U, typename std::enable_if<!std::is_fundamental<U>::value>::type *>
878void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getValues(const stencil_t &stencil, ConstProxyVector<double> *values) const
879{
880 std::size_t stencilSize = stencil.size();
881 const stencil_weight_type *stencilWeightData = stencil.weightData();
882
883 int nBlockElements = m_blockSize * m_blockSize;
884 std::size_t nRowValues = m_blockSize * stencilSize;
885 std::size_t nValues = nBlockElements * stencilSize;
887 ConstProxyVector<double>::storage_pointer expandedValuesStorage = values->storedData();
888
889
890 for (std::size_t k = 0; k < stencilSize; ++k) {
891 const double *weightData = stencilWeightData[k].data();
892 for (int i = 0; i < m_blockSize; ++i) {
893 int weightOffset = linearalgebra::linearIndexRowMajor(i, 0, m_blockSize, m_blockSize);
894 int valuesOffset = linearalgebra::linearIndexRowMajor(i, m_blockSize * k, m_blockSize, nRowValues);
895
896 std::copy_n(weightData + weightOffset, m_blockSize, expandedValuesStorage + valuesOffset);
897 }
898 }
899}
900
910template<typename stencil_t, typename solver_kernel_t>
911void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getRowData(long rowIndex, ConstProxyVector<long> *pattern, ConstProxyVector<double> *values) const
912{
913 // Get stencil information
914 const stencil_t &stencil = getRowStencil(rowIndex);
915
916 // Get pattern
917 getPattern(stencil, pattern);
918
919 // Get values
920 getValues(stencil, values);
921}
922
931template<typename stencil_t, typename solver_kernel_t>
932void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getRowConstant(long rowIndex, bitpit::ConstProxyVector<double> *constant) const
933{
934 // Get stencil information
935 const stencil_t &stencil = getRowStencil(rowIndex);
936
937 // Get constant
938 getConstant(stencil, constant);
939}
940
949template<typename stencil_t, typename solver_kernel_t>
950template<typename U, typename std::enable_if<std::is_fundamental<U>::value>::type *>
951void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getConstant(const stencil_t &stencil, bitpit::ConstProxyVector<double> *constant) const
952{
953 const stencil_weight_type &stencilConstant = stencil.getConstant();
954
955 constant->set(ConstProxyVector<double>::INTERNAL_STORAGE, m_blockSize);
956 ConstProxyVector<double>::storage_pointer constantStorage = constant->storedData();
957 std::copy_n(&stencilConstant, m_blockSize, constantStorage);
958}
959
968template<typename stencil_t, typename solver_kernel_t>
969template<typename U, typename std::enable_if<!std::is_fundamental<U>::value>::type *>
970void DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t>::getConstant(const stencil_t &stencil, bitpit::ConstProxyVector<double> *constant) const
971{
972 const stencil_weight_type &stencilConstant = stencil.getConstant();
973
974 constant->set(ConstProxyVector<double>::INTERNAL_STORAGE, m_blockSize);
975 ConstProxyVector<double>::storage_pointer constantStorage = constant->storedData();
976 for (int i = 0; i < m_blockSize; ++i) {
977 int offset_i = linearalgebra::linearIndexRowMajor(i, 0, m_blockSize, m_blockSize);
978
979 constantStorage[i] = 0;
980 for (int j = 0; j < m_blockSize; ++j) {
981 constantStorage[i] += stencil.getWeightManager().at(stencilConstant, offset_i + j);
982 }
983 }
984}
985
992template<typename stencil_t, typename solver_kernel_t>
994{
995 return m_stencils->at(rowIndex);
996}
997
1005
1009template<typename stencil_t, typename solver_kernel_t>
1011{
1012 solver_kernel_t::clear();
1013
1014 std::vector<double>().swap(m_constants);
1015}
1016
1017#if BITPIT_ENABLE_MPI==1
1025template<typename stencil_t, typename solver_kernel_t>
1026template<typename stencil_container_t>
1028{
1029 assembly(MPI_COMM_SELF, false, stencils);
1030}
1031
1039template<typename stencil_t, typename solver_kernel_t>
1040template<typename stencil_container_t>
1041void DiscretizationStencilSolver<stencil_t, solver_kernel_t>::assembly(MPI_Comm communicator, bool partitioned, const stencil_container_t &stencils)
1042#else
1048template<typename stencil_t, typename solver_kernel_t>
1049template<typename stencil_container_t>
1050void DiscretizationStencilSolver<stencil_t, solver_kernel_t>::assembly(const stencil_container_t &stencils)
1051#endif
1052{
1053 // Create the assembler
1054#if BITPIT_ENABLE_MPI==1
1055 DiscretizationStencilSolverAssembler<stencil_t, solver_kernel_t> assembler(communicator, partitioned, &stencils);
1056#else
1058#endif
1059
1060 // Assembly the system
1062}
1063
1072template<typename stencil_t, typename solver_kernel_t>
1077
1083template<typename stencil_t, typename solver_kernel_t>
1085{
1086 // Assemble matrix
1087 solver_kernel_t::matrixAssembly(assembler);
1088
1089 // Assemble constants
1090 assembleConstants(assembler);
1091}
1092
1109template<typename stencil_t, typename solver_kernel_t>
1110void DiscretizationStencilSolver<stencil_t, solver_kernel_t>::matrixUpdate(long nRows, const long *rows, const Assembler &assembler)
1111{
1112 // Update the system
1113 solver_kernel_t::matrixUpdate(nRows, rows, assembler);
1114
1115 // Update the constants
1116 updateConstants(nRows, rows, assembler);
1117}
1118
1127template<typename stencil_t, typename solver_kernel_t>
1128template<typename stencil_container_t>
1130{
1131 update(this->getRowCount(), nullptr, stencils);
1132}
1133
1143template<typename stencil_t, typename solver_kernel_t>
1144template<typename stencil_container_t>
1145void DiscretizationStencilSolver<stencil_t, solver_kernel_t>::update(const std::vector<long> &rows, const stencil_container_t &stencils)
1146{
1147 update(rows.size(), rows.data(), stencils);
1148}
1149
1162template<typename stencil_t, typename solver_kernel_t>
1163template<typename stencil_container_t>
1164void DiscretizationStencilSolver<stencil_t, solver_kernel_t>::update(std::size_t nRows, const long *rows, const stencil_container_t &stencils)
1165{
1166#if BITPIT_ENABLE_MPI==1
1168#else
1170#endif
1171
1172 // Update the system
1173 solver_kernel_t::template update<DiscretizationStencilSolver<stencil_t, solver_kernel_t>>(nRows, rows, assembler);
1174}
1175
1176
1187template<typename stencil_t, typename solver_kernel_t>
1188void DiscretizationStencilSolver<stencil_t, solver_kernel_t>::update(long nRows, const long *rows, const Assembler &assembler)
1189{
1190 solver_kernel_t::template update<DiscretizationStencilSolver<stencil_t, solver_kernel_t>>(nRows, rows, assembler);
1191}
1192
1198template<typename stencil_t, typename solver_kernel_t>
1200{
1201 long nRows = assembler.getRowCount();
1202 int blockSize = assembler.getBlockSize();
1203
1204 // Create the storage
1205 m_constants.resize(nRows * blockSize);
1206
1207 // Update the constants
1208 updateConstants(nRows, nullptr, assembler);
1209}
1210
1220template<typename stencil_t, typename solver_kernel_t>
1222 const Assembler &assembler)
1223{
1224 int blockSize = assembler.getBlockSize();
1225 ConstProxyVector<double> rowConstant(blockSize);
1226 for (std::size_t n = 0; n < nRows; ++n) {
1227 long row;
1228 if (rows) {
1229 row = rows[n];
1230 } else {
1231 row = n;
1232 }
1233
1234 assembler.getRowConstant(n, &rowConstant);
1235 std::copy_n(rowConstant.data(), blockSize, m_constants.data() + row * blockSize);
1236 }
1237}
1238
1242template<typename stencil_t, typename solver_kernel_t>
1244{
1245 // Check if the stencil solver is assembled
1246 if (!this->isAssembled()) {
1247 throw std::runtime_error("Unable to solve the system. The stencil solver is not yet assembled.");
1248 }
1249
1250 // Subtract constant terms to the RHS
1251 long nUnknowns = this->getBlockSize() * this->getRowCount();
1252 double *raw_rhs = this->getRHSRawPtr();
1253 for (long i = 0; i < nUnknowns; ++i) {
1254 raw_rhs[i] -= m_constants[i];
1255 }
1256 this->restoreRHSRawPtr(raw_rhs);
1257
1258 // Solve the system
1259 solver_kernel_t::solve();
1260}
1261
1262}
The DiscretizationStencilProxyBaseStorage class defines a proxy for stencil storage.
DiscretizationStencilProxyBaseStorage(const stencil_container_t *stencils, int stride)
const stencil_t & rawAt(std::size_t rowRawIndex) const override
const stencil_t & at(long rowIndex) const override
DiscretizationStencilProxyStorage(const stencil_container_t *stencils)
The DiscretizationStencilSolverAssembler class defines an assembler for building the stencil solver.
long getRowNZCount(long rowIndex) const override
virtual void getRowConstant(long rowIndex, bitpit::ConstProxyVector< double > *constant) const
void getRowValues(long rowIndex, ConstProxyVector< double > *values) const override
void getRowPattern(long rowIndex, ConstProxyVector< long > *pattern) const override
void setStencils(std::unique_ptr< DiscretizationStencilStorageInterface< stencil_t > > &&stencils)
DiscretizationStencilSolverAssembler(const stencil_container_t *stencils, AssemblerKernelArgs &&... assemblerKernelArgs)
void getValues(const stencil_t &stencil, ConstProxyVector< double > *values) const
void getRowData(long rowIndex, ConstProxyVector< long > *pattern, ConstProxyVector< double > *values) const override
const MPI_Comm & getCommunicator() const override
void getPattern(const stencil_t &stencil, ConstProxyVector< long > *pattern) const
assembly_options_type getOptions() const override
virtual const stencil_t & getRowStencil(long rowIndex) const
void getConstant(const stencil_t &stencil, bitpit::ConstProxyVector< double > *constant) const
void matrixAssembly(const Assembler &assembler)
void assembleConstants(const Assembler &assembler)
void matrixUpdate(long nRows, const long *rows, const Assembler &assembler)
void assembly(const stencil_container_t &stencils)
void update(const stencil_container_t &stencils)
void updateConstants(std::size_t nRows, const long *rows, const Assembler &assembler)
The DiscretizationStencilStorageInterface class defines the interface for stencil storage.
The NaturalSystemMatrixOrdering class defines allows to use a matrix natural ordering.
Metafunction for generating a pierced storage.
static constexpr __PXV_POINTER__ INTERNAL_STORAGE
__PXV_POINTER__ data() noexcept
__PXV_STORAGE_POINTER__ storedData() noexcept
__PXV_REFERENCE__ at(std::size_t n)
void set(__PXV_POINTER__ data, std::size_t size)
virtual int getBlockSize() const
void restoreRHSRawPtr(double *raw_rhs)
const MPI_Comm & getCommunicator() const
int linearIndexRowMajor(int row, int col, int nRows, int nCols)