Compare commits

..

150 Commits

Author SHA1 Message Date
1ed3fcd4c0 ENH: integration of PDRfitMesh (#1961)
- serves as a pre-processor for PDRblockMesh.
  Scans obstacles to determine an initial cell distribution for
  PDRblockMesh
2020-12-21 09:18:57 +01:00
18cd5d864e ENH: reinstate Test-decomposePar -cellDist, add -cellDist-internal
- Useful for diagnosis, the -cellDist-internal produces a
  volScalarField::Internal instead
2020-12-21 09:17:37 +01:00
73207dfcd7 BUG: Fixing cloud constructor for MPPICInterFoam 2020-12-20 19:24:12 -08:00
6d6c204745 BUG: extrudeMesh - partial fix for incorrect behaviour - see #1964
Changed IO flag so that new mesh is created
- was using old 'faces', 'owner' etc but then used the new patch starts

Corrected logic for contMap in polyTopoChange
2020-12-18 17:42:20 +00:00
04f3b26ba6 Merge branch 'feature-reactingParcelFoam-dynamicMesh' into 'develop'
INT: reactingParcelFoam: add dynamicMeshMotion capabilities

See merge request Development/openfoam!416
2020-12-18 11:58:19 +00:00
5e539b30a9 INT: reactingParcelFoam: add dynamicMeshMotion capabilities 2020-12-18 11:58:09 +00:00
6ca6b34add CONFIG: update completions 2020-12-18 11:33:46 +01:00
e9dcc59c4d STYLE: trim trailing space 2020-12-18 09:24:01 +01:00
c5dece6a09 STYLE: use IOError to report bad lookup of volumeUpdateMethod
- adjust comments for '-world' option
2020-12-18 09:21:18 +01:00
6068148c22 STYLE: adjust packing of members, header comments 2020-12-18 09:13:34 +01:00
a92cd03a89 GIT: update headers 2020-12-18 08:56:14 +01:00
9ee0023bc0 Merge branch 'feature-MPPIC-dynamicMesh' into 'develop'
ENH: MPPIC dynamic mesh

See merge request Development/openfoam!406
2020-12-17 21:17:59 +00:00
0923c1277c STY: Updating headers 2020-12-17 21:17:03 +00:00
06a0bf1868 TUT: Adding new MPPICDyMFoam and uncoupledKinematicParcelDyMFoam tutorials
STY: Style and header-content changes
2020-12-17 21:17:03 +00:00
6d4e72dc3f ENH: Using basicKinematicCloud for MPPICFoam and MPPICDyMFoam 2020-12-17 21:17:03 +00:00
eb33b7957e BUG: Correction to tgtPointFace srcPointFace member functions 2020-12-17 21:17:02 +00:00
5bc846553c ENH: Updates to MPPIC sub-models. Instantiation for kinematic clouds 2020-12-17 21:17:02 +00:00
9207140e37 ENH: Adding check for wall interaction when particle is stuck on moving
walls

A new user input parameter UrMax is added to the PatchInteractionModel.
In some occasions the partile remains on a patch face due to extremely
low relative U. If this Ur is lower than UrMax the particle is removed
2020-12-17 21:17:02 +00:00
d7b1a666b5 ENH: Adding MPPIC sub-models to Kinematic cloud 2020-12-17 21:17:02 +00:00
f7dc0d8edb ENH: Updating particle member functions
- Dealing with detA < 0 tracking issues
- Modified locate function
2020-12-17 21:17:01 +00:00
8427eccd00 ENH: Triggering oldCellCentres calculation in Clouds 2020-12-17 21:17:01 +00:00
9a39481062 ENH: Adding oldCellCentres field to polyMesh 2020-12-17 21:17:01 +00:00
fbfc09979e CONFIG: bump API to 2012 (pre-release) 2020-12-17 21:32:53 +01:00
a0fe5e4fb2 SUBMODULE: update for runTimePostProcessing 2020-12-17 21:29:56 +01:00
8afed765be ENH: memory management for exprResultGlobals via objectRegistry
- replaces previous code that used an autoPtr to hold a singleton.

  In some circumstances this deletion would conflict with clearing
  the objectRegistry - leading to error messages on exit.

  Now store directly on the registry (similar to a MeshObject)
2020-12-17 20:44:35 +01:00
66865b9fbc BUG: Correcting include path for MPPICFoam 2020-12-17 09:51:11 -08:00
260db42f7f BUG: Correcting DPMIncompressibleTurbulenceModel in DPM solvers 2020-12-17 09:26:56 -08:00
7f17a71f9c ENH: make PDRsetField ground, outer patch names configurable
- previously hard-coded, now adjustable within PDRsetFieldsDict

    // Change some predefined patch names
    patchNames
    {
        ground      ground;
        outer       outer;
    }

ENH: additions to PDRutils, improve comments

- expose enumerated expansion names and gridControl (PDRblock).
  Not commonly needed, but useful to have access when defining
  other grid generators

TUT: update PDRsetFieldsDict and tutorials to use "ground"

- remove tutorial references to unused types and legacy obstacles

- use "ground" for the boundary conditions instead of "seaGround".
  Consistent with PDRblockMesh
2020-12-17 01:23:31 +01:00
05d0a4f1d4 STYLE: add warning if function object subRegion is not found 2020-12-17 00:14:16 +01:00
4bd1bd7522 BUG: Using autoPtr for turbulence in interFoam and interIsoFoam 2020-12-16 15:00:15 -08:00
3e431de285 Merge branch 'feature-Eulerian-recycling-boundary-conditions' into 'develop'
ENH: outletMappedUniformInlet: add optional fraction and offset

See merge request Development/openfoam!399
2020-12-16 18:28:30 +00:00
12efbd8965 TUT: airRecirculationRoom: add new reactingParcelFoam tutorial 2020-12-16 18:28:18 +00:00
5af5222141 ENH: outletMappedUniformInlet: add optional fraction and offset entries
The new functionality optionally allows the patch-averaged
value to be scaled and/or offset by a pair of specified values.

Example of the boundary condition specification:

```
<patchName>
{
    // Mandatory entries (unmodifiable)
    type            outletMappedFilterInlet;
    outletPatch     <outletPatchName>;

    // Optional entries (unmodifiable)
    fraction        0.1;
    offset          10;    // (1 0 0);
    phi             phi;

    // Optional (inherited) entries
    ...
}
```
2020-12-16 18:28:18 +00:00
4a80672afb Merge branch 'feature-varRhoTurbVOF' into 'develop'
Feature var rho turb vof

See merge request Development/openfoam!405
2020-12-16 17:57:46 +00:00
3db12bbdef ENH: adding non-uniform rho to incompressible two-phase turbulent models
1) PhaseIncompressibleTurbulenceModel class was changed to use
   uniform alpha and non-uniform rho templates. This fits the need
   of incompressible two phase turbulence models.

2) A new type DPMIncompressibleTurbulenceModel was created for
   non-uniform alpha and uniform rho. It is  used in single phase flows
   in DPM solvers where alpha represents the volumen occupancy.

3) A new type incompressibleRhoTurbulenceModel  was created where
   non-uniform rho is allowed.

4) A new base templated turbulent class for two-phase VOF named
   VoFphaseTurbulentTransportModel was implemented which is created
   templating on PhaseIncompressibleTurbulenceModel and
   incompressibleRhoTurbulenceModel

5) In order to make the chnage to rho based VOF turbulence a help
   class was added incompressibleInterPhaseTransportModel templated
   on the mixing.
2020-12-16 17:57:45 +00:00
dbaed65d75 BUG: redistributePar: failing reconstruct. See #1953.
In reconstruct mode redistributePar will have
- master read undecomposed mesh
- slaves construct dummy mesh (0 faces/points etc.)
  but correct patches and zones
so all processors have two valid meshes. This was
all handled inside fvMeshTools::newMesh and this
was behaving differently.
2020-12-16 17:27:08 +00:00
723edc1c61 ENH: redistributePar: avoid temporary unassigned faces. See #1956. 2020-12-16 17:27:08 +00:00
7456335ba6 Merge branch 'issue-1849-volFieldValue-parallel-IO' into 'develop'
BUG: volFieldValue FO: parallel/empty output (#1853 #1849)

See merge request Development/openfoam!413
2020-12-16 17:09:17 +00:00
0d21f248a9 BUG: volFieldValue FO: parallel/empty output (#1853 #1849)
TUT: volFieldValue FO: adds usage example
TUT: multiply FO: adds usage example
2020-12-16 17:09:06 +00:00
062fad4662 Merge branch 'feature-function1-limit-range' into 'develop'
Feature function1 limit range

See merge request Development/openfoam!414
2020-12-16 15:25:24 +00:00
a4dc2cc94b ENH: Added new LimitRange Function1 wrapper
Function1 wrapper that limits the input range of another Function1

Example usage for limiting a polynomial:

    limitedPolyTest        limitRange;
    limitedPolyTestCoeffs
    {
        min         0.4;
        max         1.4;

        value       polynomial
        (
            (5 1)
            (-2 2)
            (-2 3)
            (1 4)
        );
    }

Here the return value will be:
- poly(0.4) for x <= 0.4;
- poly(1.4) for x >= 1.4; and
- poly(x) for 0.4 < x < 1.4.
2020-12-16 15:24:50 +00:00
9f5b8d0ebb ENH: polynomial - added clone() 2020-12-16 15:24:50 +00:00
dfe98fdf67 ENH: linearInterpolationWeights - protect against and provide early exit if input values are equal 2020-12-16 15:24:49 +00:00
2811c05444 ENH: lazier handling of dynamic libraries
- previously always called dlclose on opened libraries when destroying
  the dlLibraryTable. However, by force closing the libraries the
  situation can arise that the library is missing its own code that it
  needs on unload (#1524). This is also sometimes evident when closing
  VTK libraries for runTimePostProcessing (#354, #1585).

- The new default is to not forcibly dlclose any libraries, unless
  the dlcloseOnTerminate OptimisationSwitch specifies otherwise.

  - The dlLibraryTable::close() method can be used to explicitly close
    all libraries and clear the list.

  - The dlLibraryTable::clear() method now only clears the entries,
    without a dlclose.
2020-12-16 11:25:04 +01:00
dc0372858d ENH: Changing normalization with YMix for the ReactingMultiPhaseParcel
The parcel mass fractions transfer of ReactingMultiPhaseParcel was modified
in order to be consistent between processors.
2020-12-15 14:59:49 -08:00
373d88a4c4 ENH: Function1 - added some missing time conversions 2020-12-15 21:46:57 +00:00
d5260b18d7 ENH: add wmake -show-mpi-compile, -show-mpi-link options
- useful for diagnosing which MPI paths and flags are being used
  when setting up for a new MPI configuration.
2020-12-15 21:45:59 +01:00
c77194e6a1 BUG: incorrect return values for interpolated sampled meshedSurface (#1956)
- only slipped in recently, as part of Development/openfoam!394
2020-12-15 21:45:55 +01:00
b012475c01 ENH: snappyLayerDriver - ensure parallel consistent rebuilding of face centres 2020-12-15 20:38:41 +00:00
05bf4e119a BUG: potential fix for stale fvMesh addressing - see #1956
Failures shown in interFoam cases were found to be a result of stale ldu
addressing in fvMesh.  Potentially delete lduPtr_ alone, but likely safer to
clear all addressing:

    // deleteDemandDrivenData(lduPtr_);
    clearAddressing(true);
2020-12-15 12:06:46 +00:00
19bd7ed21f Merge branch 'feature-Bilger-mixture-fraction-fo' into 'develop'
ENH: BilgerMixtureFraction: New function object

See merge request Development/openfoam!393
2020-12-15 08:55:29 +00:00
e82956a9dc TUT: counterFlowFlame2D: add BilgerMixtureFraction FO 2020-12-15 08:55:13 +00:00
5a8caa35b2 ENH: BilgerMixtureFraction: add new reactionThermo FO
Signed-off-by: Sergio Ferraris <s.ferraris@opencfd.co.uk>
Signed-off-by: Kutalmis Bercin <kutalmis.bercin@esi-group.com>
2020-12-15 08:55:13 +00:00
a16c4ae920 ENH: Exposing specieComposition from ReactingMixture
The FO BilgerMixtureFraction needs access to specieComposition which is
stored in ReactingMixture. A virtual mechanism was added to
basicSpecieMixture to access specieComposition form rho and psi
reationThermos.

ptr was changed to autoPtr to avoid memory leaks (Kutalmis Bercin)
2020-12-15 08:55:13 +00:00
9f53fdcc36 DOC: moleFractions: improve header-file doc and style consistency
INT: moleFractions: add phaseName support
2020-12-15 08:55:13 +00:00
bb07945ad2 BUG: Change default behavior for particle vol-mass change
If keys constantVolume and volumeUpdateMethod are not preent
default to constantVolume = false
2020-12-14 13:47:04 -08:00
27ec25dfef STYLE: report address/field size mismatch 2020-12-14 17:30:08 +01:00
a629fb7db2 Merge branch 'feature-function-objects-multiply' into 'develop'
ENH: Function objects - added new 'multiply' function object

See merge request Development/openfoam!410
2020-12-14 16:08:54 +00:00
75769add98 ENH: Function objects - added new 'multiply' function object
Multiplies a given list of (at least two or more) fields and outputs the
result into a new field.

    fieldResult = field1 * field2 * ... * fieldN

Minimal example by using \c system/controlDict.functions:

    multiply1
    {
        // Mandatory entries (unmodifiable)
        type    multiply;
        libs    (fieldFunctionObjects);

        // Mandatory (inherited) entry (runtime modifiable)
        fields  (<field1> <field2> ... <fieldN>);

        ...
    }
2020-12-14 17:03:09 +01:00
b700456ac4 CONFIG: increment to ADIOS-2.6.0, petsc-3.14.2
- the adiosFoam module has been updated to handle restart with
  the newer time structure (directories only, no files)
2020-12-14 15:20:36 +01:00
75f13e1890 ENH: expose fileOperation::sortTimes as public 2020-12-14 14:23:54 +01:00
ea2e24b6c7 ENH: track old output times for lumpedPoint output (#1793)
- now also tracks the previous output time, which aids on restarts
  since it allows the FEA side the possibility of determining
  the effective deltaT between the output of forces
2020-12-14 12:32:08 +01:00
8fa0921556 COMP: resolved some compiler warnings 2020-12-14 10:35:42 +00:00
696704a0dd COMP: solidFoam: extraneous includes. See 1956. 2020-12-14 08:44:45 +00:00
4fdeb3be83 COMP: remove 64-bit label ambiguity
COMP: fix SP/DP inconsistency in fvGeometryScheme

STYLE: rename polyMesh::updateGeom to polyMesh::updateGeomPoints

- avoids compiler complaints and potential masking of
  primitiveMesh::updateGeom / fvMesh::updateGeom

- mark argument as movable, since that is what is happening inside.

GIT: remove merge cruft

TUT: better clean on MPPICInterFoam
2020-12-11 21:37:54 +01:00
b89f389606 CONFIG: support optional config.sh/readline file
- provides a hook for specifying alternative locations
2020-12-11 21:37:42 +01:00
4c501c4567 Merge branch 'feature-PDRblockMesh' into 'develop'
add outer region to PDRblockMesh.

See merge request Development/openfoam!388
2020-12-11 20:24:47 +00:00
cf3d983b80 ENH: add treatment for PDRblockMesh outer region expansions (#1906)
// Treatment of the outer region
   outer
   {
       type        sphere;
       onGround    true;
       expansion   relative;

       ratios      1.1;

       size        3;
       nCells      10;
   }
2020-12-11 20:24:25 +00:00
e2d7ad5c60 GIT: rename directory PDRsetFields -> PDR 2020-12-11 20:24:24 +00:00
649b1b1971 Merge branch 'feature-noise-weighting-and-refactor' into 'develop'
ENH: noise models - added A, B, C, and D weightings to SPL

See merge request Development/openfoam!408
2020-12-11 20:22:07 +00:00
67204543d0 ENH: noise models - added A, B, C, and D weightings to SPL
The SPL can now be weighted according to the new 'SPLweighting' entry
that can be set to:
- none: no weighting
- dBA : dB(A)
- dBB : dB(B)
- dBC : dB(C)
- dBD : dB(D)

This commit also includes code refactoring of the  noiseModel class to
remove the dependency on noiseFFT/declutter.
2020-12-11 20:21:35 +00:00
8534983b0a Merge remote-tracking branch 'origin/master' into develop 2020-12-11 17:42:29 +00:00
cfde0d679a Merge branch 'bug-1949-globalSum-in-derivative-of-merit-function' into 'master'
BUG: globalSum needed in the merit functions' directional derivative (fixes #1949)

Closes #1949

See merge request Development/openfoam!403
2020-12-11 17:39:00 +00:00
7ffa36dfa9 BUG: globalSum needed in the merit functions' directional derivative (fixes #1949)
Does not affect the current functionality of shape optimisation.
2020-12-11 17:38:22 +00:00
5d3f355d9d Merge branch 'bug-1948-wrong-first-merit-function-value' into 'master'
BUG: Wrong First extrapolated value of the merit function (fixes #1948)

Closes #1948

See merge request Development/openfoam!402
2020-12-11 17:37:35 +00:00
2eae536a70 BUG: Wrong First extrapolated value of the merit function (fixes #1948)
Affected only the first optimisation cycle, if line search was enabled

If eta was not set explicitly, it was computed after evaluating the
directional derivative of the merit function, which was computed
wrongly, leading to an erroneous value of the extrapolated merit
function value.
2020-12-11 17:37:18 +00:00
d119b8b8f9 Merge branch 'bug-1947-writing-control-points-in-collatedFormat' into 'master'
BUG: collated format and writing of NURBS3DVolume CPs - see #1947

See merge request Development/openfoam!401
2020-12-11 17:32:51 +00:00
821222834d Merge branch 'feature-adjoint-releaseCandidatev2012' into 'develop'
Adjoint: release candidate for v2012

See merge request Development/openfoam!400
2020-12-11 17:24:04 +00:00
f7e4b374d9 TUT: added a tutorial showcasing the transformBox option
for the definition of the morphing box in volumetric B-Splines.
2020-12-11 17:22:44 +00:00
d0b59a4529 TUT: updated the da entries for the multi-point, turbulent optimisations 2020-12-11 17:22:44 +00:00
73339d4985 STYLE: endl missing in the headerInfo of objectivePartialVolume 2020-12-11 17:22:44 +00:00
6dbaeaba50 ENH: added the capability of constraining the paEqn in adjointSimple 2020-12-11 17:22:44 +00:00
36159cb16d ENH: da is appended by the adjoint solver name
if useSolverNameForFields is set to true. This facilitates continuation.
2020-12-11 17:22:43 +00:00
95748b0183 ENH: deprecation of fvOptionsAdjoint
fvOptionsAdjoint was needlessly duplicating a lot of the functionality
of fvOptions in order to add an interface for computing sensitivity
contributions emerging from fvOptions. To reduce this code duplication:

- fvOptionsAdjoint was removed
- the corresponding sensitivity contributions have moved to fvOptions through
  virtual functions (returning a zero contribution in the base so
  backwards compatibility is retained)
- all sensitivity classes that were using fvOptionsAdjoint have been
  modified appropriately
- all adjoint solvers are now grabbing a reference to an fvOptionList
  from the database instead of constructing an fvOptionsAdjointList

Hence, all fvOptions contributions to the adjoint equations
or the sensitivity derivatives can be given through system/fvOptions,
removing the need for separate sub-dictionaries within optimisationDict.
2020-12-11 17:22:43 +00:00
7d83fb792a ENH: changes in objective::write
- Expanded the write function in the base class so that it can manage
  input coming from the derived ones. This reduces a lot of code
  duplication in the latter but keeps the functionality.
- Added a default width for all entries in the objective files.
- If a normalisation factor or a target is set, they are written on the
  header of the objective file.
- Cosmetic/code consistency changes in various files.
2020-12-11 17:21:38 +00:00
4981061c09 ENH: objectiveManager now writes the weighted objective function
to files, if the corresponding adjoint solver has more than one
objectives.
2020-12-11 17:21:38 +00:00
ae674b2809 ENH: changes in adjointSimple
- Added preLoop, loop and postLoop functions
- Added preIter, mainIter and postIter functions for each SIMPLE
  iteration
- Added addMomentumSource and addPressureSource virtual functions, to
  allow for additions by derived classes
2020-12-11 17:21:38 +00:00
ba300c3c6f ENH: changed the treatment of fvOptions in primal solvers
fvOptions are no longer a member of incompressiblePrimalSolver but are
looked up from the registry in each iteration of each primal solver.
This means that the main system/fvOptions dictionary is read by ALL
instances of the primal solvers and the latter no longer have their
own fvOptions dict in optimisationDict. This is safe since each fvOption
is applied to a specific field and in case of many primal solvers, the
primal fields are named differently for each of them.

In addition, simple is now split in preLoop, loop and postLoop phase.
Furthermore, each SIMPLE iteration is broken down to
a preIter, mainIter and postIter phase, to allow for different behaviour
by derived classes.
2020-12-11 17:21:37 +00:00
0fb515298d ENH: adjointRASModel now returns a reference
to the primal and adjoint solver names
2020-12-11 17:21:37 +00:00
aee0c30a3e ENH: change in the discretization of part of the (E)SI sensitivity terms
Part of the (E)SI shape sensitivities depends of grad(Ua) & nf computed
on the boundary. Up to now, the code was only computing the normal part
of grad(Ua), to avoid the potentially spurious tangential component
which is computed on the cell center and extrapolated to the boundary
faces. However, for some objectives that are strongly related to the
stresses (e.g. moment, stresses), including also the tangential part of
grad(Ua) is necessary for E-SI to replicate the outcome of FI.

Extensive testing on a number of objectives/cases showed
- No regression when including the tangential part
- Improved behaviour in some rare cases (moment, stresses)

Hence, the tangential part is now included by default. The previous code
behaviour can be replicated by setting the useSnGradInTranposeStresses
flag to true.
2020-12-11 17:21:37 +00:00
c2204eaa27 ENH: Minor NURBS3DVolume refactoring
- controlPointsDefinition is now controled by a class with
  runTimeSelection.
- Added a new controlPointsDefinition option that translates, rotates
  and scales a given box. The required entries have the same meaning as
  in the Paraview 'Transform' filter, facilitating the transition between the
  visual placement of control boxes (e.g. in Paraview) and their setup
  in the code.
- Improved performance during the parameterization, sensitivity
  computation and grid displacement phases by re-using already computed
  basis functions.
2020-12-11 17:21:37 +00:00
24d6497209 ENH: add the solver name to the MRF constructor of simple
in case useSolverNameForFields is set to true.
Used for multi-point optmisation runs.
2020-12-11 17:21:37 +00:00
27ea73f905 ENH: added a default word to the IOMRFZoneList constructor
to allow for constructing different MRF zones for multi-point
optimisation runs
2020-12-11 17:21:37 +00:00
5ec8a4d4b1 GIT: removed the deprecated forceTarget objective
since its behaviour can be replicated by the more general framework for
setting objective targets introduced in 6ee7bc66c.
2020-12-11 17:21:37 +00:00
7754e5bd6c Merge branch 'feature-iso_distance-surface' into 'develop'
Feature iso distance surface

See merge request Development/openfoam!407
2020-12-11 16:45:33 +00:00
4c3a95c808 ENH: additional filtering for distance surface (#1950)
- adds topology-based segmentation of the surfaces generated with
  distance surfaces. This can occur when the surface terminates
  close to a thin wall gap in the mesh; resulting in a cuts that
  extend into the next region.

  The cutting algorithm does not normally distinguish between these
  types of "ragged" cuts, and legitimate ones (eg, cutting multiple
  pipes). The additional segmentation controls provide for two common
  scenarios:

  largestRegion (pre-filter):
  - The cut cells are checked for topological connectivity and the
    region with the most number of cut cells is retained.
    This handles the "ragged" edge problem.

  nearestPoints (pre-filter):
  - The cut cells split into regions, the regions closest to the
    user-defined points are retained.
    Uses maxDistance for additional control.

  proximity (post-filter):
  - Checks the resulting faces against the original search surface
    and rejects faces with a distance greater than absProximity.

ENH: restructure distance surface geometric filtering

- prefilter cells, which can be used to adjust the distance
  calculation in the far field to the real distance
  (not the normal distance).

  This can also be used to artificially sharpen the transition
  between near/far regions, if required in the future.
2020-12-11 16:44:54 +00:00
7a99866db0 ENH: unify sampling code for isoSurfaces, support multiple offsets
- support multiple offsets for cutting plane samples
  and multiple iso-values
2020-12-11 16:44:53 +00:00
8fe0d1bacd ENH: improvements for managing iso-surfaces
- generic isoSurfaceBase. Provides simpler cell-cut detection and
  various functions that can be used for iso-surfaces or when
  preparing prefiltered input for iso-surfaces.

- rudimentary runtime selection

ENH: isoSurface Cell/Topo uses the isoSurfaceBase infrastructure

- simpler cell cut detection, common routines
- ensure that tetMatcher is only called once per cell

ENH: use indirect patch during edge erosion

- lower overhead, allows backtracking (future) if needed
2020-12-11 16:44:53 +00:00
4c7f92d29c Merge branch 'tut-alltest-corrections' into 'develop'
TUT: Alltest: Corrections

See merge request Development/openfoam!412
2020-12-11 14:33:26 +00:00
bcae4b7a4f TUT: Alltest: minor corrections (#1956) 2020-12-11 14:33:04 +00:00
e646218af9 BUG: Fixing reading of volumeUpdateMethod
Signed-off-by: Kutalmis Bercin <kutalmis.bercin@esi-group.com>
2020-12-11 14:33:04 +00:00
ba4a675cd3 Merge branch 'feature-PatchFunction1-ACMI' into 'develop'
Feature add additional scaling to geometric area overlap calculation inside acmi

See merge request Development/openfoam!374
2020-12-11 10:35:06 +00:00
31ecf0d732 ENH: cyclicACMI: optional scaling with PatchFunction1.
Added 'scale' parameter to cyclicACMI. Scales the amount of 'coupledness' (= mask). Allows opening/closing without mesh motion.
2020-12-11 10:35:06 +00:00
6ac8e06245 Merge branch 'feature-runtime-selection-geometry' into 'develop'
Feature runtime selection geometry

See merge request Development/openfoam!411
2020-12-11 10:31:34 +00:00
46dbfabd9d ENH: primitiveMesh: make geometry calculation runtime selectable
This adds a 'geometry' scheme section to the system/fvSchemes:

geometry
{
    type            highAspectRatio;
}

These 'fvGeometryMethod's are used to calculate
- deltaCoeffs
- nonOrthoCoeffs
etc and can even modify the basic face/cellCentres calculation.
2020-12-11 10:31:34 +00:00
4a166c6f3e Merge branch 'feature-lagrangian-patch-interaction-fields' into 'develop'
ENH: Lagrangian - added new PatchInteractionFields cloud function object

See merge request Development/openfoam!409
2020-12-10 17:26:02 +00:00
9d765adaf4 ENH: Lagrangian - added new PatchInteractionFields cloud function object
Creates volume fields whose boundaries are used to store patch interaction
statistics.

Current field output per patch face:
- \<cloud\>\<model\>:count - cumulative particle hits
- \<cloud\>\<model\>:mass - cumuluative mass of hitting particles

Fields can be reset according to:
- none: fields are not reset
- timeStep: reset at each time step
- writeTime: reset at each write time

Usage

    patchInteractionFields1
    {
        type            patchInteractionFields;
        resetMode       writeTime;
    }
2020-12-10 17:25:40 +00:00
8268d8aaba BUG: redistributePar: avoid par comms. Fixes #1953 2020-12-10 15:43:28 +00:00
b179cd355e STYLE: headers: unused includes. 2020-12-10 15:43:28 +00:00
27a676ca20 Merge branch 'feature-generalizedNewtonian' into 'develop'
Feature generalized newtonian

See merge request Development/openfoam!384
2020-12-10 13:41:46 +00:00
341aea0f5c STY: Removing redundant read function in constructor 2020-12-10 13:40:13 +00:00
b9f7f04bed BUG: Fix to HerschelBulkley model to use nu0 from thermo 2020-12-10 13:40:13 +00:00
a98fbcd493 BUG: Fix to powerLaw model to use nu0 from thermo 2020-12-10 13:40:13 +00:00
54ebe724ea ENH: Derivative of B in thermo.H (dKcdTbyKc) calculated from S and G instead of dGdT
Member function dKcdTbyKc in thermo.H is calculated from S and G at Pstd.
Thus dGdT was removed from the thermos.

- Add optional hRef, eRef and Tref as optional.

- Use new thermo to multiphase solver icoReactingMuliPhaseFoam

- Remove hRefConst and eRefConst thermos.

TUT: Updated tutorials
2020-12-10 13:40:13 +00:00
0dd91a9dc4 ENH: Adding tabulated transport and thermo.
TUT: multiphase/icoReactingMultiPhaseInterFoam/inertMultiphaseMultiComponent
2020-12-10 13:40:12 +00:00
97448c655d ENH: Using icoTabulated EoS and non-Newtonian laminar model 2020-12-10 13:40:12 +00:00
c3c4f30a55 ENH: adding generalizedNewtonian to laminar turbulence model
The generalizedNewtonian viscocity models were ported from
the org version and added to the laminar turbulence framework.

This allows use in compressible and incompressible solvers
through the turbulence dictionary under the laminar sub-dictionary.

The thermal laminar viscosity is taken from the thermo for solvers
that use thermo library or from the transportProperties dictionary
for incompressible solvers.

At the moment the option to include viscocity models through the
transportDict is still available.

The icoTabulated equation of state was ported from the org version.

STYLE: use 'model' instead of 'laminarModel' in tutorials
2020-12-10 13:40:12 +00:00
a89ecdeee0 Merge branch 'feature-vibroAcousticShell' into 'develop'
New vibro-acoustic model suite

See merge request Development/openfoam!404
2020-12-10 13:38:37 +00:00
bc430ccdef ENH: New vibro-acoustic model suite
- New solver: `acousticFoam`
  - New base finite-area region class: `regionFaModel`
  - New base shell model classes:
    - `vibrationShellModel`
    - `thermalShellModel`
  - New shell models:
    - A vibration-shell model: `KirchhoffShell`
    - A thermal-shell model: `thermalShell`
  - New finite-area/finite-volume boundary conditions:
    - `clampedPlate`
    - `timeVaryingFixedValue`
    - `acousticWaveTransmissive`
  - New base classes for `fvOption` of finite-area methods: `faOption`
  - New `faOption`s:
    - `contactHeatFluxSource`
    - `externalFileSource`
    - `externalHeatFluxSource`
    - `jouleHeatingSource`
  - New tutorial: `compressible/acousticFoam/obliqueAirJet`

Signed-off-by: Kutalmis Bercin <kutalmis.bercin@esi-group.com>
2020-12-10 13:36:12 +00:00
25246f22a6 Merge branch 'feature-localWorld' into 'develop'
Feature local world

See merge request Development/openfoam!398
2020-12-09 15:20:30 +00:00
348c2a87ad ENH: Adding dynamic mesh to solidFoam and tutorial 2020-12-09 15:17:45 +00:00
df777ce3c6 ENH: waterCooler: new tutorial. 2020-12-09 15:17:45 +00:00
b017ef47bb ENH: Added new multiWorld test case 2020-12-09 15:17:45 +00:00
faba8ee2a1 ENH: Added new solidFoam solver 2020-12-09 15:17:45 +00:00
89f2cda3ab ENH: mpi: use per-application communicator. 2020-12-09 15:17:44 +00:00
627d79dba6 ENH: reduce use of readdir on individual processors (#1946)
- implicitly enabled when timeStampMaster (default) is used
  for the fileModificationChecking

- When running with non-distributed roots (eg, NFS-share) read for
  processor directories on master only and send to sub-processes
  instead individual reads.

- If disabled (old default, or when running with distributed roots),
  uses the regular fileHandler readDir, which may perform readDir
  on each processor. Potentially slow startup times on large systems.

Improvements based on analysis from T.Aoyagi(RIST), A.Azami(RIST)
2020-12-09 14:43:27 +01:00
c51bfdcd05 Merge branch 'feature-buoyancy-fvoption' into 'develop'
ENH: buoyantTurbSource: new fvOption

See merge request Development/openfoam!397
2020-12-08 16:54:50 +00:00
3e4341ad02 ENH: buoyancyTurbSource: add a new fvOption
Applies sources on turbulent kinetic energy (i.e. `k`)
    and either turbulent kinetic energy dissipation rate (i.e. `epsilon`)
    or specific dissipation rate (i.e. `omega`) to incorporate effects
    of buoyancy on turbulence in incompressible and compressible flows.

    See buoyancyTurbSource.H for details.
2020-12-08 16:49:17 +00:00
5de23079ea DOC: fvOptions: improve header documentation
STYLE: use auto/tmp wherever possible
  ENH: make destructor/deleted constructors consistent with FOs
2020-12-08 16:49:17 +00:00
8ad61f8e9d ENH: optional innerRadius for searchable disk
- can be used directly, or in special cases like a searchable plane
  with a gap of things in the centre that are not to be sampled.
2020-12-08 15:32:50 +01:00
56b5234fbc ENH: store concrete sampled isoSurface faces/points as member data
- was previously via inheritance, but using member data instead
  supports a more flexible internal switching of the storage. It also
  ensures that data access remains safe, even in the absence of
  an isoSurface.
2020-12-08 13:31:23 +01:00
ccde68d410 ENH: cellZones support for isoSurface cell/topo sampling variants (#1678)
- better alignment of sampling Cell/Point/Topo inputs

- make exposedPatchName optional for isoSurface, cuttingPlane. This
  was a holdover requirement from an older version of fvMeshSubset
2020-12-08 13:31:23 +01:00
9da5215786 ENH: add sampledSurface::sampleOnPoints
- loop for interpolating volume elements to face points,
  which removes duplicate code in several other places
2020-12-08 13:31:22 +01:00
2f6082712e ENH: modernize some code constructs in isoSurface
- add debug field to isoSurfaceTopo
- don't need dynamic field for new points

- reduce code in sampledIsoSurfaceCell
2020-12-08 13:31:22 +01:00
811a83599e CONFIG: change default distanceSurface algorithm from 'cell' to 'topo'
- yields cleaner surfaces with few cuts.

  Can use isoMethod keyword to select cell/point/topo if they prove
  better for any particular case.

CONFIG: change default cuttingPlane algorithm from 'cell' to 'topo'
2020-12-08 13:31:22 +01:00
b1a27d3d00 ENH: rename 'classic' Foam::isoSurface as Foam::isoSurfacePoint
- better distinction between types of algorithms.
  Easier for future deprecation/replacement.
2020-12-08 13:31:22 +01:00
be783632f2 ENH: isoSurfaceParams
- bundles selection and control parameters used when creating
  iso-surfaces. This simplifies selection and specification

- drop old compatibility handling of "cell" as a bool

- harmonize filter/regularisation flags for iso-surface

- for dictionary input, accept "isoMethod" and "isoAlgorithm" as being
  synonymous. Using "isoMethod" is less subject to typing errors.
2020-12-08 13:31:22 +01:00
61dd6aa701 ENH: code consistency in sampling
TUT: dictionary form of surfaces instead of list
2020-12-08 13:18:38 +01:00
4421021e99 ENH: support use of bitSet for regionSplit 2020-12-08 13:18:38 +01:00
0b68f14f7d ENH: more explicit about handling empty matchers for index lookup
- for boundary meshes, zones etc. The behaviour with an empty matcher
  was either not properly documented, and looped through all
  names just to establish there was no match.

STYLE: removed redundant typedefs for point fields
2020-12-08 13:18:34 +01:00
df74e8448c ENH: robuster fileOperations splitProcessorPath
- robuster matching behaviour when encountering paths that themselves
  contain the word "processor" in them. For example,

    "/path/processor0generation2/case1/processor10/system"
    will now correctly match on processor10 instead of failing.

- use procRangeType for encapsulating the processor ranges

- provision for information of distributed vs non-distributed roots.
  The information is currently available from the initial setup, but
  can useful to access directly within fileOperation.

STYLE: modernize list iteration
2020-12-08 11:58:28 +01:00
a939042e1b ENH: add bitSet::null() and clarify some documentation
- the NullObject singleton can also be cast to a bitSet
  (sufficient size and bit-pattern). Useful for places that
  need to hold a reference on construction
2020-12-08 11:58:28 +01:00
08efeb1a03 ENH: define UPstream rangeType
- UPstream::rangeType as typedef for IntRange<int> for better use
  semantics
2020-12-08 11:58:27 +01:00
e697ac277f CONFIG: respect WM_QUIET=false as a logic value in wmake
- Makefile only checks set/unset, so handle 'false' within wmake
  itself
2020-12-08 11:58:27 +01:00
b966b7cd4b ENH: static test methods for matching simple cell shapes
- (tet, pyr, hex) can be identified from their number of faces
  and vertices. For these common shapes can use static `test()`
  method instead of the virtual isA() method.

  This is much cheaper for calling on an individual basis since
  it avoids the overhead of constructing an object.

ENH: tetCell edge/reverseEdge (already had tetEdge)
2020-12-08 11:58:27 +01:00
b7c8a45de2 STYLE: bracket instead of braces on List constructors
- avoid potential future mistakes if someone adds a sizing dimension
  and finds they have inadvertently called construct labelList with
  `{std::initializer_list<label>}` instead of `label`
2020-12-08 11:58:27 +01:00
7b5c6868dd BOT: Update contributors file 2020-12-08 11:58:27 +01:00
cb924ec3d2 Merge branch 'issue-1900-atmwallfunction-double-value-entry' into 'develop'
BUG:  atm wall functions: fix double "value" entry issue

See merge request Development/openfoam!395
2020-12-08 09:36:13 +00:00
1bc2ffad99 BUG: atm wall functions: fix double "value" entry issue (#1900)
STYLE: atm wall functions: use auto and bool types wherever possible
  TUT: atmosphericModels: changes for style consistency
2020-12-08 09:33:44 +00:00
3b949b66ff BUG: collated format and writing of NURBS3DVolume CPs - see #1947
The if(Pstream::master()) clause in NURBS3DVolume::writeCpsInDict() was
causing the fileName of the regIOobject not to be allocated in all
processors, giving problems when masterUncollatedFileOperation::masterOp
was called by collatedFileOperation::writeObject for the mkDirOp.
2020-12-07 16:41:26 +02:00
1086 changed files with 59410 additions and 11211 deletions

View File

@ -33,6 +33,7 @@ It is likely incomplete...
- Haakan Nilsson
- Niklas Nordin
- Mark Olesen
- Victor Olesen
- Evangelos Papoutsis-Kiachagias
- Juho Peltola
- Johan Roenby
@ -49,3 +50,7 @@ It is likely incomplete...
- Norbert Weber
- Henry Weller
- Niklas Wikstrom
- Thorsten Zirwes
<!----------------------------------------------------------------------------->

View File

@ -1,2 +1,2 @@
api=2011
patch=201012
api=2012
patch=0

View File

@ -0,0 +1,3 @@
acousticFoam.C
EXE = $(FOAM_APPBIN)/acousticFoam

View File

@ -0,0 +1,14 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fvOption/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-lsampling \
-lregionFaModels

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
acousticFoam
Group
grpAcousticSolvers
Description
Acoustic solver solving the acoustic pressure wave equation.
\f[
\ddt2{pa} - c^2 \laplacian{pa} = 0
\f]
where
\vartable
c | Sound speed
pa | Acoustic pressure
\endvartable
SourceFiles
acousticFoam.C
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "fvOptions.H"
#include "pimpleControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Acoustic solver solving the acoustic pressure wave equation."
);
#include "postProcess.H"
#include "addCheckCaseOptions.H"
#include "setRootCaseLists.H"
#include "createTime.H"
#include "createMesh.H"
#include "createControl.H"
#include "createRegionControls.H"
#include "readTransportProperties.H"
#include "createFields.H"
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
++runTime;
Info<< "Time = " << runTime.timeName() << nl << endl;
while (pimple.correct())
{
#include "paEqn.H"
}
runTime.write();
runTime.printExecutionTime(Info);
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,15 @@
Info << "\nReading pa" << endl;
volScalarField pa
(
IOobject
(
"pa",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);

View File

@ -0,0 +1,8 @@
fvSolution solutionDict(runTime);
const dictionary& pimpleDict = solutionDict.subDict("PIMPLE");
bool solvePrimaryRegion
(
pimpleDict.getOrDefault("solvePrimaryRegion", true)
);

View File

@ -0,0 +1,15 @@
fvScalarMatrix paEqn
(
fvm::d2dt2(pa) - sqr(c0)*fvc::laplacian(pa)
);
if (solvePrimaryRegion)
{
paEqn.relax();
paEqn.solve();
}
else
{
pa.correctBoundaryConditions();
}

View File

@ -0,0 +1,23 @@
Info<< "\nReading transportProperties" << endl;
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar c0("c0", dimVelocity, transportProperties);
dimensionedScalar rho("rho", dimDensity, transportProperties);
scalar MaxCo =
max(mesh.surfaceInterpolation::deltaCoeffs()*c0).value()
*runTime.deltaT().value();
Info<< "Max acoustic Courant Number = " << MaxCo << endl;

View File

@ -14,7 +14,9 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -28,4 +30,8 @@ EXE_LIBS = \
-lturbulenceModels \
-lcompressibleTurbulenceModels \
-lradiationModels \
-lregionModels
-lfvOptions \
-lfaOptions \
-lregionModels \
-lsampling \
-lregionFaModels

View File

@ -1,5 +1,4 @@
EXE_INC = \
-DFULLDEBUG -g -O0 \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \

View File

@ -0,0 +1,4 @@
const volScalarField& rho = trho();
volScalarField& h = thermo.he();
const volScalarField& betav = *betavPtr;

View File

@ -4,13 +4,6 @@ autoPtr<solidThermo> pThermo(solidThermo::New(mesh));
solidThermo& thermo = pThermo();
tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho();
tmp<volScalarField> tcp = thermo.Cp();
const volScalarField& cp = tcp();
volScalarField& p = thermo.p();
volScalarField& h = thermo.he();
autoPtr<coordinateSystem> coordinatesPtr;
autoPtr<volSymmTensorField> taniAlpha;
@ -96,7 +89,6 @@ else
)
);
}
const volScalarField& betav = *betavPtr;
#include "createRadiationModel.H"
#include "createFvOptions.H"

View File

@ -60,6 +60,7 @@ int main(int argc, char *argv[])
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "createFields.H"
#include "createFieldRefs.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,13 +37,13 @@ Description
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "singlePhaseTransportModel.H"
#include "PhaseIncompressibleTurbulenceModel.H"
#include "DPMIncompressibleTurbulenceModel.H"
#include "pimpleControl.H"
#include "CorrectPhi.H"
#ifdef MPPIC
#include "basicKinematicMPPICCloud.H"
#define basicKinematicTypeCloud basicKinematicMPPICCloud
#include "basicKinematicCloud.H"
#define basicKinematicTypeCloud basicKinematicCloud
#else
#include "basicKinematicCollidingCloud.H"
#define basicKinematicTypeCloud basicKinematicCollidingCloud
@ -110,7 +111,6 @@ int main(int argc, char *argv[])
continuousPhaseTransport.correct();
muc = rhoc*continuousPhaseTransport.nu();
Info<< "Evolving " << kinematicCloud.name() << endl;
kinematicCloud.evolve();
// Update continuous phase volume fraction field

View File

@ -1,7 +1,7 @@
EXE_INC = \
-I.. \
-I../.. \
-I../DPMTurbulenceModels/lnInclude \
-I../../DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \

View File

@ -1,6 +1,6 @@
EXE_INC = \
-I.. \
-I../DPMTurbulenceModels/lnInclude \
-I../DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -38,12 +39,12 @@ Description
#include "fvCFD.H"
#include "singlePhaseTransportModel.H"
#include "PhaseIncompressibleTurbulenceModel.H"
#include "DPMIncompressibleTurbulenceModel.H"
#include "pimpleControl.H"
#ifdef MPPIC
#include "basicKinematicMPPICCloud.H"
#define basicKinematicTypeCloud basicKinematicMPPICCloud
#include "basicKinematicCloud.H"
#define basicKinematicTypeCloud basicKinematicCloud
#else
#include "basicKinematicCollidingCloud.H"
#define basicKinematicTypeCloud basicKinematicCollidingCloud
@ -117,6 +118,12 @@ int main(int argc, char *argv[])
cloudVolSUSu.correctBoundaryConditions();
cloudSU.source() = Zero;
// cloudVolSUSu.primitiveFieldRef() =
// (cloudSU.diag()*Uc() - cloudSU.source())/mesh.V();
// cloudVolSUSu.correctBoundaryConditions();
// cloudSU.source() = cloudSU.diag()*Uc();
// --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop())
{

View File

@ -0,0 +1,186 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "DPMIncompressibleTurbulenceModel.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class TransportModel>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::
DPMIncompressibleTurbulenceModel
(
const word& type,
const volScalarField& alpha,
const geometricOneField& rho,
const volVectorField& U,
const surfaceScalarField& alphaRhoPhi,
const surfaceScalarField& phi,
const TransportModel& transportModel,
const word& propertiesName
)
:
TurbulenceModel
<
volScalarField,
geometricOneField,
incompressibleTurbulenceModel,
TransportModel
>
(
alpha,
rho,
U,
alphaRhoPhi,
phi,
transportModel,
propertiesName
)
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
template<class TransportModel>
Foam::autoPtr<Foam::DPMIncompressibleTurbulenceModel<TransportModel>>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::New
(
const volScalarField& alpha,
const volVectorField& U,
const surfaceScalarField& alphaRhoPhi,
const surfaceScalarField& phi,
const TransportModel& transportModel,
const word& propertiesName
)
{
return autoPtr<DPMIncompressibleTurbulenceModel>
(
static_cast<DPMIncompressibleTurbulenceModel*>(
TurbulenceModel
<
volScalarField,
geometricOneField,
incompressibleTurbulenceModel,
TransportModel
>::New
(
alpha,
geometricOneField(),
U,
alphaRhoPhi,
phi,
transportModel,
propertiesName
).ptr())
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class TransportModel>
Foam::tmp<Foam::volScalarField>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::pPrime() const
{
return tmp<volScalarField>::New
(
IOobject
(
IOobject::groupName("pPrime", this->alphaRhoPhi_.group()),
this->runTime_.timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
this->mesh_,
dimensionedScalar(dimPressure, Zero)
);
}
template<class TransportModel>
Foam::tmp<Foam::surfaceScalarField>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::pPrimef() const
{
return tmp<surfaceScalarField>::New
(
IOobject
(
IOobject::groupName("pPrimef", this->alphaRhoPhi_.group()),
this->runTime_.timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
this->mesh_,
dimensionedScalar(dimPressure, Zero)
);
}
template<class TransportModel>
Foam::tmp<Foam::volSymmTensorField>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::devReff() const
{
return devRhoReff();
}
template<class TransportModel>
Foam::tmp<Foam::fvVectorMatrix>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::divDevReff
(
volVectorField& U
) const
{
return divDevRhoReff(U);
}
template<class TransportModel>
Foam::tmp<Foam::volSymmTensorField>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::devRhoReff() const
{
NotImplemented;
return devReff();
}
template<class TransportModel>
Foam::tmp<Foam::fvVectorMatrix>
Foam::DPMIncompressibleTurbulenceModel<TransportModel>::divDevRhoReff
(
volVectorField& U
) const
{
NotImplemented;
return divDevReff(U);
}
// ************************************************************************* //

View File

@ -0,0 +1,144 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::DPMIncompressibleTurbulenceModel
Description
Templated abstract base class for volumen occupancy incompressible
turbulence models.
SourceFiles
DPMIncompressibleTurbulenceModel.C
\*---------------------------------------------------------------------------*/
#ifndef DPMIncompressibleTurbulenceModel_H
#define DPMIncompressibleTurbulenceModel_H
#include "TurbulenceModel.H"
#include "incompressibleTurbulenceModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class DPMIncompressibleTurbulenceModel Declaration
\*---------------------------------------------------------------------------*/
template<class TransportModel>
class DPMIncompressibleTurbulenceModel
:
public TurbulenceModel
<
volScalarField,
geometricOneField,
incompressibleTurbulenceModel,
TransportModel
>
{
public:
typedef volScalarField alphaField;
typedef geometricOneField rhoField;
typedef TransportModel transportModel;
// Constructors
//- Construct
DPMIncompressibleTurbulenceModel
(
const word& type,
const alphaField& alpha,
const geometricOneField& rho,
const volVectorField& U,
const surfaceScalarField& alphaRhoPhi,
const surfaceScalarField& phi,
const TransportModel& transportModel,
const word& propertiesName
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<DPMIncompressibleTurbulenceModel> New
(
const alphaField& alpha,
const volVectorField& U,
const surfaceScalarField& alphaRhoPhi,
const surfaceScalarField& phi,
const TransportModel& transportModel,
const word& propertiesName = turbulenceModel::propertiesName
);
//- Destructor
virtual ~DPMIncompressibleTurbulenceModel() = default;
// Member Functions
//- Return the phase-pressure'
// (derivative of phase-pressure w.r.t. phase-fraction)
virtual tmp<volScalarField> pPrime() const;
//- Return the face-phase-pressure'
// (derivative of phase-pressure w.r.t. phase-fraction)
virtual tmp<surfaceScalarField> pPrimef() const;
//- Return the effective stress tensor
virtual tmp<volSymmTensorField> devReff() const;
//- Return the source term for the momentum equation
virtual tmp<fvVectorMatrix> divDevReff(volVectorField& U) const;
//- Return the effective stress tensor
virtual tmp<volSymmTensorField> devRhoReff() const;
//- Return the source term for the momentum equation
virtual tmp<fvVectorMatrix> divDevRhoReff(volVectorField& U) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "DPMIncompressibleTurbulenceModel.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,7 +25,7 @@ License
\*---------------------------------------------------------------------------*/
#include "PhaseIncompressibleTurbulenceModel.H"
#include "DPMIncompressibleTurbulenceModel.H"
#include "singlePhaseTransportModel.H"
#include "addToRunTimeSelectionTable.H"
#include "makeTurbulenceModel.H"
@ -41,7 +41,7 @@ defineTurbulenceModelTypes
volScalarField,
geometricOneField,
incompressibleTurbulenceModel,
PhaseIncompressibleTurbulenceModel,
DPMIncompressibleTurbulenceModel,
singlePhaseTransportModel
);
@ -50,21 +50,21 @@ makeBaseTurbulenceModel
volScalarField,
geometricOneField,
incompressibleTurbulenceModel,
PhaseIncompressibleTurbulenceModel,
DPMIncompressibleTurbulenceModel,
singlePhaseTransportModel
);
#define makeLaminarModel(Type) \
makeTemplatedTurbulenceModel \
(singlePhaseTransportModelPhaseIncompressibleTurbulenceModel, laminar, Type)
(singlePhaseTransportModelDPMIncompressibleTurbulenceModel, laminar, Type)
#define makeRASModel(Type) \
makeTemplatedTurbulenceModel \
(singlePhaseTransportModelPhaseIncompressibleTurbulenceModel, RAS, Type)
(singlePhaseTransportModelDPMIncompressibleTurbulenceModel, RAS, Type)
#define makeLESModel(Type) \
makeTemplatedTurbulenceModel \
(singlePhaseTransportModelPhaseIncompressibleTurbulenceModel, LES, Type)
(singlePhaseTransportModelDPMIncompressibleTurbulenceModel, LES, Type)
#include "Stokes.H"
makeLaminarModel(Stokes);

View File

@ -1,6 +1,6 @@
EXE_INC = \
-I.. \
-I../DPMTurbulenceModels/lnInclude \
-I../DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \

View File

@ -1,5 +1,5 @@
EXE_INC = \
-I./DPMTurbulenceModels/lnInclude \
-I./DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
@ -13,7 +13,6 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/phaseIncompressible/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude

View File

@ -160,10 +160,11 @@ surfaceScalarField alphaPhic
alphacf*phic
);
autoPtr<PhaseIncompressibleTurbulenceModel<singlePhaseTransportModel>>
autoPtr<DPMIncompressibleTurbulenceModel<singlePhaseTransportModel>>
continuousPhaseTurbulence
(
PhaseIncompressibleTurbulenceModel<singlePhaseTransportModel>::New
DPMIncompressibleTurbulenceModel<singlePhaseTransportModel>::New
(
alphac,
Uc,

View File

@ -2,6 +2,8 @@ EXE_INC = \
-I../reactingParcelFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
@ -27,6 +29,8 @@ EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-ldynamicMesh \
-ldynamicFvMesh \
-lsampling \
-lturbulenceModels \
-lcompressibleTurbulenceModels \

View File

@ -81,7 +81,15 @@ else if (pimple.SIMPLErho())
rho = thermo.rho();
}
// Correct rhoUf if the mesh is moving
fvc::correctRhoUf(rhoUf, rho, U, phi);
if (thermo.dpdt())
{
dpdt = fvc::ddt(p);
if (mesh.moving())
{
dpdt -= fvc::div(fvc::meshPhi(rho, U), p);
}
}

View File

@ -3,6 +3,8 @@ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
@ -28,6 +30,8 @@ EXE_LIBS = \
-lfvOptions \
-lsampling \
-lmeshTools \
-ldynamicMesh \
-ldynamicFvMesh \
-lturbulenceModels \
-lcompressibleTurbulenceModels \
-lspecie \

View File

@ -5,8 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2011-2020 OpenFOAM Foundation
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,8 +37,8 @@ Description
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "turbulentFluidThermoModel.H"
#include "surfaceFilmModel.H"
#include "rhoReactionThermo.H"
#include "CombustionModel.H"
@ -47,6 +47,7 @@ Description
#include "fvOptions.H"
#include "pimpleControl.H"
#include "pressureControl.H"
#include "CorrectPhi.H"
#include "localEulerDdtScheme.H"
#include "fvcSmooth.H"
#include "cloudMacros.H"
@ -76,13 +77,13 @@ int main(int argc, char *argv[])
#include "addCheckCaseOptions.H"
#include "setRootCaseLists.H"
#include "createTime.H"
#include "createMesh.H"
#include "createControl.H"
#include "createTimeControls.H"
#include "createDynamicFvMesh.H"
#include "createDyMControls.H"
#include "createFields.H"
#include "createFieldRefs.H"
#include "createRegionControls.H"
#include "initContinuityErrs.H"
#include "createRhoUfIfPresent.H"
turbulence->validate();
@ -98,7 +99,23 @@ int main(int argc, char *argv[])
while (runTime.run())
{
#include "readTimeControls.H"
#include "readDyMControls.H"
// Store divrhoU from the previous mesh
// so that it can be mapped and used in correctPhi
// to ensure the corrected phi has the same divergence
autoPtr<volScalarField> divrhoU;
if (solvePrimaryRegion && correctPhi)
{
divrhoU.reset
(
new volScalarField
(
"divrhoU",
fvc::div(fvc::absolute(phi, rho, U))
)
);
}
if (LTS)
{
@ -114,6 +131,44 @@ int main(int argc, char *argv[])
Info<< "Time = " << runTime.timeName() << nl << endl;
// Store momentum to set rhoUf for introduced faces.
autoPtr<volVectorField> rhoU;
if (solvePrimaryRegion && rhoUf.valid())
{
rhoU.reset(new volVectorField("rhoU", rho*U));
}
// Store the particle positions
parcels.storeGlobalPositions();
// Do any mesh changes
mesh.update();
if (solvePrimaryRegion && mesh.changing())
{
gh = (g & mesh.C()) - ghRef;
ghf = (g & mesh.Cf()) - ghRef;
MRF.update();
if (correctPhi)
{
// Calculate absolute flux
// from the mapped surface velocity
phi = mesh.Sf() & rhoUf();
#include "../../compressible/rhoPimpleFoam/correctPhi.H"
// Make the fluxes relative to the mesh-motion
fvc::makeRelative(phi, rho, U);
}
if (checkMeshCourantNo)
{
#include "meshCourantNo.H"
}
}
parcels.evolve();
surfaceFilm.evolve();

View File

@ -103,7 +103,7 @@ License
);
}
// Update tho boundary values of the reciprocal time-step
// Update the boundary values of the reciprocal time-step
rDeltaT.correctBoundaryConditions();
// Spatially smooth the time scale field

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,7 +52,7 @@ Description
#include "CorrectPhi.H"
#include "fvcSmooth.H"
#include "basicKinematicMPPICCloud.H"
#include "basicKinematicCloud.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -147,7 +147,7 @@ volScalarField alphacRho(alphac*rho);
alphacRho.oldTime();
Info<< "Constructing kinematicCloud " << endl;
basicKinematicMPPICCloud kinematicCloud
basicKinematicCloud kinematicCloud
(
"kinematicCloud",
rho,

View File

@ -1,5 +1,7 @@
EXE_INC = \
-I../VoF \
-I$(LIB_SRC)/phaseSystemModels/twoPhaseInter/incompressibleInterPhaseTransportModel/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/twoPhaseInter/VoFphaseIncompressibleTurbulenceModels/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
@ -10,6 +12,7 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels/twoPhaseMixture/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/phaseIncompressible/lnInclude \
-I$(LIB_SRC)/transportModels/immiscibleIncompressibleTwoPhaseMixture/lnInclude
EXE_LIBS = \
@ -23,4 +26,6 @@ EXE_LIBS = \
-limmiscibleIncompressibleTwoPhaseMixture \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lwaveModels
-lwaveModels \
-lVoFphaseTurbulentTransportModels \
-lincompressibleInterPhaseTransportModels

View File

@ -70,14 +70,19 @@ surfaceScalarField rhoPhi
fvc::interpolate(rho)*phi
);
typedef incompressibleInterPhaseTransportModel
<
immiscibleIncompressibleTwoPhaseMixture
> transportModelType;
// Construct incompressible turbulence model
autoPtr<incompressible::turbulenceModel> turbulence
autoPtr<transportModelType> turbulence
(
incompressible::turbulenceModel::New(U, phi, mixture)
new transportModelType
(
rho, U, phi, rhoPhi, mixture
)
);
#include "readGravitationalAcceleration.H"
#include "readhRef.H"
#include "gh.H"

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -45,6 +46,7 @@ Description
#include "CrankNicolsonDdtScheme.H"
#include "subCycle.H"
#include "immiscibleIncompressibleTwoPhaseMixture.H"
#include "incompressibleInterPhaseTransportModel.H"
#include "turbulentTransportModel.H"
#include "pimpleControl.H"
#include "fvOptions.H"
@ -76,8 +78,6 @@ int main(int argc, char *argv[])
#include "initCorrectPhi.H"
#include "createUfIfPresent.H"
turbulence->validate();
if (!LTS)
{
#include "CourantNo.H"

View File

@ -1,5 +1,7 @@
EXE_INC = \
-I../VoF \
-I$(LIB_SRC)/phaseSystemModels/twoPhaseInter/incompressibleInterPhaseTransportModel/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/twoPhaseInter/VoFphaseIncompressibleTurbulenceModels/lnInclude \
-I../interFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
@ -14,6 +16,7 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/phaseIncompressible/lnInclude \
-I$(LIB_SRC)/transportModels/immiscibleIncompressibleTwoPhaseMixture/lnInclude
EXE_LIBS = \
@ -29,4 +32,6 @@ EXE_LIBS = \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lwaveModels \
-lgeometricVoF
-lgeometricVoF \
-lVoFphaseTurbulentTransportModels \
-lincompressibleInterPhaseTransportModels

View File

@ -71,10 +71,17 @@ surfaceScalarField rhoPhi
);
// Construct incompressible turbulence model
autoPtr<incompressible::turbulenceModel> turbulence
typedef incompressibleInterPhaseTransportModel
<
immiscibleIncompressibleTwoPhaseMixture
> transportModelType;
autoPtr<transportModelType> turbulence
(
incompressible::turbulenceModel::New(U, phi, mixture)
new transportModelType
(
rho, U, phi, rhoPhi, mixture
)
);

View File

@ -10,6 +10,7 @@
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2018 Johan Roenby
Copyright (C) 2019-2020 DLR
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -59,7 +60,7 @@ Description
#include "CrankNicolsonDdtScheme.H"
#include "subCycle.H"
#include "immiscibleIncompressibleTwoPhaseMixture.H"
#include "turbulentTransportModel.H"
#include "incompressibleInterPhaseTransportModel.H"
#include "pimpleControl.H"
#include "fvOptions.H"
#include "CorrectPhi.H"
@ -91,8 +92,6 @@ int main(int argc, char *argv[])
#include "initCorrectPhi.H"
#include "createUfIfPresent.H"
turbulence->validate();
#include "CourantNo.H"
#include "setInitialDeltaT.H"

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -164,6 +164,23 @@ inline bool compare
int main(int argc, char *argv[])
{
Info<< "bitSet::null()" << nl
<< "sizeof : " << sizeof(bitSet::null()) << " bytes" << nl;
info(bitSet::null());
{
bitSet emptySet;
info(emptySet);
extent(emptySet);
emptySet.resize(10);
info(emptySet);
extent(emptySet);
}
Info<< nl << "Tests" << nl;
bitSet list1(22);
// Set every third one on
forAll(list1, i)

View File

@ -36,6 +36,7 @@ Description
#include "bitSet.H"
#include "BitOps.H"
#include "FlatOutput.H"
#include "bitSetOrBoolList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -153,6 +154,24 @@ int main(int argc, char *argv[])
Info<< "\nafter set [13,5]\n";
compare(list1, "1..1..1..1..111111....");
{
boolList list2(5, true);
list2.unset(2);
Info<< "Test wrapper idea" << nl;
bitSetOrBoolList wrapper(list2);
if (wrapper.test(1))
{
Info<< "1 is on" << nl;
}
if (!wrapper.test(2))
{
Info<< "2 is off" << nl;
}
}
Info<< "\nDone" << nl << endl;
return 0;
}

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::bitSetOrBoolList
Description
Simple wrapper for handling test() on bitSet or boolList
without a templating layer or lambda expresssion.
\*---------------------------------------------------------------------------*/
#ifndef bitSetOrBoolList_H
#define bitSetOrBoolList_H
#include "bitSet.H"
#include "boolList.H"
/*---------------------------------------------------------------------------*\
Class bitSetOrBoolList Declaration
\*---------------------------------------------------------------------------*/
namespace Foam
{
class bitSetOrBoolList
{
const bitSet& bits_;
const boolList& bools_;
public:
// Constructors
//- Construct with a bitSet reference
explicit bitSetOrBoolList(const bitSet& select)
:
bits_(select),
bools_(boolList::null())
{}
//- Construct with a boolList reference
explicit bitSetOrBoolList(const boolList& select)
:
bits_(bitSet::null()),
bools_(select)
{}
// Member Functions
//- Is empty
bool empty() const
{
return bits_.empty() && bools_.empty();
}
//- Size
label size() const
{
return bits_.size() + bools_.size();
}
//- Test function
bool test(const label i) const
{
return bits_.test(i) || bools_.test(i);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::disabledBoolList
Description
A trivial structure to use as a boolList replacement when testing
compilation without using the [] accessors.
Example,
\code
const disableBoolList blockedFace;
...
if (blockedFace.test(facei)) ... // Good
if (blockedFace[facei]) ... // Compile error
\endcode
\*---------------------------------------------------------------------------*/
#ifndef disabledBoolList_H
#define disabledBoolList_H
/*---------------------------------------------------------------------------*\
Class disabledBoolList Declaration
\*---------------------------------------------------------------------------*/
namespace Foam
{
struct disabledBoolList
{
bool empty() const { return true; }
int size() const { return 0; }
bool test(int) const { return true; }
void set(bool) {}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -37,6 +37,7 @@ Description
#include "OSspecific.H"
#include "fvCFD.H"
#include "cpuTime.H"
#include "volFields.H"
#include "IOobjectList.H"
#include "regionProperties.H"
#include "decompositionInformation.H"
@ -89,7 +90,16 @@ int main(int argc, char *argv[])
// These are implicit so just ignore them
argList::ignoreOptionCompat({"dry-run", 0}, false);
argList::ignoreOptionCompat({"cellDist", 0}, false);
argList::addBoolOption
(
"cellDist",
"Write cell distribution as volScalarField for visualization"
);
argList::addBoolOption
(
"cellDist-internal",
"Write cell distribution (internal field) for visualization"
);
// Include explicit constant options, have zero from time range
timeSelector::addOptions(true, false);
@ -236,6 +246,68 @@ int main(int argc, char *argv[])
Info<< nl;
}
info.printSummary(Info);
if (args.found("cellDist-internal"))
{
volScalarField::Internal cellDist
(
IOobject
(
"cellDist",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("cellDist", dimless, -1)
);
forAll(cellToProc, celli)
{
cellDist[celli] = cellToProc[celli];
}
cellDist.write();
Info<< nl << "Wrote decomposition as volScalarField::Internal to "
<< cellDist.name() << " for visualization."
<< endl;
fileHandler().flush();
}
else if (args.found("cellDist"))
{
volScalarField cellDist
(
IOobject
(
"cellDist",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("cellDist", dimless, -1),
zeroGradientFvPatchScalarField::typeName
);
forAll(cellToProc, celli)
{
cellDist[celli] = cellToProc[celli];
}
cellDist.correctBoundaryConditions();
cellDist.write();
Info<< nl << "Wrote decomposition as volScalarField to "
<< cellDist.name() << " for visualization."
<< endl;
fileHandler().flush();
}
}
Info<< "\nEnd\n" << endl;

View File

@ -0,0 +1,3 @@
Test-fileOperation1.C
EXE = $(FOAM_USER_APPBIN)/Test-fileOperation1

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-fileOperation1
Description
Test string parsing and other bits for fileOperation
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "fileName.H"
#include "fileOperation.H"
#include "SubList.H"
#include "IOobject.H"
#include "IOstreams.H"
#include "OSspecific.H"
using namespace Foam;
word toString(const fileOperation::procRangeType& group)
{
if (group.empty())
{
return word::null;
}
return Foam::name(group.first()) + "-" + Foam::name(group.last());
}
void testSplitPath(const fileName& pathName)
{
fileName path, procDir, local;
fileOperation::procRangeType group;
label nProcs;
const label proci =
fileOperation::splitProcessorPath
(
pathName,
path,
procDir,
local,
group,
nProcs
);
Info<< nl
<< "Input = " << pathName << nl
<< " path = " << path << nl
<< " proc = " << procDir << nl
<< " local = " << local << nl
<< " group = " << group << " = " << toString(group) << nl
<< " proci = " << proci << nl
<< " nProcs = " << nProcs << nl;
}
void testSplitPaths(std::initializer_list<const char* const> dirNames)
{
for (const auto& dirName : dirNames)
{
testSplitPath(fileName(dirName));
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::addArgument("fileName .. fileNameN");
argList::addOption("istream", "file", "test Istream values");
testSplitPaths
({
"foo/bar",
"foo/processor5/system",
"foo/processors100_0-5/constant",
"foo/processors20_12-16/constant",
"/new-processor-gen/case1/processors20",
"/new-processor-gen/case1/processors100_0-5/constant",
"/new-processor-gen/case1/processors/input",
"devel/processor/ideas/processor0/system",
"/path/processor0Generation1/case1/processor10/input",
"path/processors100_ab-cd/constant",
"path/processors100_a11-d00/constant",
});
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -1,6 +1,8 @@
#!/bin/bash
#. /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/etc/bashrc
. $WM_PROJECT_DIR/etc/bashrc
#cd /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/chtMultiRegionSimpleFoam
chtMultiRegionSimpleFoam -case ./fluid -world fluid 2>&1 | tee run_fluid.log
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
#------------------------------------------------------------------------------
chtMultiRegionSimpleFoam -case fluid -world fluid 2>&1 | tee run_fluid.log
read dummy
#------------------------------------------------------------------------------

View File

@ -1,6 +1,8 @@
#!/bin/bash
. $WM_PROJECT_DIR/etc/bashrc
#. /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/etc/bashrc
#cd /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/chtMultiRegionSimpleFoam
chtMultiRegionSimpleFoam -case ./solid -world solid 2>&1 | tee run_solid.log
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
#------------------------------------------------------------------------------
chtMultiRegionSimpleFoam -case solid -world solid 2>&1 | tee run_solid.log
read dummy
#------------------------------------------------------------------------------

View File

@ -57,7 +57,6 @@ Usage
#include "Time.H"
#include "IOdictionary.H"
#include "OSspecific.H"
#include "OFstream.H"
using namespace Foam;
@ -97,6 +96,22 @@ int main(int argc, char *argv[])
);
argList::addOptionCompat("no-clean", {"noClean", -2006});
argList::addBoolOption
(
"no-outer",
"Create without any other region"
);
argList::addBoolOption
(
"print-dict",
"Print blockMeshDict equivalent and exit"
);
argList::addBoolOption
(
"write-dict",
"Write system/blockMeshDict.PDRblockMesh and exit"
);
argList::addOption("dict", "file", "Alternative PDRblockMeshDict");
argList::addOption
(
@ -111,6 +126,9 @@ int main(int argc, char *argv[])
// Remove old files, unless disabled
const bool removeOldFiles = !args.found("no-clean");
// Suppress creation of the outer region
const bool noOuterRegion = args.found("no-outer");
const word regionName(polyMesh::defaultRegion);
const word regionPath;
@ -149,8 +167,38 @@ int main(int argc, char *argv[])
Info<< "Creating PDRblockMesh from "
<< runTime.relativePath(dictIO.objectPath()) << endl;
// Always start from a PDRblock
PDRblock blkMesh(meshDict, true);
if (args.found("print-dict"))
{
Info<< nl << "Equivalent blockMeshDict" << nl << nl;
blkMesh.blockMeshDict(Info, true);
Info<< "\nEnd\n" << endl;
return 0;
}
if (args.found("write-dict"))
{
// Generate system/blockMeshDict and exit
blkMesh.writeBlockMeshDict
(
IOobject
(
"blockMeshDict.PDRblockMesh",
runTime.system(), // instance
runTime, // registry
IOobject::NO_READ,
IOobject::NO_WRITE,
false // Do not register
)
);
Info<< "\nEnd\n" << endl;
return 0;
}
// Instance for resulting mesh
if (useTime)
@ -170,14 +218,19 @@ int main(int argc, char *argv[])
Info<< nl << "Creating polyMesh from PDRblockMesh" << endl;
if (noOuterRegion)
{
Info<< "Outer region disabled, using ijk generation" << nl;
}
autoPtr<polyMesh> meshPtr =
blkMesh.mesh
(
IOobject(regionName, meshInstance, runTime)
);
(
args.found("no-outer")
? blkMesh.innerMesh(IOobject(regionName, meshInstance, runTime))
: blkMesh.mesh(IOobject(regionName, meshInstance, runTime))
);
const polyMesh& mesh = *meshPtr;
polyMesh& mesh = *meshPtr;
// Set the precision of the points data to 10
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));

View File

@ -704,7 +704,7 @@ int main(int argc, char *argv[])
regionName,
runTimeExtruded.constant(),
runTimeExtruded,
IOobject::NO_READ,
IOobject::NO_READ, // Do not read primitives, do read fv*
IOobject::AUTO_WRITE,
false
),

View File

@ -16,6 +16,7 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I../vectorTools
EXE_LIBS = \
@ -25,4 +26,5 @@ EXE_LIBS = \
-ldecompose \
-lmeshTools \
-ldynamicMesh \
-lsampling \
-lfiniteVolume

View File

@ -311,7 +311,7 @@ tmp<scalarField> signedDistance
)
{
tmp<scalarField> tfld(new scalarField(points.size(), Foam::sqr(GREAT)));
scalarField& fld = tfld();
scalarField& fld = tfld.ref();
// Find nearest
List<pointIndexHit> nearest;
@ -713,8 +713,7 @@ int main(int argc, char *argv[])
fvm,
cellDistance,
pointDistance,
0, //distance,
false //regularise
scalar(0) // distance
);
isoFaces.setSize(iso.size());

View File

@ -154,6 +154,7 @@ int main(int argc, char *argv[])
"cellShapes",
"cellVolume",
"cellVolumeRatio",
"cellAspectRatio",
"minTetVolume",
"minPyrVolume",
"cellRegion",

View File

@ -133,12 +133,9 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
<< endl;
// Construct shape recognizers
hexMatcher hex;
prismMatcher prism;
wedgeMatcher wedge;
pyrMatcher pyr;
tetWedgeMatcher tetWedge;
tetMatcher tet;
// Counters for different cell types
label nHex = 0;
@ -153,15 +150,15 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
for (label celli = 0; celli < mesh.nCells(); celli++)
{
if (hex.isA(mesh, celli))
if (hexMatcher::test(mesh, celli))
{
nHex++;
}
else if (tet.isA(mesh, celli))
else if (tetMatcher::test(mesh, celli))
{
nTet++;
}
else if (pyr.isA(mesh, celli))
else if (pyrMatcher::test(mesh, celli))
{
nPyr++;
}

View File

@ -7,6 +7,7 @@
#include "tetPointRef.H"
#include "regionSplit.H"
#include "wallDist.H"
#include "cellAspectRatio.H"
using namespace Foam;
@ -318,6 +319,32 @@ void Foam::writeFields
aspectRatio.write();
}
if (selectedFields.found("cellAspectRatio"))
{
volScalarField aspectRatio
(
IOobject
(
"cellAspectRatio",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
mesh,
dimensionedScalar(dimless, Zero),
zeroGradientFvPatchScalarField::typeName
);
aspectRatio.ref().field() = cellAspectRatio(mesh);
aspectRatio.correctBoundaryConditions();
Info<< " Writing approximate aspect ratio to "
<< aspectRatio.name() << endl;
aspectRatio.write();
}
// cell type
// ~~~~~~~~~

View File

@ -680,7 +680,7 @@ autoPtr<mapPolyMesh> createRegionMesh
regionName,
mesh.time().timeName(),
mesh.time(),
IOobject::NO_READ,
IOobject::READ_IF_PRESENT, // read fv* if present
IOobject::AUTO_WRITE
),
mesh

View File

@ -66,19 +66,14 @@ using namespace Foam;
// Many ways to name processor directories
//
// Uncollated | "processor0", "processor1" ...
// Collated (old) | "processors"
// Collated (new) | "processors<N>"
// Collated | "processors<N>"
// Host collated | "processors<N>_<low>-<high>"
const regExp matcher("processors?[0-9]+(_[0-9]+-[0-9]+)?");
bool isProcessorDir(const string& dir)
{
return
(
dir.starts_with("processor")
&& (dir == "processors" || matcher.match(dir))
);
return (dir.starts_with("processor") && matcher.match(dir));
}

View File

@ -71,19 +71,14 @@ using namespace Foam;
// Many ways to name processor directories
//
// Uncollated | "processor0", "processor1" ...
// Collated (old) | "processors"
// Collated (new) | "processors<N>"
// Collated | "processors<N>"
// Host collated | "processors<N>_<low>-<high>"
const regExp matcher("processors?[0-9]+(_[0-9]+-[0-9]+)?");
bool isProcessorDir(const string& dir)
{
return
(
dir.starts_with("processor")
&& (dir == "processors" || matcher.match(dir))
);
return (dir.starts_with("processor") && matcher.match(dir));
}
@ -384,13 +379,7 @@ int main(int argc, char *argv[])
{
if (leadProcIdx < 0)
{
// Collated (old)
leadProcIdx = procDirs.find("processors");
}
if (leadProcIdx < 0)
{
// Collated (new)
// Collated
leadProcIdx = procDirs.find("processors" + Foam::name(nProcs));
}

View File

@ -519,29 +519,26 @@ int main(int argc, char *argv[])
{
const fileName& d = dirs[diri];
// Starts with 'processors'
if (d.find("processors") == 0)
label proci = -1;
if
(
d.starts_with("processor")
&&
(
// Collated is "processors"
d[9] == 's'
// Uncollated has integer(s) after 'processor'
|| Foam::read(d.substr(9), proci)
)
)
{
if (fileHandler().exists(d))
{
fileHandler().rmDir(d);
}
}
// Starts with 'processor'
if (d.find("processor") == 0)
{
// Check that integer after processor
fileName num(d.substr(9));
label proci = -1;
if (Foam::read(num.c_str(), proci))
{
if (fileHandler().exists(d))
{
fileHandler().rmDir(d);
}
}
}
}
procDirsProblem = false;

View File

@ -36,6 +36,7 @@ License
#include "pointSet.H"
#include "faceSet.H"
#include "cellSet.H"
#include "basicFvGeometryScheme.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
@ -254,6 +255,19 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
auto meshPtr = autoPtr<fvMesh>::New(io);
fvMesh& mesh = *meshPtr;
// Make sure to use a non-parallel geometry calculation method
{
tmp<fvGeometryScheme> basicGeometry
(
fvGeometryScheme::New
(
mesh,
dictionary(),
basicFvGeometryScheme::typeName
)
);
mesh.geometry(basicGeometry);
}
// Sync patches

View File

@ -92,6 +92,7 @@ Usage
#include "zeroGradientFvPatchFields.H"
#include "topoSet.H"
#include "regionProperties.H"
#include "basicFvGeometryScheme.H"
#include "parFvFieldReconstructor.H"
#include "parLagrangianRedistributor.H"
@ -152,6 +153,30 @@ scalar getMergeDistance
}
void setBasicGeometry(fvMesh& mesh)
{
// Set the fvGeometryScheme to basic since it does not require
// any parallel communication to construct the geometry. During
// redistributePar one might temporarily end up with processors
// with zero procBoundaries. Normally procBoundaries trigger geometry
// calculation (e.g. send over cellCentres) so on the processors without
// procBoundaries this will not happen. The call to the geometry calculation
// is not synchronised and this might lead to a hang for geometry schemes
// that do require synchronisation
tmp<fvGeometryScheme> basicGeometry
(
fvGeometryScheme::New
(
mesh,
dictionary(),
basicFvGeometryScheme::typeName
)
);
mesh.geometry(basicGeometry);
}
void printMeshData(const polyMesh& mesh)
{
// Collect all data on master
@ -2314,6 +2339,19 @@ int main(int argc, char *argv[])
// (replacement for setRootCase that does not abort)
argList args(argc, argv);
// As much as possible avoid synchronised operation. To be looked at more
// closely for the three scenarios:
// - decompose - reads on master (and from parent directory) and sends
// dictionary to slaves
// - distribute - reads on potentially a different number of processors
// than it writes to
// - reconstruct - reads parallel, write on master only and to parent
// directory
const_cast<fileOperation&>(fileHandler()).distributed(true);
#include "foamDlOpenLibs.H"
const bool reconstruct = args.found("reconstruct");
@ -2324,15 +2362,16 @@ int main(int argc, char *argv[])
bool decompose = args.found("decompose");
bool overwrite = args.found("overwrite");
if (Foam::sigFpe::requested())
{
WarningInFunction
<< "Detected floating point exception trapping (FOAM_SIGFPE)."
<< " This might give" << nl
<< " problems when mapping fields. Switch it off in case"
<< " of problems." << endl;
}
// Disable NaN setting and floating point error trapping. This is to avoid
// any issues inside the field redistribution inside fvMeshDistribute
// which temporarily moves processor faces into existing patches. These
// will now not have correct values. After all bits have been assembled
// the processor fields will be restored but until then there might
// be uninitialised values which might upset some patch field constructors.
// Workaround by disabling floating point error trapping. TBD: have
// actual field redistribution instead of subsetting inside
// fvMeshDistribute.
Foam::sigFpe::unset(true);
const wordRes selectedFields;
const wordRes selectedLagrangianFields;
@ -2569,12 +2608,14 @@ int main(int argc, char *argv[])
// See where the mesh is
//const bool oldParRun = Pstream::parRun(false);
fileName facesInstance = runTime.findInstance
(
meshSubDir,
"faces",
IOobject::READ_IF_PRESENT
);
//Pstream::parRun(oldParRun);
//Pout<< "facesInstance:" << facesInstance << endl;
Pstream::scatter(facesInstance);
@ -2660,6 +2701,10 @@ int main(int argc, char *argv[])
);
fvMesh& mesh = meshPtr();
// Use basic geometry calculation to avoid synchronisation
// problems. See comment in routine
setBasicGeometry(mesh);
// Global matching tolerance
const scalar tolDim = getMergeDistance
(
@ -2709,6 +2754,10 @@ int main(int argc, char *argv[])
Info<< "Time = " << runTime.timeName() << endl << endl;
// Read undecomposed mesh on master and 'empty' mesh
// (zero faces, point, cells but valid patches and zones) on slaves.
// This is a bit of tricky code and hidden inside fvMeshTools for
// now.
Info<< "Reading undecomposed mesh (on master)" << endl;
autoPtr<fvMesh> baseMeshPtr = fvMeshTools::newMesh
(
@ -2721,6 +2770,8 @@ int main(int argc, char *argv[])
),
true // read on master only
);
setBasicGeometry(baseMeshPtr());
Info<< "Reading local, decomposed mesh" << endl;
autoPtr<fvMesh> meshPtr = loadOrCreateMesh
@ -2941,12 +2992,14 @@ int main(int argc, char *argv[])
runTime.caseName() = baseRunTime.caseName();
}
const bool oldParRun = Pstream::parRun(false);
masterInstDir = runTime.findInstance
(
meshSubDir,
"faces",
IOobject::READ_IF_PRESENT
);
Pstream::parRun(oldParRun);
if (decompose)
{

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -86,15 +86,7 @@ int main(int argc, char *argv[])
#include "createTime.H"
// Determine the processor count
#ifdef fileOperation_H
const label nProcs = fileHandler().nProcs(args.path());
#else
label nProcs = 0;
while (isDir(args.path()/("processor" + Foam::name(nProcs))))
{
++nProcs;
}
#endif
// Create the processor databases
PtrList<Time> databases(nProcs);

View File

@ -1,7 +1,8 @@
EXE_INC = \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/randomProcesses/lnInclude
-I$(LIB_SRC)/randomProcesses/lnInclude \
-I$(FFTW_INC_DIR)
EXE_LIBS = \
-lsampling \

View File

@ -87,7 +87,6 @@ Usage
See also
noiseFFT.H
noiseModel.H
windowModel.H

View File

@ -1,7 +1,11 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
#------------------------------------------------------------------------------
wclean libso pdrFields
wclean PDRfitMesh
wclean PDRsetFields
#------------------------------------------------------------------------------

View File

@ -5,6 +5,9 @@ cd "${0%/*}" || exit # Run from this directory
#------------------------------------------------------------------------------
wmake $targetType pdrFields
wmake $targetType PDRfitMesh
wmake $targetType PDRsetFields
#------------------------------------------------------------------------------

View File

@ -0,0 +1,7 @@
PDRfitMeshParams.C
PDRfitMeshScan.C
PDRfitMeshScans.C
PDRfitMesh.C
EXE = $(FOAM_APPBIN)/PDRfitMesh

View File

@ -0,0 +1,339 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Applications
PDRfitMesh
Description
Scans extents of obstacles to establish reasonable estimates
for generating a PDRblockMeshDict.
SourceFiles
PDRfitMesh.C
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "Fstream.H"
#include "IOdictionary.H"
#include "PDRfitMeshScans.H"
#include "PDRsetFields.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char* argv[])
{
argList::addNote
(
"Processes a set of geometrical obstructions to determine"
" reasonable estimates for generating a PDRblockMeshDict"
);
argList::noParallel();
argList::noFunctionObjects();
argList::addOption("dict", "file", "Alternative PDRsetFieldsDict");
argList::addOption("params", "file", "Alternative PDRfitMeshDict");
argList::addBoolOption
(
"overwrite",
"Overwrite existing system/PDRblockMeshDict"
);
argList::addBoolOption("verbose", "Increase verbosity");
argList::addBoolOption
(
"dry-run",
"Equivalent to -print-dict"
);
argList::addBoolOption
(
"print-dict",
"Print PDRblockMeshDict equivalent and exit"
);
argList::addBoolOption
(
"write-vtk",
"Write obstacles as VTK files"
);
#include "setRootCase.H"
#include "createTime.H"
const bool dryrun = args.found("dry-run");
const bool printDict = args.found("print-dict");
const word dictName("PDRsetFieldsDict");
#include "setSystemRunTimeDictionaryIO.H"
Info<< "Reading " << dictIO.name() << nl << endl;
IOdictionary setFieldsDict(dictIO);
const fileName& casepath = runTime.globalPath();
// Program parameters (globals)
pars.read(setFieldsDict);
// Params for fitMesh
// - like setSystemRunTimeDictionaryIO
IOobject paramIO = IOobject::selectIO
(
IOobject
(
"PDRfitMeshDict",
runTime.system(),
runTime,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
),
args.getOrDefault<fileName>("params", "")
);
if (paramIO.typeHeaderOk<IOdictionary>(true))
{
Info<< "Using PDRfitMesh parameters from "
<< runTime.relativePath(paramIO.objectPath()) << nl
<< endl;
}
else
{
paramIO.readOpt() = IOobject::NO_READ;
Info<< "No PDRfitMeshDict found, using defaults" << nl
<< endl;
}
IOdictionary fitParamsDict(paramIO, dictionary());
PDRfitMeshParams fitParams(fitParamsDict);
// Essential parameters
scalar cellWidth = 0;
if
(
!setFieldsDict.readIfPresent("cellWidth", cellWidth)
&& !fitParamsDict.readIfPresent("cellWidth", cellWidth)
)
{
FatalErrorInFunction
<< "No cellWidth specified in any dictionary" << nl
<< exit(FatalError);
}
// Storage for obstacles and cylinder-like obstacles
DynamicList<PDRobstacle> obstacles, cylinders;
// Read in obstacles
if (pars.legacyObsSpec)
{
PDRobstacle::legacyReadFiles
(
pars.obsfile_dir, pars.obsfile_names,
boundBox::invertedBox, // ie, no bounds
obstacles,
cylinders
);
}
else
{
PDRobstacle::readFiles
(
pars.obsfile_dir, pars.obsfile_names,
boundBox::invertedBox, // ie, no bounds
obstacles,
cylinders
);
}
//
// Output names
//
IOobject outputIO
(
"PDRblockMeshDict",
runTime.system(),
runTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // unregistered
);
enum class writeType { DRY_RUN, OKAY, OVERWRITE, NO_CLOBBER };
writeType writable = writeType::OKAY;
if (dryrun || printDict)
{
writable = writeType::DRY_RUN;
}
else if (isFile(outputIO.objectPath()))
{
if (args.found("overwrite"))
{
writable = writeType::OVERWRITE;
}
else
{
writable = writeType::NO_CLOBBER;
InfoErr
<< nl
<< "File exists: "
<< runTime.relativePath(outputIO.objectPath()) << nl
<< "Move out of the way or specify -overwrite" << nl << nl
<< "Exiting" << nl << nl;
return 1;
}
}
else
{
writable = writeType::OKAY;
}
if (args.found("write-vtk"))
{
PDRobstacle::generateVtk(casepath/"VTK", obstacles, cylinders);
}
//
// The fitting routines
//
// Collapse into a single list of obstacles
obstacles.append(std::move(cylinders));
PDRfitMeshScan::verbose(args.found("verbose"));
Vector<PDRblock::gridControl> griding =
PDRfitMeshScans().calcGriding(obstacles, fitParams, cellWidth);
//
// Output
//
if (writable == writeType::DRY_RUN)
{
InfoErr << nl;
if (!printDict)
{
InfoErr
<< "dry-run: ";
}
InfoErr
<< "Displaying equivalent PDRblockMeshDict" << nl
<< nl;
}
else if (writable == writeType::OKAY)
{
InfoErr
<< nl
<< "Write "
<< runTime.relativePath(outputIO.objectPath()) << nl;
}
else if (writable == writeType::OVERWRITE)
{
InfoErr
<< nl
<< "Overwrite existing "
<< runTime.relativePath(outputIO.objectPath()) << nl;
}
// NO_CLOBBER already handled
{
autoPtr<Ostream> outputFilePtr;
if
(
writable == writeType::OKAY
|| writable == writeType::OVERWRITE
)
{
outputFilePtr.reset(new OFstream(outputIO.objectPath()));
}
Ostream& os = bool(outputFilePtr) ? *outputFilePtr : Info();
outputIO.writeHeader(os, IOdictionary::typeName_());
os.writeEntry
(
"expansion",
PDRfitMeshScan::expansionName()
);
os << nl;
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
{
griding[cmpt].writeDict(os, cmpt);
}
const dictionary* outerDict;
if
(
(outerDict = setFieldsDict.findDict("outer")) != nullptr
|| (outerDict = fitParamsDict.findDict("outer")) != nullptr
)
{
outerDict->writeEntry(os);
}
else
{
// Define our own "outer"
os.beginBlock("outer");
os.writeEntry("type", "none");
os.endBlock();
}
IOobject::writeEndDivider(os);
}
Info<< nl << "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,126 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object PDRfitMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Tuning parameters (defaults) for PDRfitMesh
// - these normally do not need much changing
// Note the following are normally read from PDRsetFieldsDict
//
// - cellWidth
// - cellWidthFactor
// - outer (contains optional zmin)
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ----------------------------------------------------------------------
// Finding planes
// ----------------------------------------------------------------------
// User defined bounds
bounds
{
// xmin -1e16;
// xmax 1e16;
// ymin -1e16;
// ymax 1e16;
// zmin -1e16;
// zmax 1e16;
}
outer
{
//- Ground datum (hard zmin)
// zmin -1e16;
}
// ----------------------------------------------------------------------
// Finding planes
// ----------------------------------------------------------------------
// Ignore faces smaller than this multiple of cell face area
minFaceArea 5.0;
// Only fit a plane if the face area at the coordinate is at least
// this times the cell face area
minAreaRatio 20.0;
// Size of search zones for face areas will be this * the cell width.
// So faces closer than this zone size might be grouped together
areaWidthFactor 0.7;
// Very long zones produce bad outer boundary shape from
// makePDRmeshBlocks, so we subdivide a zone if its length is greater
// than this * the height of the area of cuboid vells
maxZoneToHeight 2.0;
// ----------------------------------------------------------------------
// Choosing cell width
//
// <cellWidth> and <cellWidthFactor> read from PDRsetFieldsDict
// ----------------------------------------------------------------------
// Minimum number of cells in any direction
nCellsMin 10;
// Width of obstacles must be less than this * cell width to added
// into subgrid length
widthFactor 1.0;
// Optimal average number of obstacles per cell
obsPerCell 2.0;
//- Maximum cellWidth when auto-sizing
maxCellWidth 1e16;
// Do not use a cellWidth more than this times the initial estimate
maxWidthEstimate 5.0;
// Assume converged if optimised width changes by less than this
maxWidthRatio 1.2;
// Maximum iterations in optimising cellWidth
maxIterations 5;
// ----------------------------------------------------------------------
// Defining outer region
//
// ----------------------------------------------------------------------
// Fraction of rectangular cell layers each side of the central region.
nEdgeLayers 5.0;
// FUTURE?
//
// // Ratio of the outer extension distance to the average radius of the
// // congested region
// ratioOuterToCongRad 20.0;
//
// // Cell size ratio - should be same as that hard-wired in makePDRmeshBlocks
// outerRatio 1.2;
// ************************************************************************* //

View File

@ -0,0 +1,123 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "PDRfitMeshParams.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::PDRfitMeshParams::readBounds(const dictionary& dict)
{
scalar value;
if (dict.readIfPresent("xmin", value))
{
minBounds.x() = optionalData<scalar>(value);
}
if (dict.readIfPresent("ymin", value))
{
minBounds.y() = optionalData<scalar>(value);
}
if (dict.readIfPresent("zmin", value))
{
minBounds.z() = optionalData<scalar>(value);
}
if (dict.readIfPresent("xmax", value))
{
maxBounds.x() = optionalData<scalar>(value);
}
if (dict.readIfPresent("ymax", value))
{
maxBounds.y() = optionalData<scalar>(value);
}
if (dict.readIfPresent("zmax", value))
{
maxBounds.z() = optionalData<scalar>(value);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::PDRfitMeshParams::PDRfitMeshParams(const dictionary& dict)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::PDRfitMeshParams::read(const dictionary& dict)
{
const dictionary* dictptr;
// Geometric limits
if ((dictptr = dict.findDict("bounds")) != nullptr)
{
readBounds(*dictptr);
}
if ((dictptr = dict.findDict("outer")) != nullptr)
{
const dictionary& d = *dictptr;
d.readIfPresent("zmin", ground);
}
// Finding planes
dict.readIfPresent("minFaceArea", minFaceArea);
dict.readIfPresent("minAreaRatio", minAreaRatio);
dict.readIfPresent("areaWidthFactor", areaWidthFactor);
dict.readIfPresent("maxZoneToHeight", maxZoneToHeight);
// Choosing cell width
dict.readIfPresent("nCellsMin", nCellsMin);
dict.readIfPresent("widthFactor", widthFactor);
dict.readIfPresent("obsPerCell", obsPerCell);
dict.readIfPresent("maxCellWidth", maxCellWidth);
dict.readIfPresent("maxWidthEstimate", maxWidthEstimate);
dict.readIfPresent("maxWidthRatio", maxWidthRatio);
dict.readIfPresent("maxIterations", maxIterations);
// Outer region
dict.readIfPresent("nEdgeLayers", nEdgeLayers);
dict.readIfPresent("outerRatio", outerRatio);
// dict.readIfPresent("outerRadius", outerRadius);
};
// ************************************************************************* //

View File

@ -0,0 +1,158 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::PDRfitMeshParams
Description
Parameters for PDRfitMesh
SourceFiles
PDRfitMeshParams.C
\*---------------------------------------------------------------------------*/
#ifndef PDRfitMeshParams_H
#define PDRfitMeshParams_H
#include "labelList.H"
#include "scalarList.H"
#include "dictionary.H"
#include "optionalData.H"
#include "MinMax.H"
#include "Vector.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class PDRfitMeshParams Declaration
\*---------------------------------------------------------------------------*/
class PDRfitMeshParams
{
// Private Member Functions
//- Read optional bounds
void readBounds(const dictionary& dict);
public:
// Data Members
//- Optional user bounds (xmin, xmax, ymin, ymax, zmin, zmax)
Vector<optionalData<scalar>> minBounds, maxBounds;
//- Ground datum (hard zmin)
scalar ground = -1e16;
// Finding planes
//- Ignore faces smaller than this multiple of cell face area
scalar minFaceArea = 5.0;
//- Only fit a plane if the face area at the coordinate is at
//- least this times the cell face area
scalar minAreaRatio = 20.0;
//- Size of search zones for face areas will be this * the
//- cell width.
// Faces closer than this zone size may be grouped together
scalar areaWidthFactor = 0.7;
// Very long zones produce bad outer boundary shape from
// makePDRmeshBlocks, so we subdivide a zone if its length is
// greater than this * the height of the area of cuboid vells
scalar maxZoneToHeight = 2.0;
// Choosing cell width
// Minimum number of cells in any direction
label nCellsMin = 10;
// Width of obstacles must be less than this * cell width to
// added into subgrid length
scalar widthFactor = 1.0;
// Optimal average number of obstacles per cell
scalar obsPerCell = 2.0;
//- Maximum cellWidth when auto-sizing
scalar maxCellWidth = 1e16;
//- Do not use a cellWidth more than this times the initial estimate
scalar maxWidthEstimate = 5.0;
//- Converged if optimised width changes by less than this amount
scalar maxWidthRatio = 1.2;
//- Maximum iterations in optimising cellWidth
label maxIterations = 5;
// Outer region
//- Fraction of rectangular cell layers on each side of the
//- central region
scalar nEdgeLayers = 5;
//- Cell size ratio - should be same as used for PDRblockMesh
scalar outerRatio = 1.2;
//FUTURE? // Ratio of the outer extension distance to the average
//FUTURE? // radius of the congested region
//FUTURE? scalar outerRadius = 20.0;
// Constructors
//- Default construct
PDRfitMeshParams() = default;
//- Construct and read dictionary
explicit PDRfitMeshParams(const dictionary& dict);
// Member Functions
//- Read program parameters from dictionary
void read(const dictionary& dict);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,859 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 Shell Research Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "PDRfitMeshScan.H"
#include "PDRfitMeshParams.H"
#include "PDRblock.H"
#include "PDRobstacle.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
bool Foam::PDRfitMeshScan::verbose_ = false;
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::word Foam::PDRfitMeshScan::expansionName()
{
return PDRblock::expansionNames_[PDRblock::EXPAND_RELATIVE];
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::PDRfitMeshScan::addCoord
(
const scalar coord,
const scalar weight
)
{
if (!limits_.contains(coord))
{
return;
}
const scalar coordOffset = (coord - limits_.min());
if (coordOffset < 0)
{
FatalErrorInFunction
<< "Negative coordinate! " << coordOffset << nl
<< exit(FatalError);
}
// We divide the range into a series of steps, and decide
// which step this coord is in
// Note: would be simpler to record the totals only in the
// half steps in this routine then get the full-step values
// at the end by adding half steps
// Add the area to the total already found in this step
// and update the weighted average position of these obstacle faces
const label stepi1 = 2*floor(coordOffset / stepWidth_);
// Also do half-step offset in case several faces
// are around the step boundary.
//
// Stored in odd-numbered elements
const label stepi2 =
Foam::max
(
0,
1 + 2*floor((coordOffset - 0.5*stepWidth_) / stepWidth_)
);
// Last, keep track of totals in half-step ranges
const label stepih = floor(coordOffset / stepWidth_);
const label maxSize = Foam::max(stepi1, stepi2);
if (weightedPos_.size() <= maxSize)
{
weightedPos_.resize(maxSize+1, Zero);
totalArea_.resize(maxSize+1, Zero);
weightedPos2_.resize(maxSize+1, Zero);
totalArea2_.resize(maxSize+1, Zero);
}
weightedPos_[stepi1] += (coord * weight);
totalArea_[stepi1] += weight;
weightedPos_[stepi2] += (coord * weight);
totalArea_[stepi2] += weight;
weightedPos2_[stepih] += (coord * weight);
totalArea2_[stepih] += weight;
}
// void Foam::PDRfitMeshScan::clear()
// {
// weightedPos_.clear(); totalArea_.clear();
// weightedPos2_.clear(); totalArea2_.clear();
// }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::PDRfitMeshScan::reset()
{
limits_.min() = GREAT;
limits_.max() = -GREAT;
hard_min_ = -GREAT;
nsteps_ = 0;
stepWidth_ = 0;
minFaceArea_ = 0;
weightedPos_.clear();
totalArea_.clear();
weightedPos2_.clear();
totalArea2_.clear();
}
void Foam::PDRfitMeshScan::resize
(
const scalar cellWidth,
const PDRfitMeshParams& pars
)
{
if (limits_.valid())
{
nsteps_ =
(
limits_.mag() / (mag(cellWidth) * pars.areaWidthFactor)
+ 0.5
);
nsteps_ = max(nsteps_, pars.nCellsMin);
stepWidth_ = limits_.mag() / nsteps_;
minFaceArea_ = pars.minFaceArea;
}
else
{
nsteps_ = 0;
stepWidth_ = 0;
minFaceArea_ = 0;
WarningInFunction
<< "No valid limits defined" << endl;
}
weightedPos_.clear();
totalArea_.clear();
weightedPos2_.clear();
totalArea2_.clear();
// resize
weightedPos_.resize(2*nsteps_+1, Zero);
totalArea_.resize(2*nsteps_+1, Zero);
weightedPos2_.resize(2*nsteps_+1, Zero);
totalArea2_.resize(2*nsteps_+1, Zero);
}
void Foam::PDRfitMeshScan::adjustLimits
(
const scalar point0,
const scalar point1
)
{
limits_.add(point0);
limits_.add(point1);
}
void Foam::PDRfitMeshScan::addArea
(
const scalar area,
const scalar point0,
const scalar point1
)
{
if (!nsteps_)
{
FatalErrorInFunction
<< "No step-size defined" << nl
<< exit(FatalError);
}
if (area < minFaceArea_ * sqr(stepWidth_))
{
return;
}
addCoord(point0, area);
addCoord(point1, area);
}
void Foam::PDRfitMeshScan::print(Ostream& os) const
{
if (nsteps_)
{
os << "steps:" << nsteps_;
}
if (limits_.valid())
{
os << " limits:" << limits_;
}
scalar totalArea = 0;
for (const scalar areaValue : totalArea_)
{
totalArea += areaValue;
}
os << " area:" << totalArea;
os << nl;
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Evaluates (r**n - 1) / (r - 1) including in the limit r=1
inline static scalar rn1r1(const scalar r, const label n)
{
if (mag(r - 1.0) < SMALL)
{
return n;
}
return (pow(r, n) - 1.0)/(r - 1.0);
}
inline static scalar end_val
(
const scalar width,
const scalar ratio,
const label n
)
{
return width / rn1r1(ratio, n);
}
static scalar fit_slope
(
const scalar left,
const scalar width,
const label n,
scalar& r
)
{
const scalar wol = width / left;
// Initial value
r = (left < width / n) ? 1.01 : 0.99;
for (int nIter = 0; nIter < 25; ++nIter)
{
scalar rm1 = r - 1.0;
scalar rn = pow(r, n);
scalar f = (rn - 1.0) * r / rm1 - wol;
scalar fprime = ((n * rm1 - 1) * rn + 1) / sqr(rm1);
scalar new_r = r - f / fprime;
scalar delta = mag(new_r - r);
r = 0.5 * (r + new_r);
// InfoErr
// << "New r: " << new_r << ' '
// << f << ' ' << fprime << ' ' << delta << ' ' << nIter << nl;
if (delta <= 1e-3)
{
break;
}
}
return end_val(width, 1.0/r, n);
}
} // End namespace Foam
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::PDRblock::gridControl
Foam::PDRfitMeshScan::calcGridControl
(
const scalar cellWidth,
const scalar max_zone,
const PDRfitMeshParams& pars
)
{
// Prune out small areas
{
const scalar minArea = sqr(cellWidth) * pars.minAreaRatio;
if (verbose())
{
Info<< "Checking planes. Min-area: " << minArea << nl;
}
for (scalar& areaValue : totalArea_)
{
if (areaValue < minArea)
{
areaValue = 0;
}
}
for (scalar& areaValue : totalArea2_)
{
if (areaValue < minArea)
{
areaValue = 0;
}
}
}
// Initially only the two outer boundaries and absolute limits
DynamicList<scalar> initialCoord(nsteps_+1);
initialCoord.resize(4);
initialCoord[0] = -GREAT;
initialCoord[1] = Foam::max(limits_.min(), hard_min_);
initialCoord[2] = limits_.max();
initialCoord[3] = GREAT;
// Select largest areas for fitting.
// - done manually (instead of via sort) to handle full/half-steps
// - find the largest area, add that to the list and remove its
// area (and immediate surroundings) from the input.
// We have the "full steps overlapping so that we do not miss
// a group of adjacent faces that are split over a boundary.
// When we have identified a plane, we need to zero that
// step, and also the overlapping ones to avoid
// double-counting. when we have done that twice, we might
// have completely removed the half-step that was between
// them. That is why we also have the areas stored in
// half-steps, so that is not lost.
while (initialCoord.size()-4 < totalArea_.size())
{
label n_big = 0;
scalar largest = 0;
// Find largest area, using "real" scanned areas
// thus checking the stored even locations.
for (label ii=0; ii < 2*nsteps_; ++ii)
{
if (largest < totalArea_[ii])
{
largest = totalArea_[ii];
n_big = ii;
}
if (largest < totalArea2_[ii])
{
largest = totalArea2_[ii];
n_big = -ii-1;
}
}
if (mag(largest) < SMALL)
{
break;
}
if (n_big >= 0)
{
// Full step
const scalar pos = averagePosition(n_big);
// Remove from future checks
totalArea_[n_big] = 0;
if (pos > hard_min_ + 0.4 * cellWidth)
{
// Only accept if not close to the ground
initialCoord.append(pos);
// Remove this and adjacent areas, which overlap this one
if (n_big > 1)
{
totalArea_[n_big-1] = 0;
}
if (n_big < 2*nsteps_ - 1)
{
totalArea_[n_big+1] = 0;
}
// Remove half-steps contained by this step
totalArea2_[n_big] = 0;
totalArea2_[n_big+1] = 0;
}
}
else
{
// Half step
n_big = -n_big-1;
const scalar pos = averageHalfPosition(n_big);
// Remove from future checks
totalArea2_[n_big] = 0;
// On the first passes, this area will be included in full steps,
// but it may eventually only remain in the half-step,
// which could be the next largest
if (pos > hard_min_ + 0.4 * cellWidth)
{
// Only accept if not close to the ground
initialCoord.append(pos);
}
}
}
// Now sort the positions
Foam::sort(initialCoord);
// Avoid small zones near the begin/end positions
if
(
(initialCoord[2] - initialCoord[1])
< (0.4 * cellWidth)
)
{
// Remove [1] if too close to [2]
initialCoord.remove(1);
}
if
(
(
initialCoord[initialCoord.size()-2]
- initialCoord[initialCoord.size()-3]
)
< (0.4 * cellWidth)
)
{
// Remove [N-3] if too close to [N-2]
initialCoord.remove(initialCoord.size()-3);
}
// This is somewhat questionable (horrible mix of C and C++ addressing).
//
// If we have specified a max_zone (max number of cells per segment)
// we will actually generate more divisions than originally
// anticipated.
// So over-dimension arrays by a larger factor (eg, 20-100)
// which is presumably good enough.
// FIXME: Needs revisiting (2020-12-16)
label nCoords = initialCoord.size();
scalarList coord(50*initialCoord.size(), Zero);
SubList<scalar>(coord, initialCoord.size()) = initialCoord;
scalarList width(coord.size(), Zero);
labelList nDivs(width.size(), Zero);
//
// Set up initially uniform zones
//
for (label ii=1; ii < (nCoords-2); ++ii)
{
width[ii] = coord[ii+1] - coord[ii];
nDivs[ii] = width[ii] / stepWidth_ * pars.areaWidthFactor + 0.5;
while (nDivs[ii] < 1)
{
// Positions too close - merge them
--nCoords;
coord[ii] = 0.5 * (coord[ii+1] + coord[ii]);
width[ii-1] = coord[ii] - coord[ii-1];
nDivs[ii-1] =
width[ii-1] / stepWidth_ * pars.areaWidthFactor + 0.5;
if (ii < (nCoords - 2))
{
for (label iii=ii+1; iii < nCoords-1; ++iii)
{
coord[iii] = coord[iii+1];
}
width[ii] = coord[ii+1] - coord[ii];
nDivs[ii] =
width[ii] / stepWidth_ * pars.areaWidthFactor + 0.5;
}
else
{
nDivs[ii] = 1; // Dummy value to terminate while
}
}
}
// Initially all steps have equal width (ratio == 1)
scalarList first(width.size(), Zero);
for (label ii=1; ii < (nCoords-2); ++ii)
{
first[ii] = width[ii] / nDivs[ii];
}
scalarList last(first);
scalarList ratio(width.size(), scalar(1));
// For diagnostics
charList marker(width.size(), char('x'));
marker[0] = '0';
// Now adjust the inter-cell ratios to reduce cell-size changes
// between zones
if (nCoords > 5)
{
// The outer zones can be adjusted to fit the adjacent steps
last[1] = first[2];
first[nCoords-3] = last[nCoords-4];
// We adjust the cell size ratio in each zone so that the
// cell sizes at the ends of the zones fit as well as
// possible with their neighbours. Work forward through the
// zones and then repeat a few times so that the adjustment
// settles down.
for (int nIter = 0; nIter < 2; ++nIter)
{
for (label ii=1; ii < (nCoords-2); ++ii)
{
if (nDivs[ii] == 1)
{
// If only one step, no grading is possible
marker[ii] = '1'; // For Diagnostics
continue;
}
marker[ii] = 'L'; // For Diagnostics
// Try making the in-zone steps equal to the step at
// the left end to the last of the previous zone.
// If the step at the right is less than this, then
// good... (fF this is the penultimate zone, we do
// not need to worry about the step on the right
// because the extent of the last zone can be
// adjusted later to fit.)
scalar r_fit = 1;
if
(
(
(ii > 1)
&& mag
(
log
(
fit_slope
(
last[ii-1],
width[ii],
nDivs[ii],
r_fit
)
/ first[ii+1]
)
)
< mag(log(r_fit))
)
|| (ii == nCoords-3)
)
{
ratio[ii] = r_fit;
}
else
{
marker[ii] = 'R';
// otherwise try making the in-zone steps equal to
// the step at the right end to the last of the
// previous zone. If the step at the right is less
// thhan this, then good... (If this is the second
// zone, we do not need to worry about the step on
// the left because the extent of the first zone
// can be adjusted later to fit.)
if
(
mag
(
log
(
fit_slope
(
first[ii+1],
width[ii],
nDivs[ii],
r_fit
)
/ last[ii-1]
)
)
< mag(log(r_fit))
|| (ii == 1)
)
{
ratio[ii] = 1.0 / r_fit;
}
else
{
ratio[ii] =
pow(first[ii+1] / last[ii-1], 1.0/(nDivs[ii]-1));
marker[ii] = 'M';
}
}
first[ii] = end_val(width[ii], ratio[ii], nDivs[ii]);
last[ii] = end_val(width[ii], 1.0/ratio[ii], nDivs[ii]);
}
};
// Adjust the ratio and the width in the first zone to
// grade from cellWidth at the outside to the first cell of
// the next zone. Increase the number of steps to keep edge
// at least two (nEdgeLayers) cell widths from min.
}
if (coord[1] > hard_min_ + first[1] / pars.outerRatio)
{
nDivs[0] = pars.nEdgeLayers;
ratio[0] = 1.0 / pars.outerRatio;
coord[0] = coord[1] - first[1] * rn1r1(pars.outerRatio, nDivs[0]);
// Reduce the number of steps if we have extended below hard_min_
while (coord[0] < hard_min_ && nDivs[0] > 1)
{
--nDivs[0];
coord[0] = coord[1] - first[1] * rn1r1(pars.outerRatio, nDivs[0]);
}
if (nDivs[0] < label(pars.nEdgeLayers))
{
// We had to adjust for hard_min_, so now fit exaxtly
coord[0] = hard_min_;
}
}
else
{
// No room for outer zone. Remove it.
--nCoords;
for (label ii = 0; ii < nCoords; ++ii)
{
coord[ii] = coord[ii+1];
nDivs[ii] = nDivs[ii+1];
ratio[ii] = ratio[ii+1];
first[ii] = first[ii+1];
last[ii] = last[ii+1];
}
coord[0] = hard_min_;
}
width[0] = coord[1] - coord[0];
first[0] = end_val(width[0],ratio[0],nDivs[0]);
last[0] = end_val(width[0],1.0/ratio[0],nDivs[0]);
// Now do the upper edge zone
{
const label np2 = nCoords - 2;
ratio[np2] = pars.outerRatio;
nDivs[np2] = pars.nEdgeLayers;
coord[np2+1] =
coord[np2] + last[np2-1] * rn1r1(pars.outerRatio, nDivs[np2]);
width[np2] = coord[np2+1] - coord[np2];
first[np2] = last[np2-1];
last[np2] = first[np2] * pow(pars.outerRatio, nDivs[np2] - 1);
}
// If we have a zone along the length of the plant that is much
// longer than the width or height, then makePDRMeshBlocks does
// not produce a very good outer boundary shape.
// So here we divide the zone into several zones of roughly equal width.
// A bit commplicated because of the increasing or decreasing step
// sizes across the zone.
if (max_zone > 0)
{
for (label ii = 0; ii < (nCoords-1); ++ii)
{
if (width[ii] > max_zone && nDivs[ii] > 1)
{
// No. of extra zones
const label nExtra = width[ii] / max_zone - 1;
// Make space for extra zones
for (label ij = nCoords-1; ij > ii; --ij)
{
width[ij+nExtra] = width[ij];
ratio[ij+nExtra] = ratio[ij];
first[ij+nExtra] = first[ij];
last[ij+nExtra] = last[ij];
nDivs[ij+nExtra] = nDivs[ij];
coord[ij+nExtra] = coord[ij];
}
nCoords += nExtra;
const scalar subWidth = width[ii] / (nExtra + 1);
scalar bdy = coord[ii];
last[ii+nExtra] = last[ii];
nDivs[ii+nExtra] = nDivs[ii]; // will be decremented
width[ii+nExtra] = width[ii]; // will be decremented
// Current position
scalar here = coord[ii];
scalar step = first[ii];
// Look for cell boundaries close to where we want
// to put the zone boundaries
for (label ij = ii; ij < ii+nExtra; ++ij)
{
label ist = 0;
bdy += subWidth;
do
{
here += step;
step *= ratio[ii];
++ist;
} while ((here + 0.5 * step) < bdy);
// Found a cell boundary at 'here' that is close to bdy
// Create this sub-zone
last[ij] = step / ratio[ii];
first[ij+1] = step;
coord[ij+1] = here;
width[ij] = coord[ij+1] - coord[ij];
nDivs[ij] = ist;
ratio[ij+1] = ratio[ij];
// Decrement what remains for the last sub-zone
nDivs[ii+nExtra] -= ist;
width[ii+nExtra] -= width[ij];
}
ii += nExtra;
}
}
}
if (verbose())
{
printf("Zone Cell widths Ratios\n");
printf("start first last left mid right\n");
for (label ii = 0; ii < (nCoords-1); ++ii)
{
printf
(
"%6.2f %6.2f %6.2f %c %6.2f %6.2f %6.2f\n",
coord[ii], first[ii], last[ii],
marker[ii],
first[ii]/last[ii-1], ratio[ii], first[ii+1]/last[ii]
);
}
printf("%6.2f\n", coord[nCoords-1]);
}
// Copy back into a gridControl form
PDRblock::gridControl grid;
grid.resize(nCoords);
for (label i = 0; i < nCoords; ++i)
{
grid[i] = coord[i];
}
for (label i = 0; i < nCoords-1; ++i)
{
grid.divisions_[i] = nDivs[i];
}
for (label i = 0; i < nCoords-1; ++i)
{
grid.expansion_[i] = ratio[i];
}
return grid;
}
// ************************************************************************* //

View File

@ -0,0 +1,224 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::PDRfitMeshScan
Description
Scanning of obstacles in a single direction for PDRfitMesh
SourceFiles
PDRfitMeshScan.C
\*---------------------------------------------------------------------------*/
#ifndef PDRfitMeshScan_H
#define PDRfitMeshScan_H
#include "scalarList.H"
#include "DynamicList.H"
#include "MinMax.H"
#include "PDRblock.H"
#include "PDRfitMeshParams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class PDRfitMeshScan Declaration
\*---------------------------------------------------------------------------*/
class PDRfitMeshScan
{
// Private Data
//- Lower and upper limits
scalarMinMax limits_;
//- Absolute lower limit (eg, for the ground plane)
scalar hard_min_ = -GREAT;
//- Number of steps
label nsteps_ = 0;
//- Step width = limits / nsteps
scalar stepWidth_ = 0;
//- Minimum per cell face area. Defined via PDRfitMeshParams
scalar minFaceArea_ = 0;
//- Area-weighted position
DynamicList<scalar> weightedPos_;
//- Area-weights for position
DynamicList<scalar> totalArea_;
//- Area-weighted half-cell position
DynamicList<scalar> weightedPos2_;
//- Area-weights for half-cell position
DynamicList<scalar> totalArea2_;
// Private Member Functions
//- Area-averaged position at index
inline scalar averagePosition(const label i) const
{
return
(
totalArea_[i] < VSMALL
? 0
: (weightedPos_[i] / totalArea_[i])
);
}
//- Area-averaged half-position at index
inline scalar averageHalfPosition(const label i) const
{
return
(
totalArea2_[i] < VSMALL
? 0
: (weightedPos2_[i] / totalArea2_[i])
);
}
//- Add coordinate and weight. Already sanity checked
void addCoord(const scalar coord, const scalar weight);
public:
// Public Data
//- Output verbosity
static bool verbose_;
//- Use gridControl as per PDRblock, with EXPAND_RELATIVE
typedef PDRblock::gridControl gridControl;
// Constructors
//- Default construct
PDRfitMeshScan()
:
limits_(GREAT, -GREAT),
hard_min_(-GREAT),
nsteps_(0),
stepWidth_(0)
{}
// Static Member Functions
//- Get verbosity
static inline bool verbose() noexcept
{
return verbose_;
}
//- Set verbosity
static inline bool verbose(const bool val) noexcept
{
bool old(verbose_);
verbose_ = val;
return old;
}
//- The expansion name
static word expansionName();
// Member Functions
//- The min/max limits
const scalarMinMax& limits() const noexcept
{
return limits_;
}
//- The min/max limits
scalarMinMax& limits() noexcept
{
return limits_;
}
//- The step-width
scalar stepWidth() const noexcept
{
return stepWidth_;
}
//- Set the hard-min
void hard_min(const scalar val) noexcept
{
hard_min_ = val;
}
//- Reset to initial state
void reset();
//- Adjust limits to accommodate the specified point coordinates
void adjustLimits(const scalar point0, const scalar point1);
//- Define number of steps (and step-size) according to the
//- current limits and the specified parameters
void resize(const scalar cellWidth, const PDRfitMeshParams& pars);
void addArea
(
const scalar weight,
const scalar point0,
const scalar point1
);
//- Calculate equivalent grid control from the scanned planes
PDRblock::gridControl
calcGridControl
(
const scalar cellWidth,
const scalar max_zone,
const PDRfitMeshParams& pars
);
void print(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,464 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 Shell Research Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "PDRfitMeshScans.H"
#include "PDRobstacle.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::PDRfitMeshScans::prepare
(
const UList<PDRobstacle>& obstacles,
const PDRfitMeshParams& fitParams,
scalar cellWidth
)
{
reset();
// Scan for obstacle limits
scanLimits(obstacles);
// Clip with optional user bounds
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
{
scalarMinMax& limits = (*this)[cmpt].limits();
if (fitParams.minBounds[cmpt].has_value())
{
limits.min() = fitParams.minBounds[cmpt].value();
}
if (fitParams.maxBounds[cmpt].has_value())
{
limits.max() = fitParams.maxBounds[cmpt].value();
}
}
// Get obstacle locations and subgrid length (if any)
scanAreas(obstacles, fitParams, cellWidth);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::PDRfitMeshScans::volume() const
{
scalar vol = 1;
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
{
const scalarMinMax& limits = (*this)[cmpt].limits();
if (limits.valid())
{
vol *= limits.mag();
}
else
{
return 0;
}
}
return vol;
}
Foam::scalar Foam::PDRfitMeshScans::cellVolume() const
{
scalar vol = 1;
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
{
vol *= (*this)[cmpt].stepWidth();
}
return vol;
}
void Foam::PDRfitMeshScans::reset()
{
subgridLen_ = 0;
for (PDRfitMeshScan& pln : *this)
{
pln.reset();
}
}
void Foam::PDRfitMeshScans::resize
(
const scalar cellWidth,
const PDRfitMeshParams& pars
)
{
for (PDRfitMeshScan& pln : *this)
{
pln.resize(cellWidth, pars);
}
}
void Foam::PDRfitMeshScans::print(Ostream& os) const
{
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
{
os << vector::componentNames[cmpt] << ' ';
(*this)[cmpt].print(os);
}
}
void Foam::PDRfitMeshScans::scanLimits
(
const UList<PDRobstacle>& obstacles
)
{
for (const PDRobstacle& obs : obstacles)
{
switch (obs.typeId)
{
case PDRobstacle::CYLINDER:
case PDRobstacle::DIAG_BEAM:
{
(*this)[obs.orient].adjustLimits
(
obs.pt[obs.orient],
obs.pt[obs.orient] + obs.len()
);
break;
}
case PDRobstacle::CUBOID_1:
case PDRobstacle::LOUVRE_BLOWOFF:
case PDRobstacle::CUBOID:
case PDRobstacle::WALL_BEAM:
case PDRobstacle::GRATING:
case PDRobstacle::RECT_PATCH:
{
(*this).x().adjustLimits(obs.x(), obs.x() + obs.span.x());
(*this).y().adjustLimits(obs.y(), obs.y() + obs.span.y());
(*this).z().adjustLimits(obs.z(), obs.z() + obs.span.z());
break;
}
}
}
}
Foam::scalar
Foam::PDRfitMeshScans::scanAreas
(
const UList<PDRobstacle>& obstacles,
const scalar minSubgridLen
)
{
scalar subgridLen = 0;
const bool checkSubgrid = (minSubgridLen > 0);
if (verbose())
{
Info<< "Scan " << obstacles.size()
<< " obstacles. Check for subgrid < " << minSubgridLen
<< nl;
}
// When sorting flat elements, convert vector -> List
List<scalar> gridSpan(3);
for (const PDRobstacle& obs : obstacles)
{
switch (obs.typeId)
{
case PDRobstacle::CYLINDER:
{
// #ifdef FULLDEBUG
// Info<< "Add " << obs.info() << nl;
// #endif
(*this)[obs.orient].addArea
(
sqr(0.5*obs.dia()),
obs.pt[obs.orient],
obs.pt[obs.orient] + obs.len()
);
// Store total length of subgrid obstcales
if (checkSubgrid && obs.dia() < minSubgridLen)
{
subgridLen += obs.len();
}
break;
}
case PDRobstacle::DIAG_BEAM:
{
// #ifdef FULLDEBUG
// Info<< "Add " << obs.info() << nl;
// #endif
(*this)[obs.orient].addArea
(
(obs.wa * obs.wb),
obs.pt[obs.orient],
obs.pt[obs.orient] + obs.len()
);
// Store total length of subgrid obstcales
if (checkSubgrid && Foam::max(obs.wa, obs.wb) < minSubgridLen)
{
subgridLen += obs.len();
}
break;
}
case PDRobstacle::CUBOID_1:
case PDRobstacle::LOUVRE_BLOWOFF:
case PDRobstacle::CUBOID:
case PDRobstacle::WALL_BEAM:
case PDRobstacle::GRATING:
case PDRobstacle::RECT_PATCH:
{
// #ifdef FULLDEBUG
// Info<< "Add " << obs.info() << nl;
// #endif
// Can be lazy here, addArea() filters out zero areas
(*this)[vector::X].addArea
(
(obs.span.y() * obs.span.z()),
obs.x(),
obs.x() + obs.span.x()
);
(*this)[vector::Y].addArea
(
(obs.span.z() * obs.span.x()),
obs.y(),
obs.y() + obs.span.y()
);
(*this)[vector::Z].addArea
(
(obs.span.x() * obs.span.y()),
obs.z(),
obs.z() + obs.span.z()
);
if (checkSubgrid)
{
gridSpan[0] = obs.span.x();
gridSpan[1] = obs.span.y();
gridSpan[2] = obs.span.z();
Foam::sort(gridSpan);
// Ignore zero dimension when considering subgrid
// Store total length of subgrid obstcales
if (gridSpan[1] < minSubgridLen)
{
subgridLen += gridSpan.last();
}
}
break;
}
}
}
return subgridLen;
}
void Foam::PDRfitMeshScans::scanAreas
(
const UList<PDRobstacle>& obstacles
)
{
(void)scanAreas(obstacles, -GREAT);
}
void Foam::PDRfitMeshScans::scanAreas
(
const UList<PDRobstacle>& obstacles,
const PDRfitMeshParams& fitParams,
scalar cellWidth
)
{
resize(mag(cellWidth), fitParams);
const scalar minSubgridLen =
(cellWidth < 0 ? (mag(cellWidth) * fitParams.widthFactor) : 0);
subgridLen_ = scanAreas(obstacles, minSubgridLen);
}
Foam::Vector<Foam::PDRblock::gridControl>
Foam::PDRfitMeshScans::calcGriding
(
const UList<PDRobstacle>& obstacles,
const PDRfitMeshParams& fitParams,
scalar cellWidth
)
{
prepare(obstacles, fitParams, cellWidth);
const scalar innerVol = volume();
// Set hard lower limit at the ground
z().hard_min(fitParams.ground);
if (z().limits().min() < fitParams.ground)
{
z().limits().min() = fitParams.ground;
}
if (verbose())
{
print(Info);
Info<< "cellWidth = " << cellWidth << nl;
Info<< "inner volume: " << innerVol << nl;
Info<< "subgrid length: " << subgridLen_ << nl;
}
// Read in obstacles and record face planes Also record length of
// subgrid obstacles so that we can optimise cell size to get
// desired average no, of obstacles oper cell. Determinuing which
// obstacles are subgrid is iself dependent on the cell size.
// Therefore we iterate (if cell_width is -ve) If cell_width is
// +ve just use the user-supplied value.
{
// The cell-widths during optimisation
scalar prev_cw = 0, cw = 0;
const bool optimiseWidth = (cellWidth < 0);
for (label nIter = 0; nIter < fitParams.maxIterations; ++nIter)
{
scanAreas(obstacles, fitParams, cellWidth);
if (cellWidth < 0)
{
constexpr scalar relax = 0.7;
prev_cw = cw;
if (subgridLen_ < cellWidth)
{
FatalErrorInFunction
<< "No sub-grid obstacles found" << endl
<< exit(FatalError);
}
// Optimise to average subgrid obstacles per cell
cw = sqrt(fitParams.obsPerCell * innerVol / subgridLen_);
cw = Foam::min(cw, fitParams.maxCellWidth);
if (cw > cellWidth * fitParams.maxWidthEstimate)
{
Warning
<< "Calculated cell width more than"
" maxWidthEstimate x estimate." << nl
<< "Too few sub-grid obstacles?"
<< nl;
}
Info<< "Current cellwidth: " << cw << nl;
scalar ratio = cw / cellWidth;
if (ratio < 1)
{
ratio = 1/ratio;
}
if (ratio < fitParams.maxWidthRatio)
{
cellWidth = -cellWidth;
}
else
{
cellWidth = relax * (-cw) + (1.0 - relax) * cellWidth;
}
Info<< "Cell width: " << cellWidth << nl;
}
if (cellWidth > 0)
{
break;
}
}
if (cellWidth < 0)
{
cellWidth = 0.5 * (cw + prev_cw);
}
if (optimiseWidth)
{
Info<< nl << "Final cell width: " << cellWidth << nl << nl;
}
}
// Now we fit the mesh to the planes and write out the result
resize(cellWidth, fitParams);
cellWidth = cbrt(cellVolume()) / fitParams.areaWidthFactor;
scanAreas(obstacles, fitParams, cellWidth);
const scalar max_zone =
(
(z().limits().mag() + fitParams.nEdgeLayers * cellWidth)
* fitParams.maxZoneToHeight
);
Vector<PDRblock::gridControl> griding;
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
{
griding[cmpt] =
(*this)[cmpt].calcGridControl(cellWidth, max_zone, fitParams);
}
return griding;
}
// ************************************************************************* //

View File

@ -0,0 +1,154 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::PDRfitMeshScans
Description
Scanning of obstacles in a multiple directions for PDRfitMesh
SourceFiles
PDRfitMeshScans.C
\*---------------------------------------------------------------------------*/
#ifndef PDRfitMeshScans_H
#define PDRfitMeshScans_H
#include "PDRfitMeshScan.H"
#include "vector.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class PDRobstacle;
/*---------------------------------------------------------------------------*\
Class PDRfitMeshScans Declaration
\*---------------------------------------------------------------------------*/
class PDRfitMeshScans
:
public Vector<PDRfitMeshScan>
{
// Private Data
//- The evaluated sub-grid length
scalar subgridLen_ = 0;
// Private Member Functions
//- Prepare limits, scan areas
void prepare
(
const UList<PDRobstacle>& obstacles,
const PDRfitMeshParams& fitParams,
scalar cellWidth
);
public:
// Default Constructors
// Member Functions
//- Verbosity
static inline bool verbose() noexcept
{
return PDRfitMeshScan::verbose();
}
//- Calculate the grid controls for the given obstacles
//- and parameters
Vector<PDRblock::gridControl>
calcGriding
(
const UList<PDRobstacle>& obstacles,
const PDRfitMeshParams& fitParams,
scalar cellWidth
);
// Low-level functions
//- The volume of the limits
scalar volume() const;
//- The volume of single cell of the respective step-width
scalar cellVolume() const;
//- Reset to initial state
void reset();
//- Define number of steps (and step-size) according to the
//- current limits and the specified parameters
void resize(const scalar cellWidth, const PDRfitMeshParams& pars);
//- Adjust directional limits to accommodate obstacles
void scanLimits(const UList<PDRobstacle>& obstacles);
//- Populate with areas/positions of the obstacles,
//- and check for sub-grid obstacles
// Sets the internal
void scanAreas
(
const UList<PDRobstacle>& obstacles,
const PDRfitMeshParams& fitParams,
scalar cellWidth
);
//- Populate with areas/positions of the obstacles,
//- and check for sub-grid obstacles
//
// \return total subgrid lengths
scalar scanAreas
(
const UList<PDRobstacle>& obstacles,
const scalar minSubgridLen
);
//- Populate with areas/positions of the obstacles,
//- without checks for sub-grid obstacles
void scanAreas(const UList<PDRobstacle>& obstacles);
//- Print information
void print(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,15 @@
EXE_INC = \
-I../pdrFields/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/mesh/blockMesh/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfileFormats \
-lsurfMesh \
-lmeshTools \
-lblockMesh \
-lpdrFields

View File

@ -83,6 +83,8 @@ int main(int argc, char* argv[])
#include "setRootCase.H"
#include "createTime.H"
const bool dryrun = args.found("dry-run");
const word dictName("PDRsetFieldsDict");
#include "setSystemRunTimeDictionaryIO.H"
@ -90,8 +92,6 @@ int main(int argc, char* argv[])
IOdictionary setFieldsDict(dictIO);
const bool dryrun = args.found("dry-run");
const fileName& casepath = runTime.globalPath();
pars.timeName = "0";

View File

@ -1149,9 +1149,9 @@ static void tail_field
const UList<PDRpatchDef>& patches
)
{
// seaGround
// ground
{
os.beginBlock("seaGround");
os.beginBlock(pars.groundPatchName);
os.writeKeyword("type") << wall_bc << token::END_STATEMENT << nl;
putUniform(os, "value", deflt);
os.endBlock();
@ -1222,13 +1222,14 @@ static void tail_field
os.endBlock();
}
if ( pars.two_d )
if (pars.two_d)
{
os.beginBlock("z_boundaries");
os.writeEntry("type", "empty");
os.endBlock();
}
if ( pars.outer_orthog )
if (pars.outer_orthog)
{
os.beginBlock("outer_inner");
os.writeEntry("type", "cyclicAMI");
@ -1285,9 +1286,10 @@ void write_scalarField
os << nl;
os.beginBlock("boundaryField");
// outer
{
os.beginBlock("outer");
os.beginBlock(pars.outerPatchName);
os.writeEntry("type", "inletOutlet");
putUniform(os, "inletValue", deflt);
@ -1329,7 +1331,8 @@ void write_uniformField
// outer
{
os.beginBlock("outer");
os.beginBlock(pars.outerPatchName);
if (fieldName == "alphat" || fieldName == "nut")
{
// Different b.c. for alphat & nut
@ -1377,17 +1380,17 @@ void write_pU_fields
os << nl;
os.beginBlock("boundaryField");
// "outer"
// outer
{
os.beginBlock("outer");
os.beginBlock(pars.outerPatchName);
os.writeEntry("type", "inletOutlet");
putUniform(os, "inletValue", vector::zero);
os.endBlock();
}
// seaGround
// ground
{
os.beginBlock("seaGround");
os.beginBlock(pars.groundPatchName);
os.writeEntry("type", "zeroGradient");
os.endBlock();
}
@ -1497,9 +1500,10 @@ void write_pU_fields
os << nl;
os.beginBlock("boundaryField");
// "outer"
// outer
{
os.beginBlock("outer");
os.beginBlock(pars.outerPatchName);
os.writeEntry("type", "waveTransmissive");
os.writeEntry("gamma", 1.3);
os.writeEntry("fieldInf", deflt);
@ -1560,7 +1564,7 @@ void write_symmTensorField
// outer
{
os.beginBlock("outer");
os.beginBlock(pars.outerPatchName);
os.writeEntry("type", "inletOutlet");
putUniform(os, "inletValue", deflt);
@ -1628,7 +1632,7 @@ void write_symmTensorFieldV
// outer
{
os.beginBlock("outer");
os.beginBlock(pars.outerPatchName);
os.writeEntry("type", "inletOutlet");
putUniform(os, "inletValue", deflt);

View File

@ -94,7 +94,7 @@ void Foam::PDRmeshArrays::classify
<< " nPoints:" << pdrBlock.nPoints()
<< " nCells:" << pdrBlock.nCells()
<< " nFaces:" << pdrBlock.nFaces() << nl
<< " min-edge:" << pdrBlock.minEdgeLen() << nl;
<< " min-edge:" << pdrBlock.edgeLimits().min() << nl;
Info<< "Classifying ijk indexing... " << nl;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -84,6 +84,20 @@ void Foam::PDRparams::readDefaults(const dictionary& dict)
dict.readIfPresent("blockageNoCT", blockageNoCT);
dict.readIfPresent("scale", scale);
const dictionary* dictptr;
groundPatchName = "ground";
outerPatchName = "outer";
if ((dictptr = dict.findDict("patchNames")) != nullptr)
{
const dictionary& d = *dictptr;
d.readIfPresent("ground", groundPatchName);
d.readIfPresent("outer", outerPatchName);
}
UPatchBc = "fixedValue;value uniform (0 0 0)";
if (dict.readIfPresent("UPatchBc", UPatchBc))
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 Shell Research Ltd.
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -62,6 +62,13 @@ public:
fileName obsfile_dir;
wordList obsfile_names;
word timeName;
//- The name for the "ground" patch
word groundPatchName;
//- The name for the "outer" patch
word outerPatchName;
string UPatchBc; //!< "fixedValue;value uniform (0 0 0)"
bool legacyMeshSpec{false};
@ -136,7 +143,7 @@ public:
// Constructors
//- Construct null
//- Default construct
PDRparams() = default;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,9 +29,6 @@ Namespace
Description
Utilities for PDR (eg, for setFields)
SourceFiles
PDRUtils.C
\*---------------------------------------------------------------------------*/
#ifndef PDRutils_H
@ -48,11 +45,17 @@ namespace Foam
// Forward Declarations
class PDRobstacle;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace PDRutils
{
} // End namespace PDRutils
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -264,6 +264,8 @@ public:
);
//- Trim obstacle to ensure it is within the specified bounding box
//- and return the intersection type.
// Returns UNKNOWN for unknown types and invalid bounding boxes
volumeType trim(const boundBox& bb);
//- Surface (points, faces) representation

Some files were not shown because too many files have changed in this diff Show More