Temperature Dependent Thermal Properties in LaplacianFoam - openfoam

I'm solving the heat equation using the finite volume method in OpenFOAM and the way it is set up right now is to average the thermal properties of the temperature field. What I want to achieve is to implement the thermal properties that correspond to the temperature of each cell/mesh. Is there a way to do that through the solver itself or in the transportProperties file.
Attached is the code I'm using. I just replaced the source term with the volumetric power that is calculated by another code.
Code:
Info<< "\nCalculating temperature distribution\n" << endl;
while (simple.loop(runTime))
{
Info<< "Time = " << runTime.timeName() << nl << endl;
while (simple.correctNonOrthogonal())
{
solve
(
fvm::ddt(T) - fvm::laplacian(DT, T) == volPower/(RHO * CP)
);
}
#include "write.H"
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
This is the script that reads the thermal properties from the transportProperties file.
Info<< "Reading field T\n" << endl;
volScalarField T
(
IOobject
(
"T",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
volScalarField volPower
(
IOobject
(
"volPower",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading transportProperties\n" << endl;
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
Info<< "Reading diffusivity DT\n" << endl;
dimensionedScalar DT
(
transportProperties.lookup("DT")
);
Info<< "Reading density RHO\n" << endl;
dimensionedScalar RHO
(
transportProperties.lookup("RHO")
);
Info<< "Reading thermal conductivity CP\n" << endl;
dimensionedScalar CP
(
transportProperties.lookup("CP")
This is how the transportProperties file is structured
DT DT [0 2 -1 0 0 0 0] 1.7620248e-5; // Diffusion Coefficent
RHO RHO [1 -3 0 0 0 0 0] 1.52082743e3; // Density
CP CP [0 2 -2 -1 0 0 0] 707.36193; // Heat Capacity
I want DT and CP to be dependant on the temperature of each cell.

If you start from a newer version of laplacianFoam you will see how they have handled this for diffusivity:
Info<< "Reading diffusivity DT\n" << endl;
volScalarField DT
(
IOobject
(
"DT",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar(dimViscosity, Zero)
);
if (!DT.headerOk())
{
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
DT = dimensionedScalar("DT", dimViscosity, transportProperties);
}
With this, the diffusivity (DT) is now a volumetric field, but can also be initialized using a uniform constant value from the transportProperties lookup.
You would need something similar for your other property fields. Of course, you still need to implement some type of material properties, but I guess that is what you already know how to do.

Related

hello, what is my mistake in writing this code? its not displaying the last 3 bullet points properly

Some insurance companies offer discounts on car insurance premiums depending on the number of years the driver has had a driver's licence and the number of claims the driver has made in the last five years.
In this program, the user inputs (as integers)
•years the number of years the driver has had a driver's license
•claims the number of insurance claims made in the last five years
The (integer) percentage of the "standard premium"that will be charged is initially calculated as follows:
•if years< 5 then percentage = 100 –10 * years + 20 * claims
•otherwise ("else") percentage = 50 + 20 * claims
The percentage calculated in this way is then further adjusted as follows:
•if percentage> 150 then insurance is refused
•otherwise,if the percentage is between 100% and 150% then set percentage = 100
•(otherwise,the percentage isn't adjusted)
cout << "enter years licenced: " << endl;
cin >> years;
cout << "enter number of claims: " << endl;
cin >> claims;
if (years < 5)
{
percentage = 100 - (10 * years) + (20 * claims);
cout << "percentage from 0 to 5:" << percentage << endl;
}
else (years > 5);
{
percentage = 50 + (20 * claims);
cout << "percentage higher than 5:" << percentage << endl;
}
if (percentage > 150)
{
cout << "insurance is refused." << percentage << endl;
}
else if (100 <= percentage <= 150)
{
cout << "percentage = 100." << endl;
}
else;
{
cout << "insurance is refused." << endl;
}
return 0;
Replace
else if (100 <= percentage <= 150)
with
else if (100 <= percentage && percentage <= 150)
In C++, chaining of comparison operators works differently than in math. To get the math meaning, don't use chaining, and connect individual comparisons with logical and (&&).
Replace
else (years > 5);
with
else if (years > 5)
The ; is equivalent to {}, thus it makes the else branch empty, and the code below (the multiline {...}) would be executed unconditionally.
Replace
else;
with
else

What is the meaning of using MPI for single server?

I am the novice in the field of distributed-computation and I know the most popular standard is the Message Passing Interface. However, if I only have one server, I can also run my program under the MPI framework as the following demo example.
# include <cmath>
# include <cstdlib>
# include <ctime>
# include <iomanip>
# include <iostream>
# include <mpi.h>
using namespace std;
int main ( int argc, char *argv[] );
double f ( double x );
void timestamp ( );
int main ( int argc, char *argv[] )
{
double end_time;
int i;
int id;
int ierr;
int m;
int p;
double r8_pi = 3.141592653589793238462643;
int process;
double q_global;
double q_local;
int received;
int source;
double start_time;
MPI_Status status;
int tag;
int target;
double x;
double xb[2];
double x_max = 1.0;
double x_min = 0.0;
//
// Establish the MPI environment.
//
ierr = MPI_Init ( &argc, &argv );
if ( ierr != 0 )
{
cout << "\n";
cout << "INTERVALS_MPI - Fatal error!";
cout << " MPI_Init returned ierr = " << ierr << "\n";
exit ( 1 );
}
//
// Determine this processes's rank.
//
ierr = MPI_Comm_rank ( MPI_COMM_WORLD, &id );
//
// Get the number of processes.
//
ierr = MPI_Comm_size ( MPI_COMM_WORLD, &p );
//
// Say hello (once), and shut down right away unless we
// have at least 2 processes available.
//
if ( id == 0 )
{
timestamp ( );
cout << "\n";
cout << "INTERVALS - Master process:\n";
cout << " C++ version\n";
cout << "\n";
cout << " An MPI example program,\n";
cout << " A quadrature over an interval is done by\n";
cout << " assigning subintervals to processes.\n";
cout << "\n";
cout << " The number of processes is " << p << "\n";
start_time = MPI_Wtime ( );
if ( p <= 1 )
{
cout << "\n";
cout << "INTERVALS - Master process:\n";
cout << " Need at least 2 processes!\n";
MPI_Finalize ( );
cout << "\n";
cout << "INTERVALS - Master process:\n";
cout << " Abnormal end of execution.\n";
exit ( 1 );
}
}
cout << "\n";
cout << "Process " << id << ": Active!\n";
//
// Every process could figure out the endpoints of its interval
// on its own. But we want to demonstrate communication. So we
// assume that the assignment of processes to intervals is done
// only by the master process, which then tells each process
// what job it is to do.
//
if ( id == 0 )
{
for ( process = 1; process <= p-1; process++ )
{
xb[0] = ( ( double ) ( p - process ) * x_min
+ ( double ) ( process - 1 ) * x_max )
/ ( double ) ( p - 1 );
xb[1] = ( ( double ) ( p - process - 1 ) * x_min
+ ( double ) ( process ) * x_max )
/ ( double ) ( p - 1 );
target = process;
tag = 1;
ierr = MPI_Send ( xb, 2, MPI_DOUBLE, target, tag, MPI_COMM_WORLD );
}
}
else
{
source = 0;
tag = 1;
ierr = MPI_Recv ( xb, 2, MPI_DOUBLE, source, tag, MPI_COMM_WORLD, &status );
}
//
// Wait here until everyone has gotten their assignment.
//
ierr = MPI_Barrier ( MPI_COMM_WORLD );
if ( id == 0 )
{
cout << "\n";
cout << "INTERVALS - Master process:\n";
cout << " Subintervals have been assigned.\n";
}
//
// Every process needs to be told the number of points to use.
// Since this is the same value for everybody, we use a broadcast.
// Again, we are doing it in this roundabout way to emphasize that
// the choice for M could really be made at runtime, by processor 0,
// and then sent out to the others.
//
m = 100;
source = 0;
ierr = MPI_Bcast ( &m, 1, MPI_INT, source, MPI_COMM_WORLD );
//
// Now, every process EXCEPT 0 computes its estimate of the
// integral over its subinterval, and sends the result back
// to process 0.
//
if ( id != 0 )
{
q_local = 0.0;
for ( i = 1; i <= m; i++ )
{
x = ( ( double ) ( 2 * m - 2 * i + 1 ) * xb[0]
+ ( double ) ( 2 * i - 1 ) * xb[1] )
/ ( double ) ( 2 * m );
q_local = q_local + f ( x );
}
q_local = q_local * ( xb[1] - xb[0] ) / ( double ) ( m );
target = 0;
tag = 2;
ierr = MPI_Send ( &q_local, 1, MPI_DOUBLE, target, tag, MPI_COMM_WORLD );
}
//
// Process 0 expects to receive N-1 partial results.
//
else
{
received = 0;
q_global = 0.0;
while ( received < p - 1 )
{
source = MPI_ANY_SOURCE;
tag = 2;
ierr = MPI_Recv ( &q_local, 1, MPI_DOUBLE, source, tag, MPI_COMM_WORLD,
&status );
q_global = q_global + q_local;
received = received + 1;
}
}
//
// The master process prints the answer.
//
if ( id == 0 )
{
cout << "\n";
cout << "INTERVALS - Master process:\n";
cout << " Estimate for PI is " << q_global << "\n";
cout << " Error is " << q_global - r8_pi << "\n";
end_time = MPI_Wtime ( );
cout << "\n";
cout << " Elapsed wall clock seconds = "
<< end_time - start_time << "\n";
}
//
// Terminate MPI.
//
MPI_Finalize ( );
//
// Terminate.
//
if ( id == 0 )
{
cout << "\n";
cout << "INTERVALS - Master process:\n";
cout << " Normal end of execution.\n";
cout << "\n";
timestamp ( );
}
return 0;
}
//****************************************************************************80
double f ( double x )
{
double value;
value = 4.0 / ( 1.0 + x * x );
return value;
}
//****************************************************************************80
void timestamp ( )
{
# define TIME_SIZE 40
static char time_buffer[TIME_SIZE];
const struct std::tm *tm_ptr;
std::time_t now;
now = std::time ( NULL );
tm_ptr = std::localtime ( &now );
std::strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm_ptr );
std::cout << time_buffer << "\n";
return;
# undef TIME_SIZE
}
Actually, this is the simple case that we use the MPI to compute the integral of specific function. I run this program by using 4 processes. I am confused that we can also use the OpenMP to do the share memory programming instead of MPI to reduce the communication cost. I do not know the meaning of MPI on single machine.

How to visualize descriptors and keypoints from raw pointcloud?

I am trying to extract NARF keypoints and descriptors for raw pointcloud data using pcl::NarfKeypoint , pcl::NarfDescriptor.
In visualization process, I can simply plot my keypoints along with the range image generated from the original ponitcloud.
The problem, however, deals with visualizing descriptors along with keypoints.
As far as I have understood, Narf computes all indices for keypoints and using getVector3fMap(), one can simply visualize them with pcl::visualization.
When it comes to descriptors, the output would be x, y, z, roll, pitch, yaw and more importantly descriptors[36].
Does anyone know how to visualize the descriptors with keypoints in PCL?
Do we really need to utilize those 36 points in descriptors[36] to address this problem?
My sample code:
// --------------------------------
// -----Extract NARF keypoints-----
// --------------------------------
clock_t begin = clock();
pcl::RangeImageBorderExtractor range_image_border_extractor;
pcl::NarfKeypoint narfKp (&range_image_border_extractor);
narfKp.setRangeImage (&range_image);
narfKp.getParameters().support_size = support_size;
narfKp.getParameters().calculate_sparse_interest_image = true;
narfKp.getParameters().use_recursive_scale_reduction = true;
pcl::PointCloud<int> keyPoIdx;
narfKp.compute (keyPoIdx);
cout << "range image = " << range_image << "\n \n";
cout << "keypoint = "<< keyPoIdx <<"\n";
cout << "time to compute NARF keyPoints = " << (float)(clock() - begin) / CLOCKS_PER_SEC << " [sec] \n";
// --------------------------------
// ----Extract NARF descriptors----
// --------------------------------
vector<int> desIdx;
desIdx.resize(keyPoIdx.points.size());
for (unsigned int i = 0; i < desIdx.size(); i++)
{
desIdx[i] = keyPoIdx.points[i];
}
pcl::NarfDescriptor narfDes (&range_image, &desIdx);
narfDes.getParameters().support_size = support_size;
narfDes.getParameters().rotation_invariant = true; // cause more descriptors than keypoints
pcl::PointCloud<pcl::Narf36> outputNarfDes;
narfDes.compute(outputNarfDes);
cout << "Extracted "<< outputNarfDes.size() <<" descriptors for " << keyPoIdx.points.size() << " keypoints.\n";
//------------------------------------------------------------------ //
//-----------------------Visualization-------------------------------//
// ----------------------------------------------------------------- //
// ----------------------------------------------
// -----Show keypoints in range image widget-----
// ----------------------------------------------
//for (size_t i=0; i<keyPoIdx.points.size (); ++i)
//range_image_widget.markPoint (keyPoIdx.points[i]%range_image.width,
//keyPoIdx.points[i]/range_image.width);
// ---------------------------------------
// -----Show Descriptors in 3D viewer-----
// ---------------------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr descriptors_ptr (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>& desVIZ = *descriptors_ptr;
desVIZ.points.resize(outputNarfDes.size());
cout << "descriptor index size = " << desVIZ.points.size() << "\n";
for (size_t i=0; i < desVIZ.points.size(); ++i)
//for (size_t i=0; i<desIdx.size(); ++i)
{
// ??????????????? MY PROBLEM ???????????????????
desVIZ.points[i].getVector3fMap () = range_image.points[outputNarfDes.points[i]].getVector3fMap ();
// ??????????????? MY PROBLEM ???????????????????
}
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> des_color_handler (descriptors_ptr, 200, 0, 50);
viewer.addPointCloud<pcl::PointXYZ> (descriptors_ptr, des_color_handler, "descriptors");
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "descriptors");
// -------------------------------------
// -----Show keypoints in 3D viewer-----
// -------------------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_ptr (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>& keyPo = *keypoints_ptr;
keyPo.points.resize(keyPoIdx.points.size());
for (size_t i=0; i<keyPoIdx.points.size(); ++i)
{
keyPo.points[i].getVector3fMap () = range_image.points[keyPoIdx.points[i]].getVector3fMap ();
}
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color_handler (keypoints_ptr, 0, 200, 0);
viewer.addPointCloud<pcl::PointXYZ> (keypoints_ptr, keypoints_color_handler, "keypoints");
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "keypoints");
//--------------------
// -----Main loop-----
//--------------------
while (!viewer.wasStopped ())
{
range_image_widget.spinOnce (); // process GUI events
viewer.spinOnce ();
pcl_sleep(0.01);
}
You can visualize the roll/pitch/yaw, by converting it to a vector. Refer to this answer for details. This vector can either be used as the normal of each points - that way, for each view, only keypoints sharing the same orientation will have a color. Alternatively you may try to draw arrows in the position of the keypoints.
To visualize the descriptor, you can project it to a three dimensional space using PCA. Than, it can be used to set the color of your keypoints.

ifstream reading multiple data types from same line BAD_ACCESS

I'm trying to read in multiple element types from a text file.
Here's an example input:
push 0
push 1
push 3
push 5
add
push 3
The code below work until the last line, then I get a BAD_ACCESS error after trying anything after it reads in a line without 'b'. Any suggestions?
ifstream infile("example.txt");
while (!infile.eof())
{
infile >> a >> b;
if (a == "push")
push(b);
if (a == "add")
{
add();
}
if (a == "subtract")
{
int y = subtract();
cout << y << endl;
}
if (a == "multiply")
{
int y = multiply();
cout << y << endl;
}
if (a == "divide")
{
int y = divide();
cout << y << endl;
}
if (a == "pop")
{
cout << b;
b = NULL;
}
cout << a << b << endl;
}

Floating point exponentiation without power-function

Currently I have to work in an environment where the power-operator is bugged. Can anyone think of a method temporarily work around this bug and compute a^b (both floating point) without a power function or operator?
if you have sqrt() available:
double sqr( double x ) { return x * x; }
// meaning of 'precision': the returned answer should be base^x, where
// x is in [power-precision/2,power+precision/2]
double mypow( double base, double power, double precision )
{
if ( power < 0 ) return 1 / mypow( base, -power, precision );
if ( power >= 10 ) return sqr( mypow( base, power/2, precision/2 ) );
if ( power >= 1 ) return base * mypow( base, power-1, precision );
if ( precision >= 1 ) return sqrt( base );
return sqrt( mypow( base, power*2, precision*2 ) );
}
double mypow( double base, double power ) { return mypow( base, power, .000001 ); }
test code:
void main()
{
cout.precision( 12 );
cout << mypow( 2.7, 1.23456 ) << endl;
cout << pow ( 2.7, 1.23456 ) << endl;
cout << mypow( 1.001, 1000.7 ) << endl;
cout << pow ( 1.001, 1000.7 ) << endl;
cout << mypow( .3, -10.7 ) << endl;
cout << pow ( .3, -10.7 ) << endl;
cout << mypow( 100000, .00001 ) << endl;
cout << pow ( 100000, .00001 ) << endl;
cout << mypow( 100000, .0000001 ) << endl;
cout << pow ( 100000, .0000001 ) << endl;
}
outputs:
3.40835049344
3.40835206431
2.71882549461
2.71882549383
393371.348073
393371.212573
1.00011529225
1.00011513588
1.00000548981
1.00000115129
You can use the identity ab = e(b log a), then all the calculations are relative to the same base e = 2.71828...
Now you have to implement f(x) = ln(x), and g(x) = e^x. The fast, low precision method would be to use lookup tables for f(x) and g(x). Maybe that's good enough for your purposes. If not, you can use the Taylor series expansions to express ln(x) and e^x in terms
of multiplication and addition.
given that you can use sqrt, this simple recursive algorithm works:
Suppose that we're calculating aˆb. The way the algorithm works is by doing Fast Exponentiation on the exponent until we hit the fractional part, once in the fractional part, do a modified binary search, until we're close enough to the fractional part.
double EPS = 0.0001;
double exponentiation(double base, double exp){
if(exp >= 1){
double temp = exponentiation(base, exp / 2);
return temp * temp;
} else{
double low = 0;
double high = 1.0;
double sqr = sqrt(base);
double acc = sqr;
double mid = high / 2;
while(abs(mid - exp) > EPS){
sqr = sqrt(sqr);
if (mid <= exp) {
low = mid;
acc *= sqr;
} else{
high = mid;
acc *= (1/sqr);
}
mid = (low + high) / 2;
}
return acc;
}
}

Resources