基于STL的油藏数据粗化程序库设计与实现

  • 格式:pdf
  • 大小:166.77 KB
  • 文档页数:4

开发案例 / 基于STL的油藏数据粗化程序库设计与实现 王家华 . 康国庆 (西安石油大学计算机学院,西安710065) 摘要:针对油藏数据粗化的应用,研究了三维数据的数据结构,结合泛型编程与面向对象编 程,并按照STL的容器、算法、迭代器的模式设计了数据粗化程序库,在这个库中可以 使用STL中算法和设施,具有重用性和扩展性。 关键词:数据粗化程序库;标准模板库(STL);容器;算法;内嵌类 

0 引言 数据粗化程序库的设计包括三维数据体和算法 的设计.而前者决定了后者如何来实现.所以三维数 据体设计是重要的 为了适应更新的粗化方法.更好 的应用于粗化数据程序.本文提供了基于标准模板库 模式.设计和实现了数据粗化程序库 

1 库设计的目标 数据粗化库的设计应该有以下几个目标: (1)在地质建模中.地质数据的格式是多种多样 的.由于用于粗化的数据源格式的不同.所以容器要 有适应用户自定义类型的能力.这里采用的是与类型 无关的模板技术来实现 (2)油藏数据粗化的应用不同于一般的应用.粗 化的算法是作用在网格单元相邻的一组模块的.通过 

一定的计算得到一个数值在模型上来取代前面计算 所使用的一组模块(图1)。所以在使用算法之前要将 网格数据体分解成若干小网格数据体.所以要便于按 任意网格数来划分小网格体 

一 图1 2x2x2的体数据粗化成一个数据 (3)算法要求能够便于添加和更改算法,每个算法 都是作用于小网格体的,即算法与容器是低耦合的。 (4)接13设计要人性化,便于使用,扩充,并封装 

内部的结构。另外对速度也提出了一定要求。 2使用标准模板库模式来设计 标准模板库(STL)是一个利用泛型编程思想开发 的模板库 sTL包含计算机科学中的许多基本算法和 数据结构.并且它将算法和数据结构完全分离.互不 耦合。STL库主要由算 ̄(Algorithm),容器(Container) 和迭代器fIterator)构成.算法通过迭代器作用于容 器。用户可以自定义仿函式,仿函式也是使用迭代器 来作用于容器的.另外为了便于与各种情况的接13匹 配,都提供了一些配接器。它们的关系如下图: 

—————————————\ 

 ̄Functors t F仿函t式配接器d tunciorAuap ePs 

—— C ncgate ’ ndc ’。。mp吣cr… 

图2 S’_几结构图 本文安照STL的模式来设计这个数据粗化库. 使得满足我们的设计目标 ●库容器设计部分: 我们采用两套底层容器.一套是用来保存体数据 原始数据,这个容器可以用户自己定义使用何种容器 来保存数据,默认是使用Vector:另一套是用来保存 安装用户设置粗化的小体数据结构.该小体结构里面 

收稿日期:2007-09-14 修稿日期:2007—12—04 作者简介:王家华(1945-),男,教授,研究方向为算法设计、油藏建模、数值模拟 

MODERN COMPUTER 2o07-12 

现 代 计 算 机 ^ 总 

第 二 七 三 期 v 

维普资讯 http://www.cqvip.com 琨 代 计 算 机 ^ 总 

第 二 七 三 期 v 

\、 .: 包含一个Vector容器。这里面存的是粗化的单元数据 (图3)。 

图3保存粗化体数据的容器(2x2x2) 库容器提供了一个可对两套底层容器进行互相转 换的方法.这样可以在运行时自动根据用户设定的粗化 参数来更改用于粗化的单元.例如2x2x2单元转为3× 3x3的单元。这样相应的接口函数就有两套。分别作用 于原始数据上和粗化的单元数据体上(接口加了m前 缀),根据需求对用户公布一些接口,方便用户使用。使 用户可以像使用STL中的容器一样使用该库的容器。 //coame_container.h  ̄mplate<typename T.class, ̄[uence vector<T>> 胴擎器保存类型T。默认底层容器vector class DamVf public: struct mVolum,,内嵌类粗化的数据结构体 f typedef type ̄e std::veetor<T>::iterator_/ter; 

iter beglnO{r ̄mm mv.beginO;l /,返回粗化单元内点的迭代器 

_iter endO{retum mv.endO;l std::vect mv;,,保存上图8个点的容器 l; typedef typerlhame Sequence::value type value_type; 

腚义STL默认规则使用的 

typedd typena/ile DataV::mVolum::_iter_miter;, 

,,迭代器.值类型等 

typedef typena/Ile vector<mVolum>::iterator iterator, 肪便引用 typedef type ̄e Sequence::size_type size_type; 

typedef tyl ̄name DataV::mVolum coaw ̄e_ceH; ,,粗化单元 protected: ,,底层数据容器 Sequence data; /,保存原始数据的容器 

●MODERN COMPUTER 2o 1_l2 

vecto ̄coarse_

cell>moddata; 

,,保存粗化数据体单元的容器 public: ,,完全利用Sequence data的操作。完成DataV的操 作。由于data是STL容器所以支 ,,持的容器操作都可以添加进来 boo1 emptyO c0nst f return data.sizeO-1;l size_type size0 const f return data.sizeo;l 

void push(consl value_type x){ tuJ1ldata.push_back(x);} void pop O{ ̄tum data.pop_backO;l iterator beg.n0f陀t啪moddata.beginO;l ,,返回粗化数据体迭代器 iterator endO{return moddata.endO;l public: ,,自己添加的适合的方法(例) 

DataV(void); template<class In>DataV(hl firsLIn last);,,由【6 t r复制,In为迭代器 

 ̄DataV(void); ,,重载0操作符,安照x,Y,z的坐标来访问任一体元 素原始数据 II&oporatorO(const im x,const int Y,const int z); coarse_

cell&oporator[](const int index); 

,,按索引访问粗化体 

boo1 isNormalO; ,,判断数据是否标准 ,,按参数映射两个容器。原始数据data到moddata.成 功返回true boo1 initVolume(int jump._x,int jump_y,int jump_z); l ●库算法设计部分: 

由于使用STL的设计模式.所以算法设计方面 就比较容易了。可以任意添加功能函数,算法设计和 容器没有必然的关联关系.算法只作用于迭代器.所 以这就和设计一般的sTL算法没有什么区别了。换句 话说,该算法也可以在别的容器中使用,例如Vector。 而且容器还可以使用sTL中的已有的各种设施来和 算法搭配完成工作,可以认为该粗化库是通用库。 //coarse_algorithm.h 

//g数平均一非仿函式法 template<class ForIterator> double althem_equ(ForIterator sourceBeg,ForIterator 

sourceEnd){……l; 如果用户想自己添加算法.也可以用下面的仿函式法 来添加算法 膊数平均一仿函式设计 

维普资讯 http://www.cqvip.com 开发案例 template<class Forlterator,typename T> struct arithmatic—mean:public binary_function<Forltera— tor.Forlterator. I { T operator0(ForIterator Beg,Forlterator End) {..…・} }; 这样设计主要具有四方面优点 ①可以实现容器的空容量启动,无须开设静态 数据区,容器的容量(即可容纳数据的能力)随数据存 取规模而实时胀缩,而且,由于库是按照STL设计,索 引的STL算法、设施都可以无缝的在该库中使用。 ②借助容器类模板的面向对象性质和所提供的 各种方法.可以实现更高级和复杂的结点数据操作.有 利于程序的扩展和复用 ③通过适当运用继承和虚拟多态性技术,派生 出增强功能的新型容器.可以方便地实现各种操作 对用户隐藏了内部实现.用户只需知道添加数据.转 换,然后计算就可以了。做到了用户接口的简洁,容易 和GU1分离开 ④通过泛型编程实现了原有目标,得到了极大的 灵活性.使用内嵌类优化了执行速度.能在线化许多 内存拷贝操作,加速了切分粗化单元的速度。 3应用扩展库来实现粗化 通过使用该粗化库就可以得到粗化后的结果.下 面以double类型为例展示如何使用该库: ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●- Vector<double>v; ,/声明对象容器,用list这样写:DataV<double,list< double>>dl: DataV<double>datav; double d=12.O: datav.push(d); ,/添加数据 ,/也可以这样直接从容器(vector)获得数据 DataV<double>datav2(v.begin0。v.end0); ●●●●●●●●●●●●●● if(datav.initVolume(2,2,2)) //初始化粗化单元 { DataV<double>::iterator it;//使用粗化单元迭代器 for(it=datav.begin0;it!=datav.end0;it++1 { DataV<double>::一miter itmb=it->begin0; ,/粗化单元内迭代器 DataV<double>::miter itme=it->end0; double SS=ahhem_equ(itmb,itme); 

//使用算数平均算法 //或使用下面的仿函式的算数平均算法.这个能 够在线化所以快些 double SS:arlthmatic—mean<DataV::一miter>0