void reset()
	{
		next_timestep_output = 0;

		last_timestep_nr_update_diagnostics = -1;

		benchmark_diff_h = 0;
		benchmark_diff_u = 0;
		benchmark_diff_v = 0;

		simVars.reset();

		prog_P.physical_update_lambda_array_indices(
			[&](int i, int j, double &io_data)
			{
				double x = (((double)i+0.5)/(double)simVars.disc.res_physical[0])*simVars.sim.domain_size[0];
				double y = (((double)j+0.5)/(double)simVars.disc.res_physical[1])*simVars.sim.domain_size[1];
				io_data = SWEPlaneBenchmarks::return_h(simVars, x, y);
			}
		);

		prog_u.physical_update_lambda_array_indices(
			[&](int i, int j, double &io_data)
			{
				double x = (((double)i)/(double)simVars.disc.res_physical[0])*simVars.sim.domain_size[0];
				double y = (((double)j+0.5)/(double)simVars.disc.res_physical[1])*simVars.sim.domain_size[1];
				io_data = SWEPlaneBenchmarks::return_u(simVars, x, y);
			}
		);

		prog_v.physical_update_lambda_array_indices(
			[&](int i, int j, double &io_data)
			{
				double x = (((double)i+0.5)/(double)simVars.disc.res_physical[0])*simVars.sim.domain_size[0];
				double y = (((double)j)/(double)simVars.disc.res_physical[1])*simVars.sim.domain_size[1];
				io_data = SWEPlaneBenchmarks::return_v(simVars, x, y);
			}
		);

		beta_plane.physical_update_lambda_array_indices(
			[&](int i, int j, double &io_data)
			{
				double y_beta = (((double)j+0.5)/(double)simVars.disc.res_physical[1]);
				io_data = simVars.sim.f0+simVars.sim.beta*y_beta;
			}
		);


		if (simVars.setup.input_data_filenames.size() > 0)
			prog_P.file_physical_loadData(simVars.setup.input_data_filenames[0].c_str(), simVars.setup.input_data_binary);

		if (simVars.setup.input_data_filenames.size() > 1)
			prog_u.file_physical_loadData(simVars.setup.input_data_filenames[1].c_str(), simVars.setup.input_data_binary);

		if (simVars.setup.input_data_filenames.size() > 2)
			prog_v.file_physical_loadData(simVars.setup.input_data_filenames[2].c_str(), simVars.setup.input_data_binary);


		if (simVars.misc.gui_enabled)
			timestep_output();
	}
Ejemplo n.º 2
0
int main(
		int i_argc,
		char *const i_argv[]
)
{
	const char *bogus_var_names[] = {
			"function-order",
			nullptr
	};

	if (!simVars.setupFromMainParameters(i_argc, i_argv, bogus_var_names))
	{
		std::cout << std::endl;
		std::cout << "Program-specific options:" << std::endl;
		std::cout << "	--function-order [order of function to test]" << std::endl;
		std::cout << std::endl;
		return -1;
	}


	planeDataConfigInstance.setupAuto(simVars.disc.res_physical, simVars.disc.res_spectral);

#if SWEET_GUI
	if (simVars.misc.gui_enabled)
	{
		SimulationTestRK *simulationTestRK = new SimulationTestRK;
		VisSweet<SimulationTestRK> visSweet(simulationTestRK);
		delete simulationTestRK;
		return 0;
	}
#endif

	if (simVars.timecontrol.max_simulation_time == -1)
	{
		std::cerr << "Max. simulation time is unlimited, please specify e.g. -t 6" << std::endl;
		return -1;
	}

	if (!std::isinf(simVars.bogus.var[0]))
		time_test_function_order = simVars.bogus.var[0];

	for (int fun_order = 0; fun_order <= 4; fun_order++)
	{
		time_test_function_order = fun_order;

		for (int ts_order = 1; ts_order <= 4; ts_order++)
		{
			timestepping_runge_kutta_order = ts_order;

			/*
			 * iterate over resolutions, starting by res[0] given e.g. by program parameter -n
			 */
			simVars.reset();

			SimulationTestRK *simulationTestRK = new SimulationTestRK;

			while(true)
			{
				if (simVars.misc.verbosity > 2)
					std::cout << simVars.timecontrol.current_simulation_time << ": " << simulationTestRK->prog_h.physical_get(0,0) << std::endl;

				simulationTestRK->run_timestep();

				if (simulationTestRK->instability_detected())
				{
					std::cout << "INSTABILITY DETECTED" << std::endl;
					break;
				}

				if (simVars.timecontrol.max_simulation_time < simVars.timecontrol.current_simulation_time)
				{
					PlaneData benchmark_h(planeDataConfig);

					benchmark_h.physical_set_all(simulationTestRK->test_function(time_test_function_order, simVars.timecontrol.current_simulation_time));

					double error = (simulationTestRK->prog_h-benchmark_h).reduce_rms_quad();
					std::cout << "with function order " << fun_order << " with RK timestepping " << ts_order << " resulted in RMS error " << error << std::endl;

					if (fun_order <= ts_order)
					{
						if (error > 0.0000001)
						{
							std::cout << "ERROR threshold exceeded!" << std::endl;
							return 1;
						}
					}
					else
					{
						if (error < 0.0000001)
						{
							std::cout << "ERROR threshold is expected to be larger, can still be valid!" << std::endl;
							return 1;
						}
					}
					std::cout << "OK" << std::endl;

					break;
				}
			}

			delete simulationTestRK;
		}
	}


	return 0;
}