摘要:渠道水力计算一直以来在渠道设计中就是一件烦琐的事情,因为其涉及到大量的试算工作,在水利工程灌溉渠系设计中常令人不胜其烦。为化繁为简,减少设计中的工作量,考虑使用计算机技术实现试算工作的程序化。我局正使用delphi编程技术进行管理信息系统(MIS)的开发建设工作,故决定将其纳入MIS系统建设中,成为本局MIS系统的一部分。Delphi技术是美国Inprise公司开发的基于pascal语言的程序开发软件,其不仅在数据库编程方面有卓越表现,而且在数学计算中也成绩斐然。
关键词:水力计算 Delphi 谢才系数 流量模数 业务服务器 客户端
一、 水力计算简介
将渠道内水流视作明渠均匀流这是渠道水力计算的前提,故计算公式采用明渠均匀流公式。主要任务是解决渠道的过水能力问题,即设计渠道的断面尺寸,以保证通过所需的流量,或校核渠道是否满足输水流量的要求等。总体而言,渠道水力计算的问题主要分两类:1、校核渠道过水能力;2、计算渠道的断面尺寸。
校核渠道的过水能力主要指在渠道的断面形式、尺寸、糙率、底坡等都已确定的情况下,计算其过水能力。计算步骤为:先根据水深h,底宽b及边坡系数m计算出过水断面面积ω、湿周χ、水力半径R。再根据糙率n及水力半径R计算(或查表)求出谢才系数C。最后用明渠均匀流公式Q=ωC(Ri)1/2计算出流量。
计算渠道的断面尺寸是渠系工程设计中遇到最多的问题。在规划设计新渠道时,设计流量由工程要求而定,坡度一般是由渠道大小根据地形条件确定,边坡系数m及糙率n,则由土质及渠壁材料与、管理运用等条件而定。也即已知Q、m、n、i,求渠道的水深h及底宽b。此问题有两个未知数b及h,故须经过试算才能确定。计算步骤为:1、根据已知的流量Q及渠道底坡i,求出流量模数k0(标准流量模数);2、初步假定一水深,计算其相应的过水断面ω、湿周χ、水力半径R,并根据糙率n及水力半径R计算或查表求出相应的谢才系数C值。然后,按公式K=ωCR1/2求出相应的流量模数值(设计流量模数);3、将计算出的设计流量模数与标准流量模数比较,若两者相等,则所设水深即为所求。若不等,则可另设一水深,重复上述步骤,直到计算出的设计流量模数与标准流量模数相等为止。然后经综合考虑各方面因素,如施工便利,超高和其他用途后最终确定渠道断面尺寸。
二、delphi技术简介
Delphi是由美国Inprise公司(前Borland公司)推出的可视化编程环境,它提供了一种方便、快捷的Windows应用程序开发工具。Delphi使用了Microsoft Windows图形用户界面的许多先进特性和设计思想,采用了可重复利用的完整的面向对象程序语言(Object-Oriented Language)、当今世界上最快的编辑器、最为领先的数据库技术。Delphi技术的基础源自pascal语言,是对pascal语言编程的可视化、面向对象化发展,从早期的对Turbo Pascal的Windows化到如今对网络化编程拥有强大功能,Delphi已经升级到了如今的第七个版本,功能更加强大,对网络开发的需求更为适应,对数据库开发的技术更为成熟与稳定。
三、程序实现的方法
本程序作为我局管理信息系统(MIS)的一部分外挂于我局管理信息系统的主界面上,属于常用计算模块。我局管理信息系统采用客户端、业务服务器、数据库管理系统(DBMS)三级,客户端和业务服务器采用dephi开发实现,数据库管理系统(DBMS)选择美国Microsoft 公司倍受业界好评的sql server 2000。因此,本程序的数据计算、数据添加和数据删除功能以函数的形式建于业务服务器中,在客户端通过函数调用达到功能的实现。为实现数据的保存与查询,相应地在我局管理信息系统的业务数据库lsdata中建立一个数据库表watercalculationtable。客户端除实现业务服务器相关函数的调用外,还承担程序外观界面设置和部分简单功能的实现。用户只能通过程序客户端实现对的操作。
1、功能设计
本程序设计的主要目的在于实现对渠道水力计算的程序化和智能化,主要功能包括计算、成果显示、数据打印,另外为方便数据输入加入重置功能,为便于数据管理加入删除功能,另外为实现计算界面的退出而加入界面退出功能。
2、界面设计
为实现计算成果的显示功能在界面上添加一个dxdbgrid控件,作为成果显示的载体。为方便数据的录入和计算成果的单条显示添加十五个coastedit控件,为逐一说明各个coastedit控件代表的数据而增入十五个与之对应的label控件,为程序美观用一个groupbox将所有coastedit控件和label控件归为一组。为了实现计算、删除、重置、打印、退出功能,引入五个 button控件其中计算按钮除在单击时触发计算功能外,在计算结束后自动执行数据添加功能,将计算数据添加入数据库中;删除按钮实现对库内单条数据的删除;重置按钮主要对coastedit控件中的数据进行清除,以利于新数据的输入;打印功能作用在于将计算所得的成果通过外接打印机打印出来;退出按钮的功能在于实现界面的退出,返回主界面。
程序界面中渠道名称、试算次序数、渠道底宽、渠道水深、渠道比降、边坡系数、渠道糙率、设计流量等数据可以手动输入,其他数据不能在界面上输入,由程序自动计算,并显示。根据渠道水力计算原理,可输入的数据除设计流量外均不允许为空,此外渠道糙率和渠道比降不能为零,出现上述情况,计算时程序将予以提示。
为实现程序的打印功能,特增加一打印界面,在点击打印按钮时自动弹出,打印界面可以实现打印、打印预览功能,在此界面可以调用windows打印程序。
具体界面设计图样见图1。
(图一)
3、数据库表设计
本程序只有一张库表,即渠道水力计算表(watercalculationtable),经过慎密的数据分析,设计该表共包含十五个字段,分别为:渠道名称、试算次序数、渠道宽度、渠道水深、渠道比降、边坡系数、设计流量、渠道糙率、湿周、标准流量模数、过水断面面积、水力半径、谢才系数、设计断面过水流量、设计流量模数。具体库表设计见表一:
渠道水力计算表(watercalculationtable)
表一
编号 |
中文名 |
字段名 |
数据类型 |
数据长度 |
可否为空 |
备注 |
1 |
渠道名称 |
Ditchname |
Char |
20 |
否 |
主键 |
2 |
试算次序数 |
Calculationno |
Char |
8 |
否 |
|
3 |
渠道底宽 |
Ditchwidth |
Numer |
8 |
否 |
|
4 |
渠道水深 |
ditchheight |
Numer |
8 |
否 |
|
5 |
渠道比降 |
Ditchslope |
Numer |
8 |
否 |
|
6 |
边坡系数 |
Slopenumer |
Numer |
8 |
否 |
|
7 |
设计流量 |
Planvolume |
Numer |
8 |
可 |
|
8 |
渠道糙率 |
Ditchrough |
Numer |
8 |
否 |
|
9 |
湿周 |
Xnumer |
Numer |
12 |
可 |
|
10 |
标准流量模数 |
Kstandard |
Numer |
12 |
可 |
|
11 |
过水断面面积 |
Flowarea |
Numer |
12 |
可 |
|
12 |
水力半径 |
Waterradius |
Numer |
12 |
可 |
|
13 |
谢才系数 |
Cnumer |
Numer |
12 |
可 |
|
14 |
过水流量 |
Designvolume |
Numer |
12 |
可 |
|
15 |
设计流量模数 |
Kdesign |
Numer |
12 |
可 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4、内置代码设计
内置代码主要是针对程序中相关控件触发的事件而设定的相应响应。本程序包含的事件主要有各button控件引发的单击事件、单击dxdbgrid控件引发的事件(dxdbgridclick)、数据集控件滚动事件(ADODataSet1AfterScroll)和程序界面建立时的事件(formcreat)。另外,业务服务器(teoperationserver)中包含的两个函数addwatercalculation和deletewatercalculation也用程序代码建立。
各事件代码分别如下:
1) addwatercalculation函数,代码为:
function TTeOperationServer.addwatercalculation(
const ditchname: WideString; ditchwidth, ditchheight, ditchslope,
slopenumer, ditchrough, planvolume: Currency;
const calculationno: WideString): LongWord;
var
strSql : string;
dwAffected : Integer;
kstandard,flowarea,waterradius,cnumer,designvolume,kdesign,xnumer:currency;
begin
Result := MakeResult(Sev_Error,Facility_Account,Err_Suc);
kstandard:=strtofloat(formatfloat('0.00',(planvolume/sqrt(ditchslope)))); flowarea:=strtofloat(formatfloat('0.00',((ditchwidth+slopenumer*ditchheight)*ditchheight))); xnumer:=strtofloat(formatfloat('0.00',(ditchwidth+2*ditchheight*sqrt(1+sqr(slopenumer)))));
waterradius:=strtofloat(formatfloat('0.000',(flowarea/xnumer))); cnumer:=strtofloat(formatfloat('0.00',(1/ditchrough*power(waterradius,1/6))));
kdesign:=strtofloat(formatfloat('0.00',(flowarea*cnumer*sqrt(waterradius)))); designvolume:=strtofloat(formatfloat('0.00',(flowarea*cnumer*sqrt(waterradius*ditchslope))));
strsql:='insert into watercalculationtable (ditchname,ditchwidth,ditchheight,'
+ ' ditchslope,slopenumer,planvolume,ditchrough,kstandard,'
+ ' flowarea,waterradius,cnumer,designvolume,Kdesign,xnumer,calculationno)'
+ ' values ('+''''+ditchname+''','
+ ' '''+floattostr(ditchwidth)+''','
+ ' '''+floattostr(ditchheight)+''','
+ ' '''+floattostr(ditchslope)+''','
+ ' '''+floattostr(slopenumer)+''','
+ ' '''+floattostr(planvolume)+''','
+ ' '''+floattostr(ditchrough)+''','
+ ' '''+floattostr(kstandard)+''','
+ ' '''+floattostr(flowarea)+''','
+ ' '''+floattostr(waterradius)+''','
+ ' '''+floattostr(cnumer)+''','
+ ' '''+floattostr(designvolume)+''','
+ ' '''+floattostr(kdesign)+''','
+ ' '''+floattostr(xnumer)+''','
+ ' '''+calculationno+''')';
ExecuteSQL(strSql,@dwAffected);
if dwAffected &<= 0 then
begin
Result := MakeResult(SEV_Error,Facility_Account,err_Insert);
exit;
end;
end;
2)deletewatercalculation函数的代码为:
function TTeOperationServer.deletewatercalculation(const ditchname,
calculationno: WideString): LongWord;
var
strSql : string;
dwAffected : Integer;
begin
Result := MakeResult(Sev_Error,Facility_Account,Err_Suc);
StrSql := ' Delete from watercalculationtable '
+ ' where ditchname= ' + '''' + ditchname + ''''
+ ' and calculationno = ' + '''' + calculationno + '''';
ExecuteSQL(strSql,@dwAffected);
if dwAffected &< 0 then
begin
Result := MakeResult(SEV_Error,Facility_Account,err_Delete);
exit;
end;
end;
3)计算按钮(Button1Click)的代码为:
procedure TFormPrice.Button1Click(Sender: TObject);
var
resultcode:hresult;
begin
resultcode:=-1;
if coastedit1.text='' then
begin
application.messagebox('对不起,''渠道名称'' 不能为空.','提示',mb_ok+mb_iconwarning);
coastedit1.setfocus;
exit;
end;
if coastedit2.text='' then
begin
application.messagebox('对不起,''渠道底宽'',不能为空','提示',mb_ok+mb_iconwarning);
coastedit2.SetFocus;
exit;
end;
if coastedit3.text='' then
begin
application.messagebox('对不起,''渠道水深'',不能为空','提示',mb_ok+mb_iconwarning);
coastedit3.SetFocus;
exit;
end;
if coastedit4.text='' then
begin
application.messagebox('对不起,''边坡系数'',不能为空','提示',mb_ok+mb_iconwarning);
coastedit4.SetFocus;
exit;
end;
if coastedit5.text='' then
begin
application.messagebox('对不起,''渠道糙率'',不能为空','提示',mb_ok+mb_iconwarning);
coastedit5.SetFocus;
exit;
end;
if coastedit6.text='' then
begin
application.messagebox('对不起,''渠道比降'',不能为空','提示',mb_ok+mb_iconwarning);
coastedit6.SetFocus;
exit;
end;
if coastedit15.text='' then
begin
application.messagebox('对不起,''试算次序数'',不能为空','提示',mb_ok+mb_iconwarning);
coastedit15.SetFocus;
exit;
end;
if coastedit2.value=0 then
begin
application.messagebox('对不起,''渠道底宽'',不能为零','提示',mb_ok+mb_iconwarning);
coastedit2.SetFocus;
exit;
end;
if coastedit3.value=0 then
begin
application.messagebox('对不起,''渠道水深'',不能为零','提示',mb_ok+mb_iconwarning);
coastedit3.SetFocus;
exit;
end;
if coastedit6.value=0 then
begin
application.messagebox('对不起,''渠道比降'',不能为零','提示',mb_ok+mb_iconwarning);
coastedit6.SetFocus;
exit;
end;
if coastedit5.value=0 then
begin
application.messagebox('对不起,''渠道糙率'',不能为零','提示',mb_ok+mb_iconwarning);
coastedit5.SetFocus;
exit;
end;
try
teoperationserver.begintrans; resultcode:=teoperationserver.Addwatercalculation(coastedit1.text,coastedit2.value,coastedit3.value,coastedit6.value,coastedit4.value,coastedit5.value,coastedit7.value,coastedit15.text);
finally
if HResultCode(ResultCode) = 0 then
begin
teoperationserver.commit;
Refresh;
coastedit1.text:='';
coastedit2.text:='';
coastedit3.text:='';
coastedit4.text:='';
coastedit5.text:='';
coastedit6.text:='';
coastedit7.text:='';
coastedit8.text:='';
coastedit9.text:='';
coastedit10.text:='';
coastedit11.text:='';
coastedit12.text:='';
coastedit13.text:='';
coastedit14.text:='';
coastedit15.text:='';
coastedit1.setfocus;
end
else
begin
teoperationserver.rollback;
application.MessageBox('添加失败','提示',mb_ok+mb_iconwarning);
coastedit1.SetFocus;
end;
end;
end;
4)打印按钮(Button2Click)的代码为:
procedure TFormPrice.Button2Click(Sender: TObject);
var
svdata: string;
Iheader: integer;
IheaderObject: integer;
strsql: string;
Recordset10: _Recordset;
begin
SvDatafile :=GetParentDir(ExtractFilePath(ParamStr(0))) + 'data\watercalculation.txt';
ppReport1.CloseDataPipelines;
if HFile &<&> 0 then FIleCLose(HFile);
if FileExists(svdatafile) then
Deletefile(svdatafile);
hFile := FileCreate(svDatafile);
strSQL := 'select * from lsdata.dbo.watercalculationtable' ;
svdata:= teOperationServer.ResultStrOrder(strSQL);
FileWrite(hFile, Pointer(SvData)^, Length(SvData));
FileClose(HFile);
ppTextPipeline1.FileName := SvDataFile;
ppReport1.DataPipeline := pptextPipeLine1;
//处理表尾
if ppReport1.ObjectByName(iHeader, iHeaderObject, 'ppLabel8') then
TPpLabel(PpReport1.Bands[iheader].Objects[iHeaderObject]).caption := Fmainframeobject.operatorname;
with TfrmReportPreview1.Create(self) do
try
ppViewer1.Report := ppReport1;
ppViewer1.FirstPage;
show;
except
free;
end;
ppReport1.CloseDataPipelines;
fileclose(hfile);
end;
5)重置按钮(Button5Click)的代码为:
procedure TFormPrice.Button5Click(Sender: TObject);
begin
coastedit1.text:='';
coastedit2.text:='';
coastedit3.text:='';
coastedit4.text:='';
coastedit5.text:='';
coastedit6.text:='';
coastedit7.text:='';
coastedit8.text:='';
coastedit9.text:='';
coastedit10.text:='';
coastedit11.text:='';
coastedit12.text:='';
coastedit13.text:='';
coastedit14.text:='';
coastedit15.text:='';
end;
end.
6)删除按钮(Button4Click)的代码为:
procedure TFormPrice.Button4Click(Sender: TObject);
var
resultcode:Hresult;
begin
resultcode:=-1;
if application.MessageBox(' 您确实要删除吗?','删除确认',MB_YesNo+MB_ICONWARNING+MB_DefButton2+MB_SystemModal)=IdNo then
exit;
try
teOperationServer.BeginTrans;
resultcode:=teOperationServer.deletewatercalculation(coastedit1.text,coastedit15.text);
finally
if HResultCode(ResultCode) = 0 then
begin
application.MessageBox('删除成功','提示',MB_OK+MB_ICONWARNING);
teOperationServer.Commit;
Refresh;
coastedit1.text:='';
coastedit2.text:='';
coastedit3.text:='';
coastedit4.text:='';
coastedit5.text:='';
coastedit6.text:='';
coastedit7.text:='';
coastedit8.text:='';
coastedit9.text:='';
coastedit10.text:='';
coastedit11.text:='';
coastedit12.text:='';
coastedit13.text:='';
coastedit14.text:='';
coastedit15.text:='';
end
else
begin
application.MessageBox('删除失败','提示',MB_OK+MB_ICONWARNING);
teOperationServer.RollBack;
end;
end;
end;
7)退出按钮(Button4Click)的代码为:
procedure TFormPrice.Button3Click(Sender: TObject);
begin
close;
end;
8)程序界面创建事件(formcreat)的代码为:
procedure TFormPrice.FormCreate(Sender: TObject);
var
strsql:string;
codestring1: string;
begin
teOperationServer:=getserver('teOperationServer');
Refresh;
coastedit1.text:='';
coastedit2.text:='';
coastedit3.text:='';
coastedit4.text:='';
coastedit5.text:='';
coastedit6.text:='';
coastedit7.text:='';
coastedit8.text:='';
coastedit9.text:='';
coastedit10.text:='';
coastedit11.text:='';
coastedit12.text:='';
coastedit13.text:='';
coastedit14.text:='';
coastedit15.text:='';
end;
9)单击dxdbgrid事件和数据集控件滚动事件的代码(两事件代码基本一样):
begin
if (adodataset1.recordset&<&>nil ) and (adodataset1.recordcount&>0 ) then
begin
CoastEdit1.text:=AdoDataset1.Fields[0].Value;
CoastEdit2.value:=AdoDataset1.Fields[1].Value;
CoastEdit3.value:=AdoDataset1.Fields[2].Value;
CoastEdit4.value:=AdoDataset1.Fields[3].Value;
CoastEdit5.value:=AdoDataset1.Fields[4].Value;
CoastEdit6.value:=AdoDataset1.Fields[5].Value;
CoastEdit7.value:=AdoDataset1.Fields[6].Value;
CoastEdit8.value:=AdoDataset1.Fields[7].Value;
CoastEdit9.value:=AdoDataset1.Fields[8].Value;
CoastEdit10.value:=AdoDataset1.Fields[9].Value;
CoastEdit11.value:=AdoDataset1.Fields[10].Value;
CoastEdit12.value:=AdoDataset1.Fields[11].Value;
CoastEdit13.value:=AdoDataset1.Fields[12].Value;
CoastEdit14.value:=AdoDataset1.Fields[13].Value;
CoastEdit15.text:=AdoDataset1.Fields[14].Value;
end;
10)refresh函数的代码为:
procedure TFormPrice.refresh;
var
strsql:string;
begin
strSQL := ' select * from watercalculationtable' ;
ADODataset1.Recordset:=Vartorecordset(teOperationServer.query(strsql));
end;
转贴于
四、程序最终成果
1)计算成果
点击“计算”按钮,则程序根据输入的已知值自动进行计算,并将计算所得以一条数据的形式,自动添加入数据库,并在dxdbgrid控件中显示出来。具体如图二
(图二)
2)打印成果
点击“打印”按钮,则程序自动弹出打印界面,从此可以预览计算成果,并完成打印功能。打印操作界面见图3。
(图三)
结束语
渠道水力计算作为水利工程中常遇到的问题尽管其计算难度不算高,但由于计算涉及多次试算,因而计算量大,且较为单调烦琐。但由于其计算步骤明确,没有过多的非公式化计算数据,故可以考虑用计算机代替人工手算。作为当前编程工具的一种优秀,delphi系列不仅在数据库开发上具有无以伦比的优越性,在数学计算中也同样具有强大的功能,其计算的精度,比起科学计算中常用的面向程序的开发语言fortran并不逊色。实践证明,水利工作中部分常用的程式化高的计算利用编程的方法将其计算机软件化,对于提高设计工作中的效率是大有裨益的。