adf321Foam.C
/*---------------------------------------------------------------------------*\
Changed from scalarTransportFoam to adv121Foam
Application
adf321Foam
Description
Solves training examples 3.2.1 problem.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "fvOptions.H"
#include "simpleControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCaseLists.H"
#include "createTime.H"
#include "createMesh.H"
simpleControl simple(mesh);
#include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nCalculating scalar transport\n" << endl;
#include "CourantNo.H"
while (simple.loop(runTime))
{
Info<< "Time = " << runTime.timeName() << nl << endl;
while (simple.correctNonOrthogonal())
{
fvScalarMatrix TEqn
(
fvm::ddt(T)
+ fvm::div(phi, T)
- fvm::laplacian(DT, T)
==
fvOptions(T)
);
TEqn.relax();
fvOptions.constrain(TEqn);
TEqn.solve();
fvOptions.correct(T);
}
runTime.write();
}
// t = runTime.value()
scalar my_t = 1.0;
scalar my_a = 1.0;
volScalarField T_ex(T);
using std::sqrt;
forAll(T_ex,celli)
{
scalar xx = mesh.C()[celli].x();
scalar yy = mesh.C()[celli].y();
T_ex[celli] = exp(-8*M_PI*M_PI*my_mu*my_t)*sin(2*M_PI*(xx+yy-2*my_a*my_t));
}
scalar L1=0;
scalar up = 0;
scalar low =0;
forAll(T,celli)
{
up += mag(T_ex[celli]-T[celli]) * mesh.V()[celli];
low += mag(T_ex[celli])*mesh.V()[celli];
}
L1 = up/low;
Info << "L1 error = " << L1 << endl;
scalar L2 = 0;
up = 0;
low = 0;
forAll(T,celli)
{
up += mag(T_ex[celli]-T[celli])*mag(T_ex[celli]-T[celli])*mesh.V()[celli];
low += T_ex[celli]*T_ex[celli]*mesh.V()[celli];
}
using std::sqrt;
L2 = sqrt(up/low);
Info << "L2 error = " << L2 << endl;
scalar L3 = 0;
scalar up_max = 0;
scalar low_max = 0;
forAll(T,celli)
{
my_tmp = mag(T_ex[celli]-T[celli]);
if (up_max<=my_tmp)
{
up_max = my_tmp;
}
else {}
my_tmp = mag(T_ex[celli]);
if (low_max<=my_tmp)
{
low_max = my_tmp;
}
else {}
}
L3 = up_max / low_max;
Info << "L3 error = " << L3 << endl;
scalar dampRate = 0;
scalar end_max = 0;
forAll(T,celli)
{
my_tmp = mag(T[celli]);
if (end_max<=my_tmp)
{
end_max = my_tmp;
}
else {}
}
dampRate = 1 - end_max / ini_max;
Info << "Damping Rate = " << 100*dampRate << " %"<< endl;
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //
createFields.H
Info<< "Reading field T\n" << endl;
volScalarField T
(
IOobject
(
"T",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
// Info<< "Reading field X\n" << endl;
//
// volVectorField X
// (
// IOobject
// (
// "X",
// runTime.timeName(),
// mesh,
// IOobject::NO_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")
);
using std::sqrt;
// forAll(X,celli)
// {
// scalar xx = mesh.C()[celli].x();
// scalar yy = mesh.C()[celli].y();
// X[celli].x() = xx;
// X[celli].y() = yy;
// X[celli].z() = 0;
// }
using Foam::exp;
using std::sin;
forAll(T,celli)
{
scalar xx = mesh.C()[celli].x();
scalar yy = mesh.C()[celli].y();
T[celli] = sin(2*M_PI*(xx+yy));
}
T.correctBoundaryConditions();
T.write();
scalar my_tmp = 0;
scalar ini_max = 0;
forAll(T,celli)
{
my_tmp = mag(T[celli]);
if (ini_max<=my_tmp)
{
ini_max = my_tmp;
}
else {}
}
scalar my_mu = 0.01;
#include "createPhi.H"
#include "createFvOptions.H"
boundary
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 7
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class polyBoundaryMesh;
location "constant/polyMesh";
object boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
5
(
frontAndBack
{
type empty;
physicalType empty;
nFaces 1600;
startFace 1160;
}
lowerWall
{
type cyclic;
physicalType cyclic;
nFaces 20;
startFace 2760;
neighbourPatch upperWall;
}
rightWall
{
type cyclic;
physicalType cyclic;
nFaces 20;
startFace 2780;
neighbourPatch leftWall;
}
upperWall
{
type cyclic;
physicalType cyclic;
nFaces 20;
startFace 2800;
neighbourPatch lowerWall;
}
leftWall
{
type cyclic;
physicalType cyclic;
nFaces 20;
startFace 2820;
neighbourPatch rightWall;
}
)
// ************************************************************************* //
singleGraph/3.2.2/
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 7
\\/ M anipulation |
-------------------------------------------------------------------------------
Description
Writes graph data for specified fields along a line, specified by start
and end points.
Contour Profiles 2.2.1
\*---------------------------------------------------------------------------*/
/*
// Line: y = 0.25
start (0 0.25 0);
end (1 0.25 0);
fields (T);
*/
/*
// Line: y = 0.75
start (0 0.75 0);
end (1 0.75 0);
fields (T);
*/
/*
// Line: x = 0.25
start (0.25 0 0);
end (0.25 1 0);
fields (T);
*/
// Line: x = -0.5
start (-0.5 -1 0);
end (-0.5 1 0);
fields (T);
// Sampling and I/O settings
#includeEtc "caseDicts/postProcessing/graphs/sampleDict.cfg"
// Override settings here, e.g.
setConfig
{
type lineCell;
axis y; // y, z, xyz
}
/*
setConfig
{
type lineCell;
axis x; // y, z, xyz
}
*/
// Must be last entry
#includeEtc "caseDicts/postProcessing/graphs/graph.cfg"
// ************************************************************************* //
cal_N_func.m
function N = cal_N_func(Err1, Err2, Delta1, Delta2, n)
N = log10(Err1/Err2) / log10( (Delta2/Delta1)^(1/n) );
end
cal_adf321phiExt_func.m
function phiExt = cal_adf321phiExt_func(xExt, yExt, t)
a = 1; mu = 0.01;
phiExt = exp(-8*pi*pi*mu*t)*sin(2*pi*(xExt+yExt-2*a*t));
end
adf321cr.m
clearvars; clc; % adf321cr.m
L1_Err20 = 0.104019; L2_Err20 = 0.102752; L3_Err20 = 0.101908;
L1_Err20T = 0.0172747; L2_Err20T = 0.0173481; L3_Err20T = 0.018802;
L1_Err40 = 0.025572; L2_Err40 = 0.0255393; L3_Err40 = 0.025839;
Delta20 = 20*20; Delta20T = 20*20*2; Delta40 = 40*40; n = 2;
NL12040 = cal_N_func(L1_Err20, L1_Err40, Delta20, Delta40, n);
NL22040 = cal_N_func(L2_Err20, L2_Err40, Delta20, Delta40, n);
NL32040 = cal_N_func(L3_Err20, L3_Err40, Delta20, Delta40, n);
NL1QT20 = cal_N_func(L1_Err20, L1_Err20T, Delta20, Delta20T, n);
NL2QT20 = cal_N_func(L2_Err20, L2_Err20T, Delta20, Delta20T, n);
NL3QT20 = cal_N_func(L3_Err20, L3_Err20T, Delta20, Delta20T, n);
NL1TQ2040 = cal_N_func(L1_Err20T, L1_Err40, Delta20T, Delta40, n);
NL2TQ2040 = cal_N_func(L2_Err20T, L2_Err40, Delta20T, Delta40, n);
NL3TQ2040 = cal_N_func(L3_Err20T, L3_Err40, Delta20T, Delta40, n);
clearvars; clc; % adf321T20plot.m % edit
dataPath = 'D:\SJTU_senior_1st_total\Sundry\grad\hw\hw1\data\3.2.1\';
targetPath = 'D:\SJTU_senior_1st_total\Sundry\grad\hw\hw1\figs\3.2.1\';
targetName = 'adf321T20.png'; % edit
targetName = [targetPath, targetName];
tria100nameY025 = '20trX050nu.xlsx'; % edit
tria100nameY025 = [dataPath, tria100nameY025];
tria100matY025 = importdata(tria100nameY025);
yExt = tria100matY025(:,1); xExt = ones(size(yExt,1),1) .* 0.5; runTime = 1.0; % (may edit)
phiExt = zeros(size(xExt,1),1);
for i = 1 : size(phiExt,1)
phiExt(i,1) = cal_adf321phiExt_func(xExt(i,1), yExt(i,1), runTime);
end
tria100matexY025 = [yExt, phiExt];
figure(1);
y_llim = -0.6; y_rlim = 0.6; x_llim = 0.025; x_rlim = 0.925;% (may edit)
set(gca, 'ylim', [y_llim, y_rlim]); hold on;
set(gca, 'xlim', [x_llim, x_rlim]); hold on;
x_to_plot = tria100matY025(:,1); y_to_plot = tria100matY025(:,2);
size = 20;
scatter(x_to_plot, y_to_plot, size, 'Black', 'c', 'filled');
hold on;
x_to_plot = tria100matexY025(:,1); y_to_plot = tria100matexY025(:,2);
plot(x_to_plot, y_to_plot, 'Black', 'LineWidth', 1);
title('3.2.1 20 Tria. Linear. X = 0.5', 'FontSize', 15); % edit
legend('Numerical','Analytic','Location','NW', 'FontSize', 15);
saveas(gcf, targetName); close all;
3.2.1.linear | 3.2.1的对流-扩散问题,使用三角网格收敛性更好 | 题目有误,扩散率应该取0.01 | |||||||||
grids | L1Err | order | L2Err | order | L3Err | order | |||||
20*20 | 0.104019 | / | 0.102752 | / | 0.101908 | / | |||||
20*20*2 | 0.0172747 | 5.180229024 | 0.0173481 | 5.13263381 | 0.018802 | 4.876618547 | |||||
40*40 | 0.025572 | 2.02421017 | 0.0255393 | 2.00837559 | 0.025839 | 1.979645168 |