BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
cl_Cochain.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California,
4 * through Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12
13#include <iostream>
14#include "typedefs.hpp"
15#include "assert.hpp"
16#include "cl_Map.hpp"
17#include "cl_Cell.hpp"
18#include "cl_Vertex.hpp"
19#include "cl_Mesh.hpp"
20#include "cl_Chain.hpp"
21
22#ifndef BELFEM_CL_COCHAIN_HPP
23#define BELFEM_CL_COCHAIN_HPP
24
25namespace belfem
26{
27 namespace mesh
28 {
29//-----------------------------------------------------------------------------
36 class Cochain
37 {
38 //Dimensions of the cochain
39 int mDim ;
40
41 //Mesh
42 Mesh * mMesh ;
43
44 //Map of the k-simplices coefficients
45 OrderedMap< index_t, int > mSimplicesMap ;
46
47 //Coboundary cochain of the given cochain
48 Cochain * mCoboundary = nullptr;
49
50 //Boundary
51 Cochain * mBoundary = nullptr;
52
53 bool mIsBound = false;
54 bool mIsCobound = false;
55
56//-----------------------------------------------------------------------------
57 public:
58//-----------------------------------------------------------------------------
59
60 Cochain(const uint aDim, Mesh* aMesh,
61 const bool aIsBound, const bool aIsCobound) ;
62
63//-----------------------------------------------------------------------------
64
65 ~Cochain();
66
67//-----------------------------------------------------------------------------
68
69 void
70 operator+( Cochain * aCochain ) ;
71
72//-----------------------------------------------------------------------------
73
74 void
75 operator-( Cochain * aCochain ) ;
76
77//-----------------------------------------------------------------------------
78
79 int
80 operator()( Chain * aChain ) ;
81
82//-----------------------------------------------------------------------------
83
84 void
85 addSimplexToCochain(const index_t aID, const int aCoeff ) ;
86
87//-----------------------------------------------------------------------------
88
89 void
91
92//-----------------------------------------------------------------------------
93
94 void
95 addCochainToCochain(Cochain * aCochain, const int aCoeff) ;
96
97//-----------------------------------------------------------------------------
98
99 void
101
102//-----------------------------------------------------------------------------
103
106
107//-----------------------------------------------------------------------------
108
109 int
110 getCoefficient(const index_t aID) ;
111
112//-----------------------------------------------------------------------------
113
114 Cochain*
115 getCoboundary() ;
116
117//-----------------------------------------------------------------------------
118
119 Cochain*
120 getBoundary() ;
121
122//-----------------------------------------------------------------------------
123
124 void
125 add_simplex_to_coboundary(index_t aID, const int aCoeff) ;
126
127//-----------------------------------------------------------------------------
128
129 void
130 add_simplex_to_boundary(index_t aID, const int aCoeff) ;
131
132//-----------------------------------------------------------------------------
133
134 int
135 getDim() ;
136
137//-----------------------------------------------------------------------------
138
139 bool
140 isBound() ;
141
142//-----------------------------------------------------------------------------
143
144 bool
145 isCobound() ;
146
147//-----------------------------------------------------------------------------
148
149 void
150 setCoefficient(const index_t aID, const int tCoeff) ;
151
152//-----------------------------------------------------------------------------
153
154 void
155 print() ;
156
157//-----------------------------------------------------------------------------
158
159 };
160
161//-----------------------------------------------------------------------------
162
165 {
166 return mSimplicesMap;
167 }
168
169//------------------------------------------------------------------------------
170
171 inline int
173 {
174 auto it = mSimplicesMap.find(aID);
175 if (it != mSimplicesMap.end()) {
176 return it->second;
177 }
178 else {
179 return 0;
180 }
181 }
182
183//------------------------------------------------------------------------------
184
185 inline Cochain *
187 {
188 return mCoboundary;
189 }
190
191//------------------------------------------------------------------------------
192
193 inline Cochain *
195 {
196 return mBoundary;
197 }
198
199//------------------------------------------------------------------------------
200
201 inline void
203 {
204 mCoboundary->addSimplexToCochain(aID,aCoeff);
205 }
206
207//------------------------------------------------------------------------------
208
209 inline void
211 {
212 mBoundary->addSimplexToCochain(aID,aCoeff);
213 }
214
215//------------------------------------------------------------------------------
216
217 inline int
219 {
220 return mDim;
221 }
222
223//------------------------------------------------------------------------------
224
225 inline bool
227 {
228 return mIsBound;
229 }
230
231//------------------------------------------------------------------------------
232
233 inline bool
235 {
236 return mIsCobound;
237 }
238
239//------------------------------------------------------------------------------
240
241 inline void
242 Cochain::setCoefficient(const index_t aID, const int tCoeff)
243 {
244 if (tCoeff == 0)
245 {
246 mSimplicesMap.erase_key(aID);
247 }
248 else
249 {
250 mSimplicesMap[aID] = tCoeff;
251 }
252 }
253
254//-----------------------------------------------------------------------------
255
256 inline void
257 Cochain::addSimplexToCochain( const index_t aID, const int aCoeff )
258 {
259 if ( aCoeff == 0 ) return;
260
261 auto & tMap = mSimplicesMap.map_data() ;
262 auto tIterator = tMap.find(aID) ;
263
264 if ( tIterator != tMap.end() )
265 {
266 // Key exists - update in place
267 tIterator->second += aCoeff;
268
269 // Remove if coefficient becomes 0
270 if ( tIterator->second == 0 )
271 {
272 tMap.erase( tIterator ) ;
273 }
274 }
275 else // we know that aCoeff != 0
276 {
277 // only add if non-zero coefficient
278 tMap[ aID ] = aCoeff ;
279 }
280
281 }
282
283
284//-----------------------------------------------------------------------------
285
286 inline void
287 Cochain::addCochainToCochain(Cochain * aCochain, int aCoeff)
288 {
289 if ( aCoeff == 0 ) return; // Early exit - nothing to add
290
291 if (mDim == aCochain->getDim())
292 {
293 // Add all the simplices from the input chain
294 for( const auto& [tID, tCoeff] : aCochain->getSimplicesMap() )
295 {
296 this->addSimplexToCochain(tID,tCoeff*aCoeff);
297 }
298 if(mDim != 0 and !mIsBound)
299 {
300 mBoundary->addCochainToCochain(aCochain->getBoundary(),aCoeff);
301 }
302
303 if (mDim != 3 and !mIsCobound)
304 {
305 mCoboundary->addCochainToCochain(aCochain->getCoboundary(),aCoeff);
306 }
307
308 }
309 else
310 {
311 std::cout << "Dimensions don't agree, not adding the cochain" << std::endl;
312 }
313 }
314
315//------------------------------------------------------------------------------
316 }
317}
318#endif //BELFEM_CL_COCHAIN_HPP
Top-level container for all mesh entities.
Definition cl_Mesh.hpp:60
auto find(const Key &tKey) const -> decltype(mMap.find(tKey))
Definition cl_OrderedMap.hpp:139
Formal sum of k-simplices (homology).
Definition cl_Chain.hpp:36
Cochain: a functional on chains (cohomology).
Definition cl_Cochain.hpp:37
void print()
Definition cl_Cochain.cpp:118
bool isCobound()
Definition cl_Cochain.hpp:234
Cochain * getBoundary()
Definition cl_Cochain.hpp:194
void add_simplex_to_boundary(index_t aID, const int aCoeff)
Definition cl_Cochain.hpp:210
int getDim()
Definition cl_Cochain.hpp:218
OrderedMap< index_t, int > & getSimplicesMap()
Definition cl_Cochain.hpp:164
int getCoefficient(const index_t aID)
Definition cl_Cochain.hpp:172
void removeSimplexToCochain(const index_t aID)
Definition cl_Cochain.cpp:91
Cochain(const uint aDim, Mesh *aMesh, const bool aIsBound, const bool aIsCobound)
Definition cl_Cochain.cpp:21
void removeCochainFromCochain(Cochain *aChain)
Definition cl_Cochain.cpp:100
void setCoefficient(const index_t aID, const int tCoeff)
Definition cl_Cochain.hpp:242
void addSimplexToCochain(const index_t aID, const int aCoeff)
Definition cl_Cochain.hpp:257
void operator-(Cochain *aCochain)
Definition cl_Cochain.cpp:65
int operator()(Chain *aChain)
Definition cl_Cochain.cpp:73
Cochain * getCoboundary()
Definition cl_Cochain.hpp:186
void add_simplex_to_coboundary(index_t aID, const int aCoeff)
Definition cl_Cochain.hpp:202
void operator+(Cochain *aCochain)
Definition cl_Cochain.cpp:57
void addCochainToCochain(Cochain *aCochain, const int aCoeff)
Definition cl_Cochain.hpp:287
bool isBound()
Definition cl_Cochain.hpp:226
Definition cl_EF_EdgeFunction.hpp:17
USER GUIDES:
Definition cl_Capacitor.cpp:16
unsigned int uint
Definition typedefs.hpp:30
uint32_t index_t
Definition typedefs.hpp:52