DHSVM Subdailiy to Daily streamflow

DHSVM模型流域出口的河川径流的格式(3小时为例):

现在要将Subdaily的streamflow转化为daily,我写了一个C的程序来实现,先贴结果.

源代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MaxLine 1024

int main(int argc, char *argv[])

{

FILE *InputFid, *OutputFid;

int TempStrComp, CountForDay;

long offset;

char strline01[MaxLine];

char StartLine[MaxLine];

double TempDischarge, ReadDischarge, MeanDailyDischarge;

char StrDate01[11],TempStrDate[11];

const char  *input_name = “Streamflow.Only”;

const char  *Output_name = “Streamflow_daily.Only”;

char *TempStrDischarge;

if ((InputFid=fopen(input_name,”r”))==NULL){

printf(“Open %s Failed”, input_name);

return;

}

if ((OutputFid=fopen(Output_name,”w+”))==NULL){

printf(“Open %s Failed”, Output_name);

return;

}

/* Write header, DATE OUTLET */

fgets(strline01,MaxLine,InputFid);

fprintf(OutputFid,”%s  %s\n”, “DATE”, “Discharge(m^3/timestep)”);

/* Provide StartLine */[……]

Read more

C 字符串处理

首先我们来看下面的代码。这个代码,目的是想对一行字符串(以#符号开始)的注释前后空白进行去除。如“  this is what I want   #this is the comment”, 我想得到“this is what i want”。

首先我们将字符串地址赋值给StrStart, 然后判断是否空白,如果是,则将地址向后移动一位,以此类推,这样找到了非空白字符地址(注意:这里没有删掉buffer前面的空白);

然后我们找到#所在的位置,然后将地址赋值给StrEnd (注意:这个地址是指向这个字符及其之后字符所组成的字符串首地址),然后将该地址所指的字符串复制为’\0’字符串结束标识。比如上面的例子,StrEnd会指向“#this is the comment”,赋值过后,*StrEnd = “”,即上面的字符变为“   this is what I want   \0this is the comment ”;因为字符串以’\0’为结束标志,因此当我们对Buffer取值时,会得到“   this is what I want   ”。

最后一步,我们去掉字符串后面的空格。完成!

上面用了两种方法定义字符串,第一种是定义字符指针,然后拷贝字符串;第二种是建立字符数组并初始化。这里注意,不能通过char *Buffer= “”来定义可变字符串。如果定义了,后面就不能对其进行修改了。第一种方法和第二种方法是区别的,第一种,我们修改某个元素为’\0’,后面的元素不改变,但是当我取值时,就只取’\0’前面的内容。第二种,我们修改某个元素为’\0’,后面的元素不改变,因为是数组,我们调试的时候,读取到的值是“xxxx \000xxx”,但对其输出时,因为C语言中字符串是以NUL(\000)结尾,所以当读到NUL(\000)时就认为字符串已经结束,后面的内容就被忽略了

但是这里好几个与字符串指针,字符数组的相关的问题我之前搞错了。

(1) 首先我之前给字符串Buffer指针赋值,是这样写的,char * Buffer = “# DHSVM INPUT FILE FORMAT”, 然后程序执行到23行就报错。原因是这样的。 把”abc”赋给一个字符指针变量时,如
char* ptr = “abc”;
因为定义的是一个普通字[……]

Read more

Explict vs Implict FInite Difference Scheme

数值差分方法一般分为显式差分与隐式差分,对二者的区别我查阅了相关的资料。我后面发现关于二者区分不是有一些差异。如Wiki:

Explicit methods calculate the state of a system at a later time from the state of the system at the current time, whileimplicit methods find a solution by solving an equation involving both the current state of the system and the later one. Mathematically, if Y(t) is the current system state and Y(t+.Delta t) is the state at the later time (.Delta t is a small time step), then, for an explicit method

Y(t+.Delta t)=F(Y(t)).,

while for an implicit method one solves an equation

{.displaystyle G{.Big (}Y(t),Y(t+.Delta t){.Big )}=0.qquad (1).,}

to find Y(t+.Delta t).

下面几个链接是其它的一些讨论:

http://earthscience.stackexchange.com/questions/2253/what-are-the-differences-between-implicit-and-explicit-methods-when-applied-to-m

http://www.cfd-online.com/Forums/main/5982-implicit-vs-explicit-method.html

这几个讨论,认为如果下一时刻状态值,能通过当前时刻值进行直接计算,则表示显式差分,如果下一时刻状态值,不能通过当前时刻值进行直接计算,而必须求解(1)式来计算,则表示隐式差分。

这个定义似乎很简单,也容易理解,但现在有一个情况是,式(1)如果是线性的,并且通过式(1),我们能反解出Y(t+dt),使其能够写出显示差分的格式。举一个例子吧,

du/dt = f(u)
where u is a vector and f is a known function. Then[……]

Read more

Qt GUI初探

周末花点时间折腾QT GUI的东西,基本东西掌握得差不多了,现在点总结。

(1)第一步,我们新建一个主窗口,然后添加三个文本框,计算两个数据之和:

在UI deigner中拖入文本框,然后加入两个按钮,我们右键button1,选择->转入槽,关于基本概念,我就不解释了,进入到click事件响应函数里面:

然后,即可实现两个数据之和,并显示在文本3中。这里,为了理解Qt中信号与槽的机制,我做了一个的测试,我首先添加button Connect,然后再click事件响应函数中添加:

connect(this->ui->add,SIGNAL(clicked()),this,SLOT(myslot1()));

其中add即Button1,myslot函数即上面函数中的内容,这样打开界面,先输入前面两个数,然后点击connect,最后点Button1即可。注意,此connet函数不能放在MainWindow的构造函数,否则this->ui->add无效,我现在的理解是,在建立新建窗口时,便首先进入窗口的构造函数,然而此时窗口的组成部分如button,editText并未实例化,所以this->ui->add无效显示NULL;当然这种方法,完全没有必要,有点画蛇添加的意思,主要是为学习。

(2)建立菜单和工具

如上图所示,我们建立三个主菜单和四个工具,建立菜单方法简单,直接在文本框输入菜单名字,并双击即可,点击菜单,可以建立多个Action,如下图所示:

相应地,我们可以拖到Action Editor下面的刚刚建立的Action到工具栏,构成工具,如下图:

(3)为Action建立响应函数

右键上面建立的Action,转入槽,然后进入函数,这里我们编写了一个打开文本文件,并显示到MainWindow上 文本框上,修改文本框内容,点击保存,可以保持到打开的文本文件中,代码如下:

演示:

(4)最后,我们要建立多窗口,并实现数据的传递

首先我们添加Dialog类,方法就是右键项目文件,选择添加新文件,选择QT设计师界面类,如下:

这时候在工程文件中,就会多了三个,dialog1.h和di[……]

Read more