From cfa58e08195b881f60a6bdffda0d530a55affa83 Mon Sep 17 00:00:00 2001
From: mattijs <mattijs>
Date: Mon, 21 Feb 2011 11:25:13 +0000
Subject: [PATCH] ENH: codeStream: documentation

---
 ReleaseNotes-dev                              |  39 ++++++
 doc/changes/onTheFly.txt                      | 122 ++++++++++++++++++
 src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C |   2 +-
 .../codedFixedValueFvPatchScalarField.C       |   2 +-
 4 files changed, 163 insertions(+), 2 deletions(-)
 create mode 100644 doc/changes/onTheFly.txt

diff --git a/ReleaseNotes-dev b/ReleaseNotes-dev
index 230a1168263..06a9bb7c776 100644
--- a/ReleaseNotes-dev
+++ b/ReleaseNotes-dev
@@ -134,6 +134,28 @@
     + single integer reduction instead of one reduction per monitored file.
     + only files that can be re-read are being checked. Drastic reduction of
       number of files to check.
+*** *New* #codeStream dictionary entry method. Uses on-the-fly compilation
+    of OpenFOAM C++ code to construct dictionary.
+    E.g. in blockMeshDict:
+
+        convertToMeters 0.001;
+
+        vertices #codeStream
+        {
+            code
+            #{
+                label nVerts =
+                    readLabel(dict.lookup("nx"))
+                  * readLabel(dict.lookup("ny"))
+                  * readLabel(dict.lookup("nz"));
+                pointField verts(nVerts);
+                // Now fill verts here
+                // ..
+                os  << verts;
+            #};
+        }
+    See also doc/changes/onTheFly.txt
+
 * Solvers
   A number of new solvers have been developed for a range of engineering
   applications.  There has been a set of improvements to certain classes of
@@ -163,6 +185,23 @@
     + takes optional fieldName to sample
     + directMapped patch added 'normal' method to calculate sample points
       to e.g. sample fields just above wall (e.g. for streaklines)
+  + *New* codedFixedValue: Uses the on-the-fly code compilation from #codeStream
+    to provide an in-line fixedValueFvPatchScalarField. E.g.
+
+    outlet
+    {
+        type            codedFixedValue;
+        value           uniform 0;
+        redirectType    fixedValue10;
+
+        code
+        #{
+            operator==(min(10, 0.1*this->db().time().value()));
+        #};
+    }
+
+    See doc/changes/onTheFly.txt
+
 * Utilities
   There have been some utilities added and updated in this release.
 *** *New* utilities
diff --git a/doc/changes/onTheFly.txt b/doc/changes/onTheFly.txt
new file mode 100644
index 00000000000..51665755aa4
--- /dev/null
+++ b/doc/changes/onTheFly.txt
@@ -0,0 +1,122 @@
+On-the-fly code compilation
+---------------------------
+
+1. #codeStream
+This is a dictionary preprocessing directive ('functionEntry') which provides
+a snippet of OpenFOAM
+C++ code which gets compiled and executed to provide the actual dictionary
+entry. The snippet gets provided as three sections of C++ code which just gets
+inserted into a template:
+- 'code' section: the actual body of the code. It gets called with
+    arguments
+
+        const dictionary& dict,
+        OStream& os
+
+    and the C++ code can do a dict.lookup to find current dictionary values.
+
+- optional 'codeInclude' section: any #include statements to include
+OpenFOAM files.
+
+- optional 'codeOptions' section: any extra compilation flags to be added to
+EXE_INC in Make/options
+
+To ease inputting mulit-line code there is the #{ #} syntax. Anything
+inbetween these two delimiters becomes a string with all newlines, quotes etc
+preserved.
+
+Example: Look up dictionary entries and do some calculation
+
+    startTime       0;
+    endTime         100;
+    ..
+    writeInterval   #codeStream
+    {
+        code
+        #{
+            scalar start = readScalar(dict["startTime"]);
+            scalar end = readScalar(dict["endTime"]);
+            label nDumps = 5;
+            label interval = end-start
+            os  << ((start-end)/nDumps)
+        #}
+    };
+
+
+
+2. Implementation
+- the #codeStream entry reads the dictionary following it, extracts the
+code, codeInclude, codeOptions sections (these are just strings) and
+calculates the SHA1 checksum of the contents.
+- it writes library source files to constant/codeStream/<sha1> and compiles it
+using 'wmake libso'.
+- the resulting library gets loaded (dlopen, dlsym) and the function
+executed
+- the function will have written its output into the Ostream which then
+gets used to construct the entry to replace the whole #codeStream section.
+- using the sha1 means that same code will only be compiled & loaded once.
+
+
+3. codedFixedValue
+This uses the code from codeStream to have an in-line specialised
+fixedValueFvPatchScalarField:
+
+    outlet
+    {
+        type            codedFixedValue;
+        value           uniform 0;
+        redirectType    fixedValue10;
+
+        code
+        #{
+            operator==(min(10, 0.1*this->db().time().value()));
+        #};
+    }
+
+It by default always includes fvCFD.H and adds the finiteVolume library
+to the include search path.
+
+
+4. Security
+Allowing the case to execute C++ code does introduce security risks.
+A thirdparty case might have a #codeStream{#code system("rm -rf .");};
+hidden somewhere in a dictionary. #codeStream is therefore not enabled by
+default - you have to enable it by setting in the system-wide controlDict
+
+    InfoSwitches
+    {
+        // Allow case-supplied c++ code (#codeStream, codedFixedValue)
+        allowSystemOperations   1;
+    }
+
+
+5. Field manipulation.
+Fields are read in as IOdictionary so can be upcast to provide access to the
+mesh:
+
+internalField  #codeStream
+{
+    codeInclude
+    #{
+        #include "fvCFD.H"
+    #};
+
+    code
+    #{
+        const IOdictionary& d = refCast<const IOdictionary&>(dict);
+        const fvMesh& mesh = refCast<const fvMesh>(d.db());
+        scalarField fld(mesh.nCells(), 0.0);
+        fld.writeEntry("", os);
+    #};
+
+    codeOptions
+    #{
+        -I$(LIB_SRC)/finiteVolume/lnInclude
+    #};
+};
+
+
+
+6. Other
+- the implementation is still a bit raw - it compiles code overly much
+- parallel running not tested a lot. What about distributed data parallel.
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
index 6bbb130a49a..135f61823af 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
@@ -550,7 +550,7 @@ Foam::Istream& Foam::ISstream::read(string& str)
 
 Foam::Istream& Foam::ISstream::readVerbatim(string& str)
 {
-    static const int maxLen = 1024;
+    static const int maxLen = 8000;
     static const int errLen = 80; // truncate error message for readability
     static char buf[maxLen];
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C
index 80a8096fa3e..388d013b553 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C
@@ -165,7 +165,7 @@ void Foam::codedFixedValueFvPatchScalarField::updateLibrary()
     }
 
     const fileName dir =
-        db().time().constantPath()/"codedFixedValue"/redirectType_;
+        db().time().constantPath()/"codeStream"/redirectType_;
     //Info<< "dir:" << dir << endl;
 
     const fileName libPath
-- 
GitLab