上海交通大学船舶海洋与建筑工程学院谢彬Numerical TESTs for PDEs解答3.2.2

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会导致无法旋转,不知道为什么

 

猜你喜欢

转载自blog.csdn.net/joshua_shi_t/article/details/121426004