WIP: The units of the main governing eq are inconsistent - see EP1950
Applies sources on temperature ('T' - incompressible)
or energy ('h'/'e' - compressible) equation to incorporate
evapotranspiration heat-transfer effects from the specified
plant canopy. Heat transfer is usually calculated based on
empirical relations between plants and solar radiation.
Two submodels to incorporate heat transfer effects
- 'tree': specified tree canopy - uses empirical relations between solar
radiation and evapotranspiration.
- 'grass': specified grass canopy - uses Pemnan-Monteith Equation model.
- in renumberMesh replace calculation of a subMesh connectivity
with calculation of the full mesh connectivity followed by subsetting
of the full adjacency matrix. This should reduce the overall number of
operations. (MR !669)
- added solidBodyMotionFunctions to topoSet which allows things like
moving cellSet selection for fvOptions etc.
COMP: relocate solidBodyMotionFunctions to meshTools
Co-authored-by: Kutalmis Bercin <>
- provide no_topology() characteristic to avoid triggering potentially
expensive mesh connectivity calculations when they are not required.
- remove/deprecate unused pointField references from the renumber
methods. These appear to have crept in from outer similarities
with decompositionMethod, but have no meaning for renumbering.
- remove/deprecate various unused aggregation renumberings since these
have been previously replaced by pre-calling calcCellCells, or
using bandCompression directly.
- make regionFaceOrder for block-wise renumbering optional and
treat as experimental (ie, default is now disabled).
The original idea was to sort the intra-region and inter-region faces
separately. However, this will mostly lead to non-upper triangular
ordering between regions, which checkMesh and others don't really like.
ENH: add timing information for various renumberMesh stages
ENH: add reset of clockTime and cpuTime increment
- simplifies section-wise timings
ENH: add globalIndex::null() and fieldTypes::processorType conveniences
- provides more central management of these characteristics
- particularly useful in these combinations:
1.
OCharStream buf;
// populate
ISpanStream is(buf.view());
// parse
2.
// read from file
ifile.getLine(str);
ISpanStream is(str);
// parse
These avoid making a copy of the character content, compared to
versions with stringstream:
OStringStream buf;
IStringStream is(buf.str());
- a few places still used listCombineReduce instead of
newer constructs (eg allGatherList) with fewer MPI calls.
- align triangulation handling of turbulentDFSEMInlet and
patchInjectionBase with meshTools/triangulatedPatch
(will ease future code refactoring)
- renumberMesh now has -dry-run, -write-maps, -no-fields,
-renumber-method, -renumber-coeffs options.
* Use -dry-run with -write-maps to visualize the before/after
effects of renumbering (creates a VTK file).
* -no-fields to renumber the mesh only.
This is useful and faster when the input fields are uniform
and the -overwrite option is specified.
* -renumber-method allows a quick means of specifying a different
default renumber method (instead of Cuthill-McKee).
The -renumber-coeffs option allows passing of dictionary content
for the method.
Examples,
// Different ways to specify reverse Cuthill-McKee
* -renumber-method RCM
* -renumber-coeffs 'reverse true;'
* -renumber-method CuthillMcKee
* -renumber-coeffs 'reverse true;'
* -renumber-coeffs 'method CuthillMcKee; reverse true;'
// Other (without dictionary coefficients)
* renumberMesh -renumber-method random
// Other (with dictionary coefficients)
renumberMesh \
-renumber-method spring \
-renumber-coeffs 'maxCo 0.1; maxIter 1000; freezeFraction 0.99;'
// Other (with additional libraries)
renumberMesh -renumber-method zoltan -lib zoltanRenumber
COMP: build zoltan renumbering to MPI-specific location
- zoltan and Sloan renumbering are now longer automatically linked to
the renumberMesh utility but must be separately loaded by a
command-line option or through a dictionary "libs" entry.
ENH: add output cellID for decomposePar -dry-run -cellDist
ENH: eliminate unnecessary duplicate communicator
- in globalMeshData previously had a comm_dup hack to avoid clashes
with deltaCoeffs calculations. However, this was largely due to a
manual implementation of reduce() that used point-to-point
communication. This has since been updated to use an MPI_Allreduce
and now an MPI_Allgather, neither of which need this hack.
- this was previously a UList instead of SubList,
but SubList supports better assignment of values
ENH: add invertOneToManyCompact
- returns a CompactListList<label> instead of labelListList, which
allows for reuse as partitioning table etc and/or slightly reduced
memory overhead
- add convenience forms for common combinations
- avoid allocation for 1:1 identity agglomerations
- support subsetting forms (avoids an intermediate fvMeshSubset)
that also return the cellMap
- refactored to eliminate code duplication between weighted and
unweighted forms
- construct Map/HashTable from key/value lists.
- invertToMap() : like invert() but returns a Map<label>,
which is useful for sparse numbering
- inplaceRenumber() : taking a Map<label> for the mapper
ENH: construct/reset CStringList for list of C-strings
- surfaceWriter TryNew() factory methods for more failure tolerant
handling
- reduce communication for sampledSurfaces.
Track non-empty surfaces as bool, only updated on change
(expire/update).
- use Pstream::listScatterValues() instead of the old hand-rolled
method.
Reduces code and since it is mostly used with primitives it
will use MPI_Scatter directly (see #3087)
COMP: fix some inconsistent masterOp return types
- can use UList signature since the routines do not resize the list
or attempt to broadcast it: useful for SubList handling.
ENH: add IPstream/OPstream send/recv static methods
- related to issue #3095. Some type of geometry is required when
loading "measured" ensight data.
ENH: emit a fallback geometry-box for foamToEnsight
- eg, with "foamToEnsight -no-internal -no-boundary" and lagrangian
- process the contents of the cloud object registry, which enables
output support for calculated values such as Reynolds, Weber numbers
etc.
ENH: select any/all clouds by default instead of defaultCloud
- adds robustness
- the old Pstream::scatter routines (which were largely a misnomer)
have been superseded by various broadcast routines, but were left in
the code with #ifndef/#ifdef Foam_Pstream_scatter_nobroadcast
guards. Now noisily deprecate them, and remove the old manual tree
communication in favour of MPI broadcast and/or
serialize/de-serialize with wrapped Pstream::broadcast
- consolidate various gather methods to include the communication
structure directly. No functional change, but reduces the number of
methods.
ENH: add parallel guard to UPstream::whichCommunication() method
- returns List::null() as the schedule for non-parallel instead
of an inappropriate linear or tree schedule
ENH: Pstream::listGatherValues, Pstream::listScatterValues
- like the existing UPstream versions but supporting non-contiguous
- range(proci) instead of localStart(proci), localSize(proci) combination.
* does the same thing, can be used directly with various other
routines for slicing etc.
Eg,
Foam::identity(globalNumbering.range(myProci))
- globalIndex::calcOffset() instead of constructing a globalIndex and
taking the localStart(). Avoids intermediate resizing and storing of
an offsets table (which is then discarded) as well as the subsequent
lookup into that table
- creates an IOobject at the current time instance (timeName) with
NO_READ/NO_WRITE/NO_REGISTER characteristics.
This generalises and replaces the Cloud fieldIOobject() to simplify
some common use.
// Shorter version (new):
volScalarField fld
(
mesh.newIOobject(name),
...
);
// Longer version:
volScalarField fld
(
IOobject
(
name,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
IOobject::NO_REGISTER
),
...
);
- can be useful when using memory-based streams for buffering,
in which case the name() can be used to specify the filesystem
location instead of the default stream names ("input", "output").
- shape optimisation: SQP failed due to wrong divScheme for the adjoint
equations
- shape optimisation: tutorials designed to show the impact of different flow
conditions were actually using the same U
- topology optimisation: tutorials designed to show the impact of the
flow rate distribution were actually using the same target
fractions
- topology optimisation: updated old fvSolution syntax
- shape optimisation: SQP failed due to wrong divScheme for the adjoint
equations
- shape optimisation: tutorials designed to show the impact of different flow
conditions were actually using the same U
- topology optimisation: tutorials designed to show the impact of the
flow rate distribution were actually using the same target
fractions
- topology optimisation: updated old fvSolution syntax
- had max(std::streamsize, label) but this does not resolve properly
on OSX, so write out in long form instead.
The similar logic in DynamicList is okay since there it compares
max(label, label) instead
In steadyOptimisation mode, each time-step corresponds to an
optimisation cycle and is sub-cycled, to allow for iterating the flow
and adjoint equations. This sub-cycling does not allow the execution of
function objects. This was circumvented in 8947735b1d, by explicitly
calling the execution of the function objects in the simple solver
of adjointOptimisationFoam.
However, each sub-cycled iteration is a writeTime, if the current
optimisation cycle corresponds to a writeTime. This means that function
objects with a
writeControl write;
will be executed in each iteration of the flow equations, within this
specific optimisation cycle, leading to a lot of disc space and file
clutter, if the function object outputs fields (e.g. yPlus).
8947735b1d is partially rolled back, by protecting the call to the
execution of the function objects with a bool that defaults to false.
- adjointOptimisation : missing link to fileFormats
- snappyHexMesh : add fvMotionSolvers link (#3058)
STYLE: remove remnant -DFULLDEBUG hints
- now more easily covered with wmake -debug ...
- the fileHandler changes included setting cacheLevel(0) to avoid
blocking with redistributePar. However, this meant if clouds
were not uniformly present on all ranks the fileHandler would follow
different code paths and lead to blocking.
Now switch to distributed mode for the lagrangian operations within
redistributePar based on the cacheLevel information.
FIX: avoid triggering a false processor check in argList
- when redistributing to few ranks
The solution of the QP subproblem can become quite expensive, especially
for cases with many design variables (e.g. topology optimisation).
A (potentially dense) matrix with the size of the design variables is
solved using a matrix-free CG solver. The convergence speed greatly
depends on the used preconditioner. This commit adds
preconditioner-vector products based on the L-BFGS inverse Hessian and,
more importantly, a preconditioner computed using the Sherman-Morrison
formula. The latter is applicable here since the LHS of the QP problem
is computed as the sum of rank-2 L-BFGS updates, a sum of rank-1 updates
(as many as the flow-related constraints) and a diagonal matrix
depending on the bound constraints.
Additionally, the QP subproblem could have no feasible points. To relax
this, constraints can be applied gradually through the
targetConstraintReduction enty (typical value of 0.1 for topology
optimisation).
Most cases now rely on the nullSpace update method, instead of MMA,
since it has proven more reliable.
Also, added some constrained optimisation cases, including constraints
on the flow rate partition and total pressure losses as well as cases
targeting uniformity as the objective function.
Added a 3D topology optimisation case which also includes constraints.
of the STL written by topology optimisation.
BUG: when determining which mesh faces are cut by iso-surface faces,
only append the latter if it contains more than two points
by a small amount, if all of them lay on the lower or upper bounds at
the beginning of the optimisation, to avoid singular matrices when
computing the update of the design variables.
and the Jacobian of the objective function wrt the turbulence variables
is called (rare/unorthodox case).
Additionally, objectivePowerDissipation dissipation can now be used in
topology optimisation, adding the necessary blockage dependency to it.
- Building the iso-surface spliting fluid and solid parts in topology
optimisation has been re-worked to obtain an iso-surface with unique
point numbering
- The mechanism behind marchingCells for dynamicTopODesignVariables has
been slightly reworked
The derivatives of the objective and constraint functions can optionally
be normalised in each optimisation cycle, so that MMA does not put an
excesive stress on the constraints, which can negatively affect the
course of the optimisation
A 1-Inlet-2-Outlet geometry is showcased for laminar and turbulent
flows, set-up with different variants of porosity-based and
level-set-based topology optimisation
Both porosity-based and level-set-based topO frameworks are included
through the topO and levelSet designVariables, respectively.
Both frameworks work by manipulating an underlying field of design
variables, defined in all cells of the computational domain. That field
is then regularised through a Helmholtz-like filter, before being
processed in a different way from the two topO frameworks (the
porosity-based topO sharpens/projects it while the level-set-based topO
computes signed distances around its zero iso-surface). The result of
this processing is then fed into functions that define source terms to
be added to the mean flow and turbulence model equations, to block
off/solidify parts of the mesh that are counterproductive with respect
to the objective function. These source terms are added through
fvOptions.
Since the designed walls are only simulated through source terms, the
outcome of topO should be re-analyzed on a body-fitted grid, to quantify
the actual gain in the objective function. Both topO frameworks output
the designed wall in STL format which can be used, for instance with
snappyHexMesh, to construct such a body fitted grid.
This provides a list of faces (can be internal ones) to act as
additional seeds for the wave algorithm. The default argument provides
an empty list, so the behaviour of patchWave should not change.
Useful in topology optimisation, for propagating the active design
variables from the seed faces to the interior, with a given number of
cells at a time.
- advectionDiffusion is frequently used within optimisation loops since
it is differentiable. In shape optimisation, the re-computation of
mesh distances is performed at the very beginning of a new
optimisation cycle, due to inheriting from MeshObject. If the mesh
quality is poor enough, the advectionDiffusion PDE might diverge and
crash the run, before the problematic mesh is written to files for
inspection. The default behaviour now is to check the mesh before
solving the advectionDiffusion PDE and write the mesh points if some
mesh check fails.
- fvOptions can now be included in advectionDiffusion (necessary for
topology optimisation of turbulent flows for models that include the
distance field)
- Minor changes in the numerical treatment of the diffusion term, to
enhance stability
Parts of the adjoint optimisation library were re-designed to generalise
the way sensitivity derivatives (SDs) are computed and to allow easier
extension to primal problems other than the ones governed by
incompressible flows. In specific:
- the adjoint solver now holds virtual functions returning the part of
SDs that depends only on the primal and the adjoint fields.
- a new class named designVariables was introduced which, apart from
defining the design variables of the optimisation problem and
providing hooks for updating them in an optimisation loop, provides
the part of the SDs that affects directly the flow residuals (e.g.
geometric variations in shape optimisation, derivatives of source
terms in topology optimisation, etc). The final assembly of the SDs
happens here, with the updated sensitivity class acting as an
intermediate.
With the new structure, when the primal problem changes (for instance,
passive scalars are included), the same design variables and sensitivity
classes can be re-used for all physics, with additional contributions to
the SDs being limited (and contained) to the new adjoint solver to be
implemented. The old code structure would require new SD classes for
each additional primal problem.
As a side-effect, setting up a case has arguably become a bit easier and
more intuitive.
Additional changes include:
---------------------------
- Changes in the formulation and computation of shape sensitivity derivatives
using the E-SI approach. The latter is now derived directly from the
FI approach, with proper discretization for the terms and boundary
conditions that emerge from applying the Gauss divergence theorem used
to transition from FI to E-SI. When E-SI and FI are based on the same
Laplace grid displacement model, they are now numerically equivalent
(the previous formulation proved the theoretical equivalence of the
two approaches but numerical results could differ, depending on the
case).
- Sensitivity maps at faces are now computed based (and are deriving
from) sensitivity maps at points, with a constistent point-to-face
interpolation (requires the differentiation of volPointInterpolation).
- The objective class now allocates only the member pointers that
correspond to the non-zero derivatives of the objective w.r.t. the
flow and geometric quantities, leading to a reduced memory footprint.
Additionally, contributions from volume-based objectives to the
adjoint equations have been re-worked, removing the need for
objectiveManager to be virtual.
- In constrained optimisation, an adjoint solver needs to be present for
each constraint function. For geometric constraints though, no adjoint
equations need to solved. This is now accounted for through the null
adjoint solver and the geometric objectives which do not allocate
adjoint fields for this kind of constraints, reducing memory
requirements and file clutter.
- Refactoring of the updateMethod to collaborate with the new
designVariables. Additionally, all updateMethods can now read and
write restart data in binary, facilitating exact continuation.
Furthermore, code shared by various quasi-Newton methods (BFGS, DBFGS,
LBFGS, SR1) has been organised in the namesake class. Over and above,
an SQP variant capable of tackling inequality constraints has been
added (ISQP, with I indicating that the QP problem in the presence of
inequality constraints is solved through an interior point method).
Inequality constraints can be one-sided (constraint < upper-value)
or double-sided (lower-value < constraint < upper-value).
- Bounds can now be defined for the design variables.
For volumetricBSplines in specific, these can be computed as the
mid-points of the control points and their neighbouring ones. This
usually leads to better-defined optimisation problems and reduces the
chances of an invalid mesh during optimisation.
- Convergence criteria can now be defined for the optimisation loop
which will stop if the relative objective function reduction over
the last objective value is lower than a given threshold and
constraints are satisfied within a give tolerance. If no criteria are
defined, the optimisation will run for the max. given number of cycles
provided in controlDict.
- Added a new grid displacement method based on the p-Laplacian
equation, which seems to outperform other PDE-based approaches.
TUT: updated the shape optimisation tutorials and added a new one
showcasing the use of double-sided constraints, ISQP, applying
no-overlapping constraints to volumetric B-Splines control points
and defining convergence criteria for the optimisation loop.
- enhance POSIX compliance
- apply distinct colours and dash type for each line
- standardize the frame size to 1200x627
- dynamically replace the title with <function-object-name>/<file-name>
- address underscore character issues
- introduce legend components for tensors
- resolve a bug caused by parentheses in tensor files
BUG: particleTrackProperties: correct the typo (fixes#3050)
- on large memory systems (eg, 6TB) the process information
exceeds an 'int' range, so adjust parsing of the /proc/..
to use int64
ENH: update/modernize OSspecific system information
ENH: minor update of profiling code
- std::string, noexcept, lazier evaluations
STYLE: use direct call of memInfo
- use Foam::zero as a dispatch tag
FIX: return moleculeCloud::constProps() List by reference not copy
STYLE: range-for when iterating cloud parcels
STYLE: more consistent typedefs / declarations for Clouds
- better code style and seems to avoid triggering a gcc warning about
possibly uninitialized values
COMP: JSONformatter writeEntry missing a return value
STYLE: accept 'json' for checkMesh write format
- consistent with caseInfo functionObject
- for clang-based compilers the default linker may be lld or simply ld.
Support '+link-ld' to explicitly select use of the ld linker.
- consolidate linker rules into single files
STYLE: adjust SPDX Identifier
redistributePar -decompose switches communicator when
reading on master. However other processors still get
constructed with the worldComm. >v2306 AMI stores the communicator
from construction time there was a mismatch
- regression introduced by commit 0ff86ee2
(only affects recent develop).
- now split off first/final iterations into a separate
"controls" dictionary (instead of lumping them into "solver") to
make them persistent between iterations.
- updating the header information (by copying) was closing the stream,
removing all watches and doing a checkOut/checkIn, which could lead to
dangling references.
Now just close the stream and simply copy the IOobject header
information directly.
STYLE: mark regIOobject assignment operator as possibly deprecated
- will revisit to revise or remove in the future
- the faMesh/fvMesh copy constructors were using the readOption from
the base-mesh schemes/solution instead of copying their contents.
This would not really affect fvMesh (since it has its own IOobject
for the constructor), but did affect faMesh. However, the problem
only shows up with collated + redistribute, since that is where
the ranks can be doing uncoordinated IO.
Only consider as a bug for recent develop since previous versions
had other problems with collated+redistribute with finite-area
anyhow.
- simplifies handling.
* enables unprotecting to avoid accidentally cloning.
* removes the need for dedicated constructor or factory forms.
* simplfies DimensionedField and GeometricField New factory methods
- update objectRegistry management method (internal use)
old: bool cacheTemporaryObject(...)
new: bool is_cacheTemporaryObject(...)
to clarify that it is a query, not a request for caching etc.
- give precedence to ~openmp (-no-openmp) over +openmp (-openmp)
in the general rules and in the Makefile. This makes it robuster
when specifying +openmp in general, but ~openmp for specific build
components.
- disable openmp for OSspecific and Pstream components.
Neither should contain any openmp code anyhow.
Additionally, since OSspecific is generally built as a static
object, it can become problematic (eg, with AMD ROCm) if the
compiler generates information that openmp is required but then uses
static linkage.
- the fields for finite-area are currently stored directly on the
polyMesh registry, but for future relocation to a sub-registry
provide a uniform accessor.
ENH: use thisDb() for faMatrix access and extrapolatedCalculated
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.