Skip to content

Commit 2e65b53

Browse files
authored
Merge pull request #3386 from roystgnr/code_dedup2
More code deduplication
2 parents beee9d4 + 2fc8f81 commit 2e65b53

16 files changed

Lines changed: 732 additions & 1841 deletions

include/base/dof_map.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,18 @@ class DofMap : public ReferenceCountedObject<DofMap>,
15841584
void distribute_local_dofs_node_major (dof_id_type & next_free_dof,
15851585
MeshBase & mesh);
15861586

1587+
/*
1588+
* Helper method for the above two to count + distriubte SCALAR dofs
1589+
*/
1590+
void distribute_scalar_dofs (dof_id_type & next_free_dof);
1591+
1592+
#ifdef DEBUG
1593+
/*
1594+
* Internal assertions for distribute_local_dofs_*
1595+
*/
1596+
void assert_no_nodes_missed(MeshBase & mesh);
1597+
#endif
1598+
15871599
/*
15881600
* A utility method for obtaining a set of elements to ghost along
15891601
* with merged coupling matrices.

include/mesh/mesh_function.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ class MeshFunction : public FunctionBase<Number>,
353353
std::set<const Elem *> find_elements(const Point & p,
354354
const std::set<subdomain_id_type> * subdomain_ids = nullptr) const;
355355

356+
/**
357+
* Helper function for finding a gradient as evaluated from a
358+
* specific element
359+
*/
360+
void _gradient_on_elem (const Point & p,
361+
const Elem * element,
362+
std::vector<Gradient> & output);
363+
356364
/**
357365
* The equation systems handler, from which
358366
* the data are gathered.

include/numerics/dense_matrix.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,20 @@ class DenseMatrix : public DenseMatrixBase<T>
767767
DenseVector<T> & dest,
768768
const DenseVector<T> & arg,
769769
bool trans=false) const;
770+
771+
/**
772+
* Left multiplies by the transpose of the matrix \p A which
773+
* may contain a different numerical type.
774+
*/
775+
template <typename T2>
776+
void _left_multiply_transpose (const DenseMatrix<T2> & A);
777+
778+
/**
779+
* Right multiplies by the transpose of the matrix \p A which
780+
* may contain a different numerical type.
781+
*/
782+
template <typename T2>
783+
void _right_multiply_transpose (const DenseMatrix<T2> & A);
770784
};
771785

772786

include/numerics/dense_matrix_impl.h

Lines changed: 18 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -95,68 +95,21 @@ void DenseMatrix<T>::left_multiply_transpose(const DenseMatrix<T> & A)
9595
if (this->use_blas_lapack)
9696
this->_multiply_blas(A, LEFT_MULTIPLY_TRANSPOSE);
9797
else
98-
{
99-
//Check to see if we are doing (A^T)*A
100-
if (this == &A)
101-
{
102-
//libmesh_here();
103-
DenseMatrix<T> B(*this);
104-
105-
// Simple but inefficient way
106-
// return this->left_multiply_transpose(B);
107-
108-
// More efficient, but more code way
109-
// If A is mxn, the result will be a square matrix of Size n x n.
110-
const unsigned int n_rows = A.m();
111-
const unsigned int n_cols = A.n();
112-
113-
// resize() *this and also zero out all entries.
114-
this->resize(n_cols,n_cols);
115-
116-
// Compute the lower-triangular part
117-
for (unsigned int i=0; i<n_cols; ++i)
118-
for (unsigned int j=0; j<=i; ++j)
119-
for (unsigned int k=0; k<n_rows; ++k) // inner products are over n_rows
120-
(*this)(i,j) += B(k,i)*B(k,j);
121-
122-
// Copy lower-triangular part into upper-triangular part
123-
for (unsigned int i=0; i<n_cols; ++i)
124-
for (unsigned int j=i+1; j<n_cols; ++j)
125-
(*this)(i,j) = (*this)(j,i);
126-
}
98+
this->_left_multiply_transpose(A);
99+
}
127100

128-
else
129-
{
130-
DenseMatrix<T> B(*this);
131-
132-
this->resize (A.n(), B.n());
133-
134-
libmesh_assert_equal_to (A.m(), B.m());
135-
libmesh_assert_equal_to (this->m(), A.n());
136-
libmesh_assert_equal_to (this->n(), B.n());
137-
138-
const unsigned int m_s = A.n();
139-
const unsigned int p_s = A.m();
140-
const unsigned int n_s = this->n();
141-
142-
// Do it this way because there is a
143-
// decent chance (at least for constraint matrices)
144-
// that A.transpose(i,k) = 0.
145-
for (unsigned int i=0; i<m_s; i++)
146-
for (unsigned int k=0; k<p_s; k++)
147-
if (A.transpose(i,k) != 0.)
148-
for (unsigned int j=0; j<n_s; j++)
149-
(*this)(i,j) += A.transpose(i,k)*B(k,j);
150-
}
151-
}
152101

102+
template<typename T>
103+
template<typename T2>
104+
void DenseMatrix<T>::left_multiply_transpose(const DenseMatrix<T2> & A)
105+
{
106+
this->_left_multiply_transpose(A);
153107
}
154108

155109

156-
157110
template<typename T>
158111
template<typename T2>
159-
void DenseMatrix<T>::left_multiply_transpose(const DenseMatrix<T2> & A)
112+
void DenseMatrix<T>::_left_multiply_transpose(const DenseMatrix<T2> & A)
160113
{
161114
//Check to see if we are doing (A^T)*A
162115
if (this == &A)
@@ -267,67 +220,23 @@ void DenseMatrix<T>::right_multiply_transpose (const DenseMatrix<T> & B)
267220
if (this->use_blas_lapack)
268221
this->_multiply_blas(B, RIGHT_MULTIPLY_TRANSPOSE);
269222
else
270-
{
271-
//Check to see if we are doing B*(B^T)
272-
if (this == &B)
273-
{
274-
//libmesh_here();
275-
DenseMatrix<T> A(*this);
276-
277-
// Simple but inefficient way
278-
// return this->right_multiply_transpose(A);
279-
280-
// More efficient, more code
281-
// If B is mxn, the result will be a square matrix of Size m x m.
282-
const unsigned int n_rows = B.m();
283-
const unsigned int n_cols = B.n();
284-
285-
// resize() *this and also zero out all entries.
286-
this->resize(n_rows,n_rows);
287-
288-
// Compute the lower-triangular part
289-
for (unsigned int i=0; i<n_rows; ++i)
290-
for (unsigned int j=0; j<=i; ++j)
291-
for (unsigned int k=0; k<n_cols; ++k) // inner products are over n_cols
292-
(*this)(i,j) += A(i,k)*A(j,k);
293-
294-
// Copy lower-triangular part into upper-triangular part
295-
for (unsigned int i=0; i<n_rows; ++i)
296-
for (unsigned int j=i+1; j<n_rows; ++j)
297-
(*this)(i,j) = (*this)(j,i);
298-
}
299-
300-
else
301-
{
302-
DenseMatrix<T> A(*this);
303-
304-
this->resize (A.m(), B.m());
305-
306-
libmesh_assert_equal_to (A.n(), B.n());
307-
libmesh_assert_equal_to (this->m(), A.m());
308-
libmesh_assert_equal_to (this->n(), B.m());
309-
310-
const unsigned int m_s = A.m();
311-
const unsigned int p_s = A.n();
312-
const unsigned int n_s = this->n();
313-
314-
// Do it this way because there is a
315-
// decent chance (at least for constraint matrices)
316-
// that B.transpose(k,j) = 0.
317-
for (unsigned int j=0; j<n_s; j++)
318-
for (unsigned int k=0; k<p_s; k++)
319-
if (B.transpose(k,j) != 0.)
320-
for (unsigned int i=0; i<m_s; i++)
321-
(*this)(i,j) += A(i,k)*B.transpose(k,j);
322-
}
323-
}
223+
this->_right_multiply_transpose(B);
324224
}
325225

326226

327227

328228
template<typename T>
329229
template<typename T2>
330230
void DenseMatrix<T>::right_multiply_transpose (const DenseMatrix<T2> & B)
231+
{
232+
this->_right_multiply_transpose(B);
233+
}
234+
235+
236+
237+
template<typename T>
238+
template<typename T2>
239+
void DenseMatrix<T>::_right_multiply_transpose (const DenseMatrix<T2> & B)
331240
{
332241
//Check to see if we are doing B*(B^T)
333242
if (this == &B)

include/solvers/petsc_linear_solver.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,26 @@ class PetscLinearSolver : public LinearSolver<T>
279279
*/
280280
virtual std::pair<unsigned int, Real>
281281
shell_solve_common (const ShellMatrix<T> & shell_matrix,
282-
const PetscMatrix<T> * precond_matrix,
282+
PetscMatrix<T> * precond_matrix,
283283
NumericVector<T> & solution_in,
284284
NumericVector<T> & rhs_in,
285285
const double tol,
286286
const unsigned int m_its);
287287

288+
/*
289+
* Helper function for the helper functions
290+
*/
291+
std::pair<unsigned int, Real>
292+
solve_base (SparseMatrix<T> * matrix,
293+
PetscMatrix<T> * precond,
294+
Mat mat,
295+
NumericVector<T> & solution_in,
296+
NumericVector<T> & rhs_in,
297+
const double tol,
298+
const unsigned int m_its,
299+
ksp_solve_func_type solve_func);
300+
301+
288302
/**
289303
* Tells PETSC to use the user-specified solver stored in
290304
* \p _solver_type

include/utils/xdr_cxx.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@
3636
#include "libmesh/restore_warnings.h"
3737
#endif
3838

39+
#include <complex>
3940
#include <iosfwd>
4041
#include <vector>
4142
#include <string>
42-
#ifdef LIBMESH_USE_COMPLEX_NUMBERS
43-
# include <complex>
44-
#endif
4543

4644
const unsigned int xdr_MAX_STRING_LENGTH=256;
4745

@@ -197,6 +195,27 @@ class Xdr
197195
template <typename T>
198196
void do_write(std::vector<std::complex<T>> & a);
199197

198+
/**
199+
* Helper method for complex types
200+
*/
201+
template <typename T>
202+
void _complex_data_stream (std::complex<T> * val, const unsigned int len,
203+
const unsigned int line_break);
204+
205+
/**
206+
* Helper method for extended FP types
207+
*/
208+
template <typename XFP>
209+
void _xfp_data_stream (XFP * val, const unsigned int len,
210+
#ifdef LIBMESH_HAVE_XDR
211+
xdrproc_t
212+
#else
213+
void *
214+
#endif
215+
xdr_proc,
216+
const unsigned int line_break,
217+
const int n_digits);
218+
200219
/**
201220
* The mode used for accessing the file.
202221
*/

src/base/dof_map.C

Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,46 +1274,10 @@ void DofMap::distribute_local_dofs_node_major(dof_id_type & next_free_dof,
12741274
}
12751275
}
12761276

1277-
// Finally, count up the SCALAR dofs
1278-
this->_n_SCALAR_dofs = 0;
1279-
for (unsigned vg=0; vg<n_var_groups; vg++)
1280-
{
1281-
const VariableGroup & vg_description(this->variable_group(vg));
1282-
1283-
if (vg_description.type().family == SCALAR)
1284-
{
1285-
this->_n_SCALAR_dofs += (vg_description.n_variables()*
1286-
vg_description.type().order.get_order());
1287-
continue;
1288-
}
1289-
}
1290-
1291-
// Only increment next_free_dof if we're on the processor
1292-
// that holds this SCALAR variable
1293-
if (this->processor_id() == (this->n_processors()-1))
1294-
next_free_dof += _n_SCALAR_dofs;
1277+
this->distribute_scalar_dofs(next_free_dof);
12951278

12961279
#ifdef DEBUG
1297-
{
1298-
// libMesh::out << "next_free_dof=" << next_free_dof << std::endl
1299-
// << "_n_SCALAR_dofs=" << _n_SCALAR_dofs << std::endl;
1300-
1301-
// Make sure we didn't miss any nodes
1302-
MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1303-
1304-
for (auto & node : mesh.local_node_ptr_range())
1305-
{
1306-
unsigned int n_var_g = node->n_var_groups(this->sys_number());
1307-
for (unsigned int vg=0; vg != n_var_g; ++vg)
1308-
{
1309-
unsigned int n_comp_g =
1310-
node->n_comp_group(this->sys_number(), vg);
1311-
dof_id_type my_first_dof = n_comp_g ?
1312-
node->vg_dof_base(this->sys_number(), vg) : 0;
1313-
libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1314-
}
1315-
}
1316-
}
1280+
this->assert_no_nodes_missed(mesh);
13171281
#endif // DEBUG
13181282
}
13191283

@@ -1405,9 +1369,19 @@ void DofMap::distribute_local_dofs_var_major(dof_id_type & next_free_dof,
14051369
}
14061370
} // end loop on variable groups
14071371

1408-
// Finally, count up the SCALAR dofs
1372+
this->distribute_scalar_dofs(next_free_dof);
1373+
1374+
#ifdef DEBUG
1375+
this->assert_no_nodes_missed(mesh);
1376+
#endif
1377+
}
1378+
1379+
1380+
1381+
void DofMap::distribute_scalar_dofs(dof_id_type & next_free_dof)
1382+
{
14091383
this->_n_SCALAR_dofs = 0;
1410-
for (unsigned vg=0; vg<n_var_groups; vg++)
1384+
for (auto vg : make_range(this->n_variable_groups()))
14111385
{
14121386
const VariableGroup & vg_description(this->variable_group(vg));
14131387

@@ -1423,28 +1397,29 @@ void DofMap::distribute_local_dofs_var_major(dof_id_type & next_free_dof,
14231397
// that holds this SCALAR variable
14241398
if (this->processor_id() == (this->n_processors()-1))
14251399
next_free_dof += _n_SCALAR_dofs;
1400+
}
1401+
1402+
14261403

14271404
#ifdef DEBUG
1428-
{
1429-
// Make sure we didn't miss any nodes
1430-
MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1405+
void DofMap::assert_no_nodes_missed(MeshBase & mesh)
1406+
{
1407+
MeshTools::libmesh_assert_valid_procids<Node>(mesh);
14311408

1432-
for (auto & node : mesh.local_node_ptr_range())
1433-
{
1434-
unsigned int n_var_g = node->n_var_groups(this->sys_number());
1435-
for (unsigned int vg=0; vg != n_var_g; ++vg)
1436-
{
1437-
unsigned int n_comp_g =
1438-
node->n_comp_group(this->sys_number(), vg);
1439-
dof_id_type my_first_dof = n_comp_g ?
1440-
node->vg_dof_base(this->sys_number(), vg) : 0;
1441-
libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1442-
}
1443-
}
1444-
}
1445-
#endif // DEBUG
1409+
for (auto & node : mesh.local_node_ptr_range())
1410+
{
1411+
unsigned int n_var_g = node->n_var_groups(this->sys_number());
1412+
for (unsigned int vg=0; vg != n_var_g; ++vg)
1413+
{
1414+
unsigned int n_comp_g =
1415+
node->n_comp_group(this->sys_number(), vg);
1416+
dof_id_type my_first_dof = n_comp_g ?
1417+
node->vg_dof_base(this->sys_number(), vg) : 0;
1418+
libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1419+
}
1420+
}
14461421
}
1447-
1422+
#endif // DEBUG
14481423

14491424

14501425
void

0 commit comments

Comments
 (0)