如何使用Runge-Kutta方法(RK4)求解牛顿冷却定律

时间:2019-06-02 05:45:28

标签: java for-loop math runge-kutta

我需要实施我的工作四阶Runge-Kutta方法来解决牛顿冷却定律,需要帮助。由于引入了问题的时间(t),因此我对给定条件的排名感到困惑。给出的结果是:时间间隔从t = 0到t = 20(以秒为单位)开始,对象温度= 300,环境温度= 70,时间增量为.1,比例常数为0.19

public class RungeKutta {

public static double functionXnYn(double x,double  y)
     {
         return y-x;
     }

public static void main(String[] args) {

    double deltaX = (1.005 - 0)/10000;
    double y = 10.0;
    double result = 0.0;  

    for(double x = 1.0; x <= 1.005; x = x + deltaX)
    {
        double k1 = deltaX * functionXnYn(x,y);
        double k2 = deltaX * functionXnYn(x + (deltaX/2.0),y + (k1/2.0));
        double k3 = deltaX * functionXnYn(x + (deltaX/2.0), y + (k2/2.0));
        double k4 = deltaX * functionXnYn(x + deltaX, y + k3);
        y = y + (1.0/6.0) * (k1 + (2.0 * k2) + (2.0 * k3) + k4);
        result = y;
    }       
    System.out.println("The value of y(1.005) is: " + result);

}

}

贝洛是我的RK4解决ODE的方法。在下面的代码中,假设y(1)= 10且delta x = 0.001,我求解ODE y'= y-x近似y(1.005)

[Symfony\Component\Debug\Exception\FatalThrowableError]  
  Call to a member function prepare() on null              


Exception trace:
 () at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Connection.php:326
 Illuminate\Database\Connection->Illuminate\Database\{closure}() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Connection.php:657
 Illuminate\Database\Connection->runQueryCallback() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Connection.php:624
 Illuminate\Database\Connection->run() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Connection.php:333
 Illuminate\Database\Connection->select() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Connection.php:304
 Illuminate\Database\Connection->selectFromWriteConnection() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Schema/Builder.php:75
 Illuminate\Database\Schema\Builder->hasTable() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php:169
 Illuminate\Database\Migrations\DatabaseMigrationRepository->repositoryExists() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Migrations/Migrator.php:583
 Illuminate\Database\Migrations\Migrator->repositoryExists() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Console/Migrations/MigrateCommand.php:91
 Illuminate\Database\Console\Migrations\MigrateCommand->prepareDatabase() at /home/masoud/Codes/TheSite/api/vendor/illuminate/database/Console/Migrations/MigrateCommand.php:63
 Illuminate\Database\Console\Migrations\MigrateCommand->handle() at n/a:n/a
 call_user_func_array() at /home/masoud/Codes/TheSite/api/vendor/illuminate/container/BoundMethod.php:32
 Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() at /home/masoud/Codes/TheSite/api/vendor/illuminate/container/BoundMethod.php:90
 Illuminate\Container\BoundMethod::callBoundMethod() at /home/masoud/Codes/TheSite/api/vendor/illuminate/container/BoundMethod.php:34
 Illuminate\Container\BoundMethod::call() at /home/masoud/Codes/TheSite/api/vendor/illuminate/container/Container.php:576
 Illuminate\Container\Container->call() at /home/masoud/Codes/TheSite/api/vendor/illuminate/console/Command.php:183
 Illuminate\Console\Command->execute() at /home/masoud/Codes/TheSite/api/vendor/symfony/console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at /home/masoud/Codes/TheSite/api/vendor/illuminate/console/Command.php:170
 Illuminate\Console\Command->run() at /home/masoud/Codes/TheSite/api/vendor/symfony/console/Application.php:921
 Symfony\Component\Console\Application->doRunCommand() at /home/masoud/Codes/TheSite/api/vendor/symfony/console/Application.php:273
 Symfony\Component\Console\Application->doRun() at /home/masoud/Codes/TheSite/api/vendor/symfony/console/Application.php:149
 Symfony\Component\Console\Application->run() at /home/masoud/Codes/TheSite/api/vendor/illuminate/console/Application.php:90
 Illuminate\Console\Application->run() at /home/masoud/Codes/TheSite/api/vendor/laravel/lumen-framework/src/Console/Kernel.php:115
 Laravel\Lumen\Console\Kernel->handle() at /home/masoud/Codes/TheSite/api/artisan:35

基于公式T(t)= Ts +(T0-Ts)* e ^(-k * t),对于牛顿DE求解,我应该具有75.1的近似值。 Ts =环境温度,T0 =对象初始温度,t = 20(经过的秒数),k = .19比例常数

1 个答案:

答案 0 :(得分:0)

我猜测(但不是很难)您要解决的ODE是

dT(t)/dt = -k*(T(t)-T_amb)

如您所见,右侧并不直接取决于时间。 当您不尝试为系统编码时,环境温度T_amb可能是一个常数。因此,在常量周围移动并使用一致的函数名称,然后将ODE函数参数返回为格式time, state variable

public class RungeKutta {

    public static double CoolingLaw(double time, double objectTemp)
         {
             double k = 0.19, ambientTemp = 70.0;     
             return -k * (objectTemp - ambientTemp);
         }

    public static void main(String[] args) {

        double result = 0.0;  
        double  objectTemp = 300.0;
        double dt = 0.1

        for(double t = 0.0; t <= 20.0; t += dt)
        {        
            double k1 = dt * CoolingLaw(t, objectTemp);
            double k2 = dt * CoolingLaw(t + (dt/2.0), objectTemp + (k1/2.0));
            double k3 = dt * CoolingLaw(t + (dt/2.0), objectTemp + (k2/2.0));
            double k4 = dt * CoolingLaw(t + dt, objectTemp + k3);
            objectTemp = objectTemp + (1.0/6.0) * (k1 + (2.0 * k2) + (2.0 * k3) + k4);
            result = objectTemp;
        }       
        System.out.println("The approx. object temp after 20 seconds is: " + result);

    }


}