Under the hood: solids4FoamModels
This directory holds the sources of libsolids4FoamModels, the main solids4foam library. It is built by the Allwmake script in this directory, which is called in turn by src/Allwmake.
The solids4Foam application in applications/solvers/solids4Foam is a thin front end: it creates a physics model and advances it in time. Everything else lives in this library.
Library overview
Physics models
physicsModel is the virtual base class for the three families of solution procedure, each of which is selected at run time from its own dictionary:
- Solid: base class
solidModel, read fromconstant/solidProperties, insolidModels; - Fluid: base class
fluidModel, read fromconstant/fluidProperties, influidModels; - Fluid-solid: base class
fluidSolidInterface, read fromconstant/fsiProperties, influidSolidInterfaces.
Which family is used for a case is set by the type entry in constant/physicsProperties, i.e. solid, fluid or fluidSolidInteraction.
A solid model solves the governing momentum equation in a solid domain. The available models differ in whether the geometry is linear or nonlinear, whether a total or updated Lagrangian formulation is used, whether the discretisation is cell-centred or vertex-centred, and whether the solution algorithm is segregated, coupled or explicit. They are described in solid models.
A fluid model solves the flow equations, using either a solver built on the standard OpenFOAM ones or a solver specific to solids4foam; see fluid models.
A fluid-solid interface owns one fluid model and one solid model and implements the partitioned coupling algorithm between them, for example fixed relaxation, Aitken or IQN-ILS. See fluid-solid interfaces.
Material behaviour
The constitutive behaviour of a solid is separate from the solid model that uses it, so the two can be varied independently:
materialModels/mechanicalModelreadsconstant/mechanicalPropertiesand creates the mechanical laws. AmechanicalLawreturns the stress for a given deformation; the laws are grouped intolinearGeometryLawsandnonLinearGeometryLaws. Multiple materials are supported, each region taking its own law, with corrections at bi-material interfaces to keep the stress continuous without oscillations.materialModels/thermalModeldoes the same for thermal properties, readingconstant/thermalPropertiesand creatingthermalLawobjects.
Supporting components
physicsModel: the base class of the three physics model families;solidModels/fvPatchFieldsandsolidModels/pointPatchFields: solid boundary conditions, including tractions, contact, symmetry and prescribed displacement and rotation;numerics: discretisation and linear algebra support, including gradient schemes, stabilisation models, interpolation, additional tensor types and PETSc helpers;higherOrderHelpers: higher-order finite volume support, including moving least squares, quadrature and the associated operators;dynamicFvMesh: meshes which change topology, such ascrackerFvMeshfor crack propagation;functionObjects: run-time post-processing, and the analytical solutions used by the tutorials; see function objects.
Adding a class
New classes follow the usual OpenFOAM run-time selection pattern: derive from the relevant base class, add the TypeName and addToRunTimeSelectionTable entries, and add the source to the canonical list described below. Please also see the contributing guide.
Source lists
The sources are listed in one of two canonical lists, which differ because the library supports both OpenFOAM and foam-extend:
Make/files.openfoamfor OpenFOAM.com and OpenFOAM.org;Make/files.foamextendfor foam-extend.
Allwmake selects the appropriate one and links it to Make/files, which is the file wmake reads and which is not tracked by Git. A new class is added to the canonical list for the versions it supports, exactly as in any other OpenFOAM library.
Unity builds
Compiling the library in the conventional way means each of its ~230 sources is a separate translation unit, so the large set of OpenFOAM headers is re-parsed once per source. That parsing, rather than the solids4foam code itself, dominates the build time.
A "unity build" (also called a "jumbo build") instead groups the sources into a small number of buckets, where each bucket is a generated source file that #includes the sources assigned to it. The headers are then parsed once per bucket. The resulting library is the same either way.
To enable it, set S4F_UNITY_BUILD before building:
export S4F_UNITY_BUILD=1
./Allwmake -j 16
As a guide, a from-scratch build of the library with -j 16 on a 192-core machine takes 119 s conventionally and 41 s as a unity build, a speed-up of about 2.9.
Unsetting S4F_UNITY_BUILD returns to a conventional build; the generated sources and their objects are discarded automatically.
Number of buckets
By default, the number of buckets follows the number of compilation processes, clamped to between 8 and 32. Fewer buckets means less repeated header parsing, but larger translation units and so a higher peak memory use per compiler process; more buckets gives diminishing returns in wall-clock time while the total compilation cost keeps growing.
The default can be overridden with S4F_UNITY_NBUCKETS:
export S4F_UNITY_BUILD=1
export S4F_UNITY_NBUCKETS=24
./Allwmake -j 24
What is generated
Make/makeUnityFiles reads the canonical source list, expands its $(var) path variables, and writes:
unityBuild/unityNN.C, the bucket sources;Make/files, listing the buckets in place of the individual sources.
Both are generated and neither is tracked by Git. The canonical list remains the single point of maintenance: new classes are added there as before and are picked up automatically.
Sharing a translation unit
Sources which share a translation unit also share its file scope, so a macro or a file-scope name defined in one source is visible to those which follow it in the same bucket. Macros defined in a .C file should therefore be #undefined at the end of that file, as is done in numerics/logExpVolFields/eig3/eig3.C.
Where that is not practical, a source can be listed in Make/unity-exclude, using the path exactly as it appears in the canonical list with any $(var) references expanded. Listed sources are compiled on their own, as they are in a conventional build.
When not to use it
Unity builds pay off when building the library from scratch, for example in continuous integration, in a container image, or after a wclean. They are a poor fit for day-to-day development of the library itself: editing any source rebuilds its whole bucket rather than the single file.