【CFD小工坊】尝试完成一个简单的溃坝流算例(2)——get_val系列函数

本文详细介绍了CFD模拟中如何使用get_val系列函数从文本文件input.txt中读取和解析不同类型的参数值,包括get_int_val、get_double_val和get_string_val函数的工作原理及实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【CFD小工坊】尝试完成一个简单的溃坝流算例(2)——get_val系列函数

前言

在上一个博文《尝试完成一个简单的溃坝流算例(1)》中,我们提到了gat_val系列函数。该系列函数的功能是从一个文本文件(.txt)中读入模型所需的参数。
我们浅水模型中涉及参数众多,一般来说我们需要以如下的格式记录这些参数(以下是一个参数文件input.txt的示例):

//**time parameter**
TimeStr = 0.0
TimeEnd = 1.0
CFL = 0.75
DtMin = 0.00001
DtMax = 1.0000
//**Bottom elevation (zb.txt)**
BotType = 0
Bot0 = 0.0
//**Initial condtition**
Initial_Eta = 0
Eta0 = 0.0
Initial_Vel = 0
//**Boundary condition**

//**physical parameters**
Viscosity = 1.0E-6
Manning = 0.03
//**numerical parameter**
DepDry = 1.0E-4
DepWet = 5.0E-4
Theta_fric = 1.0
//**output**
OutStr = 0.0
OurInt = 0.5

gat_val系列函数需要在input.txt中寻找对应的变量名,并读取对应的变量值。

设计思路

一般来说,gat_val系列函数只需一个自变量,即索要读取参数的参数名。例如,get_val(“CFL”)。这个自变量是一个字符串,而返回值是数(可以是整数、浮点数)或者字符串。
执行步骤的设计思路如下:

  1. 打开input.txt文件
  2. 从上至下,以字符串的方式读取每一行的信息,这行的形式为“变量名 = 变量值”
  3. 识别等号"="前的字符串,并判断这个字符串信息是否和自变量信息一致,以确定自变量在的哪一行;
  4. 若该自变量对应这一行,识别并读入等号后面的变量值;若不是,则继续读入下行信息,回到第3步骤;
  5. 关闭input.txt文件。

代码讲解

以下将给出我写的get_val系列函数的代码。

get_int_val函数

/*
* Function: get_int_val(var_)
* Usage: read the values (int) from the file input.txt
*        For example, INI_eta = get_int_val("Initial_Eta")
* Called by: input
*/
int get_int_val(char *var_) {
	char *var_name;
	int num;
	int i, len, flag = 0;

	FILE* fp = fopen("input.txt", "r");
	if (fp == NULL) {
		fprintf(stderr, "Fail to read input files! \n");
		exit(EXIT_FAILURE);
	}
	char* row1 = (char*)malloc(sizeof(char) * N_str);
	char* var_read = (char*)malloc(sizeof(char) * N_str);

	while (fgets(row1, N_str, fp) != NULL) {
		len = strlen(row1);
		if (row1[0] == '/')	continue;
		for (i = 0; i < len; i++) {
			if (row1[i] == '=') break;
			var_read[i] = row1[i];
		}
		var_read[i] = '\0';
		var_read = Trim(var_read);

		if (strcmp(var_read, var_) == 0) {
			sscanf(row1, "%s = %d \n", &var_name, &num);
			flag = 1;
			return num;
		}
	}

	if (flag == 0) {
		fprintf(stderr, "%s cannot be found in input.txt \n", var_);
	}

	free(row1);
	free(var_read);
	fclose(fp);
}

首先,通过fopen函数打开input.txt文件。之后,进入一个while循环(第20行);在每次循环开始时,通过fgets函数读出这一行存储的信息,并存在字符串row1中。
此时,我们需要通过一个for循环来找出这行中等号所在的位置,并把等号前的字符串存储在var_read中(第20~27行)。在给var_read赋值后,我们再通过一个函数Trim来去掉var_read头部、尾部的多余空格(第28行);自定义函数Trim的代码详见下一小节。
判断var_read和自变量var_是否一致(第30行)。如果一致,则通过sscanf函数读如等号后面的数值,赋值到num中。
在整个while循环过程中,我们设置了一个识别符flag,并设置初值为0。如果找到了var_对应的参数值,则赋值flag = 1 (第32行)。如果没有找到var_对应的参数值,则flag = 0,则程序会报错(第37~39行)。
最后使用fclose关闭input.txt文件。

Trim函数

Trim函数也仅有一个自变量,即字符串src。它的功能是去掉src头部和尾部的多余空格,并返回。
代码如下:

/*
* Function: char* Trim(char *src)
* Usage: cut out the extra spaces of src at its beginning and end
* Called by:
*/
char* Trim(char *src)
{
	char *ori_src = src;
	char *begin = src;
	char *end = src + strlen(src);

	if (begin == end)  return ori_src;

	while (*begin == ' ' || *begin == '\t')
		++begin;

	while (*end == '\0' || *end == ' ' || *end == '\t')
		--end;

	if (begin > end) {
		*src = '\0';   return  ori_src;
	}
	while (begin != end) {
		*src++ = *begin++;
	}

	*src++ = *end;
	*src = '\0';

	return ori_src;
}

其余get系列函数

此外,我们的模型中还用了get_double_val(char *var_)和get_string_val(char *var_)。他们的代码均与get_int_val函数的代码类似;唯一的区别是在找到变量var_所在的行后,用于读取、赋值的变量的类型为double或char。
此外,对于get_string_val的代码,一般sscanf(row1, “%s = %d \n”, &var_name, &num)的方式读取参数,而是通过更直接的一种方式:

  1. 将"="号后面的字符串赋值给一个空字符串(如char *res)。
  2. 利用Trim去掉res头部和尾部的多余空格,之后得到的res即所需的参数值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值