20 #ifndef __mast_libmesh_wrapper_elasticity_null_space_h__ 21 #define __mast_libmesh_wrapper_elasticity_null_space_h__ 31 #include <libmesh/system.h> 32 #include <libmesh/dof_map.h> 33 #include <libmesh/mesh_base.h> 34 #include <libmesh/petsc_vector.h> 35 #include <libmesh/node.h> 42 namespace Elasticity {
43 namespace libMeshWrapper {
57 "Number of unknowns should be equal to spatial dimension");
61 Assert0(
_sys.variable_type(i).family == libMesh::LAGRANGE,
62 "Variables are expected to be LAGRANGE");
73 PetscErrorCode ierr = 0;
75 ierr = MatNullSpaceDestroy(&
_mns);
76 CHKERRABORT(
_sys.comm().get(), ierr);
80 inline MatNullSpace
get() {
89 PetscErrorCode ierr = 0;
91 ierr = MatSetNearNullSpace(m,
_mns);
92 CHKERRABORT(
_sys.comm().get(), ierr);
104 n_translation =
_dim,
115 std::vector<libMesh::NumericVector<real_t>*>
116 vecs(n_translation+n_rotation,
nullptr);
118 std::vector<libMesh::dof_id_type>
122 for (
uint_t i=0; i<vecs.size(); i++)
123 vecs[i] =
_sys.solution->zero_clone().release();
125 libMesh::MeshBase::const_node_iterator
126 it =
_sys.get_mesh().local_nodes_begin(),
127 end =
_sys.get_mesh().local_nodes_end();
129 for ( ; it != end; it++) {
131 const libMesh::Node& n = **it;
135 _sys.get_dof_map().dof_indices(&n, dof_ids);
138 Assert2(dof_ids.size() == n_translation,
139 dof_ids.size(), n_translation,
140 "Invalid number of dofs on node");
143 for (
uint_t i=0; i<n_translation; i++)
144 vecs[i]->
set(dof_ids[i], 1.);
147 for (
uint_t i=0; i<n_rotation; i++) {
149 libMesh::NumericVector<real_t>
150 &v = *vecs[n_translation + i];
162 (cos(th) * n(0) - sin(th) * n(1)) - n(0));
164 (sin(th) * n(0) + cos(th) * n(1)) - n(1));
175 (cos(th) * n(1) - sin(th) * n(2)) - n(1));
177 (sin(th) * n(1) + cos(th) * n(2)) - n(2));
188 (cos(th) * n(0) + sin(th) * n(2)) - n(0));
190 (-sin(th) * n(0) + cos(th) * n(2)) - n(2));
195 Error(
false,
"Invalid rotation vector index");
203 for (
uint_t i=0; i<vecs.size(); i++)
214 n_translation =
_dim;
217 std::vector<libMesh::NumericVector<real_t>*>
218 vecs(n_translation,
nullptr);
220 std::vector<libMesh::dof_id_type>
224 for (
uint_t i=0; i<vecs.size(); i++)
225 vecs[i] =
_sys.solution->zero_clone().release();
227 libMesh::MeshBase::const_node_iterator
228 it =
_sys.get_mesh().local_nodes_begin(),
229 end =
_sys.get_mesh().local_nodes_end();
231 for ( ; it != end; it++) {
233 const libMesh::Node& n = **it;
237 _sys.get_dof_map().dof_indices(&n, dof_ids);
240 Assert2(dof_ids.size() == n_translation,
241 dof_ids.size(), n_translation,
242 "Invalid number of dofs on node");
245 for (
uint_t i=0; i<n_translation; i++)
246 vecs[i]->
set(dof_ids[i], 1.);
252 for (
uint_t i=0; i<vecs.size(); i++)
259 (std::vector<libMesh::NumericVector<real_t>*>& vecs) {
265 for (
uint_t i=0; i<vecs.size(); i++) {
271 for (
uint_t j=0; j<i; j++) {
274 v = vecs[i]->dot(*vecs[j]);
276 vecs[i]->add(-v, *vecs[j]);
280 l2 = vecs[i]->l2_norm();
282 vecs[i]->scale(1./l2);
284 l2 = vecs[i]->l2_norm();
287 for (
uint_t j=0; j<i; j++) {
291 v = vecs[i]->dot(*vecs[j]);
293 Assert2(fabs(v) < std::sqrt(std::numeric_limits<real_t>::epsilon()),
294 fabs(v), std::sqrt(std::numeric_limits<real_t>::epsilon()),
295 "Vector should be orthogonal");
300 std::vector<Vec> v(vecs.size());
301 for (
uint_t i=0; i<vecs.size(); i++)
302 v[i] =
dynamic_cast<libMesh::PetscVector<real_t>*
>(vecs[i])->vec();
304 ierr = MatNullSpaceCreate(
_sys.comm().get(),
309 CHKERRABORT(
_sys.comm().get(), ierr);
327 #endif // __mast_libmesh_wrapper_elasticity_null_space_h__
void _orthonormalize_and_create_basis(std::vector< libMesh::NumericVector< real_t > *> &vecs)
#define Assert1(cond, v1, msg)
NullSpace(libMesh::System &sys, uint_t dim, bool enable_rotation)
void attach_to_matrix(Mat m)
void _init_without_rotation()
void _init_with_rotation()
#define Assert0(cond, msg)
#define Assert2(cond, v1, v2, msg)