4自定义新的本构模型4.1介绍FLAC3D自定义本构模型跟FLAC手册中讲到的用FISH来自定义本构模型一样。然而在FLAC3D中不支撑FISH语言来自定义本构模型,自定义本构模型开发必须用C++语言,且编译成DLL文件(动态链接库),动态链接库文件能在需要的时候随时加载上去。本构模型的主函数主要是返回新的应力,给出应变增量。然而自定义本构模型也必须给出一些其他的信息:比如模型名称和读入、写出保存文件等操作。C++语言是一种面向对象的程序设计语言,使用类(classes)来代表对象(objects)。对象的数据被对象封装起来,在对象的外面数据是不可见的。通过成员函数来访问对象,而成员函数可以对封装的数据进行操作。另外C++语言强烈支持对象的等级结构,新的对象性质可以从一个基本对象产生,基本对象的成员函数可以被派生出来的对象的成员函数替代。这些特点使程序更加模块化。举个例子:主程序需要在程序代码的不同地方建立与派生类的不同变量之间的接口关系,但是这些仅仅只关系到基类,与派生类无关。运行时间系统自动的调用适当的派生类的成员函数。对C++比较好的介绍来自Stevens(1994);它假象读者有一定得编程语言知识,特别是对C语言的了解。在4.2部分将介绍怎么用C++语言开发自定义本构模型。这节主要包括基类、成员函数、本构模型编号、自定义本构模型与FLAC3D之间的传递信息,本构模型状态指示器。在4.3节中将介绍怎样生成DLL本构模型。这一节主要包括自定义本构模型的支持函数,实例本构的源代码,FISH支持的用户自定义本构,和怎样生成和加载一个DLL文件。在这一节中所有的参考文件被包含在“\ITASCA\Models\UDM”文件夹下面的“UDM.ZIP”这个压缩包文件里面。注意:FLAC3D3.0版本是用MicrosoftVisualC++(VC++)7.1版本编译的。用户自定义的DLL文件最好采用与其相当的编译器来编译,以使用户自定义的DLL文件能与FLAC3D兼容。4.2自定义本构的方法4.2.1自定义本构的基类以上介绍的方法是FLAC3D自定义本构支持的方法。基类为从基类派生出来的实际的本构模型提供框架。这个基类叫ConstitutiveModel类,被称为“绝对”的类,因为他声明了许多完全虚有的成员函数(通过=0语法附加到函数原型)。这意味着这个基类不能产生任何对象,以及从这个基类派生出来的任何对象都必须提供真实的成员函数,以替代ConstitutiveModel类中的虚有成员函数。例子4.1,提供了ConstitutiveModel(包含在文件“CONMODEL.H”中)这个类的部分代码,ConstitutiveModel类中的一些成员函数,像公共函数在例子4.1中省略掉了。公有函数的使用(像YoungPoissonFromBulkShear)是不用证明的,有关他们使用的例子可以在提供的本构模型源程序中找到,FLAC3D使用其它的函数来操作和访问本构模型,用户可以毫无理由的使用和重新定义这些。classConstitutiveModel{public:EXPORTConstitutiveModel(unsigneduTypeIn,boolbRegister=false);EXPORTvirtual˜ConstitutiveModel(void);//ROUTINESTHATMUSTBESPECIFIEDBYTHEDERIVEDTYPEvirtualconstchar*Keyword(void)const=0;virtualconstchar*Name(void)const=0;virtualconstchar**Properties(void)const=0;virtualconstchar**States(void)const=0;virtualdoubleGetProperty(unsignedul)const=0;virtualConstitutiveModel*Clone(void)const=0;virtualdoubleConfinedModulus(void)const=0;virtualdoubleShearModulus(void)const=0;virtualdoubleBulkModulus(void)const=0;virtualdoubleSafetyFactor(void)const=0;virtualunsignedVersion(void)const=0;virtualvoidSetProperty(unsignedul,constdouble&d)=0;EXPORTvirtualconstchar*Copy(constConstitutiveModel*cm)=0;virtualconstchar*Initialize(unsigneduDim,State*pst)=0;virtualconstchar*Run(unsigneduDim,State*pst)=0;EXPORTvirtualconstchar*SaveRestore(ModelSaveObject*mso)=0;};4.2.2成员函数任何派生出来的本构模型必须提供真实的成员函数来代替ConstitutiveModel类中的虚拟函数。这些函数的功能在以下描述。constchar*Keyword()表示返回字符数组的指针,这个字符数组包括本构模型的名字,用户在使用MODEL这个命令时需要用到。举个例子:“elastic”在C++中是个有效地字符串。constchar*Name()表示返回字符数组的指针,这个字符数组包括的本构模型名称是用来在输出时使用的(举个例子:PRINTzone这个命令当中可能用到)。它的名字可能和Keyword()这个成员函数的名字相同,也有可能不同,但是要注意FLAC3D在输出的时候会截去长的字符串。举个例子:“Linear/elastic”是个有效地字符串。constchar**Properties(),表示返回字符串数组的指针,这个字符串数组包括模型的材料参数名称,和一个指向这个字符串末尾的空指针。接下来的例子是一个有效地字符串数组:{“shear”,“bulk”,0},给出的材料参数名字将会被PROPERTY命令识别。注意到字符串数据就像上面一样必须以0为结尾。constchar*States()表示返回字符串数组的指针,这个字符串数组表示单元状态名称,以及一个指向字符串末尾的空指针。这个名字用在输出或是显示用户自定义本构模型内部状态(比如塑性流动)。接下来的例子是一个有效的字符串数组:{“yielding”,“tension”,0}。变量mState在4.2.4中介绍。注意到字符串数据就像上面一样必须以0为结尾。SetProperty(unsignedn,constdouble&dVal),变量dVal的值在FLAC3D中以“PROPname=dVal”这个命令赋值。变量n是一个从1开始的序列数,通过调用Properties()这个函数来表示材料参数名称。本构对象需要在他适当的私有内存中存取以上提供的数值。doubleGetProperty(unsignedn)返回本构模型材料参数一个序号n(在Properties()函数中定义的,n=1从第一个材料参数开始)constchar*Copy(constConstitutiveModel*cm),这个成员函数首先调用基类Copy函数,然后通过cm从对象本构中复制所有必须的数据(假定目前的本构模型与其是相同的派生类)。假如发生错误,将返回一个描述错误的字符串,反之返回0。当调用Initialize()这个函数时,就没有必要复制数据重新计算。constchar*Initialize(unsigneduDim,State*ps),当CYCLE这个命令使用时或是大变形模式时,这个函数在每个模型对象中仅仅被调用一次(例如每个单元)。这个对象能够初始化材料参数或是单元状态变量,或是什么都不初始化。求解问题的维数用uDim这个变量来表示。结构体ps(4.2.4)包含本构模型中单元当前的信息。当检测到错误信息时,必须有一个指针指向一个表示错误的字符串,反之就返回0。注意,当调用Initialize()这个函数时,并不给出应变。对整个单元的平均应力分量可以从状态结构体重得到,他们不能被Initialize()这个函数的成员函数调用。constchar*Run(unsigneduDim,State*ps)当FLAC3D对每个单元尽心扫描时,这个函数被调用起来主要是针对自结构(每个单元最多可以划分为10个子结构)。这个模型通过应变增量来更新应力张量。Ps这结构体包括目前的应力分量,并且计算每个子结构的应变增量分量。当这个函数调用时,同时也考虑了由于旋转而产生的应力误差。当发现错误时,应当返回一个表示错误的字符串指针,反之就返回0.doubleConfinedModulus(void)这个对象返回一个值,这个值可以更好的估计最大的受压模量。它应用在FLAC3D计算稳定时间步中,对于一个线性的弹性模型来说,这个受压模量是K+4G/3。doubleShearModulus(void)这个对象返回一值,这个值可以更好的估计当前的正切剪切模量。这个使用在FLAC3D动力本构模型中粘滞静态边界系数。doubleBulkModulus(void)FLAC3D目前还没有使用这个对象,但是这个对象可以很好的返回对当前的正切体积模量的估计。doubleSafetyFactor(void)这个对象目前也还没有使用,它必须返回一些值,像10.0。unsignedVersion(void)这个对象返回本构模型版本号。这个用来处理早期本构模型版本保存的结果文件,而这早期的本构模型可能忽略了一些变量。ConstitutiveModel*Clone(void)创建一个新的对象,必须与当前类相同,返回一个ConstitutiveModel类指针。不管FLAC3D什么时候在一个单元中调用本构,它都被调用。constchar*SaveRestore(ModelSaveObject*mso)当SAVE或是RESTORE命令给出时,这个被函数调用。本构模型必须首先调用基类的SaveRestore()这个函数。SaveRestore()允许本构模型保存或是恢复每个对象的数据。仅仅允许保存整数类型或是浮点数类型,其他的数据类型必须要转换成这两种类型。派生类函数必须首先调用mso-Initialize(nd,ni),这里nd表示双精度存取(或是恢复)数据字节数,ni表示整型存取(或是恢复)数据字节数。变量通过mso-Save(ns,var)这个函数识别,这里ns是变量的序号(从0到nd-1或是从0到ni-1),而这主要取决于实际整型或是浮点型数据存取或恢复的位数,var是需要保存的变量。有单独的Save()去处理整型或是实型变量。这个结构体类ModelSaveObject是不怎么重要的,除了以上提到的函数。它被定义在“CONMODEL.H”这个头文件中。重新定义的类也必须包含构造函数,而这个构造函数调用基类的构造函数。如果这个bRegister变量的值为true,基类的构造函数就被调用,然后派生出来的本构模型就被FLAC3D注册登记过。一个与模型相关的数(uTypeIn)也必须通过;这使得当从一个文件中恢复出来的单元能够重新设置正确的本构模型。一般取一个比较的值来表示这个(比如100或是更大),以避免与从1开始的模型内置变量产生冲突。在其他的所有情况中,派生类构造函数在被调用时,应当不含任何参数,就像Clone这个成员函数一样。通过构造函数可以初始化成员数据,就像例4.2所示。在这个例子中本构模型的特别号是整型变量mnUserMohrModel(具体看例4.5),这些符号“dBulk”、“dShear”等等是派生类的数据成员。Example4.2TypicalmodelconstructorUserMo