NimbleSM
NimbleSM is a solid mechanics simulation code for dynamic systems
Loading...
Searching...
No Matches
nimble_linear_solver.h
Go to the documentation of this file.
1/*
2//@HEADER
3// ************************************************************************
4//
5// NimbleSM
6// Copyright 2018
7// National Technology & Engineering Solutions of Sandia, LLC (NTESS)
8//
9// Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government
10// retains certain rights in this software.
11//
12// Redistribution and use in source and binary forms, with or without
13// modification, are permitted provided that the following conditions are
14// met:
15//
16// 1. Redistributions of source code must retain the above copyright
17// notice, this list of conditions and the following disclaimer.
18//
19// 2. Redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution.
22//
23// 3. Neither the name of the Corporation nor the names of the
24// contributors may be used to endorse or promote products derived from
25// this software without specific prior written permission.
26//
27// THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY EXPRESS OR IMPLIED
28// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
30// NO EVENT SHALL NTESS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact David Littlewood (djlittl@sandia.gov)
39//
40// ************************************************************************
41//@HEADER
42*/
43
44#ifndef NIMBLE_LINEAR_SOLVER_H
45#define NIMBLE_LINEAR_SOLVER_H
46
47#ifdef NIMBLE_HAVE_DARMA
48#include "darma.h"
49#else
50#include <vector>
51#endif
52
53#ifdef NIMBLE_HAVE_MPI
54#include <mpi.h>
55#endif
56
57namespace nimble {
58
60{
61 public:
62 MatrixContainer() : num_rows_(0) {}
63
65
66 void
67 AllocateNonzeros(std::vector<int> const& i_index, std::vector<int> const& j_index)
68 {
69 num_rows_ = 0;
70 for (auto const& entry : i_index) {
71 if (entry > num_rows_) { num_rows_ = entry; }
72 }
73 num_rows_ += 1;
74 data_.resize(num_rows_ * num_rows_, 0.0);
75 }
76
77 void
78 SetAllValues(double value)
79 {
80 for (unsigned int i = 0; i < data_.size(); i++) { data_[i] = value; }
81 }
82
83 void
84 SetRowValues(int row, double value)
85 {
86 for (int i = 0; i < num_rows_; ++i) { data_[num_rows_ * row + i] = value; }
87 }
88
89 void
90 SetColumnValues(int col, double value)
91 {
92 for (int i = 0; i < num_rows_; ++i) { data_[num_rows_ * i + col] = value; }
93 }
94
95 unsigned int
97 {
98 return data_.size();
99 }
100
101 inline double
102 operator()(int i, int j) const
103 {
104 return data_[num_rows_ * i + j];
105 }
106
107 inline double&
108 operator()(int i, int j)
109 {
110 return data_[num_rows_ * i + j];
111 }
112
113 private:
114 int num_rows_;
115 std::vector<double> data_;
116};
117
119{
120 public:
121 CRSMatrixContainer() : num_rows_(0) {}
122
124
125 void
126 AllocateNonzeros(std::vector<int> const& i_index, std::vector<int> const& j_index);
127
128 void
130 {
131 if (num_rows_ == num_rows) { return; }
132 num_rows_ = num_rows;
133 data_.resize(num_rows_);
134 i_index_.resize(num_rows_);
135 j_index_.resize(num_rows_);
136 row_first_index_.resize(num_rows_);
137 for (int i = 0; i < num_rows_; i++) {
138 data_[i] = 0.0;
139 i_index_[i] = i;
140 j_index_[i] = i;
141 row_first_index_[i] = i;
142 }
143 }
144
145 void
146 SetAllValues(double value)
147 {
148 for (double& d_data : data_) d_data = value;
149 }
150
151 void
152 SetRowValues(int row, double value);
153
154 void
155 SetColumnValues(int col, double value);
156
157 int
158 NumRows() const
159 {
160 return num_rows_;
161 }
162
163 unsigned int
165 {
166 return data_.size();
167 }
168
169 void
170 MatVec(const double* vec, double* result) const;
171
172 void
173 DiagonalMatrixMatVec(const double* vec, double* result) const;
174
175 inline double
176 operator()(int i_index, int j_index) const
177 {
178 return data_[FindIndex(i_index, j_index)];
179 }
180
181 inline double&
182 operator()(int i_index, int j_index)
183 {
184 return data_[FindIndex(i_index, j_index)];
185 }
186
187#ifdef NIMBLE_HAVE_DARMA
188 template <typename ArchiveType>
189 void
190 serialize(ArchiveType& ar)
191 {
192 ar | num_rows_ | data_ | i_index_ | j_index_ | row_first_index_;
193 }
194#endif
195
196 private:
197 int
198 FindIndex(int i_index, int j_index) const;
199
200 int num_rows_;
201 std::vector<double> data_;
202 std::vector<int> i_index_;
203 std::vector<int> j_index_;
204 std::vector<int> row_first_index_;
205
206 /// \brief Generate a diagonal preconditioner from a sparse matrix
207 ///
208 /// \param A Input sparse matrix
209 /// \param M Diagonal preconditioner (mathematically M = (diag(A))^{-1})
210 friend void
212};
213
214inline double
215InnerProduct(unsigned int num_entries, const double* vec_1, const double* vec_2)
216{
217 double result(0.0);
218 for (unsigned int i = 0; i < num_entries; i++) { result += vec_1[i] * vec_2[i]; }
219#ifdef NIMBLE_HAVE_MPI
220 double restmp = result;
221 MPI_Allreduce(&restmp, &result, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
222#endif
223 return result;
224}
225
226inline double
227InnerProduct(const std::vector<double>& vec_1, const std::vector<double>& vec_2)
228{
229 return InnerProduct(vec_1.size(), &vec_1[0], &vec_2[0]);
230}
231
232void
233LU_Decompose(int num_entries, MatrixContainer& mat, int* index);
234
235void
236LU_Solve(int num_entries, MatrixContainer& mat, double* vec, int* index);
237
238void
239LU_SolveSystem(int num_entries, MatrixContainer& mat, double* vec, int* scratch);
240
242{
244
245 void
246 Resize(int len)
247 {
248 if (len != len_) {
249 len_ = len;
250 d.resize(len_);
251 r.resize(len_);
252 s.resize(len_);
253 q.resize(len_);
254 M.AllocateDiagonalMatrix(len_);
255 }
256 }
257
258 int len_;
259 std::vector<double> d;
260 std::vector<double> r;
261 std::vector<double> s;
262 std::vector<double> q;
264};
265
266bool
269 const double* b,
270 CGScratchSpace& cg_scratch,
271 double* x,
272 int& num_iterations,
273 double cg_tol = 1.0e-16,
274 int max_iterations = 1000);
275
276} // namespace nimble
277
278#endif
Definition nimble_linear_solver.h:119
void MatVec(const double *vec, double *result) const
Definition nimble_linear_solver.cc:118
friend void PopulateDiagonalPreconditioner(const CRSMatrixContainer &A, CRSMatrixContainer &M)
Generate a diagonal preconditioner from a sparse matrix.
Definition nimble_linear_solver.cc:138
unsigned int NumNonzeros() const
Definition nimble_linear_solver.h:164
CRSMatrixContainer()
Definition nimble_linear_solver.h:121
void SetColumnValues(int col, double value)
Definition nimble_linear_solver.cc:86
void AllocateNonzeros(std::vector< int > const &i_index, std::vector< int > const &j_index)
Definition nimble_linear_solver.cc:57
void SetAllValues(double value)
Definition nimble_linear_solver.h:146
void AllocateDiagonalMatrix(int num_rows)
Definition nimble_linear_solver.h:129
void DiagonalMatrixMatVec(const double *vec, double *result) const
Definition nimble_linear_solver.cc:125
int NumRows() const
Definition nimble_linear_solver.h:158
void SetRowValues(int row, double value)
Definition nimble_linear_solver.cc:80
double & operator()(int i_index, int j_index)
Definition nimble_linear_solver.h:182
double operator()(int i_index, int j_index) const
Definition nimble_linear_solver.h:176
Definition nimble_linear_solver.h:60
unsigned int NumNonzeros() const
Definition nimble_linear_solver.h:96
void SetAllValues(double value)
Definition nimble_linear_solver.h:78
double & operator()(int i, int j)
Definition nimble_linear_solver.h:108
~MatrixContainer()
Definition nimble_linear_solver.h:64
void AllocateNonzeros(std::vector< int > const &i_index, std::vector< int > const &j_index)
Definition nimble_linear_solver.h:67
double operator()(int i, int j) const
Definition nimble_linear_solver.h:102
void SetRowValues(int row, double value)
Definition nimble_linear_solver.h:84
MatrixContainer()
Definition nimble_linear_solver.h:62
void SetColumnValues(int col, double value)
Definition nimble_linear_solver.h:90
Definition kokkos_contact_manager.h:49
void LU_Solve(int num_entries, MatrixContainer &mat, double *vec, int *index)
void LU_SolveSystem(int num_entries, MatrixContainer &mat, double *vec, int *scratch)
double InnerProduct(unsigned int num_entries, const double *vec_1, const double *vec_2)
Definition nimble_linear_solver.h:215
bool CG_SolveSystem(nimble::CRSMatrixContainer &A, const double *b, CGScratchSpace &cg_scratch, double *x, int &num_iterations, double cg_tol, int max_iterations)
Definition nimble_linear_solver.cc:155
void LU_Decompose(int num_entries, MatrixContainer &mat, int *index)
Definition nimble_linear_solver.h:242
std::vector< double > q
Definition nimble_linear_solver.h:262
std::vector< double > d
Definition nimble_linear_solver.h:259
CGScratchSpace()
Definition nimble_linear_solver.h:243
int len_
Definition nimble_linear_solver.h:258
std::vector< double > r
Definition nimble_linear_solver.h:260
void Resize(int len)
Definition nimble_linear_solver.h:246
CRSMatrixContainer M
Definition nimble_linear_solver.h:263
std::vector< double > s
Definition nimble_linear_solver.h:261