296535043

A Framework for Developing Finite Element Codes for Multi-Disciplinary Applications
为多学科应用开发有限元代码的框架

Pooyan Dadvand翻译: Jiaqi-2021-8-10

Abstract

近年来,计算模拟的世界经历了巨大的进步,需要更多的多学科挑战来满足即将到来的新需求。解决多学科问题的重要性不断增加,这使得开发人员更加关注这些问题,并处理好在这一领域开发软件所涉及的困难。

传统的有限元代码在处理多学科问题时有一些困难。许多这些代码是为解决某种类型的问题而设计和实施的,通常涉及单一领域。将这些代码扩展到处理另一个领域的分析,通常包括几个问题和大量的修改和实现。一些典型的困难是:每个节点预定义的自由度集,具有固定定义变量集的数据结构,所有实体的全局变量列表,基于领域的接口,读取新数据和写入新结果的IO限制以及代码内的算法定义。一个常见的方法是通过一个主程序连接不同的求解器,该程序实现了交互算法,也将数据从一个求解器转移到另一个求解器。这种方法在实践中得到了成功的应用,但其结果是重复的实施和多余的数据存储和传输的开销,这可能会对求解器的数据结构产生重大影响。

这项工作的目的是设计和实现一个框架来建立多学科的有限元程序。通用性、可重用性、可扩展性、良好的性能和内存效率被认为是设计和实现该框架的要点。为团队开发准备结构是另一个目标,因为通常不同领域的专家团队会参与多学科代码的开发。

Kratos ,在这项工作中创建的框架提供了几个工具,以方便实现有限元的应用,也为其应用的不同方式的自然互动提供了一个共同平台。这不仅是通过一些创新来实现的,也是通过收集和重用几个现有的作品来实现的。

在这项工作中,设计并实现了一个创新的变量基础接口,它被用于不同的抽象层次,并显示出非常清晰和可扩展。另一个创新是一个非常有效和灵活的数据结构,它可以用来以类型安全的方式存储任何类型的数据。一个可扩展的IO也被创建,以克服处理多学科问题的另一个瓶颈。收集现有工作的不同概念并使其适应耦合问题被认为是这项工作的另一个创新。例如,使用解释器、不同的数据组织和每个节点的可变自由度数量。内核和应用的方法被用来减少不同领域的开发者之间可能产生的冲突,层的设计反映了不同开发者的工作空间,也考虑了他们的编程知识。最后,为了提高Kratos的性能和效率,应用了一些技术细节,这使得它可以实际使用。

这项工作通过在实践中演示该框架的功能而完成。 首先,实现了一些经典的单一领域的应用,如热、流体和结构应用,并作为基准来证明其性能。这些应用被用来解决耦合问题,以展示该框架提供的自然交互设施。最后实现了一些不太经典的耦合有限元算法,以显示其高度的灵活性和可扩展性。

1. Introduction

汽车、航空航天和建筑部门传统上使用仿真程序来改进他们的产品或服务,将计算集中在几个主要的物理过程:流体动力学、结构、金属成型等。然而,对更安全、更便宜和更有效的产品的新需求,以及计算设施的惊人增长,要求对多学科问题有一个同等的解决方案。此外,在食品、化学和电磁工业等领域的新应用,如果没有多学科的方法,根本就没有用。
一些说明性的案例可以在风帆和帆船的设计中找到,在这些设计中必须考虑到结构和流体动力学计算、消毒过程(热和流体动力学分析)、强磁设计(结构、热和磁分析)或光伏电池(热和电计算)等等。
解决多学科问题的重要性日益增加,使得开发人员更加关注这些问题,并处理在该领域开发软件所涉及的困难。

1.1. Motivation

近年来,计算模拟的世界经历了巨大的进步,需要更多的多学科挑战来满足新的需求。
由于不同领域的单用途代码在工业上的成熟,生产部门已经提高了期望值,因为他们意识到需要以更现实的方式解决他们处理的问题,以保持竞争力。强烈的简化是过去困难问题得以解决的原因。这些简化导致的模型与真实的模型有很大的不同,就像所做的假设的严重程度一样。如果我们在一个并发的世界中增加每一个所需的精度,那么我们就需要放松假设,在解决多学科问题的方式上变得更加普遍。
这种情况其实并不新鲜。新颖的是解决多学科问题的需要,结合来自不同领域的大部分信息,获得更精确的信息,从而获得更好的优化方法。这意味着要解决更复杂的问题。有许多策略来解决这类问题。一个简单的方法是假设现有的分析方法是好的,人们应该在现有的代码之间建立接口,以解决多学科的问题。不幸的是,这种策略对于高度耦合问题的单体解决方案来说根本不起作用,而且由于数据格式转换和重复数据产生的内存开销,通常会有执行时间的开销。这些缺点也正是为创建一个多学科编程框架提供了强大的动力,该框架将允许以一种更自然和灵活的方式处理这类问题。
此外,它还计划在多学科解决方案中整合另一个有趣的主题,如优化。用于解决工业优化问题的大量研究工作构成了提供一个负担得起的库作为优化程序的数字引擎的强大动力。

1.2. Problem

如今有限元方法的相关主题之一是将不同的分析(热、流体动力学、结构)与优化方法结合起来,并在一个全局软件包中进行自适应网格划分,只需一个用户界面,并有可能将实现的解决方案扩展到新的问题类型,作为一种多学科仿真环境的方法。
传统的有限元代码在处理涉及两个或多个不同领域(即流体-结构、热-机械、热-流体等)的耦合解决方案的多学科问题时遇到了一些困难。许多这些代码是为解决某种类型的问题而设计和实施的,通常涉及单一领域。例如,只解决结构、流体或电磁问题。将这些代码扩展到处理另一个领域的分析,通常需要大量的修改。
一个常见的方法是通过一个主程序连接不同的求解器,该程序实现了交互算法,也将数据从一个求解器传输到另一个求解器。这种方法在实践中已被成功使用,但也有其自身的问题。 首先,所有的完全独立的程序导致许多重复的实现,这在代码维护方面造成了额外的成本。在许多情况下,不同求解器之间的数据传输不是微不足道的,而且根据每个程序的数据结构,可能会造成将数据从一个数据结构复制到另一个数据结构的冗余开销。最后,这种方法只能用于主从耦合,不能用于单体耦合方案。
一些较新的实现方法在设计中使用了现代软件工程的概念,以使程序更具可扩展性。他们通常在程序中实现了对新算法的可扩展性,但将其扩展到新的领域则超出了他们的本意。
使用面向对象的范式有助于提高代码的可重复使用性。这被认为是简化解决新类型问题的模块实施的一个关键点。不幸的是,在他们的设计中,许多特定领域的概念限制了他们对其他模块的重用性。
现有的处理多学科问题的代码的典型瓶颈是。
  • 预先定义的每个节点的自由度集合。
  • 具有固定定义变量集的数据结构。
  • 所有实体的全局变量链表。
  • 基于接口的Domain定义。
  • IO读取新数据和写入新结果时的限制。
  • 代码内部的算法定义。
这些缺点需要对代码进行大量的重写,以便将其扩展到新的领域。许多程序对每个节点的自由度有一个预定义的集合。例如,在一个三维结构程序中,每个节点有六个自由度 ,其中 是节点位移, 是节点旋转。假设所有的节点都只有这一组自由度,有助于开发者优化他们的代码,也简化了他们的实施任务。但是这个假设阻碍了将代码扩展到每个节点具有不同自由度集合的其他领域。
通常情况下,程序的数据结构被设计为持有某些变量和历史值。这种设计的主要原因是:更容易实现,数据结构的性能更好,维护起来更省力。尽管有这些优点,使用刚性的数据结构通常需要进行重要的修改,以容纳来自其他领域的新变量。
当程序的数据结构被设计为为所有实体保存相同的数据集时,就会出现另一个问题。在这种情况下,向数据结构中添加一个节点变量意味着向模型中的所有节点添加这个变量。在这种实现中,在数据结构中添加一个域的变量会导致在另一个域中为其分配多余的空间。例如在一个流体与结构的相互作用问题中,这种设计导致每个结构节点都有压力值,所有流体节点都有位移值存储在内存中。尽管这不是一个限制,但它严重影响了程序的内存效率。
此外,在单用途程序中,为了提高代码的清晰度,通常会创建特定领域的接口。例如,为元素的属性提供一个Conductivity方法来获取元素的电导率,如下所示。
c = properties.Conductivity ()
虽然这提高了代码的清晰度,但它与对新领域的扩展性完全不相容。
IO是扩展程序到新字段的另一个瓶颈。每个字段都有其数据和结果集,简单的IO通常无法处理新的数据集。这可能会造成巨大的实施和维护成本,这些成本来自于为每个新问题的解决而更新IO。
最后在现有代码中引入新的算法需要内部实现。这导致封闭的程序是不可扩展的,因为无法访问其源代码。对于开放源码程序,这需要外部开发者了解代码的内部结构。

1.3. Objectives

这项工作的目的是设计和实现一个框架,用于构建多学科的有限元程序。这个框架被称为Kratos,将有助于建立各种各样的有限元程序,从最简单的公式,例如热传导问题,到最复杂的,如多学科的优化技术。从一方面来说,它将提供一集完整的灵活的工具来快速实现实验性的学术算法,从另一方面来说,它必须是快速有效的,以用于真正的工业分析。
通用性是我们设计的第一个目标。如果一个框架的通用性足以适应各种各样的有限元算法,它就可以被使用。当涉及到多学科分析时,通用性变得更加重要,代码结构必须支持不同领域的各种算法。
可重用性是这个设计的另一个目标。有限元方法有几个步骤在不同的算法之间是相似的,即使是对不同类型的问题。一个好的设计和实现可以使所有这些步骤在所有的算法中都可以重复使用。这就减少了实施工作和代码的维护成本。
另一个目标是为 Kratos 提供高水平的可扩展性。有限元方法论的不断创新可能导致未来出现具有完全不同要求的新算法。因此,仅仅支持大量的当前算法不能保证代码在未来的实用性。解决办法是提供一些方法,将代码的不同部分扩展到新的情况。对于设计一个多学科的代码,可扩展性起着更重要的作用。多学科代码的可扩展性对于支持不同领域的新问题也是必要的。所以可扩展性被认为是 Kratos 的一个重要目标。
良好的性能和内存效率也是 Kratos 的目标。解决多学科的工业问题是Kratos的目标,需要良好的性能和良好的内存效率水平。通用性和灵活性不利于代码的性能和效率。所以很明显,Kratos不能达到完全优化的单域代码的相同性能。但其想法是保持尽可能快的速度,同时通过减少域之间的数据转换和传输来提高解决多学科问题的总性能。

1.4. Solutions

应用面向对象的范式已被证明对提高代码的灵活性和可重用性非常有帮助。在这项工作中,面向对象的设计被成功地用于将代码的不同部分组织在一集具有明确界面的对象中。这样一来,用一个对象替换另一个对象就非常容易,这就增加了代码的灵活性,而且在其他地方重复使用一个对象也变得更加实用。
设计和实现一个多学科的概念界面是为以前的问题提供的另一个解决方案。在Kratos的设计中,接口是以一种非常通用的方式定义的,与任何具体的概念无关。这种设计产生的变量基础接口非常通用,解决了将程序扩展到新领域时产生的接口问题。
一个灵活和可扩展的数据结构是另一个用来保证代码对新概念的可扩展性的解决方案。建议的数据结构能够存储与任何概念相关的任何类型的数据。它还为处理多领域问题时所需的数据的全局组织提供了不同的方法。同样的策略被应用于为任何节点分配任何的自由度集以解决新问题的灵活性上。
为了在实现不同算法时增加代码的灵活性,提供了一个交互式界面。通过这种方式可以引入新的算法,而不需要在程序内部实现。这使代码具有高度的可扩展性,对于实现优化和多学科的交互算法非常有用。
一个可自动配置的IO模块被添加到这些组件中,提供处理多学科问题所需的完整的一套解决方案。这个IO模块使用不同的组件列表,在读写源自不同分析领域的新概念时进行自我调整。

1.5. Organization

这项工作提出了一个新的面向对象的有限元框架的设计。其想法是提出其设计的一般观点,然后将设计程序分为其主要部分,同时在单独的章节中对每个部分进行单独描述。按照这一思路,工作的布局安排如下:
Chapter 2: Background 在这一章中,给出了有限元编程的背景。
Chapter 3: Concepts 本章首先简要介绍了数值分析的一般情况,然后继续详细解释了有限元方法及其概念。最后,它描述了整个工作中使用的不同设计模式,并简要介绍了用于编写高性能数值应用程序的一些高级 技术。
Chapter 4: General Structure 解释了Kratos的面向对象设计,它的主要对象,代码组织以及内核和应用程序之间的分离。
Chapter 5: Basic Tools 本章介绍了为帮助开发者实现其程序而提供的不同工具。解释了正交方法、线性求解器和几何图形的设计,并提到了其可重用性和通用性的关键点。
Chapter 6: Variable Base Interface (VBI) 介绍了一个新的变量基础接口,可在代码的不同层次上使用。 首先,给出了设计新接口的动机。然后,描述了这个新的接口,并解释了一些应用。之后,有一节是关于它的实现和使用这种方法设计接口的方法。最后,还给出了一些例子来说明VBI在实践中的能力。
Chapter 7: Data Structure 本章首先解释了容器编程的基本概念,并继续描述了不同的容器。然后介绍了为有限元编程设计的新容器。最后,提供了Kratos中数据分配的全局方案。
Chapter 8: Finite Element Implementation 重点介绍了代表 Kratos 中实现的有限元方法的组件。它描述了元素和条件的设计,还解释了 Kratos 中过程和策略的结构。最后,它解释了元素表达式和公式及其设计的目的。
Chapter 9: Input Output 首先,它解释了设计IO模块的不同方法,并提出了一个灵活和通用的IO结构。然后,它继续介绍了专门用于编写解释器的部分,其中包括对概念的少量介绍,以及对相关工具和库的使用的简要解释。最后,它描述了使用Python作为解释器的情况,并对使用Python的原因作了一些说明,该接口库和一些例子显示了其强大的能力。
Chapter 10: Validation Examples 它给出了一些用 Kratos 实现的多学科问题的不同有限元应用的例子。它还包括一些基准来比较Kratos与现有程序的效率。
Chapter 11: Conclusions and Future Work 概述了解决方案及其在解决多学科问题方面的有效性,并解释了本项目的未来方向。

2. Background

面向对象的有限元程序设计的历史可以追溯到90年代初甚至更早。1990年,Forde等人[1]发表了关于将面向对象的设计应用于有限元程序的最早的详细描述之一。他们使用有限元方法的基本组成部分来设计主要对象。他们的结构包括NodeElementDispBCForcedBCMaterialDof作为有限元组件和一些附加对象,如GaussShapeFunction用于协助数值分析。他们还引入了元素组以及节点和元素的list来管理网格和构建系统。他们的方法已经被一些作者在组织他们的面向对象的有限元程序结构时重新使用。这种方法专注于结构领域,对象的接口反映了这种依赖性。
在那些年里,其他作者开始撰写关于面向对象范式及其在有限元编程中的应用。Filho和Devloo[2]对面向对象的设计进行了介绍,将其应用于元素设计。Mackie[3]通过设计一个简单的分层元素,对有限元程序的面向对象设计做了另一个介绍。后来他发表了一个更详细的有限元程序结构,为实体提供了一个数据结构,还介绍了迭代器的使用 [4] 。Pidaparti和Hudli [5] 发表了一个更详细的面向对象的结构,为结构的动态分析中的不同算法提供对象。Raphael和Krishnamoorthy [6]也对面向对象的编程进行了介绍,并为结构应用提供了复杂的元素层次结构。他们还设计了一些数值表达式来处理有限元方法中的常见数值操作。所有这些作者的共同点是他们认识到了面向对象编程相对于传统Fortran方法的优势,并打算在他们的有限元代码中使用这些优势。
Miller[7][8][9]发表了一个面向对象的非线性动态有限元程序的结构。他在设计中引入了无坐标方法,定义了几何类,处理所有从局部坐标到全局坐标的转换。他设计的主要对象是 DofJointElementTimeDependentLoadConstrain被添加到其中,以处理边界条件。他还定义了一个Material类,能够处理线性和非线性材料。Assemblage类持有所有这些组件并封装了结构的时间历史建模。
Zimmermann等人[10][11][12]设计了一个用于线性动态有限元分析的结构。他们的结构由三类对象组成。 首先,有限元方法对象,它们是: Node , Element , Load , LoadTimeFunction , Material , Dof , Domain , 和 LinearSolver 。其次,是一些工具,如 GaussPoint , 和 Polynomial 。第三,是集合类,如Array , Matrix , String , 等等。他们首先在Smalltalk中实现了这个结构的原型,然后在 中实现了一个高效的结构,后者提供了与Fortran代码相当的性能。
在他们的结构中,Element计算刚度矩阵 、质量矩阵 ,以及全局坐标下的载荷向量 。它还在全局方程组中集合其组成部分,并在求解后更新自己。 Node保持其位置并管理自由度。它还计算和组装其载荷向量,最后在解算后更新与时间有关的数据。 Dof保存未知信息和其值。它还存储其在全球系统中的位置,并提供有关边界条件的信息。TimeStep实现了时间离散化。 Domain是一个总管理器,管理节点和元素等组件,也管理求解过程。它还为读取数据和写入结果提供了输入输出功能。最后LinearSystem持有方程组组件:左手边、右手边和解。它还执行了方程编号,并实现了解决全局方程组的解算器。
他们还对其结构进行了非线性扩展,这使得他们重新定义了一些原有的类,如 DomainElementMaterial ,以及一些 LinearSystems [13]
Lu等人 [14][15] 在他们的有限元代码中提出了一个不同的结构 。他们的结构由少量的有限元组件组成,如NodeElementMaterialAssemble,是在一个复杂的数值库上设计的。在他们的设计中,Assemble是中心对象,不仅实现了正常的装配程序,而且还负责坐标转换,这在其他方法中是元素的职责之一。它还负责分配方程编号。Element是他们对新配方的扩展点。他们在实现数值部分的努力导致了一个相当于LAPACK的面向对象的线性代数库 [16] 。这个库提供了一个使用面向对象语言特征的高级接口。
Archer等人[17][18]提出了另一种面向对象的结构,用于专门模拟线性和非线性、静态和动态结构的有限元程序。他们回顾了当时不同的其他设计所提供的功能,并将它们结合到一个新的结构中,同时加入了一些新的概念。
他们的设计由两个层次的抽象组成。在顶层,Analysis 封装了算法,Model代表有限元组件。 Map将模型中的自由度与分析中的未知数联系起来,并消除了这些对象之间的依赖关系。它还将刚度矩阵从元素的局部坐标转换为全局坐标,并计算响应。除了这三个对象之外,不同的处理程序被用来处理算法中与模型相关的部分。ReorderHandler优化了未知数的顺序。MatrixHandler提供不同的矩阵并在给定的模型上构建它们。最后ConstraintHandler提供了分析的未知数和模型中的自由度之间的初始映射。
在另一个层面,有不同的有限元组件代表模型。 Node封装了一个通常的有限元节点,持有其位置和自由度。 ScalarDofVectorDof派生自Dof类,代表不同的自由度类型。 Element使用ConstitutiveModelElementLoad来计算本地坐标系中的刚度矩阵 、质量矩阵 、阻尼矩阵 由载荷、规定位移和初始元素状态对象组成,并计算本地坐标系中的载荷vector
Cardona, et al. [19][20][21] 开发了 Object Oriented Finite Elements 由交互式执行器(OOFELIE)引导的方法 [22] 。他们设计了一种高级语言,还实现了一个解释器来执行该语言中的输入。这种方法使他们能够开发一个非常灵活的工具来处理不同的有限元问题。在他们的结构中,一个Domain类持有数据集,如。 Nodeset, Elemset, Fixaset, Loadset, Materset, 和 DofsetElement 提供了计算刚度矩阵 、质量矩阵 等的方法。 FixasetLoadset提供了计算边界条件和载荷的Fixations和Loads的方法。
他们把这个灵活的工具也用于解决耦合问题,他们的高级语言解释机制在处理耦合问题的不同算法方面提供了额外的灵活性。他们还在其结构中加入了分区和连接类,以增加其代码在处理和组织耦合问题数据方面的功能。Partition被定义为处理领域的一部分,Connection提供了自由度的图形并对它们进行排序。
Touzani [23] 开发了Object Finite Element Library(OFELI) [24] 。这个库有一个基于有限元方法的直观结构,可用于开发不同领域的有限元程序,如传热、流体流动、固体力学和电磁。
Node, Element, Side, Material, ShapeMesh是其结构的主要组成部分,不同的问题解决器类实现算法。这个库还提供了不同的类,这些类以FEEqua类的形式衍生,实现了不同领域的分析公式。它使用了一个静态的Material类,其中每个参数被存储为成员变量。Element只提供几何信息,有限元的实现是通过FEEqua类封装的。Element提供了一些功能,使其对复杂的公式也很有用,但保留所有这些成员数据使其对标准的工业实现来说过于沉重。
Bangerth等人 [25][26][27] 创建了一个用于实现偏微分方程的自适应网格化有限元求解的库,名为微分方程分析库(DEAL)II [28] 。他们关注的是库的灵活性、效率和类型安全,同时也希望实现高水平的抽象性。所有这些要求使他们使用 语言的高级功能来共同实现他们的所有目标。
他们的方法是在一个域上解决一个偏微分方程。 TriangulationFiniteElementDoFHandlerQuadratureMappingFEValues是这个结构中的主要类。 Triangulation 尽管它的名字是一个网格生成器,它可以根据给定的尺寸作为模板参数创建线段、四边形和六面体。它还提供了一个有规律的细化单元,并保留了网格的分层历史。FiniteElement 封装了形状函数空间。它计算 FEValues 的形状函数值。 Quadrature 提供不同阶数的单元格上的四分法。 Mapping 负责坐标转换。 DoFHandler 管理自由度的布局,以及它们在三角测量中的编号。 FEValues封装了将在域上使用的公式。它使用FiniteElementQuadratureMapping来进行计算,并提供本地组件以组装成全局求解器。
广泛使用模板和 编程语言的其他高级功能,在不牺牲其性能的情况下增加了该库的灵活性。他们创建了抽象的类,以便统一处理不同尺寸的几何体。通过这种方式,他们让用户以独立于尺寸的方式创建他们的配方。他们的方法还包括在 中实现公式和算法,有时也包括模型本身。通过这种方式,库可以更好地根据问题配置自己,并获得更好的性能,但由于要求它作为一个封闭的包来使用,所以降低了程序的灵活性。在他们的结构中,没有像节点、元素、条件等通常的有限元组件的痕迹。这使得具有一般有限元背景的开发者不太熟悉它。
Patzák等人[29]发表了一个用于面向对象的有限Element建模(OOFEM)[30]程序中的结构。在这个结构中Domain包含了完整的问题描述,它可以分为几个工程模型,为解决方程系统做准备。数值方法封装了解决方案的算法。 Node, Element, DOF, Boundary condition, Initial condition,以及Material是这个结构的其他主要对象。该程序以结构分析为导向。

2.1. Discussion

在组织有限元代码方面做了大量工作,试图提高其灵活性并降低维护成本。在文献中可以追踪到两类有限元程序的设计。一类是使用有限元方法进行设计,这导致了诸如元素、节点、网格等对象。另一种方法是处理偏微分方程,导致对象函数与域上的矩阵和向量一起工作。
Zimmermann, et al. [10:1][11:1][12:1]的工作是设计代码结构的经典方法之一,考虑了有限元方法。然而,在他们的设计中没有几何学,也没有涉及像进程、命令解释器等新组件。
Miller等人的努力是为了将坐标转换封装在几何学中,这对于放松元素公式对特定几何学的依赖很有帮助。
Cardona等人[19:1][20:1][21:1]增加了一个解释器,以一种非常灵活的方式管理代码的全局流。解释器用于向程序引入新的求解算法而不改变其内部。这段代码也被扩展到解决耦合问题,使用解释器来引入交互算法,这给它带来了很大的灵活性。他们的方法的缺点是在绑定现有的解释器的同时,还要用新定义的语言来实现一个新的解释器。这意味着解释器本身的维护成本,并阻止他们使用其他可能有接口的脚本语言的库。
Touzani [23:1]为多学科的有限元程序设计了一个结构。他的设计清晰易懂,但对其组件使用了特定领域的接口,这些接口对所有领域都不统一。这降低了算法从一个领域到另一个领域的可重复使用性。
Lu, et al. [14:1][15:1]的方法是在设计偏微分求解器的路线上,强调了数值组件。Archer等人[17:1][18:1]将这种方法扩展到一个更灵活和可扩展的点上,最近Bangerth等人在设计他们的代码时使用了同样的方法。然而这种设计的结构结果对于通常的有限元程序员来说可能是不熟悉的。例如,在后者的设计中,没有代表节点和元素的对象,而节点和元素是有限元程序员的常用组件。
在这项工作中,标准的有限元对象,如节点、元素、条件等,都是从以前的设计中重复使用的,但经过修改,适应了多学科的视角。此外,还增加了一些新的组件,如模型部分、过程、内核和应用,以涵盖多学科问题中出现的新概念。设计了一个新的变量基础接口,提供了字段之间的统一接口,增加了代码的可重复使用性。使用解释器的想法是通过使用现有的解释器来实现的。还做了大量的工作来设计和实现一个快速和非常灵活的数据结构,使其能够存储来自不同领域的任何类型的数据,并保证数据的统一转换。还创建了一个可扩展的IO,以完成处理多学科问题时通常遇到的瓶颈的工具。

3. Concepts

这项工作的目的是创建一个框架来实现多学科的有限元应用。在开始之前,有必要解释一下有限元方法本身的一些基本概念,多学科问题及其解决方案,以及与其设计和实现有关的编程概念。
在本章中,首先对有限元的概念进行了简要介绍。然后描述了耦合系统的一些基本概念。最后解释了一些编程概念和技术。

3.1. Numerical Analysis

在这一节中,将简要介绍一般的数值分析,并简要介绍不同的数值方法,它们的相似之处和不同之处。

3.1.1. Numerical Analysis Scheme

有几种数值分析方法在其方法和应用类型上是不同的。除了它们之间的差异,它们还依赖于一个总体方案,这使得它们在整体方法上是相似的,并且在某种程度上是可以混合或互换的。这个总体方案由以下三个主要步骤组成。
Idealization:定义一个反映物理系统的数学模型。由于这个原因,这个步骤也被称为 mathematical modeling 。在这一步骤中,物理系统的管理方程及其条件被转化为一些可以用数字解决的一般形式。通常情况下,不同的假设是必要的,以使这种建模成为可能。这些假设使模型与物理问题不同,并在我们的解决方案中引入modeling error
Discretization:将具有无限数量未知数的数学模型,称为degrees of freedom(自由度),转换为有限数量的未知数。虽然具有无限数量未知数的原始模型不能用数值来解决,但由此产生的具有有限数量未知数的discrete model可以用数值方法来解决。这里要提到的是这个步骤中涉及的近似。这个过程将discretization error引入到解决方案中,这在很大程度上取决于离散化的质量和使用的方法。
Solution:求解discrete model,并获得阻尼和其他相关结果。这一步引入了来自使用算法的不精确性、机器的数字精度或其他来源的solution error
3.1显示了这个总体方案。这里的一个重要观察是不同概念引入的不同错误和近似的存在。这些误差的积累会影响到这些方法得到的结果的有效性。由于这个原因,每个步骤的有效性和减少每个过程中的误差是使用数值方法的主要挑战之一。

3.1.2. Idealization

理想化是某些物理现象的mathematical modeling。这一步的主要任务是为一个给定的物理问题找到一个合适的数学模型。
数学模型通常基于不同的假设。这种依赖性使它们对这些假设正确或接近现实的问题有用。由于这个原因,找到一个好的数学模型不仅需要对问题有很好的了解,还需要对模型的假设有很好的了解。
例如,在解决一个流体问题时,理想化包括为问题中的某种流体找到最佳的流体模型。在这种情况下,主要的问题是。这个流体是牛顿式的吗?它是可压缩的还是不可压缩的?它是层流吗?根据这些条件,一个模型可以被认为比其他模型更适合于某个问题。然而,所选择的模型仍然可能给我们的解决方案带来某些建模错误。
有不同形式的数学模型。一些常见的是。
Strong Form 将数学模型定义为一个普通或偏微分方程系统和一些相应的边界条件。
Weak Form 它使用加权残差近似法,以特定的修正形式表达数学方程。
Variational Form 在这种形式下,数学模型被表述为一个函数,其静止条件产生了弱形式。
Strong Form 如前所述,强形式将数学模型定义为一个普通或偏微分方程系统和一些相应的边界条件。考虑到图3.2所示的具有边界 的域 ,这种形式通过域和边界上的方程组定义了模型,如下所示。
其中 是未知数, 是在域上应用的算子 代表在边界上应用的算子 。第一个方程代表域上的治理方程,第二个方程代表这个问题的边界条件。例如,图3.3域上的热问题可以用下面的强形式来建模。
其中 是温度, 是边界通量, 是内部热源, 是固定温度的边界 是固定通量的边界
Weak Form
是一个Banach空间,考虑寻找方程 的解的问题
这个问题等价于在满足任意 下, 找到方程的解
这被称为问题的weak formulation。弱形式定义了使用强形式的weak formulation的数学模型。现在使用以下标量乘积。
结果是integral form,它是模型的加权积分表示。
这种表述也可以应用于涉及边界条件。例如,由方程 [1] 表示的相同问题可以重写如下:
其中 是分别定义在域和边界上的残差函数。
以及 是域和边界上的任意加权函数。通常情况下,为了减少方程中导数的最大阶数并通过对加权函数应用一些导数来平衡它,使用部分积分是很方便的。对方程 [7] 进行分项积分可以得到。
减少 中的导数顺序,相对于 ,允许在选择 函数时降低连续性的顺序要求。然而,现在对 更高的连续性是必要的。
Variational Form
变分形式通常来自问题的一些基本量,如质量、动量或能量,其静止状态是令人感兴趣的。这种形式通过以下形式的函数定义了数学模型。
这个量的静止状态是必需的,因此,它的变化要等于零,这就产生了下面的方程式。
从守恒定律推导出变异方程对科学家来说是有吸引力的,因为它呈现了问题的相同基本特征。最后必须提到的是,弱形式也可以从变分形式的静止状态导出。

3.1.3. Discretization

数值分析的第一步是定义一个与实际物理问题相对应的数学或连续模型。在实践中,除了某些领域和条件外,连续模型不能用分析法解决,这就是数值解决的原因。连续模型有无限多的未知数,对应于域和边界的点,不能直接用数值方法解决。因此,第二步是必要的,以便将连续模型转换为具有有限数量未知数的离散模型,可以用数值方法求解。
有几种方法可以进行这种转换,从而产生不同的数值方法。适当的离散化方法不仅取决于问题的类型,也取决于描述它的数学模型的类型。以下是对不同模型的适当离散化的简要描述。
Discretization of the Strong Form
强形式的离散化通常使用 finite difference method 进行。这里的想法来自于用差分代替导数的数值计算。例如,函数 的一阶导数可以改变为其离散形式,如下所示。
其中离散化参数 是网格点的距离。这种方法也可用于计算函数的高阶导数。
离散化只是域上的一个笛卡尔网格。图3.4显示了一个二维空间中的网格样本。
这种方法已经在许多领域得到了实际应用,并在许多应用中得到了实现。它的方法很简单,也很容易编程。这些使得它成为数值分析中最受欢迎的方法之一。然而,这种方法也有其不足之处。 首先,它对规则域工作得很好,但对任意的几何形状和边界条件就会遇到困难。例如,图3.5(a)的不规则域可以用图3.5(b)所示的离散域来近似。可以很容易地看到,这种离散化改变了任意几何的域边界。
另一个缺点是它的近似解,只能在网格点得到,因此没有提供网格内其他点的信息。
Discretization of the Weak Form
连续数学模型的离散化包括将工作空间转换为一些选定的离散空间。考虑到连续空间中的以下弱形式
这个形式可以被转换到离散空间 ,以近似解
如前所述,数学模型的弱形式可以用加权积分表示为。
其中 是分别定义在域和边界上的残差函数。 是域和边界上的任意加权函数。这里选择一个离散空间 作为我们的工作空间,结果是discrete model
其中 是残差函数。方程 [18] 是残差的加权积分。所以这类近似方法被称为加权残差法。一些众所周知的方法如有限Element Method(FEM)、Finite Volume(FV)和Least squares fitting都是这种方法的子类。通常选择一个由已知trial functions 的集合组成的离散空间 ,并按以下方式定义离散解。
其中 是未知系数, 是已知试算函数, 是未知数的数量。将其代入方程 [18] 的结果。
其中 为任意系数, 为任意函数, 为未知数。展开方程 [20] 可以得到。
由于 是任意的,为了满足方程,上述和的所有分量必须为零。这导致了以下的方程组。
有几组的函数可以作为加权函数使用。下面是一些常见选择的list
搭配法 使用Diracdelta 作为加权函数。
其中 是一个函数,以便于。
将这个加权函数代入我们的参考方程 [23] ,得出以下discrete model
这种方法满足了方程在拼合点集合中的要求,并给出了与finite difference method得到的方程相似的的离散方程组。
子域法 它是前一种方法的延伸。它使用一个加权函数 ,该函数在子域 中是相同的,在其他地方是零。
discrete model可以通过将这个加权函数代入方程3.23的一般弱形式得到。
这种方法在每个子域中提供了一个统一的近似值,并建立了一种将域划分为子域的方法来解决问题。
最小平方法 这种方法使用应用于试验函数的治理算子作为其加权函数。
下面是将上述加权函数代入方程3.23的结果discrete model
我们可以验证,所得到的方程等同于在域上最小化全局残差 的平方。
其中,
Galerkin方法使用试验函数作为加权函数。
将方程 [33] 代入方程 [23] ,得到以下Galerkin discrete model 。
这种方法通常能改善求解过程,因为它经常(但不总是)导致对称矩阵和其他一些有用的特征,这使得它成为最受欢迎的方法和有限元求解的通常基础。
Discretization of the Variational Form
Rayleigh-Ritz方法是连续模型的变量形式的经典离散化方法。它也是第一个试用函数的方法。其思想是通过 来近似解 ,该方法由以下Trial函数集合的定义。
其中 为未知系数, 为已知试算函数, 为未知数。现在考虑以下连续模型的变化形式。
将方程 [35] 的试验函数展开插入方程 [36] 中,得到。
由于这个方程对任何变化都必须是真的 ,它的所有分量必须等于零。这就形成了以下的方程组。
Mixed Discretization
有时,为了描述复杂的现象,或者只是为了简化一些近似值,而在问题的其他方面保持更详细的方法,混合两种或更多类型的离散化是有用的。混合不同形式的一个典型案例是时间相关问题的建模,可以在时间上使用有限差分离析,而在空间上使用加权残差分析。

3.1.4. Solution

数值方法的最后一步是求解。这一步包括使用适当的算法来解决discrete model,以找到主要的未知数,同时计算问题的其他额外未知数。这个过程包括。
Calculating Components 计算discrete model的所有组成部分(如finite difference method中的导数,加权残差法或变分法中的积分,等等)。
Creating the Global System discrete model的组成部分被放在一起,以建立代表discrete model的全局方程组。
Solving the Global System 全局系统必须被解决以计算问题的未知数。对于一些模型,这导致了一个线性方程组,可以用线性求解器来解决。一些算法创建了一个对角线全局系统,使求解部分完全变得微不足道。
Calculating Additional Results 在许多问题中,不仅主要的未知数,即结构问题中的位移,是感兴趣的,而且一些额外的结果,如结构问题中的应力和应变,也必须被计算。
Iterating 在许多算法中,还需要一些迭代来确定未知数或计算不同的未知数集。解决非线性问题,计算与时间有关的未知数,以及优化问题,都是需要迭代的算法的例子。

3.2. Finite Element Method

在上一节中,对数值方法进行了简要介绍。由于这项工作是以有限元方法为基础的,因此对这种方法及其基本步骤进行了简要描述。
有限元方法(FEM)一般以问题的integral form为基础,使用分片多项式作为其试验函数。导致有限元法的公式有很多,但最常用的是Galerkin方法,这里用来描述有限元法及其基本步骤。

3.2.1. Discretization

考虑到一个连续问题。
和它的integral form如下:
其中 是分别定义在域和边界上的残差函数。
将离散有限元空间 定义为多项式函数的组成
并将方程 [40] 转换到这个空间,结果是: