PolyFEM
Loading...
Searching...
No Matches
VarFormUtils.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <polyfem/Common.hpp>
4
9
10#include <unsupported/Eigen/SparseExtra>
11
12#include <algorithm>
13#include <map>
14#include <unordered_map>
15#include <vector>
16
18{
19
21 const mesh::Mesh &mesh,
22 const std::vector<basis::ElementBases> &field_bases,
23 const std::vector<basis::ElementBases> &gbases,
24 const io::OutputSample &sample,
25 const Eigen::MatrixXd &dof_values,
26 Eigen::MatrixXd &values,
27 Eigen::MatrixXd *gradients = nullptr)
28 {
29 if (dof_values.size() <= 0)
30 return false;
31
32 const bool has_element_samples =
33 sample.local_points.rows() > 0
34 && sample.local_points.rows() == sample.element_ids.size();
35
36 if (has_element_samples)
37 {
38 values.resize(sample.local_points.rows(), 1);
39 if (gradients)
40 gradients->resize(sample.local_points.rows(), mesh.dimension());
41 for (int i = 0; i < sample.local_points.rows(); ++i)
42 {
43 const int element_id = sample.element_ids(i);
44 if (element_id < 0)
45 {
46 values(i) = 0;
47 if (gradients)
48 gradients->row(i).setZero();
49 continue;
50 }
51
52 Eigen::MatrixXd local_sol, local_grad;
54 mesh, 1, field_bases, gbases,
55 element_id, sample.local_points.row(i), dof_values, local_sol, local_grad);
56 values(i) = local_sol(0);
57 if (gradients)
58 gradients->row(i) = local_grad;
59 }
60 return true;
61 }
62
63 if (sample.node_ids.size() > 0)
64 {
65 values.resize(sample.node_ids.size(), 1);
66 for (int i = 0; i < sample.node_ids.size(); ++i)
67 {
68 const int node_id = sample.node_ids(i);
69 if (node_id < 0 || node_id >= dof_values.rows())
70 return false;
71 values(i) = dof_values(node_id);
72 }
73 return true;
74 }
75
76 return false;
77 }
78
80 const int full_size,
81 const StiffnessMatrix &primary,
82 StiffnessMatrix &expanded)
83 {
84 std::vector<Eigen::Triplet<double>> blocks;
85 blocks.reserve(primary.nonZeros());
86 for (int k = 0; k < primary.outerSize(); ++k)
87 {
88 for (StiffnessMatrix::InnerIterator it(primary, k); it; ++it)
89 blocks.emplace_back(it.row(), it.col(), it.value());
90 }
91
92 expanded.resize(full_size, full_size);
93 expanded.setFromTriplets(blocks.begin(), blocks.end());
94 expanded.makeCompressed();
95 }
96
97 inline bool write_matrix_market(const json &args, const StiffnessMatrix &stiffness)
98 {
99 const std::string full_mat_path = args["output"]["data"]["full_mat"];
100 if (full_mat_path.empty())
101 return false;
102
103 Eigen::saveMarket(stiffness, full_mat_path);
104 return true;
105 }
106} // namespace polyfem::varform::internal
static void interpolate_at_local_vals(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const int el_index, const Eigen::MatrixXd &local_pts, const Eigen::MatrixXd &fun, Eigen::MatrixXd &result, Eigen::MatrixXd &result_grad)
interpolate solution and gradient at element (calls interpolate_at_local_vals with sol)
Abstract mesh class to capture 2d/3d conforming and non-conforming meshes.
Definition Mesh.hpp:41
int dimension() const
utily for dimension
Definition Mesh.hpp:153
bool write_matrix_market(const json &args, const StiffnessMatrix &stiffness)
bool sample_scalar_field(const mesh::Mesh &mesh, const std::vector< basis::ElementBases > &field_bases, const std::vector< basis::ElementBases > &gbases, const io::OutputSample &sample, const Eigen::MatrixXd &dof_values, Eigen::MatrixXd &values, Eigen::MatrixXd *gradients=nullptr)
void expand_primary_matrix(const int full_size, const StiffnessMatrix &primary, StiffnessMatrix &expanded)
nlohmann::json json
Definition Common.hpp:9
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
Definition Types.hpp:24
Eigen::VectorXi node_ids
Eigen::VectorXi element_ids
Eigen::MatrixXd local_points