LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
write_matlab.cc
1
3#include "write_matlab.h"
4
5#include <fstream>
6
7namespace lf::io {
8
9void writeMatlab(const lf::mesh::Mesh& mesh, std::string filename) {
10 using size_type = std::size_t; // unsigned integer
11 using dim_t = lf::base::RefEl::dim_t; // type for dimensions
12 const Eigen::MatrixXd zero(Eigen::MatrixXd::Zero(0, 1));
13
14 // Preprocess filename: append .m, if not there already
15 {
16 const size_type fn_len = filename.size();
17 if ((fn_len > 1) && (filename[fn_len - 2] != '.') &&
18 (filename[fn_len - 1] != 'm')) {
19 filename += ".m";
20 }
21 }
22 // Open file for writing
23 std::ofstream file(filename);
24 if (file.is_open()) {
25 // Start regular writing operations
26 // Remove trailing .m
27 filename.pop_back();
28 filename.pop_back();
29 file << "function [x,y,TRI,QUAD,EDS] = " << filename << "()" << '\n';
30 file << "% Data for an unstructure planar hybrid 2D mesh" << '\n';
31
32 // Obtain topological dimension of the mesh
33 const dim_t dim_mesh = mesh.DimMesh();
34 LF_VERIFY_MSG(dim_mesh == 2,
35 "write_matlab() only avvailable for 2D meshes");
36
37 // Run through the nodes of the mesh and write x coordinates
38 const dim_t node_codim(dim_mesh);
39 // Number of nodes of the mesh
40 const size_type no_of_nodes = mesh.NumEntities(node_codim);
41 file << "x = zeros(" << no_of_nodes << ",1);" << '\n';
42 file << "y = zeros(" << no_of_nodes << ",1);" << '\n';
43
44 // Write node coordinates to file
45 size_type node_cnt = 0;
46 for (const mesh::Entity* node : mesh.Entities(node_codim)) {
47 const lf::base::glb_idx_t node_index = mesh.Index(*node);
48 const geometry::Geometry* geo_ptr = node->Geometry();
49 Eigen::MatrixXd node_coord(geo_ptr->Global(zero));
50 file << "x(" << node_index + 1 << ") = " << node_coord(0, 0) << "; "
51 << '\n';
52 file << "y(" << node_index + 1 << ") = " << node_coord(1, 0) << "; "
53 << '\n';
54 node_cnt++;
55 }
56 LF_VERIFY_MSG(node_cnt == no_of_nodes, "Node count mismatch");
57
58 // Write edge information to file
59 const size_type no_of_edges = mesh.NumEntities(1);
60 file << "EDS = zeros(" << no_of_edges << ",2);" << '\n';
61 size_type ed_cnt = 0;
62 for (const mesh::Entity* edge : mesh.Entities(1)) {
63 const lf::base::glb_idx_t edge_index = mesh.Index(*edge);
64 const base::RefEl ref_el = edge->RefEl();
65 LF_VERIFY_MSG(ref_el == lf::base::RefEl::kSegment(),
66 "Edge must be a segment");
67 // Access endpoints = sub-entities of relative co-dimension 1
68 const auto sub_ent = edge->SubEntities(1);
69 file << "EDS(" << edge_index + 1 << ",:) = ["
70 << mesh.Index(*sub_ent[0]) + 1 << ", " << mesh.Index(*sub_ent[1]) + 1
71 << "];" << '\n';
72 ed_cnt++;
73 }
74
75 // Write cell (entities of co-dimension 0) information to file
76 file << "TRI = []; QUAD = [];" << '\n';
77 size_type cell_cnt = 0;
78 size_type triag_cnt = 0;
79 size_type quad_cnt = 0;
80 for (const mesh::Entity* e : mesh.Entities(0)) {
81 const lf::base::glb_idx_t cell_index = mesh.Index(*e);
82 // Access vertices = sub-entities of relative co-dimension 2
83 const auto sub_ent = e->SubEntities(2);
84 const base::RefEl ref_el = e->RefEl();
85 switch (ref_el) {
87 file << "TRI(" << triag_cnt + 1 << ",:) = ["
88 << mesh.Index(*sub_ent[0]) + 1 << ", "
89 << mesh.Index(*sub_ent[1]) + 1 << ", "
90 << mesh.Index(*sub_ent[2]) + 1 << ", " << cell_index << " ];"
91 << '\n';
92 triag_cnt++;
93 break;
94 }
96 file << "QUAD(" << quad_cnt + 1 << ",:) = ["
97 << mesh.Index(*sub_ent[0]) + 1 << ", "
98 << mesh.Index(*sub_ent[1]) + 1 << ", "
99 << mesh.Index(*sub_ent[2]) + 1 << ", "
100 << mesh.Index(*sub_ent[3]) + 1 << ", " << cell_index << " ];"
101 << '\n';
102 quad_cnt++;
103 break;
104 }
105 default: {
106 LF_VERIFY_MSG(false,
107 "write_matlab can only handle triangles and quads");
108 break;
109 }
110 }
111 cell_cnt++;
112 }
113 }
114}
115
116} // namespace lf::io
Represents a reference element with all its properties.
Definition ref_el.h:109
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
Definition ref_el.h:153
constexpr RefEl(RefElType type) noexcept
Create a RefEl from a lf::base::RefElType enum.
Definition ref_el.h:175
unsigned int dim_t
Definition ref_el.h:132
static constexpr RefEl kTria()
Returns the reference triangle.
Definition ref_el.h:161
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Definition ref_el.h:169
Interface class for shape information on a mesh cell in the spirit of parametric finite element metho...
virtual Eigen::MatrixXd Global(const Eigen::MatrixXd &local) const =0
Map a number of points in local coordinates into the global coordinate system.
Interface class representing a topological entity in a cellular complex
Definition entity.h:42
Abstract interface for objects representing a single mesh.
virtual std::span< const Entity *const > Entities(unsigned codim) const =0
All entities of a given codimension.
virtual size_type NumEntities(unsigned codim) const =0
The number of Entities that have the given codimension.
virtual unsigned DimMesh() const =0
The dimension of the manifold described by the mesh, or equivalently the maximum dimension of the ref...
virtual size_type Index(const Entity &e) const =0
Acess to the index of a mesh entity of any co-dimension.
unsigned int glb_idx_t
type for global index of mesh entities (nodes, edges, cells)
Definition types.h:24
Mesh input (from file) and output (in various formats) facilities.
void writeMatlab(const lf::mesh::Mesh &mesh, std::string filename)
Writes affine triangulation data to file in MATLAB format.