Commit 55e5a777 authored by shunbo's avatar shunbo
Browse files

initial commit

parents
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
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-Polynomial
Description
Test application for the templated Polynomial class
\*---------------------------------------------------------------------------*/
#include "Polynomial.H"
#include "FixedList.H"
#include "polynomialFunction.H"
#include "ITstream.H"
#include "OTstream.H"
#include "Random.H"
#include "cpuTime.H"
using namespace Foam;
std::initializer_list<scalar> coeffs
{
0.11, 0.45, -0.94, 1.58, -2.58, 0.08, 3.15, -4.78
};
const FixedList<scalar, 8> coeff(coeffs);
scalar polyValue(const scalar x)
{
// Hard-coded polynomial 8 coeff (7th order)
return
coeff[0]
+ coeff[1]*x
+ coeff[2]*sqr(x)
+ coeff[3]*pow3(x)
+ coeff[4]*pow4(x)
+ coeff[5]*pow5(x)
+ coeff[6]*pow6(x)
+ coeff[7]*x*pow6(x);
}
scalar intPolyValue(const scalar x)
{
// Hard-coded integral form of above polynomial
return
coeff[0]*x
+ coeff[1]/2.0*sqr(x)
+ coeff[2]/3.0*pow3(x)
+ coeff[3]/4.0*pow4(x)
+ coeff[4]/5.0*pow5(x)
+ coeff[5]/6.0*pow6(x)
+ coeff[6]/7.0*x*pow6(x)
+ coeff[7]/8.0*x*x*pow6(x);
}
scalar polyValue1(const scalar x)
{
// Naive evaluation using pow()
scalar value = coeff[0];
for (label i=1; i < coeff.size(); ++i)
{
value += coeff[i]*pow(x, i);
}
return value;
}
scalar polyValue2(const scalar x)
{
// Calculation avoiding pow()
scalar value = coeff[0];
scalar powX = x;
for (label i=1; i < coeff.size(); ++i)
{
value += coeff[i] * powX;
powX *= x;
}
return value;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
constexpr label n = 10000;
constexpr label nIters = 1000;
scalar sum = 0;
Info<< "null poly = " << (Polynomial<8>{}) << nl
<< "null poly = " << (polynomialFunction{8}) << nl
<< endl;
Polynomial<8> poly{coeffs};
Polynomial<9> intPoly{poly.integral(0)};
polynomialFunction polyfunc;
// Could profit from a bi-directional stream
{
OTstream os;
os << poly;
ITstream is("input", std::move(os.tokens()));
is >> polyfunc;
}
Info<< "poly = " << poly << nl
<< "intPoly = " << intPoly << nl
<< endl;
Info<< "2*poly = " << 2*poly << nl
<< "poly+poly = " << poly + poly << nl
<< "3*poly = " << 3*poly << nl
<< "poly+poly+poly = " << poly + poly + poly << nl
<< "3*poly - 2*poly = " << 3*poly - 2*poly << nl
<< endl;
Info<< nl << "--- as polynomialFunction" << nl << endl;
Info<< "polyf = " << polyfunc << nl
<< "intPoly = " << poly.integral(0.0) << nl
<< endl;
Info<< "2*polyf = " << 2*polyfunc << nl
<< "polyf+polyf = " << polyfunc + polyfunc << nl
<< "3*polyf = " << 3*polyfunc << nl
<< "polyf+polyf+polyf = " << polyfunc + polyfunc + polyfunc << nl
<< "3*polyf - 2*polyf = " << 3*polyfunc - 2*polyfunc << nl
<< endl;
Polynomial<8> polyCopy = poly;
Info<< "poly, polyCopy = " << poly << ", " << polyCopy << nl << endl;
polyCopy = 2.5*poly;
Info<< "2.5*poly = " << polyCopy << nl << endl;
Random rnd(123456);
for (label i=0; i<10; ++i)
{
scalar x = rnd.sample01<scalar>()*100;
scalar px = polyValue(x);
scalar ipx = intPolyValue(x);
scalar pxTest = poly.value(x);
scalar ipxTest = intPoly.value(x);
Info<<"\nx = " << x << nl
<< " px, pxTest = " << px << ", " << pxTest << nl
<< " ipx, ipxTest = " << ipx << ", " << ipxTest << nl;
if (mag(px - pxTest) > SMALL)
{
Info<< " *** WARNING: px != pxTest: " << px - pxTest << nl;
}
if (mag(ipx - ipxTest) > SMALL)
{
Info<< " *** WARNING: ipx != ipxTest: " << ipx - ipxTest << nl;
}
Info<< endl;
}
//
// test speed of Polynomial:
//
Info<< "start timing loops" << nl
<< "~~~~~~~~~~~~~~~~~~" << endl;
cpuTime timer;
for (label loop = 0; loop < n; ++loop)
{
sum = 0.0;
for (label iter = 0; iter < nIters; ++iter)
{
sum += poly.value(loop+iter);
}
}
Info<< "value: " << sum
<< " in " << timer.cpuTimeIncrement() << " s\n";
for (label loop = 0; loop < n; ++loop)
{
sum = 0.0;
for (label iter = 0; iter < nIters; ++iter)
{
sum += polyfunc.value(loop+iter);
}
}
Info<< "via function: " << sum
<< " in " << timer.cpuTimeIncrement() << " s\n";
for (label loop = 0; loop < n; ++loop)
{
sum = 0.0;
for (label iter = 0; iter < nIters; ++iter)
{
sum += polyValue(loop+iter);
}
}
Info<< "hard-coded 0: " << sum
<< " in " << timer.cpuTimeIncrement() << " s\n";
for (label loop = 0; loop < n; ++loop)
{
sum = 0.0;
for (label iter = 0; iter < nIters; ++iter)
{
sum += polyValue1(loop+iter);
}
}
Info<< "hard-coded 1: " << sum
<< " in " << timer.cpuTimeIncrement() << " s\n";
for (label loop = 0; loop < n; ++loop)
{
sum = 0.0;
for (label iter = 0; iter < nIters; ++iter)
{
sum += polyValue2(loop+iter);
}
}
Info<< "hard-coded 2: " << sum
<< " in " << timer.cpuTimeIncrement() << " s\n";
Info<< nl << "Done." << endl;
return 0;
}
// ************************************************************************* //
Test-PrecisionAdaptor.C
EXE = $(FOAM_USER_APPBIN)/Test-PrecisionAdaptor
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 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-PrecisionAdaptor
Description
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "primitiveFields.H"
#include "PrecisionAdaptor.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
Field<double> content1(8);
Field<double> content2(8);
forAll(content1, i)
{
content1[i] = 10 * i;
content2[i] = 10 * i;
}
Foam::reverse(content2);
ConstPrecisionAdaptor<float, double, Field> cadaptor1;
cadaptor1.set(content1);
cadaptor1.commit(); // This is a no-op
Info<< "wrapped: " << cadaptor1() << nl;
cadaptor1.set(content2);
Info<< "wrapped: " << cadaptor1() << nl;
Info<< nl;
PrecisionAdaptor<float, double, Field> adaptor2;
adaptor2.set(content1);
adaptor2.ref() *= 2;
adaptor2.commit(); // Propagate changes back to input now
Info<< "modified wrapped: " << adaptor2() << nl;
adaptor2.set(content2);
adaptor2.ref() *= 2;
adaptor2.commit(); // Propagate changes back to input now
Info<< "modified wrapped: " << adaptor2() << nl;
Info<< "source: " << content1 << nl;
Info<< "source: " << content2 << nl;
content2 *= 2;
Info<< nl
<< "set with " << content2 << nl;
Info<< "wrapped was " << adaptor2() << nl;
adaptor2.set(content2);
Info<< "wrapped now " << adaptor2() << nl;
Info<< "source: " << content2 << nl;
// Can even do this
Foam::reverse(adaptor2.ref());
adaptor2.ref() *= 2;
adaptor2.set(content1); // implicit commit
Info<< "updated: " << content2 << nl;
Info<< nl
<< "input: " << content1 << nl;
adaptor2.ref() *= 2;
adaptor2.clear(); // discard
adaptor2.commit();
Info<< "unchanged: " << content1 << nl;
Info<< nl << "Done" << nl << endl;
return 0;
}
// ************************************************************************* //
Test-PtrList.C
EXE = $(FOAM_USER_APPBIN)/Test-PtrList
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-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/>.
Description
Test behaviour of UPtrList, PtrList
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "scalar.H"
#include "IOstreams.H"
#include "PtrDynList.H"
#include "DLPtrList.H"
#include "SLPtrList.H"
#include "plane.H"
#include "DynamicList.H"
#include "PtrListOps.H"
using namespace Foam;
class Scalar
{
scalar data_;
public:
Scalar()
:
data_(0)
{}
Scalar(scalar val)
:
data_(val)
{}
~Scalar()
{
Info<<"delete Scalar: " << data_ << endl;
}
const scalar& value() const
{
return data_;
}
scalar& value()
{
return data_;
}
autoPtr<Scalar> clone() const
{
return autoPtr<Scalar>::New(data_);
}
friend Ostream& operator<<(Ostream& os, const Scalar& val)
{
os << val.data_;
return os;
}
};
// As per
//
// template<class T>
// Ostream& operator<<(Ostream& os, const UPtrList<T>& list)
//
// but handle nullptr
template<class T>
Ostream& printAddr
(
Ostream& os,
const UPtrList<T>& list
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
os << "addr=" << name(list(i)) << nl;
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
// As per
//
// template<class T>
// Ostream& operator<<(Ostream& os, const UPtrList<T>& list)
//
// but handle nullptr
template<class T>
Ostream& print
(
Ostream& os,
const UPtrList<T>& list,
const bool debug=false
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
const T* ptr = list(i);
if (ptr)
{
os << *ptr << nl;
}
else
{
os << "nullptr" << nl;
}
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
template<class T, int SizeMin>
Ostream& print
(
Ostream& os,
const PtrDynList<T, SizeMin>& list,
const bool debug=false
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
const T* ptr = list(i);
if (ptr)
{
os << *ptr << nl;
}
else
{
os << "nullptr" << nl;
}
}
if (debug)
{
const label cap = list.capacity();
for (label i=len; i < cap; ++i)
{
const T* ptr = list(i);
os << "unused " << name(ptr) << nl;
}
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
template<class T>
Ostream& print
(
Ostream& os,
const UList<T*>& list
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
const T* ptr = list[i];
if (ptr)
{
os << *ptr << nl;
}
else
{
os << "nullptr" << nl;
}
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
template<class T>
Ostream& report
(
Ostream& os,
const UPtrList<T>& list,
const bool debug=false
)
{
return print(os, list, debug);
}
template<class T, int SizeMin>
Ostream& report
(
Ostream& os,
const PtrDynList<T,SizeMin>& list,
const bool debug=false
)
{
os << "capacity=" << list.capacity() << nl;
return print(os, list, debug);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
PtrList<Scalar> list1(10);
PtrList<Scalar> list2(15);
PtrList<Scalar> listApp;
{
DLPtrList<Scalar> llist1;
llist1.insert(new Scalar(100));
llist1.insert(new Scalar(200));
llist1.insert(new Scalar(300));
auto citer = llist1.begin();
Info<< *citer << endl;
Info<< typeid(*citer).name() << endl;
++citer;
++citer;
--citer;
Info<< typeid(llist1.begin()).name() << endl;
forAllIters(llist1, it)
{
Info<< typeid(*it).name() << nl
<< "reversed: " << *it << endl;
}
for (const auto& it : llist1)
{
Info<< typeid(it).name() << nl
<< "for-: " << it << endl;
}
}
// Same but as SLPtrList
{
SLPtrList<Scalar> llist1;
llist1.insert(new Scalar(100));
llist1.insert(new Scalar(200));
llist1.insert(new Scalar(300));
for (const auto& it : llist1)
{
Info<< typeid(it).name() << nl
<< "for-: " << it << endl;
}
PtrList<Scalar> list1b(llist1);
Info<< list1b << endl;
}
forAll(list1, i)
{
list1.set(i, new Scalar(1.3*i));
}
Info<<"Emplace set " << list2.size() << " values" << nl;
forAll(list2, i)
{
list2.emplace(i, (10 + 1.3*i));
}
for (label i = 0; i < 5; ++i)
{
listApp.append(new Scalar(1.3*i));
}
listApp.emplace_append(100);
Info<< nl
<<"list1: " << list1 << nl
<<"list2: " << list2 << nl
<<"list-appended: " << listApp << endl;
// Release values
{
DynamicList<Scalar*> ptrs;
forAll(listApp, i)
{
auto old = listApp.release(i);
if (old)
{
ptrs.append(old.release());
}
}
Info<<"Released pointers from";
print(Info, listApp) << nl;
Info<<"Into plain list of pointers";
print(Info, ptrs) << nl;
PtrDynList<Scalar> newlist1(ptrs);
Info<<"Constructed from plain list of pointers";
print(Info, ptrs) << nl;
print(Info, newlist1) << nl;
}
Info<<"indirectly delete some items via set(.., nullptr) :" << endl;
for (label i = 2; i < 5; i++)
{
list1.set(i, nullptr);
}
Info<<"release some items:" << endl;
for (label i = -2; i < 5; i++)
{
auto old = list1.release(i);
if (!old)
{
Info<< i << " was already released" << nl;
}
}
Info<<"list1: ";
print(Info, list1) << nl;
list1.resize(list1.squeezeNull());
Info<<"squeezed null: ";
print(Info, list1) << nl;
Info<<"transfer list2 -> list1:" << endl;
list1.transfer(list2);
Info<<"list1: " << list1 << nl
<<"list2: " << list2 << endl;
Info<<"indirectly delete some items via setSize :" << endl;
list1.setSize(4);
Info<<"list1: " << list1 << endl;
{
PtrList<Scalar> list1a(list1, false);
Info<<"Clone constructed" << endl;
Info<<"in: " << list1 << nl
<<"out: " << list1a << nl
<<"addresses:" << nl;
printAddr(Info, list1);
printAddr(Info, list1a);
Info<<"values:" << nl;
print(Info, list1a);
// This should not cause problems (ie, no deletion)
{
auto* ptr = &(list1a.first());
list1a.set(0, ptr);
Info<<"values:" << nl;
print(Info, list1a);
}
PtrList<Scalar> list1b(list1a, true);
Info<<"Reuse constructed" << endl;
Info<<"in: " << list1a << nl
<<"out: " << list1b << nl
<<"addresses:" << nl;
printAddr(Info, list1a);
printAddr(Info, list1b);
PtrList<Scalar> list1c(list1b.clone());
Info<<"Explicit clone()" << endl;
Info<<"in: " << list1b << nl
<<"out: " << list1c << nl
<<"addresses:" << nl;
printAddr(Info, list1b);
printAddr(Info, list1c);
}
PtrList<Scalar> list3(std::move(list1));
Info<<"Move constructed" << endl;
Info<<"list1: " << list1 << nl
<<"list2: " << list2 << nl
<<"list3: " << list3 << endl;
Info<<"Move construct:" << endl;
PtrList<Scalar> list4(std::move(list3));
Info<<"list3: " << list3 << nl
<<"list4: " << list4 << endl;
Info<<"Move assign:" << endl;
list3 = std::move(list4);
Info<<"list3: " << list3 << nl
<<"list4: " << list4 << endl;
Info<<"UPtrList from PtrList" << nl;
UPtrList<Scalar> ulist1(list3);
Info<<"ulist1: " << ulist1 << nl;
Info<<"PtrList addresses:";
printAddr(Info, list3);
Info<<"UPtrList addresses:";
printAddr(Info, ulist1);
Info<< nl;
{
Info<<"UPtrList(const UPtrList&)" << nl;
const UPtrList<Scalar>& cref = ulist1;
UPtrList<Scalar> ulist1cp(cref);
Info<<"src addresses:";
printAddr(Info, cref);
Info<<"dst addresses:";
printAddr(Info, ulist1cp);
Info<< nl;
}
Info<<"Move construct:" << endl;
UPtrList<Scalar> ulist2(std::move(ulist1));
Info<<"ulist1: " << ulist1 << nl
<<"ulist2: " << ulist2 << nl;
Info<<"Copy assign:" << endl;
ulist1 = ulist2;
Info<<"ulist1: " << ulist1 << nl
<<"ulist2: " << ulist2 << nl;
Info<<"Move assign:" << endl;
ulist1 = std::move(ulist2);
Info<<"ulist1: " << ulist1 << nl
<<"ulist2: " << ulist2 << nl;
// Test iterator random access
{
auto iter1 = ulist1.begin();
auto iter2 = iter1 + 3;
Info<<"begin:" << *iter1 << " (+3):" << *iter2 << nl;
Info<< "diff= " << (iter1 - iter2) << nl;
Info<< "iter[2]=" << iter1[2] << nl;
Info<< "iter1 < iter2 : " << (iter1 < iter2) << nl;
Info<< "iter1 >= iter2 : " << (iter1 >= iter2) << nl;
Info<<"->" << iter1->value() << nl;
Info<<"*" << (*iter1).value() << nl;
Info<<"()" << iter1().value() << nl;
}
PtrList<plane> planes;
planes.emplace_append(vector::one, vector::one);
planes.emplace_append(vector(1,2,3), vector::one);
Info<< nl << "appended values" << nl;
for (const plane& p : planes)
{
Info<< " plane " << p << endl;
}
Info<<"Testing PtrDynList" << nl;
PtrDynList<plane> dynPlanes;
{
dynPlanes.emplace_append(vector::one, vector::one);
dynPlanes.emplace_append(vector(1,2,3), vector::one);
dynPlanes.append(nullptr);
dynPlanes.set(6, new plane(vector(2,2,1), vector::one));
dynPlanes.set(10, new plane(vector(4,5,6), vector::one));
dynPlanes.emplace(12, vector(3,2,1), vector::one);
dynPlanes.emplace_append(Zero, vector::one);
}
Info<< nl << "PtrDynList: ";
report(Info, dynPlanes, true);
dynPlanes.resize(9);
Info<< nl << "resize()";
report(Info, dynPlanes, true);
dynPlanes.clear();
Info<<"clear()" << nl;
report(Info, dynPlanes);
Info<<"now append again" << endl;
{
dynPlanes.append(new plane(vector::one, vector::one));
dynPlanes.append(new plane(vector(1,2,3), vector::one));
dynPlanes.set(5, new plane(vector(2,2,1), vector::one));
}
report(Info, dynPlanes, true);
{
// No clone for plane - do manual copy
PtrList<plane> stdPlanes(dynPlanes.size());
forAll(dynPlanes, i)
{
const plane* pln = dynPlanes.set(i);
if (pln)
{
stdPlanes.set(i, new plane(*pln));
}
}
report(Info, stdPlanes);
printAddr(Info, stdPlanes);
stdPlanes.resize(stdPlanes.squeezeNull());
Info<<"After pruning nullptr entries" << endl;
printAddr(Info, stdPlanes);
}
dynPlanes.resize(dynPlanes.squeezeNull());
Info<<"After pruning nullptr entries" << endl;
report(Info, dynPlanes, true);
{
PtrDynList<plane> dynPlanes2;
dynPlanes2.append(new plane(vector::one, vector::one));
dynPlanes2.append(new plane(vector(1,2,3), vector::one));
dynPlanes2.append(nullptr);
dynPlanes2.set(6, new plane(vector(2,2,1), vector::one));
dynPlanes2.set(10, new plane(Zero, vector::one));
labelList order;
sortedOrder(dynPlanes2, order);
Info<< "sorted order: " << flatOutput(order) << nl;
sortedOrder(dynPlanes2, order, PtrListOps::greater<plane>(dynPlanes2));
Info<< "sorted order: " << flatOutput(order) << nl;
sort(dynPlanes2);
// dynPlanes2.squeezeNull();
Info<<"Append" << endl;
report(Info, dynPlanes2, false);
dynPlanes.append(std::move(dynPlanes2));
Info<<"Result" << endl;
report(Info, dynPlanes, false);
Info<<"From" << endl;
report(Info, dynPlanes2, false);
}
Info<<"free()" << endl;
dynPlanes.free();
report(Info, dynPlanes, true);
Info<< nl << "Done." << endl;
return 0;
}
// ************************************************************************* //
Test-PtrListDictionary.C
EXE = $(FOAM_USER_APPBIN)/Test-PtrListDictionary
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation
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
Description
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "scalar.H"
#include "IOstreams.H"
#include "PtrListDictionary.H"
using namespace Foam;
class Scalar
{
scalar data_;
public:
Scalar()
:
data_(0)
{}
Scalar(scalar val)
:
data_(val)
{}
~Scalar()
{
Info<<"delete Scalar: " << data_ << endl;
}
friend Ostream& operator<<(Ostream& os, const Scalar& val)
{
os << val.data_;
return os;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
PtrListDictionary<Scalar> scalarDict(10);
forAll(scalarDict, i)
{
word key("ent" + name(i));
scalarDict.set(i, key, new Scalar(1.3*i));
}
Info<< nl << "scalarDict1: " << endl;
forAll(scalarDict, i)
{
Info<< "elem " << i << " = " << scalarDict[i] << endl;
}
const Scalar* ent8Ptr = scalarDict.lookup("ent8");
Info<< "ent8 = " << *ent8Ptr << endl;
PtrListDictionary<Scalar> scalarDict2(15);
forAll(scalarDict2, i)
{
word key("ent" + name(i));
scalarDict2.set(i, key, new Scalar(1.3*i));
}
Info<< nl << "scalarDict2: " << endl;
forAll(scalarDict2, i)
{
Info<< "elem " << i << " = " << scalarDict2[i] << endl;
}
scalarDict.transfer(scalarDict2);
const Scalar* p = scalarDict.cfind("ent8");
if (p)
{
Info<< "found: " << *p << endl;
}
else
{
Info<< "no p: " << endl;
}
scalarDict.clear();
Info<< nl << "Done." << endl;
return 0;
}
// ************************************************************************* //
Test-PtrMap.C
EXE = $(FOAM_USER_APPBIN)/Test-PtrMap
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2019 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/>.
Description
\*---------------------------------------------------------------------------*/
#include <iostream>
#include "PtrMap.H"
using namespace Foam;
template<class T>
void printTable(const PtrMap<T>& table)
{
Info<< table.size() << nl << "(" << nl;
forAllConstIters(table, iter)
{
const T* ptr = iter.val();
Info<< iter.key() << " = ";
if (ptr)
{
Info<< *ptr << " (" << name(ptr) << ")";
}
else
{
Info<< "nullptr";
}
Info<< nl;
}
Info<< ")" << endl;
// Values only, with for-range
Info<< "values (";
for (auto val : table)
{
Info<< ' ';
if (val)
{
Info<< *val;
}
else
{
Info<< "nullptr";
}
}
Info<< " )" << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
PtrMap<double> myTable;
myTable.set(1, new double(42.1));
myTable.set(2, nullptr);
myTable.set(3, new double(3.14159));
myTable.set(4, new double(2.718282));
myTable.set(4, new double(1.414214));
// Info<< myTable << endl;
printTable(myTable);
PtrMap<double> copy(myTable);
// Info<< copy << endl;
printTable(copy);
Info<< copy << endl;
Info<<"\nerase some existing and non-existing entries" << nl;
auto iter = myTable.find(3);
myTable.erase(iter);
iter = myTable.find(1000); // unknown key
myTable.erase(iter);
myTable.erase(1);
iter = myTable.find(100000); // unknown key
printTable(myTable);
PtrMap<double> moved(std::move(copy));
Info<< nl << "test movable" << nl;
Info<<"input:" << nl;
printTable(copy);
Info<<"output:" << nl;
printTable(moved);
PtrMap<double> other;
Info<<"move assign" << nl;
other = std::move(moved);
printTable(other);
Info<<"old" << nl;
printTable(moved);
return 0;
}
// ************************************************************************* //
Test-Random.C
EXE = $(FOAM_USER_APPBIN)/Test-Random
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2021 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-Random
Description
Simple test for sequence of random numbers
\*---------------------------------------------------------------------------*/
#include "Random.H"
#include <cstdlib>
#include <iostream>
#include <iomanip>
#ifdef __linux__
#define TEST_POSIX_RAND
#define TEST_RAW_IEEE
#endif
// Construct a positive double with the 48 random bits distributed over
// its fractional part so the resulting FP number is [0.0,1.0).
//
// As per glibc erand48() implementation
#ifdef TEST_RAW_IEEE
#include <ieee754.h>
double randomFraction(const uint64_t bits)
{
// 48-bit value
unsigned short int xsubi[3];
xsubi[0] = (bits & 0xffff);
xsubi[1] = ((bits >> 16) & 0xffff);
xsubi[2] = ((bits >> 32) & 0xffff);
union ieee754_double temp;
temp.ieee.negative = 0;
temp.ieee.exponent = IEEE754_DOUBLE_BIAS;
temp.ieee.mantissa0 = (xsubi[2] << 4) | (xsubi[1] >> 12);
temp.ieee.mantissa1 = ((xsubi[1] & 0xfff) << 20) | (xsubi[0] << 4);
// The lower 4 bits of mantissa1 are always 0.
return temp.d - 1.0;
}
#endif
using namespace Foam;
// Test uniformity of random
void testPosition(const label n)
{
List<label> samples(n, Zero);
Random rnd(123456);
for (label i=0; i < 100000*n; ++i)
{
++samples[rnd.position<label>(0,n-1)];
}
Info<< nl << "uniform [0," << n << ")\n "
<< flatOutput(samples) << nl;
}
// Output with cout instead of Info to retain unsigned values on output
using std::cout;
using std::setw;
#define PutValue(arg) \
cout<< setw(12) << (arg);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
// Allow multiple passes to ensure reset is working properly
const label maxIter = 1;
std::default_random_engine deflt(123456);
std::mt19937 mtwist(123456);
std::uniform_real_distribution<scalar> uniform01;
{
Rand48 rnd(123456);
for (label iter=0; iter < maxIter; ++iter)
{
rnd.seed(123456);
#ifdef TEST_POSIX_RAND
::srand48(123456);
#endif
mtwist.seed(123456);
cout<< nl << "32-bit random with seed = 123456" << nl;
PutValue("Rand48()");
#ifdef TEST_POSIX_RAND
PutValue("lrand48()");
#endif
PutValue("mtwister");
PutValue("default");
cout<< nl;
for (int i=0; i<25; i++)
{
PutValue(rnd());
#ifdef TEST_POSIX_RAND
PutValue(long(::lrand48()));
#endif
PutValue(long(mtwist()));
PutValue(long(deflt()));
cout<< nl;
}
}
}
{
Random rnd(123456);
Rand48 manual(123456);
mtwist.seed(123456);
deflt.seed(123456);
// Two passes to ensure that reset is working properly
for (label iter=0; iter < maxIter; ++iter)
{
#ifdef TEST_POSIX_RAND
::srand48(123456);
#endif
rnd.reset(123456);
manual.seed(123456);
mtwist.seed(123456);
deflt.seed(123456);
cout<< nl << "Random (Rand48) with seed = " << rnd.seed()
<< " interval [0,1000]" << nl;
PutValue("Rand48()");
#ifdef TEST_RAW_IEEE
PutValue("manual");
#endif
PutValue("mtwister");
cout<< nl;
for (int i=0; i<25; i++)
{
PutValue(rnd.sample01<scalar>()*1000);
#ifdef TEST_POSIX_RAND
PutValue(drand48()*1000);
#endif
#ifdef TEST_RAW_IEEE
PutValue(randomFraction(manual.raw())*1000);
#endif
PutValue(uniform01(mtwist)*1000);
PutValue(uniform01(deflt)*1000);
cout<< nl;
}
}
}
{
Rand48 rnd1(123456);
Rand48 rnd2(123456);
#ifdef TEST_POSIX_RAND
::srand48(123456);
#endif
rnd2.discard(10);
cout<< nl << "Rand48 - test with offset of 10" << nl;
PutValue("Rand48()");
PutValue("offset-10");
#ifdef TEST_POSIX_RAND
PutValue("lrand48()");
#endif
cout<< nl;
for (int i=0; i<25; i++)
{
PutValue(rnd1());
PutValue(rnd2());
#ifdef TEST_POSIX_RAND
PutValue(long(::lrand48()));
#endif
cout<< nl;
}
}
// Test uniformity of random
testPosition(20);
testPosition(3);
// Generators
{
const label n = 20;
List<label> samples(n, Zero);
Random::uniformGeneratorOp<label> gen(0, n-1);
// Test uniformity of random
samples = Zero;
for (label i=0; i < 100000*n; ++i)
{
// Calling with/without parameter is the same
if (i % 3)
{
++samples[gen()];
}
else
{
// Unary ignores any parameter
++samples[gen(3.14159)];
}
}
Info<< nl << "Uniform generator [0," << n << ")\n "
<< flatOutput(samples) << nl;
}
{
Random::gaussianGeneratorOp<scalar> gen;
Info<< "Some gaussian generated values" << nl;
for (label i=0; i < 20; ++i)
{
Info<< ' ';
// Calling with/without parameter is the same
if (i % 3)
{
Info<< gen();
}
else
{
// Unary ignores any parameter
Info<< gen(3.14159);
}
}
Info<< nl;
}
// This should fail (in FULLDEBUG)
const bool oldThrowingError = FatalError.throwing(true);
try
{
Info<<"Random position(10,5): "
<< Random().position<label>(10, 5) << endl;
}
catch (const Foam::error& err)
{
Info<< "Caught FatalError " << err << nl << endl;
}
FatalError.throwing(oldThrowingError);
Info<< "\nDone" << nl << endl;
return 0;
}
// ************************************************************************* //
Test-SLList.C
EXE = $(FOAM_USER_APPBIN)/Test-SLList
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 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
Description
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "IOstreams.H"
#include "SLList.H"
#include "List.H"
#include "FlatOutput.H"
#include "ListOps.H"
using namespace Foam;
template<class T>
void printAddress(const UList<T>& list)
{
Info<< "list addr: " << name(&list)
<< " data addr: " << name(list.cdata()) << nl;
}
template<class T>
void printAddresses(const SLList<List<T>>& sll)
{
for (const auto& elem : sll)
{
printAddress(elem);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
SLList<scalar> myList{2.1, 3.4};
myList = {2.1, 3.4, 4.3};
for (int i = 0; i<10; i++)
{
myList.append(1.3*i);
}
myList.append(100.3);
myList.append(500.3);
Info<< "SLList<scalar>" << myList << nl;
Info<< nl << "flat-output: " << flatOutput(myList) << nl;
Info<< nl << "range-for:" << nl;
for (const auto& val : myList)
{
Info<< " " << val << nl;
}
Info<< nl << "const_iterator:" << nl;
const SLList<scalar>& const_myList = myList;
forAllConstIters(const_myList, iter)
{
Info<< " " << *iter << endl;
}
Info<< nl << "Remove elements:" << nl;
forAllIters(myList, iter)
{
Info<< " remove " << *iter;
myList.remove(iter);
Info<< " => " << flatOutput(myList) << nl;
}
for (int i = 0; i<10; i++)
{
myList.append(1.3*i);
}
myList.append(100.3);
myList.append(500.3);
Info<< nl << "Transfer: " << nl;
Info<< "original: " << flatOutput(myList) << endl;
SLList<scalar> newList;
newList.transfer(myList);
Info<< nl
<< "source: " << flatOutput(myList) << nl
<< "target: " << flatOutput(newList) << nl;
Info<< nl << "Move Construct: " << nl;
SLList<scalar> list2(std::move(newList));
Info<< nl
<< "in : " << flatOutput(newList) << nl
<< "out: " << flatOutput(list2) << nl;
// Move back
Info<< nl << "Move Assignment: " << nl;
newList = std::move(list2);
Info<< nl
<< "in : " << flatOutput(newList) << nl
<< "out: " << flatOutput(list2) << nl;
// Try delete data recovery
{
SLList<List<label>> labList;
for (int i = 0; i<5; i++)
{
labList.append(identity(6));
}
Info<< nl
<< "SLList<labelList> : " << labList << nl;
printAddresses(labList);
auto elem = labList.removeHead();
Info<< " removed head" << nl;
printAddress(elem);
elem = labList.removeHead();
Info<< " removed head" << nl;
printAddress(elem);
List<label> content1 = identity(10);
Info<< nl
<< " move append ";
printAddress(content1);
labList.append(std::move(content1));
Info<< " content " << flatOutput(content1) << nl
<< " list" << labList << nl;
printAddresses(labList);
// labList.append(content1);
}
Info<< nl << "Done." << endl;
return 0;
}
// ************************************************************************* //
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment