File: programming

package info (click to toggle)
feenox 1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 12,068 kB
  • sloc: ansic: 28,856; sh: 7,201; makefile: 556; python: 554; xml: 500
file content (469 lines) | stat: -rw-r--r-- 18,375 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
FeenoX programming guide

- 1 Why we program FeenoX
- 2 Compiling and debugging
- 3 How we program FeenoX
  - 3.1 Operating systems
  - 3.2 Languages
  - 3.3 Programming IDEs
    - 3.3.1 Netbeans
  - 3.4 Makefiles
  - 3.5 Test suite
  - 3.6 Coding style
  - 3.7 Virtual methods
  - 3.8 Memory management
  - 3.9 Naming conventions
  - 3.10 Comments
  - 3.11 Indices in PDEs
  - 3.12 Git workflow
  - 3.13 Standards
  - 3.14 Mentioning other libraries, programs, codes, etc.
  - 3.15 Documentation
- 4 What we program in FeenoX
- 5 Code of conduct
- 6 Release plans

  [1 Why we program FeenoX]: #why-we-program-feenox
  [2 Compiling and debugging]: #compiling-and-debugging
  [3 How we program FeenoX]: #how-we-program-feenox
  [3.1 Operating systems]: #operating-systems
  [3.2 Languages]: #languages
  [3.3 Programming IDEs]: #programming-ides
  [3.3.1 Netbeans]: #netbeans
  [3.4 Makefiles]: #makefiles
  [3.5 Test suite]: #sec:test-suite
  [3.6 Coding style]: #coding-style
  [3.7 Virtual methods]: #virtual-methods
  [3.8 Memory management]: #memory-management
  [3.9 Naming conventions]: #naming-conventions
  [3.10 Comments]: #comments
  [3.11 Indices in PDEs]: #indices-in-pdes
  [3.12 Git workflow]: #git-workflow
  [3.13 Standards]: #standards
  [3.14 Mentioning other libraries, programs, codes, etc.]: #mentioning-other-libraries-programs-codes-etc.
  [3.15 Documentation]: #documentation
  [4 What we program in FeenoX]: #what-we-program-in-feenox
  [5 Code of conduct]: #code-of-conduct
  [6 Release plans]: #release-plans

Why we program FeenoX

The main objective is to comply with the Software Requirements
Specification. Within this goal, there are three levels of importance:

1.  FeenoX is Free Software as defined by the Free Software Foundation.
    The four essential freedoms ought to be assured. Feenox is GPLv3+ so
    make sure you understand what “free-as-in-free-speech” means and all
    the details that the license implies regarding using other libraries
    and code copyright.
2.  FeenoX is Open Source as defined by The Open Source initiative.
    Stick to open standards, formats, practices, etc. Make sure you
    understand what the difference between “free software” and “open
    source” is.
3.  Only after making sure every piece of code meets the two criteria
    above, the technical and/or efficiency aspects mentioned in the SRS
    are to be considered.

Compiling and debugging

See the compilation instructions.

  [compilation instructions]: compilation.md

How we program FeenoX

Operating systems

- The main target operating system is GNU/Linux, particularly
  linux-x86_64.
- The reference distribution is Debian stable. All the required
  dependencies should be available in any decently-modern Debian
  repositories.
- Support for other architectures (mainly the other two non-server
  end-user mainstream OSes which are non-free and we do not want to
  mention explicitly) is encouraged but not required.

Languages

  Rule of Simplicity: Design for simplicity; add complexity only where
  you must.

C++ is a great language when used to solve problems it solves naturally
well without being forced to solve it (see LibreBlackjack). C++ is a
terrible language whenever else. It is messy, overwhelming, complicated,
not robust and hard to debug (especially when using templates and this
nightmare called smart pointers). The cons are far more than the pros.
There is no need to add complexity.

Fortran is a terrible language. Fortran90+ is a patched FORTRAN 77. The
assumptions that the language had over the kind of computers it has to
run on worked in the early days but are now widely outdated. That’s it.

Go & Rust, I think still nobody knows for sure right now. But Rust’s
automatic memory handling is not a point strong enough for CAE/DAE/FEA
software.

C is the best language for FeenoX. Its assumptions still hold,
especially in

i.  bare-metal servers,
ii. virtualized machines, and
iii. dockerized containers.

  In the late 1990s, Gerrit Blaauw and Fred Brooks observed in Computer
  Architecture: Concepts and Evolution [BlaauwBrooks] that the
  architectures in every generation of computers, from early mainframes
  through minicomputers through workstations through PCs, had tended to
  converge. The later a design was in its technology generation, the
  more closely it approximated what Blaauw & Brooks called the
  “classical architecture”: binary representation, flat address space, a
  distinction between memory and working store (registers),
  general-purpose registers, address resolution to fixed-length bytes,
  two-address instructions, big-endianness,[46] and data types a
  consistent set with sizes a multiple of either 4 or 6 bits (the 6-bit
  families are now extinct).

  Thompson and Ritchie designed C to be a sort of structured assembler
  for an idealized processor and memory architecture that they expected
  could be efficiently modeled on most conventional computers. By happy
  accident, their model for the idealized processor was the PDP-11, a
  particularly mature and elegant minicomputer design that closely
  approximated Blaauw & Brooks’s classical architecture. By good
  judgment, Thompson and Ritchie declined to wire into their language
  most of the few traits (such as little-endian byte order) where the
  PDP-11 didn’t match it.[47]

  The PDP-11 became an important model for the following generations of
  microprocessor architectures. The basic abstractions of C turned out
  to capture the classical architecture rather neatly. Thus, C started
  out as a good fit for microprocessors and, rather than becoming
  irrelevant as its assumptions fell out of date, actually became a
  better fit as hardware converged more closely on the classical
  architecture. One notable example of this convergence was when Intel’s
  386, with its large flat memory-address space, replaced the 286’s
  awkward segmented-memory addressing after 1985; pure C was actually a
  better fit for the 386 than it had been for the 286.

  It is not a coincidence that the experimental era in computer
  architectures ended in the mid-1980s at the same time that C (and its
  close descendant C++) were sweeping all before them as general-purpose
  programming languages. C, designed as a thin but flexible layer over
  the classical architecture, looks with two decades’ additional
  perspective like almost the best possible design for the
  structured-assembler niche it was intended to fill. In addition to
  compactness, orthogonality, and detachment (from the machine
  architecture on which it was originally designed), it also has the
  important quality of transparency that we will discuss in Chapter 6.
  The few language designs since that are arguably better have needed to
  make large changes (like introducing garbage collection) in order to
  get enough functional distance from C not to be swamped by it.

  This history is worth recalling and understanding because C shows us
  how powerful a clean, minimalist design can be. If Thompson and
  Ritchie had been less wise, they would have designed a language that
  did much more, relied on stronger assumptions, never ported
  satisfactorily off its original hardware platform, and withered away
  as the world changed out from under it. Instead, C has flourished —
  and the example Thompson and Ritchie set has influenced the style of
  Unix development ever since. As the writer, adventurer, artist, and
  aeronautical engineer Antoine de Saint-Exupéry once put it, writing
  about the design of airplanes: «La perfection est atteinte non quand
  il ne reste rien à ajouter, mais quand il ne reste rien à enlever».
  (“Perfection is attained not when there is nothing more to add, but
  when there is nothing more to remove”.)

Therefore:

- Stick to plain C.

    C enables us to build data structures for storing sparse matrices,
    solver information, etc. in ways that Fortran simply does not allow.
    ANSI C is a complete standard that all modern C compilers support.
    The language is identical on all machines. C++ is still evolving and
    compilers on different machines are not identical. Using C function
    pointers to provide data encapsulation and polymorphism allows us to
    get many of the advantages of C++ without using such a large and
    more complicated language.

    PETSc FAQs
    https://www.mcs.anl.gov/petsc/documentation/faq.html#why-c

- Keep C++ away.

    C++ is a horrible language. It’s made more horrible by the fact that
    a lot of substandard programmers use it, to the point where it’s
    much much easier to generate total and utter crap with it. Quite
    frankly, even if the choice of C were to do nothing but keep the C++
    programmers out, that in itself would be a huge reason to use C.

    Linus Torvalds about why Git is written in C
    http://harmful.cat-v.org/software/c++/linus

  Libraries written in C++ are allowed as long as they provide C
  wrappers and do not meddle with stuff we do not need nor want.

- Keep Fortran even farther away. It is allowed only for existing
  libraries dating from ancient well-tested and optimized code, but for
  nothing else.

- Modern high-level languages like Python or Julia are targets and not
  sources of FeenoX.

- For documentation and comments within the code, American English
  should be used.

  [LibreBlackjack]: https://seamplex.com/blackjack/

Programming IDEs

Netbeans

To work on FeenoX using NetBeans, first make sure you have the C/C++
module working. If you don’t, do this:

  In Netbeans go to Tools->Plugins->Settings. Entry NetBeans 8.2 Plugin
  Portal is already present. Click the checkbox next to this entry.
  Switch to Available Plugins tab, click Check for Newest. C/C++ is now
  on the list.

Then create a new C/C++ project File->New Project… choose C/C++ Project
with Existing Sources click Next, browse to find the root directory of
your local FeenoX sources. It is important to have the configure script
already created there, so make sure you have run ./autogen.sh. Make sure
the configuration mode is set to Automatic and that NetBeans detected
the configure script by adding “using configure” next to “Automatic.”
Click to create the project. This will create a directory nbproject
which will be ignored by .gitignore.

  [NetBeans]: https://netbeans.apache.org/

Makefiles

- FeenoX uses the GNU Autools (i.e. Autoconf and Automake).
- If you really feel that you have to use CMake for your contributions,
  feel free to do so (Unix rule of diversity) but make sure that at the
  end of the day ./configure && make still works.

  [GNU Autools]: https://en.wikipedia.org/wiki/GNU_Autotools
  [Autoconf]: https://www.gnu.org/software/autoconf/
  [Automake]: https://www.gnu.org/software/automake/
  [CMake]: https://cmake.org/

Test suite

- The directory tests contains the test suite with shell scripts that
  return appropriate errorlevels according to Automake’s generic test
  scripts. In a nutshell:

    When no test protocol is in use, an exit status of 0 from a test
    script will denote a success, an exit status of 77 a skipped test,
    an exit status of 99 a hard error, and any other exit status will
    denote a failure.

- If you add a new feature please also write a test script not just to
  check your feature works but to prevent further changes by other
  people (or even by yourself) from breaking the feature.

- Try to make the check results meaningful and not just check for random
  results. Try to create tests cases with analytical solution or use
  benchmarks with known results.

- We will eventually add some code coverage tools to have as most lines
  covered by at least one test.

  [Automake’s generic test scripts]: https://www.gnu.org/software/automake/manual/html_node/Scripts_002dbased-Testsuites.html

Coding style

- K&R 1TBS with no tabs and two spaces per indent
  https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)

      void checknegative(x) {
        if (x < 0) {
          puts("Negative");
        } else {
          nonnegative(x);
        }
      }

- Do not worry about long lines. Only wrap lines when it makes sense to
  from a logic point of view not because “it looks bad on screen”
  because “screen” can be anything from a mobile phone to a desktop with
  many 24” LED monitors.

- Make sure you understand and follow the 17 rules of Unix philosophy
  https://en.wikipedia.org/wiki/Unix_philosophy

  1.  modularity
  2.  clarity
  3.  composition
  4.  separation
  5.  simplicity
  6.  parsimony
  7.  transparency
  8.  robustness
  9.  representation
  10. least surprise
  11. silence
  12. repair
  13. economy
  14. generation
  15. optimization
  16. diversity
  17. extensibility

Virtual methods

Even though we use C, we can still have some “virtual methods” by using
function pointers. So in a FEM formulation, the routines that build the
stiffness matrix are mostly independent of the problem type (for the
same family, say elliptic problems) but in the integrands. So a good
practice is to have a common set of routines that loop over elements and
over gauss points and then at the inner loop a virtual method is called
which depends on the particular problem (thermal, mechanical, etc). This
is accomplished by using function pointers so all problems have to
provide more or less the same sets of routines: initialization,
integrands, BCs, etc. See the basic problems to see how this idea works.

Reading and writing mesh/post-processing files work the same way. Each
format has to provide a virtual reader/writer method.

Memory management

- Check all malloc() calls for NULL. You can use the
  feenox_check_alloc()/feenox_check_alloc_null() macros.

- Use the macro feenox_free() instead of plain free(). The former
  explicitly makes the pointer equal to NULL after freeing it, which is
  handy.

- Use valgrind to check for invalid memory access and leaks

    Memory analysis tools such as valgrind can be useful, but don’t
    complicate a program merely to avoid their false alarms. For
    example, if memory is used until just before a process exits, don’t
    free it simply to silence such a tool.

    GNU Coding Standards
    https://www.gnu.org/prep/standards/html_node/Memory-Usage.html

  Mind that FeenoX might be used in parametric or minimization mode
  which would re-allocate some stuff so make sure you know which alarms
  you ignore.

Naming conventions

- Use snake case such as in this_is_a_long_name.

- All functions ought to start with feenox_. This is the small price we
  need to pay in order to keep a magnificent beast like C++ away from
  our lives (those who can). The names of functions should go from
  general to particular such as feenox_expression_parse() and
  feenox_expression_eval() (and not
  feenox_parse_expression()/feenox_eval_expression()) so all function
  related with expressions can be easily found. There are exceptions,
  like functions which do similar tasks such as feenox_add_assignemnt()
  and feenox_add_instructions(). Here the add part is the common one.

- In a similar way, “virtual” methods should add the particularity at
  the end, like

  - feenox_build_element_volumetric_gauss_point()—the function pointer
    which is invoked in the code
  - feenox_build_element_volumetric_gauss_point_thermal()—the particular
    function the pointer will point to and which is actually called

Comments

- Use single-line comments // to add comments to the code so we can
  easily comment out certain parts of code using multi-line comments
  /*—*/ while developing new features.

- Explain any non-trivial block or flag that needs to be set. Example

        switch (c = fgetc(file_ptr)) {
          case '"':
            // if there's an escaped quote, we take away the escape char 
            // and put a magic marker 0x1e, afterwards in get_next_token() 
            // we change back the 0x1e with the unescaped quote
            feenox_parser.line[i++] = 0x1e;

- Focus on the why and not on the how, except for very complex loops.

- All nice-to-have things that are welcome to be done should be written
  as

      // TODO: allow refreshing file data before each transit step

- Features that might or might not be added should be written as
  questions

      // TODO: should we allow unquoted names in the $PhysicalNames section?

Indices in PDEs

  -----------------------------------------------------------------------
    Index    Loop over…
  ---------- ------------------------------------------------------------
      i      elements or cells

      j      nodes, either global or local. If there are loops which need
             both, use j_local and j_global.

      k      dummy index

      d      dimensions

      g      degree of freedoms (from groups of energy actually)

      q      Gauss (quadrature) points
  -----------------------------------------------------------------------

Git workflow

- Of course, use git. This may seem obvious but predecessors of this
  project have used Subversion, Bazaar and Mercurial in that order. I
  have myself used CVS (in the past century).
- Only team members are allowed to commit directly to the main branch.
- All contributions ought to come from pull/merge requests either from
  forked repositories and/or non-main branches.
- Issues can be opened forked for
  - bug reporting
  - feature requests
  - development discussion
  - general questions (installation, usage, etc)

Standards

- Try to adhere to POSIX as much as possible. Eventually all operating
  systems will adopt it.

Mentioning other libraries, programs, codes, etc.

- Try no to mention any piece of software which is not free and open
  source.

Documentation

- See the README in the doc directory.
- TLDR;
  1.  Use Pandoc-flavored Markdown as the main source.
  2.  Knock yourself out with LaTeX math.
  3.  Bitmaps are off the table for figures.

What we program in FeenoX

- The features described in the SRS.

Code of conduct

- See the code of conduct.

  [code of conduct]: CODE_OF_CONDUCT.md

Release plans

- v1.x first stable release meaning:
  - usable features
  - full documentation matching the code features (PhD thesis)
- v2.x further features and improvements