adf322Foam.C
/*---------------------------------------------------------------------------*\
Changed from scalarTransportFoam to adv121Foam
Application
adf322Foam
Description
Solves training examples 3.2.2 problem.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "fvOptions.H"
#include "simpleControl.H"
scalar get_xhat(scalar x0, scalar y0, scalar t){
using std::sin;
using std::cos;
scalar xhat = x0*cos(t) - y0*sin(t);
return xhat;
}
scalar get_yhat(scalar x0, scalar y0, scalar t){
using std::sin;
using std::cos;
scalar yhat = y0*cos(t) - x0*sin(t);
return yhat;
}
scalar get_my_r2(scalar x, scalar xhat, scalar y, scalar yhat){
scalar my_r2 = 0;
my_r2 = (x-xhat)*(x-xhat) + (y-yhat)*(y-yhat);
return my_r2;
}
scalar get_phiExt(scalar r2, scalar t){
scalar epsilon = 1e-3;
scalar phiExt = 0;
using Foam::exp;
phiExt = (1/(4*M_PI*epsilon*t)*exp(-(r2/(4*epsilon*t))));
return phiExt;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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;
// Calculate Exact Number
forAll(T_ex,celli)
{
scalar xx = mesh.C()[celli].x();
scalar yy = mesh.C()[celli].y();
scalar my_r21 = get_my_r2(xx, xhat1, yy, yhat1);
scalar phiExt1 = get_phiExt(my_r21, my_t1);
T_ex[celli] = phiExt1;
}
// Error Analysis
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;
using Foam::exp;
using std::sin;
using std::cos;
scalar my_x0 = 0;
scalar my_y0 = 0.5;
scalar my_t0 = M_PI / 2;
scalar my_t1 = my_t0 + 2*M_PI;
scalar xhat0 = get_xhat(my_x0, my_y0, my_t0);
scalar yhat0 = get_yhat(my_x0, my_y0, my_t0);
scalar xhat1 = get_xhat(my_x0, my_y0, my_t1);
scalar yhat1 = get_yhat(my_x0, my_y0, my_t1);
forAll(U,celli)
{
scalar xx = mesh.C()[celli].x();
scalar yy = mesh.C()[celli].y();
U[celli].x() = -yy;
U[celli].y() = xx;
U[celli].z() = 0;
}
U.correctBoundaryConditions();
U.write();
forAll(T,celli)
{
scalar xx = mesh.C()[celli].x();
scalar yy = mesh.C()[celli].y();
scalar my_r20 = get_my_r2(xx, xhat0, yy, yhat0);
scalar phiExt0 = get_phiExt(my_r20, my_t0);
T[celli] = phiExt0;
}
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"
40tr.geo
Point(1) = {-1.0, -1.0, 0, 1e22};
Point(2) = {1.0, -1.0, 0, 1e22};
Point(3) = {1.0, 1.0, 0, 1e22};
Point(4) = {-1.0, 1.0, 0, 1e22};
//+
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
//+
Line Loop(1) = {1, 2, 3, 4};
Plane Surface(1) = {1};
Transfinite Line {3,1} = 41 Using Progression 1;
Transfinite Line {2,4} = 41 Using Progression 1;
Transfinite Surface {1};
// Recombine Surface {1};
Extrude {0, 0, 0.1} {
Surface{1}; Layers{1}; Recombine;
}
Physical Surface("frontAndBack") = {26, 1};
Physical Surface("leftWall") = {25};
Physical Surface("rightWall") = {17};
Physical Surface("upperWall") = {21};
Physical Surface("lowerWall") = {13};
Physical Volume("box") = {1};
/*--------------------------------*- 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 6400;
startFace 4720;
}
lowerWall
{
type cyclic;
physicalType cyclic;
nFaces 40;
startFace 11120;
neighbourPatch upperWall;
}
rightWall
{
type cyclic;
physicalType cyclic;
nFaces 40;
startFace 11160;
neighbourPatch leftWall;
}
upperWall
{
type cyclic;
physicalType cyclic;
nFaces 40;
startFace 11200;
neighbourPatch lowerWall;
}
leftWall
{
type cyclic;
physicalType cyclic;
nFaces 40;
startFace 11240;
neighbourPatch rightWall;
}
)
// ************************************************************************* //
function my_r2 = get_my_r2(x, xhat, y, yhat)
my_r2 = (x-xhat)*(x-xhat) + (y-yhat)*(y-yhat);
end
function phiExt = get_phiExt(r2, t)
epsilon = 0.001;
phiExt = (1/(4*pi*epsilon*t)*exp(-(r2/(4*epsilon*t))));
end
function xhat = get_xhat(x0, y0, t)
xhat = x0*cos(t) - y0*sin(t);
end
function yhat = get_yhat(x0, y0, t)
yhat = y0*cos(t) - x0*sin(t);
end
clearvars; clc; % adf322cr.m
L1_Err40 = 0.379025; L2_Err40 = 0.288677; L3_Err40 = 0.334004;
L1_Err40T = 0.139142; L2_Err40T = 0.117188; L3_Err40T = 0.163116;
L1_Err80 = 0.109069; L2_Err80 = 0.0999403; L3_Err80 = 0.115498;
Delta40 = 40*40; Delta40T = 40*40*2; Delta80 = 80*80; n = 2;
NL14080 = cal_N_func(L1_Err40, L1_Err80, Delta40, Delta80, n);
NL24040 = cal_N_func(L2_Err40, L2_Err80, Delta40, Delta80, n);
NL34040 = cal_N_func(L3_Err40, L3_Err80, Delta40, Delta80, n);
NL1QT40 = cal_N_func(L1_Err40, L1_Err40T, Delta40, Delta40T, n);
NL2QT40 = cal_N_func(L2_Err40, L2_Err40T, Delta40, Delta40T, n);
NL3QT40 = cal_N_func(L3_Err40, L3_Err40T, Delta40, Delta40T, n);
NL1TQ4080 = cal_N_func(L1_Err40T, L1_Err80, Delta40T, Delta80, n);
NL2TQ4080 = cal_N_func(L2_Err40T, L2_Err80, Delta40T, Delta80, n);
NL3TQ4080 = cal_N_func(L3_Err40T, L3_Err80, Delta40T, Delta80, n);
clearvars; clc; % adf322T40plot.m % edit
dataPath = 'D:\SJTU_senior_1st_total\Sundry\grad\hw\hw1\data\3.2.2\'; % (may edit)
targetPath = 'D:\SJTU_senior_1st_total\Sundry\grad\hw\hw1\figs\3.2.2\'; % (may edit)
targetName = 'adf322T40.png'; % edit
targetName = [targetPath, targetName];
tria100nameY025 = '40trX00nu.xlsx'; % edit
tria100nameY025 = [dataPath, tria100nameY025];
tria100matY025 = importdata(tria100nameY025);
yExt = tria100matY025(:,1); xExt = ones(size(yExt,1),1) .* -0.5;% (may edit)
phiExt = zeros(size(xExt,1),1);
for i = 1 : size(phiExt,1)
phiExt(i,1) = cal_adf322phiExt_func(xExt(i,1), yExt(i,1));
end
tria100matexY025 = [yExt, phiExt];
figure(1);
y_llim = -2; y_rlim = 12; x_llim = -0.975; x_rlim = 0.975;% (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.2 40 Tria. Linear. X = - 0.5', 'FontSize', 15); % edit
legend('Numerical','Analytic','Location','NW', 'FontSize', 15);
saveas(gcf, targetName); close all;
3.2.2.linear | ||||||
grids | L1Err | order | L2Err | order | L3Err | order |
40*40 | 0.379025 | 2.891470094 | 0.288677 | 2.60126264 | 0.334004 | 2.067934156 |
40*40*2 | 0.139142 | 1.797051898 | 0.117188 | 1.53031771 | 0.163116 | 1.531997511 |
80*80 | 0.109069 | 0.702633703 | 0.0999403 | 0.45937278 | 0.115498 | 0.996060866 |
旋转了之后,误差增大了10倍左右 | 题目有误,r的表达式错误,缺少根号 | 在createFields里,先写T,后写U会导致无法旋转,不知道为什么 |