diff --git a/src/OpenFOAM/primitives/functions/Function2/Function1/Function12.C b/src/OpenFOAM/primitives/functions/Function2/Function1/Function12.C
new file mode 100644
index 0000000000..51a4fe3b88
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Function1/Function12.C
@@ -0,0 +1,91 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "Function12.H"
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template
+Foam::Function2s::Function12::Function12
+(
+ const word& name,
+ const dictionary& dict
+)
+:
+ FieldFunction2>(name),
+ index_(),
+ f_()
+{
+ static const word name1 = "value1", name2 = "value2";
+ const bool found1 = dict.found(name1), found2 = dict.found(name2);
+
+ if (found1 && found2)
+ {
+ FatalIOErrorInFunction(dict)
+ << "Both keywords " << name1 << " and " << name2
+ << " are undefined in dictionary " << dict.name()
+ << exit(FatalError);
+ }
+
+ if (!found1 && !found2)
+ {
+ FatalIOErrorInFunction(dict)
+ << "Neither keywords " << name1 << " or " << name2
+ << " are defined in dictionary " << dict.name()
+ << exit(FatalError);
+ }
+
+ index_ = found2;
+
+ f_ = Function1::New(found2 ? name2 : name1, dict);
+}
+
+
+template
+Foam::Function2s::Function12::Function12(const Function12& se)
+:
+ FieldFunction2>(se),
+ index_(se.index_),
+ f_(se.f_, false)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+template
+Foam::Function2s::Function12::~Function12()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+void Foam::Function2s::Function12::write(Ostream& os) const
+{
+ writeEntry(os, f_());
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Function1/Function12.H b/src/OpenFOAM/primitives/functions/Function2/Function1/Function12.H
new file mode 100644
index 0000000000..b8825b1f64
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Function1/Function12.H
@@ -0,0 +1,148 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+Class
+ Foam::Function2s::Function12
+
+Description
+ Function2 which returns a Function1 using just one of the arguments given
+ to the function2. The function1 is specified as value1 or value2, depending
+ on which argument it is to be evaluated with.
+
+ Example for a scalar:
+ \verbatim
+
+ {
+ type function1;
+ value1 constant 10; // <-- The value1 function is evaluated with
+ // the first argument
+ }
+ \endverbatim
+
+ Example for a vector:
+ \verbatim
+
+ {
+ type function1;
+ value2 table // <-- The value2 function is evaluated with
+ ( // the second argument
+ (0.00 (0 0 0))
+ (0.35 (0 0 1))
+ (0.71 (0 0 0))
+ );
+ }
+ \endverbatim
+
+SourceFiles
+ Function12.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Function12_H
+#define Function12_H
+
+#include "Function1.H"
+#include "Function2.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Function2s
+{
+
+/*---------------------------------------------------------------------------*\
+ Class Function12 Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class Function12
+:
+ public FieldFunction2>
+{
+ // Private Data
+
+ //- The index of the argument to use. 0 or 1, hence a bool.
+ bool index_;
+
+ //- Function
+ autoPtr> f_;
+
+
+public:
+
+ // Runtime type information
+ TypeName("function1");
+
+
+ // Constructors
+
+ //- Construct from name and dictionary
+ Function12
+ (
+ const word& name,
+ const dictionary& dict
+ );
+
+ //- Copy constructor
+ Function12(const Function12& se);
+
+
+ //- Destructor
+ virtual ~Function12();
+
+
+ // Member Functions
+
+ //- Return value
+ virtual inline Type value(const scalar x, const scalar y) const;
+
+ //- Write data to dictionary stream
+ virtual void write(Ostream& os) const;
+
+
+ // Member Operators
+
+ //- Disallow default bitwise assignment
+ void operator=(const Function12&) = delete;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Function2s
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "Function12I.H"
+
+#ifdef NoRepository
+ #include "Function12.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Function1/Function12I.H b/src/OpenFOAM/primitives/functions/Function2/Function1/Function12I.H
new file mode 100644
index 0000000000..f45fd2df0d
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Function1/Function12I.H
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "Function12.H"
+#include "vector2D.H"
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+inline Type Foam::Function2s::Function12::value
+(
+ const scalar x,
+ const scalar y
+) const
+{
+ return f_->value(index_ ? y : x);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Product/Product2.C b/src/OpenFOAM/primitives/functions/Function2/Product/Product2.C
new file mode 100644
index 0000000000..1bccd8bc76
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Product/Product2.C
@@ -0,0 +1,314 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "Product2.H"
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template
+Foam::Function2s::ProductFunction1s::ProductFunction1s
+(
+ const dictionary& dict,
+ const Pair>& typeAndRanks
+)
+:
+ ProductFunction1s(dict, typeAndRanks)
+{
+ forAll(fs, i)
+ {
+ if (typeAndRanks[i].second() == rank)
+ {
+ fs[i] =
+ function1Type::New
+ (
+ valueName(i, typeAndRanks[i]),
+ dict
+ );
+ }
+ }
+}
+
+
+template
+Foam::Function2s::ProductFunction1s::ProductFunction1s
+(
+ const dictionary& dict,
+ const Pair>& typeAndRanks
+)
+{
+ forAll(fs, i)
+ {
+ if (typeAndRanks[i].second() == 0)
+ {
+ fs[i] =
+ Function1::New
+ (
+ valueName(i, typeAndRanks[i]),
+ dict
+ );
+ }
+ }
+}
+
+
+template
+Foam::Function2s::ProductFunction1s::ProductFunction1s
+(
+ const ProductFunction1s& p2f1s
+)
+:
+ ProductFunction1s(p2f1s),
+ fs
+ (
+ autoPtr(p2f1s.fs.first(), false),
+ autoPtr(p2f1s.fs.second(), false)
+ )
+{}
+
+
+template
+Foam::Function2s::ProductFunction1s::ProductFunction1s
+(
+ const ProductFunction1s& p2f1s
+)
+:
+ fs
+ (
+ autoPtr>(p2f1s.fs.first(), false),
+ autoPtr>(p2f1s.fs.second(), false)
+ )
+{}
+
+
+template
+Foam::Function2s::Product::Product
+(
+ const word& name,
+ const dictionary& dict
+)
+:
+ FieldFunction2>(name),
+ fs_(dict, lookupValueTypeAndRanks(dict))
+{}
+
+
+template
+Foam::Function2s::Product::Product(const Product& se)
+:
+ FieldFunction2>(se),
+ fs_(se.fs_)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+template
+Foam::Function2s::Product::~Product()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+void Foam::Function2s::ProductFunction1s::write(Ostream& os) const
+{
+ ProductFunction1s::write(os);
+
+ forAll(fs, i)
+ {
+ if (fs[i].valid())
+ {
+ writeEntry(os, fs[i]());
+ }
+ }
+}
+
+
+template
+void Foam::Function2s::ProductFunction1s::write(Ostream& os) const
+{
+ forAll(fs, i)
+ {
+ if (fs[i].valid())
+ {
+ writeEntry(os, fs[i]());
+ }
+ }
+}
+
+
+template
+void Foam::Function2s::Product::write(Ostream& os) const
+{
+ fs_.write(os);
+}
+
+
+// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
+
+template
+void Foam::Function2s::lookupValueTypeAndRank
+(
+ const dictionary& dict,
+ const direction argument,
+ Tuple2& typeAndRank,
+ label& found
+)
+{
+ if (dict.found(valueName(argument)))
+ {
+ if (found != -1)
+ {
+ FatalIOErrorInFunction(dict)
+ << "Multiple " << valueName(argument) << " and/or "
+ << valueName(argument, "Type") << "-s specified"
+ << exit(FatalIOError);
+ }
+
+ typeAndRank =
+ Tuple2
+ (
+ pTraits::typeName,
+ pTraits::rank
+ );
+
+ found = ProductValueTypeIsValid::value;
+ }
+}
+
+
+template
+Foam::Tuple2 Foam::Function2s::lookupValueTypeAndRank
+(
+ const dictionary& dict,
+ const direction argument
+)
+{
+ Tuple2 typeAndRank(word::null, -1);
+ label found = dict.found(valueName(argument)) ? 1 : -1;
+
+ #define LOOKUP_VALUE_TYPE_AND_RANK(ValueType, nullArg) \
+ lookupValueTypeAndRank \
+ ( \
+ dict, \
+ argument, \
+ typeAndRank, \
+ found \
+ );
+ FOR_ALL_FIELD_TYPES(LOOKUP_VALUE_TYPE_AND_RANK);
+ #undef LOOKUP_VALUE_TYPE_AND_RANK
+
+ if (found == -1)
+ {
+ FatalIOErrorInFunction(dict)
+ << "Function " << valueName(argument)
+ << " undefined in dictionary " << dict.name()
+ << exit(FatalIOError);
+ }
+
+ if (found == 0)
+ {
+ FatalIOErrorInFunction(dict)
+ << "Function " << valueName(argument, typeAndRank)
+ << " returns a type that cannot be used to produce a product"
+ << " of type " << pTraits::typeName
+ << exit(FatalIOError);
+ }
+
+ return typeAndRank;
+}
+
+
+template
+Foam::Pair>
+Foam::Function2s::lookupValueTypeAndRanks(const dictionary& dict)
+{
+ Pair> typeAndRanks
+ (
+ lookupValueTypeAndRank(dict, 0),
+ lookupValueTypeAndRank(dict, 1)
+ );
+
+ // If this is a non-scalar type then at least one of the value entries must
+ // have specified the type
+ if
+ (
+ pTraits::rank > 0
+ && typeAndRanks.first().second() == -1
+ && typeAndRanks.second().second() == -1
+ )
+ {
+ FatalIOErrorInFunction(dict)
+ << "One of the functions " << valueName(0) << " and "
+ << valueName(1) << " needs to specify the return type, e.g., as "
+ << valueName(0) << exit(FatalIOError);
+ }
+
+ // If both types are specified then the sum of their ranks must equal the
+ // rank of the function
+ if
+ (
+ typeAndRanks.first().second() != -1
+ && typeAndRanks.second().second() != -1
+ && typeAndRanks.first().second()
+ + typeAndRanks.second().second()
+ != pTraits::rank
+ )
+ {
+ FatalIOErrorInFunction(dict)
+ << "The functions " << valueName(0, typeAndRanks.first())
+ << " and " << valueName(1, typeAndRanks.second()) << " return "
+ << "types for which the product is not of type "
+ << pTraits::typeName << exit(FatalIOError);
+ }
+
+ // If this is a scalar type, then neither entry needs to specify the type.
+ // They both must be scalars.
+ if
+ (
+ pTraits::rank == 0
+ && typeAndRanks.first().second() == -1
+ && typeAndRanks.second().second() == -1
+ )
+ {
+ typeAndRanks.first().second() = 0;
+ typeAndRanks.second().second() = 0;
+ }
+
+ // Determine remaining unspecified ranks
+ forAll(typeAndRanks, i)
+ {
+ if (typeAndRanks[i].second() == -1)
+ {
+ typeAndRanks[i].second() =
+ pTraits::rank - typeAndRanks[!i].second();
+ }
+ }
+
+ return typeAndRanks;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Product/Product2.H b/src/OpenFOAM/primitives/functions/Function2/Product/Product2.H
new file mode 100644
index 0000000000..7dea70c8ee
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Product/Product2.H
@@ -0,0 +1,348 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+Class
+ Foam::Function2s::Product
+
+Description
+ Function2 which returns the product of two independent Function1-s of the
+ two input arguments. The two function1s are specified as value1 and value2.
+
+ Example to scale a table of vectors in the first argument with a ramp in
+ the second argument:
+ \verbatim
+
+ {
+ type product;
+ value1 table
+ (
+ (0.00 (0 0 0))
+ (0.25 (1 0 0))
+ (0.50 (0 0 0))
+ );
+ value2
+ {
+ type linearRamp;
+ start 1;
+ duration 4;
+ }
+ }
+ \endverbatim
+
+ Note that only one type specification (the //... part)
+ is needed in general for the value entries, and no type specifications
+ are needed if the function is scalar.
+
+SourceFiles
+ Product.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Product2_H
+#define Product2_H
+
+#include "Function1.H"
+#include "Function2.H"
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Function2s
+{
+
+/*---------------------------------------------------------------------------*\
+ Class ProductValueTypeIsValid Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+struct ProductValueTypeIsValid
+{
+ static const bool value = false;
+};
+
+
+template
+struct ProductValueTypeIsValid
+{
+ static const bool value = true;
+};
+
+
+template
+struct ProductValueTypeIsValid
+<
+ Type,
+ ValueType,
+ typename std::enable_if
+ <
+ (pTraits::rank > 0)
+ && (pTraits::rank <= pTraits::rank)
+ >::type
+>
+{
+ static const bool value =
+ std::is_same
+ <
+ Type,
+ typename outerProduct
+ <
+ ValueType,
+ typename typeOfRank
+ <
+ scalar,
+ pTraits::rank - pTraits::rank
+ >::type
+ >::type
+ >::value;
+};
+
+
+/*---------------------------------------------------------------------------*\
+ Class ProductFilter Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+struct ProductFilter
+{
+ inline const Type& operator()(const Type& value) const
+ {
+ return value;
+ }
+
+ template
+ const Type& operator()(const WrongType& value) const
+ {
+ return NullObjectRef();
+ }
+};
+
+
+/*---------------------------------------------------------------------------*\
+ Class ProductFunction1s Declaration
+\*---------------------------------------------------------------------------*/
+
+template::rank>
+class ProductFunction1s
+:
+ public ProductFunction1s
+{
+ // Private Typedefs
+
+ //- Type of the function
+ typedef
+ Function1
+ <
+ typename std::conditional
+ <
+ rank == pTraits::rank,
+ Type,
+ typename typeOfRank::type
+ >::type
+ > function1Type;
+
+
+public:
+
+ // Public Data
+
+ //- Functions
+ Pair> fs;
+
+
+ // Constructors
+
+ //- Construct from a dictionary
+ ProductFunction1s
+ (
+ const dictionary& dict,
+ const Pair>& typeAndRanks
+ );
+
+ //- Copy construct
+ ProductFunction1s(const ProductFunction1s& p2f1s);
+
+
+ // Public Member Functions
+
+ //- Evaluate
+ inline Type value(const scalar x, const scalar y) const;
+
+ //- Write to a stream
+ void write(Ostream& os) const;
+};
+
+
+/*---------------------------------------------------------------------------*\
+ Class ProductFunction1s<0> Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class ProductFunction1s
+{
+public:
+
+ // Public Data
+
+ //- Functions
+ Pair>> fs;
+
+
+ // Constructors
+
+ //- Construct from a dictionary
+ ProductFunction1s
+ (
+ const dictionary& dict,
+ const Pair>& typeAndRanks
+ );
+
+ //- Copy construct
+ ProductFunction1s(const ProductFunction1s& p2f1s);
+
+
+ // Public Member Functions
+
+ //- Evaluate
+ inline Type value(const scalar x, const scalar y) const;
+
+ //- Write to a stream
+ void write(Ostream& os) const;
+};
+
+
+/*---------------------------------------------------------------------------*\
+ Class Product Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class Product
+:
+ public FieldFunction2>
+{
+ // Private Data
+
+ //- Functions
+ ProductFunction1s fs_;
+
+
+public:
+
+ // Runtime type information
+ TypeName("product");
+
+
+ // Constructors
+
+ //- Construct from name and dictionary
+ Product
+ (
+ const word& name,
+ const dictionary& dict
+ );
+
+ //- Copy constructor
+ Product(const Product& se);
+
+
+ //- Destructor
+ virtual ~Product();
+
+
+ // Member Functions
+
+ //- Return value
+ virtual inline Type value(const scalar x, const scalar y) const;
+
+ //- Write data to dictionary stream
+ virtual void write(Ostream& os) const;
+
+
+ // Member Operators
+
+ //- Disallow default bitwise assignment
+ void operator=(const Product&) = delete;
+};
+
+
+// Global Functions
+
+//- Return the name of the value entry for the given argument
+inline word valueName(const direction argument);
+
+//- Return the name of the value entry for the given argument and type name
+inline word valueName(const direction argument, const word& typeName);
+
+//- Return the name of the value entry for the given argument and type
+template
+inline word valueName(const direction argument);
+
+//- Return the name of the value entry for the given argument and type and rank
+inline word valueName
+(
+ const direction argument,
+ const Tuple2& typeAndRank
+);
+
+//- Lookup the type and rank for the value entry for the given argument
+template
+void lookupValueTypeAndRank
+(
+ const dictionary& dict,
+ const direction argument,
+ Tuple2& typeAndRank,
+ label& found
+);
+
+//- Lookup the type and rank for the value entry for the given argument
+template
+Tuple2 lookupValueTypeAndRank
+(
+ const dictionary& dict,
+ const direction argument
+);
+
+//- Lookup the types and ranks for the value entries
+template
+Pair> lookupValueTypeAndRanks(const dictionary& dict);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Function2s
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "Product2I.H"
+
+#ifdef NoRepository
+ #include "Product2.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Product/Product2I.H b/src/OpenFOAM/primitives/functions/Function2/Product/Product2I.H
new file mode 100644
index 0000000000..ee1c27199e
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Product/Product2I.H
@@ -0,0 +1,117 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "Product2.H"
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+inline Type Foam::Function2s::ProductFunction1s::value
+(
+ const scalar x,
+ const scalar y
+) const
+{
+ const ProductFilter filter;
+ static const direction otherRank = pTraits::rank - rank;
+ const ProductFunction1s& other = *this;
+
+ if (fs.first().valid())
+ {
+ return filter(fs.first()->value(x)*other.fs.second()->value(y));
+ }
+ else if (fs.second().valid())
+ {
+ return filter(other.fs.first()->value(x)*fs.second()->value(y));
+ }
+ else
+ {
+ return ProductFunction1s::value(x, y);
+ }
+}
+
+
+template
+inline Type Foam::Function2s::ProductFunction1s::value
+(
+ const scalar x,
+ const scalar y
+) const
+{
+ const ProductFilter filter;
+ return filter(fs.first()->value(x)*fs.second()->value(y));
+}
+
+
+template
+inline Type Foam::Function2s::Product::value
+(
+ const scalar x,
+ const scalar y
+) const
+{
+ return fs_.value(x, y);
+}
+
+
+// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
+
+inline Foam::word Foam::Function2s::valueName(const direction argument)
+{
+ return "value" + Foam::name(argument + 1);
+}
+
+
+inline Foam::word Foam::Function2s::valueName
+(
+ const direction argument,
+ const word& typeName
+)
+{
+ return
+ typeName.empty()
+ ? valueName(argument)
+ : valueName(argument) + "<" + typeName + ">";
+}
+
+
+template
+inline Foam::word Foam::Function2s::valueName(const direction argument)
+{
+ return valueName(argument, pTraits::typeName);
+}
+
+
+inline Foam::word Foam::Function2s::valueName
+(
+ const direction argument,
+ const Tuple2& typeAndRank
+)
+{
+ return valueName(argument, typeAndRank.first());
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2.C b/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2.C
new file mode 100644
index 0000000000..0c9677d6ec
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2.C
@@ -0,0 +1,66 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "Radial2.H"
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template
+Foam::Function2s::Radial::Radial
+(
+ const word& name,
+ const dictionary& dict
+)
+:
+ FieldFunction2>(name),
+ value_(Function1::New("value", dict))
+{}
+
+
+template
+Foam::Function2s::Radial::Radial(const Radial& se)
+:
+ FieldFunction2>(se),
+ value_(se.value_, false)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+template
+Foam::Function2s::Radial::~Radial()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+void Foam::Function2s::Radial::write(Ostream& os) const
+{
+ value_->write(os);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2.H b/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2.H
new file mode 100644
index 0000000000..0d6e4d79f2
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2.H
@@ -0,0 +1,134 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+Class
+ Foam::Function2s::Radial
+
+Description
+ Function2 which returns a Function1 of the magnitude of the two-dimensional
+ vector with components equal to the input arguments.
+
+ Example
+ \verbatim
+
+ {
+ type radial;
+ value table
+ (
+ (0.00 (0 0 0))
+ (0.35 (0 0 1))
+ (0.71 (0 0 0))
+ );
+ }
+ \endverbatim
+
+SourceFiles
+ Radial.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Radial2_H
+#define Radial2_H
+
+#include "Function1.H"
+#include "Function2.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Function2s
+{
+
+/*---------------------------------------------------------------------------*\
+ Class Radial Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class Radial
+:
+ public FieldFunction2>
+{
+ // Private Data
+
+ //- Function of the radius
+ autoPtr> value_;
+
+
+public:
+
+ // Runtime type information
+ TypeName("radial");
+
+
+ // Constructors
+
+ //- Construct from name and dictionary
+ Radial
+ (
+ const word& name,
+ const dictionary& dict
+ );
+
+ //- Copy constructor
+ Radial(const Radial& se);
+
+
+ //- Destructor
+ virtual ~Radial();
+
+
+ // Member Functions
+
+ //- Return value
+ virtual inline Type value(const scalar x, const scalar y) const;
+
+ //- Write data to dictionary stream
+ virtual void write(Ostream& os) const;
+
+
+ // Member Operators
+
+ //- Disallow default bitwise assignment
+ void operator=(const Radial&) = delete;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Function2s
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "Radial2I.H"
+
+#ifdef NoRepository
+ #include "Radial2.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2I.H b/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2I.H
new file mode 100644
index 0000000000..3aa96f1f83
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function2/Radial/Radial2I.H
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "Radial2.H"
+#include "vector2D.H"
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+inline Type Foam::Function2s::Radial::value
+(
+ const scalar x,
+ const scalar y
+) const
+{
+ return value_->value(mag(vector2D(x, y)));
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function2/makeFunction2s.H b/src/OpenFOAM/primitives/functions/Function2/makeFunction2s.H
index 74f0bdaaf3..21ac42b188 100644
--- a/src/OpenFOAM/primitives/functions/Function2/makeFunction2s.H
+++ b/src/OpenFOAM/primitives/functions/Function2/makeFunction2s.H
@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
- \\ / A nd | Copyright (C) 2020-2023 OpenFOAM Foundation
+ \\ / A nd | Copyright (C) 2020-2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@@ -37,6 +37,9 @@ Description
#include "ZeroConstant2.H"
#include "OneConstant2.H"
#include "Scale2.H"
+#include "Function12.H"
+#include "Product2.H"
+#include "Radial2.H"
#include "UniformTable2.H"
#include "CodedFunction2.H"
@@ -53,6 +56,9 @@ Description
addFunction2(ZeroConstant, Type); \
addFunction2(OneConstant, Type); \
addFunction2(Scale, Type); \
+ addFunction2(Function12, Type); \
+ addFunction2(Product, Type); \
+ addFunction2(Radial, Type); \
addFunction2(UniformTable, Type); \
addFunction2(Coded, Type); \
}