games103——作业3

news2024/11/27 8:24:08

实验三主要使用FEM和hyperelastic模型完成弹性体的模拟

完整项目已上传至github。

文章目录

  • Linear finite element method(FEM)
    • 二维空间有限元方法
      • 变形梯度(Deformation Gradient)
      • 格林应变(Green Strain)
      • 应变能量密度函数(Strain Energy Density Function)
      • 力(Force)
  • Finite Volume Method(FVM)
    • Traction and Stress
    • The Finite Volume Method
    • 不同参考状态下的stress
    • 算法流程
    • 代码
    • 结果
  • Hyperelastic Models
    • Isotropic Materials
    • Isotropic Models
    • 算法流程
    • 代码
    • 结果


Linear finite element method(FEM)

弹性的力永远都是想阻碍形变的(划重点)。有限元方法(Finite Element Method) 把物体分割成一个个有体积的单元来模拟。例如,线性有限元方法在二维空间中把物体分割成三角形,在三维空间中把物体分割成四面体。

下面以二维空间上的有限元方法为例

二维空间有限元方法

如下图所示,我们把三角形静止时(未发生形变)的状态称为 Reference 状态。假设三角形内部的形变是均匀的,三角形内任意点 X ⃗ \vec{X} X 形变以后的位置 x ⃗ = F ⃗ X ⃗ + c ⃗ \vec{x}=\vec{F}\vec{X}+\vec{c} x =F X +c 。注意大写表示形变之前的状态,小写表示形变之后的状态。

则任意向量 X ⃗ b a \vec{X}_{ba} X ba 形变后变成 x ⃗ b a = F ⃗ X ⃗ b a \vec{x}_{ba}=\vec{F}\vec{X}_{ba} x ba=F X ba

变形梯度(Deformation Gradient)

因为是二维情况(力有两个未知项),所以需要用形变前后三角形两个边向量就能求出 F ⃗ = [ x ⃗ 10   x ⃗ 20 ] [ X ⃗ 10   X ⃗ 20 ] − 1 \vec{F}=[\vec{x}_{10}\space\vec{x}_{20}][\vec{X}_{10}\space\vec{X}_{20}]^{-1} F =[x 10 x 20][X 10 X 20]1。但是求出的力还包括了与旋转相关的部分。

格林应变(Green Strain)

我们可以使用SVD(前两个部分与形变有关,最后一个与旋转有关)分解,求出仅与形变有关的部分。但做SVD分解太复杂了,这里引入 Green Strain,其与旋转无关,仅描述形变(就是做一些矩阵运算,消去旋转部分)。

应变能量密度函数(Strain Energy Density Function)

我们再引入一个新的量 W ( G ⃗ ) W(\vec{G}) W(G ) 描述参考区域的能量密度。由于在三角形内量,能量密度是常量,总能量就是 W ( G ⃗ ) ∗ d A W(\vec{G})*dA W(G )dA 在参考域上的积分。 W ( G ⃗ ) W(\vec{G}) W(G ) 直接决定了材料的性质,这里使用StVK模型。

这里最后的 2 μ + λ t r a c e ( G ⃗ I ) = S 2\mu+\lambda trace(\vec{G}I)=S 2μ+λtrace(G I)=S 适用于任意维度。这里都是相对静止状态的,所以这里就得到第二皮奥拉-基尔霍夫应力(Second Piola-Krichhoff Stress Tensor)

力(Force)

有了能量的定义,力就可以由能量关于位矢求偏导取负号得到了。

由之前关于 F ⃗ \vec{F} F G ⃗ \vec{G} G 的公式,代入可以最后得到 f ⃗ 1 \vec{f}_1 f 1 关于 A r e f A^{ref} Aref F F F S S S的表示。


f ⃗ 2 \vec{f}_2 f 2 也同理能求得,而由系统内合力为 0,我们也可以求得 f ⃗ 0 \vec{f}_0 f 0


Finite Volume Method(FVM)

FVM 从有限体积的角度考虑,其实对于简单的线性的三角形或四面体,这两个方法是等价的。

Traction and Stress

基于力是从何而来的思想;定义一个 traction 表示单位长度(面积)上的力,那么表面上的全部力就是 traction 在表面上的积分,而 traction 是与应力张量和法向量有关

The Finite Volume Method

相当于对法向量进行积分,而在封闭曲线上对法向量积分结果为 0。取中点是为了对三个点力的共享是均匀的。


三维的情况就是面积分了

不同参考状态下的stress

在FEM中,能量密度 W 是在参考状态下定义的。因此,应力 S 是一个将参考状态的法向量 N ⃗ \vec{N} N 映射到参考状态的 traction T ⃗ \vec{T} T 。而在FVM中,则是在形变状态下的映射。


这些应力实际是等价的,只不过参考的状态不同。我们可以由Second Piola-Kirchhoff stress乘上 F 得到 First Piola-Kirchoff stress。再由 First Piola-Kirchoff stress得到Cauchy stress。

下面我们根据两个状态下 Area Weighted Normals 之间的关系,找到 First Piola-Kirchhoff stress 与 Cauchy Stress 之间的关系


我们得到不同状态下应力之间的关系


有了上面应力之间的转换关系,我们可以把之前形变状态下的公式,转化一下,因为后面叉乘求和是个常量,因此可用提前计算得到。


后续可以进一步化简,比如 X 10 X_{10} X10 X 01 × X 21 X_{01}\times X_{21} X01×X21 的点乘结果肯定是 0,因为叉乘产生的向量垂直于 X 10 X_{10} X10
1 d e t ( [ X ⃗ 10   X ⃗ 20   X ⃗ 30 ] − 1 ) = d e t [ X ⃗ 10   X ⃗ 20   X ⃗ 30 ] \frac{1}{det([\vec{X}_{10}\space\vec{X}_{20}\space\vec{X}_{30}]^{-1})} = det[\vec{X}_{10}\space\vec{X}_{20}\space\vec{X}_{30}] det([X 10 X 20 X 30]1)1=det[X 10 X 20 X 30] 可进一步得到如下公式

算法流程

根据上面的推导,可以总结为如下算法流程

代码

核心代码如下,就是按照上面的算法流程,把对应的物理量计算出来,带入公式即可。这里由于是显式积分,所以存在数值不稳定性,使用拉普拉斯平滑进行处理(就是加权平均一个体的其他三个点的速度)

    	for(int tet=0; tet<tet_number; tet++)
    	{
            //TODO: Deformation Gradient
            Matrix4x4 F = Build_Edge_Matrix(tet) * inv_Dm[tet];
            //TODO: Green Strain
            Matrix4x4 G = Matrix4x4_mul_float(Matrix4x4_minus_Matrix4x4(F.transpose * F, Matrix4x4.identity), 0.5f);
            //TODO: Second PK Stress
            Matrix4x4 S = Matrix4x4.zero;
            float trace = G[0, 0] + G[1, 1] + G[2, 2];
            S = Matrix4x4_add_Matrix4x4(Matrix4x4_mul_float(G, 2.0f * stiffness_1), Matrix4x4_mul_float(Matrix4x4.identity, stiffness_0 * trace));
            //TODO: Elastic Force
            float volume = 1.0f / (inv_Dm[tet].determinant * 6);
            Matrix4x4 Elastic_force = Matrix4x4_mul_float(F * S * inv_Dm[tet].transpose, -volume);
            for (int k=0; k<3; k++)
            {
                Force[Tet[tet * 4 + k + 1]].x += Elastic_force[0, k];
                Force[Tet[tet * 4 + k + 1]].y += Elastic_force[1, k];
                Force[Tet[tet * 4 + k + 1]].z += Elastic_force[2, k];
            }

            // Elastic_force0 = -Elastic_force1-Elastic_force2-Elastic_force3
            Force[Tet[tet * 4 + 0]].x -= Elastic_force[0, 0] + Elastic_force[0, 1] + Elastic_force[0, 2];
            Force[Tet[tet * 4 + 0]].y -= Elastic_force[1, 0] + Elastic_force[1, 1] + Elastic_force[1, 2];
            Force[Tet[tet * 4 + 0]].z -= Elastic_force[2, 0] + Elastic_force[2, 1] + Elastic_force[2, 2];
        }

        Smooth_V(0.75f);

结果


Hyperelastic Models

Isotropic Materials

各向同性材料,其与拉伸方向无关。P可以认为是F的一个函数,Principal stretches是对角元素,表示三个方向上的拉伸量

在论文中,一般以下面的方式表示,PPT里把 I I C II_C IIC I I I C III_C IIIC写反了

论文里的如下

Isotropic Models

第一项抵抗拉伸,第二项阻止体积改变

算法流程

这里就是使用SVD分解F,利用上面公式计算 P,这里可以替换不同的 W 以更换不同的模型

代码

W 对 λ \lambda λ 求偏导结果如下

核心代码如下,在前面需要把 stiffness_0 改为 5000.0f

        // Hyperelastic Models
        for (int tet = 0; tet < tet_number; tet++)
        {
            //TODO: Deformation Gradient
            Matrix4x4 F = Build_Edge_Matrix(tet) * inv_Dm[tet];
            F[3, 3] = 1.0f;
            //TODO: Green Strain
            Matrix4x4 U = new Matrix4x4();
            Matrix4x4 S = new Matrix4x4();
            Matrix4x4 V = new Matrix4x4();
            svd.svd(F, ref U, ref S, ref V);
            //TODO: First PK Stress
            Matrix4x4 P = new Matrix4x4();
            Matrix4x4 Diag = new Matrix4x4();
            float sum2 = S[0, 0] * S[0, 0] + S[1, 1] * S[1, 1] + S[2, 2] * S[2, 2] - 3.0f;
            Diag[0, 0] = stiffness_0 * sum2 * 2.0f * S[0, 0] + stiffness_1 * (S[0, 0] * S[0, 0] * S[0, 0] - S[0, 0]);
            Diag[1, 1] = stiffness_0 * sum2 * 2.0f * S[1, 1] + stiffness_1 * (S[1, 1] * S[1, 1] * S[1, 1] - S[1, 1]);
            Diag[2, 2] = stiffness_0 * sum2 * 2.0f * S[2, 2] + stiffness_1 * (S[2, 2] * S[2, 2] * S[2, 2] - S[2, 2]);
            U[3, 3] = Diag[3, 3] = V[3, 3] = 1.0f;
            P = U * Diag * V.transpose;
            //TODO: Elastic Force
            float volume = 1.0f / (inv_Dm[tet].determinant * 6);
            Matrix4x4 Elastic_force = Matrix4x4_mul_float(P * inv_Dm[tet].transpose, -volume);
            for (int k = 0; k < 3; k++)
            {
                Force[Tet[tet * 4 + k + 1]].x += Elastic_force[0, k];
                Force[Tet[tet * 4 + k + 1]].y += Elastic_force[1, k];
                Force[Tet[tet * 4 + k + 1]].z += Elastic_force[2, k];
            }

            // Elastic_force0 = -Elastic_force1-Elastic_force2-Elastic_force3
            Force[Tet[tet * 4 + 0]].x -= Elastic_force[0, 0] + Elastic_force[0, 1] + Elastic_force[0, 2];
            Force[Tet[tet * 4 + 0]].y -= Elastic_force[1, 0] + Elastic_force[1, 1] + Elastic_force[1, 2];
            Force[Tet[tet * 4 + 0]].z -= Elastic_force[2, 0] + Elastic_force[2, 1] + Elastic_force[2, 2];
        }

结果

因为使用了 SVD,导致仿真速度变慢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/533579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

威胁猎人 | 2018年上半年国内公有云云上资产合规现状报告

声明&#xff1a;本报告版权属于威胁猎人情报中心&#xff0c;并受法律保护。转载、摘编或利用其它方式使用本报告文字或者观点的&#xff0c;应注明“来源&#xff1a;威胁猎人”。违反上述声明者&#xff0c;将追究其相关法律责任。 一、报告背景 自2005年亚马逊发布AWS伊始…

基于nodejs+vue3 的高仿网易云音乐

大家好&#xff0c;我是小寻&#xff0c;欢迎大家关注我的公众号&#xff1a;工具优选&#xff0c;加入前端、java群聊哦&#xff01; 今天给大家分享一个超高水准的项目&#xff1a;基于nodejsvue3研发的高仿网易云音乐&#xff0c;项目内容出自寻码网&#xff01; 技术栈&a…

行业唯一丨冠珠瓷砖荣获人民日报社“ESG年度案例”

践行社会责任&#xff0c;推动品牌高质量发展。5月11日&#xff0c;由人民日报社指导、人民日报社经济社会部主办的“中国企业社会责任高峰论坛”在上海盛大举行。 本次论坛围绕乡村振兴、共同富裕、绿色低碳等重点议题进行深入研讨&#xff0c;邀请国家发展和改革委员会、商务…

Thread线程学习(2) Linux线程的创建、终止和回收

目录 1.首先要了解什么是线程ID&#xff0c;以及它的作用是什么 2.创建线程 3.终止线程 4.回收线程 5.总结 在Linux系统中&#xff0c;线程是轻量级的执行单元&#xff0c;能够在同一个进程中并发执行。本文将介绍如何在Linux环境下创建、终止和回收线程&#xff0c;并提供…

〖Web全栈开发③〗—HTTP协议和静态web服务器

HTTP协议和静态web服务器 &#xff08;一&#xff09;三次握手和四次挥手&#xff08;二&#xff09;HTTP协议2.1 HTTP协议的定义2.2 HTTP协议的组成 &#xff08;三&#xff09;搭建python自带静态web服务器3.1 静态web服务器是什么3.2 如何搭建python自带的静态web服务器3.3 …

【栈和队列】的特性以及基本接口的实现

目录 一、栈 1.1 栈的概念 1.2 栈的接口实现 二、队列 2.1 队列的概念 2.2 队列的接口实现 2.3 栈和队列的区别 三、栈和队列LeetCode练习 3.1 力扣_232.用栈实现队列 3.2 力扣_225.用队列实现栈 3.3 力扣_622.设计循环队列 3.4 力扣_20.有效的括号 一、栈 第一次学…

电容在电路中的作用

电容、也称为电容器&#xff0c;字面意思理解就是一种“装电的容器”&#xff0c;是一种容纳电荷的器件。它拥有两个电极板&#xff0c;由两个电极板及其中间所夹的介质封装而成。 常用电容极性判断&#xff1a;   铝电解电容&#xff1a;长脚为正极&#xff0c;短脚为负极&…

【MySQL学习】MySQL索引特性

文章目录 一、初识MySQL索引1.1 MySQL索引的概念1.2 MySQL索引的作用 二、MySQL的数据存储2.1 MySQL存储与磁盘之间的关系2.2 MySQL与磁盘交互的基本单位2.3 认识数据页Page 三、索引的理解3.1 测试案例3.2 探究单个和多个Page存储数据时的情况3.3 页目录3.4 为什么InooDB存储引…

《面试1v1》CAS

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 上个面试官对你的基础有了一定了解&#xff0c;听说你小子很不错&#xff01;下面我们聊点有深度的。 面试官&#xff1a; 简单介绍下 CAS 你了…

10款Photoshop免费在线工具推荐

AdobePhotoshop下载繁琐&#xff0c;付费昂贵&#xff0c;让很多设计师望而却步&#xff01; 经过几个小时的筛选和测试&#xff0c;筛选出10款Photoshop免费在线工具&#xff0c;与Photoshop一样强大。让我们看看&#xff01; 1.即时设计 智能抠图 当我们想要去重图片背景&…

【鲁棒优化、机会约束】具有分布鲁棒联合机会约束的能源和储备调度研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

JAVA中的深情哥-Exception(异常)-上

文章目录 目录 文章目录 前言 一&#xff0c;Exception的起源 二&#xff0c;异常类 三&#xff0c;自定义异常 总结 前言 大家好,我是最爱吃兽奶,今天给大家介绍一下java中的深情哥 - Exception 秋风依依秋水寒&#xff0c;一点离愁两黯然&#xff1b;今生默默唯轻舞&a…

抖音林客系统开发

抖音林客系统是一款基于AI技术的推荐算法系统&#xff0c;主要应用于抖音平台中用户的内容推荐和个性化服务。开发抖音林客系统需要掌握以下关键技术&#xff1a; 数据采集与处理&#xff1a;需要对海量的用户数据进行采集和处理&#xff0c;包括用户的观看历史、互动行为、…

K-Village NFT 作品集

K-Village 是韩国领先的娱乐公司和 Cube 娱乐公司所拥有的空间&#xff0c;引领了元宇宙行业的发展。在这个虚拟的「韩国村」中&#xff0c;可以参观代表韩国文化的韩国公司和品牌。 此外&#xff0c;这个系列的购买者还将获得特别奖励&#xff01;如果你刚好拥有 20 个 K-Vill…

不懂Spring IOC?你可能已经OUT了!快来了解它的奥秘!

大家好&#xff0c;我是小米&#xff0c;一个热衷于技术分享的小伙伴。今天&#xff0c;我想和大家聊一聊Spring IoC&#xff08;Inversion of Control&#xff09;的理解、原理与实现。对于使用Spring框架的开发者来说&#xff0c;IoC容器是一个非常重要的概念&#xff0c;它帮…

C++ ---- 日期类实现+阅读文档(文档可直接下载)

日期类文档下载(日期类详细介绍) word文档 MyDate/MyDate/日期类阅读文档.docx 张喜阳/进阶代码仓库 - Gitee.comhttps://gitee.com/niuniuzxy/advanced-code-warehouse/blob/a25baeee2bd0f0c64f96315bb0d0023308329d92/MyDate/MyDate/%E6%97%A5%E6%9C%9F%E7%B1%BB%E9%98%85…

十六、Config分布式配置中心

目录 分布式配置中心概述 1、为什么需要分布式配置中心&#xff1f; 2、配置中心的作用&#xff1a; Spring Cloud Config简介 新建项目springcloud-config-server 1、引入配置中心config-server的依赖 2、在github/gitee上新建一个远程仓库作为config的远程配置中心 3、…

3年测试技术面一题都看不懂,字节面试真的变态.....

最近我的一个读者朋友去了字节面试&#xff0c;来给我发信息吐槽&#xff0c;说字节的面试太困难了&#xff0c;像他这种三年经验的测试员&#xff0c;在技术面&#xff0c;居然一题都答不上来&#xff0c;这要多高的水平才能有资格去面试字节的测试岗位。 确实&#xff0c;字…

Vue2+CSS实现一个瀑布流布局案例

在练习代码的时候&#xff0c;看到了携程的首页下方的布局还挺好看 就是一个瀑布流的布局效果&#xff0c;在携程上是一共两列布局&#xff0c;然后每个格子的高度都会根据图片的高度做排布 一开始是想使用flex进行布局&#xff0c;先让每个格子各占百分之49&#xff0c;然后贴…

微信小程序实现电子书搜索与下载

1、背景 自己已经做了一版电子书下载网站&#xff08;走蛟电子书&#xff09;&#xff0c;但用户使用手机更方便些&#xff0c;为改善用户体验&#xff0c;准备做一款微信小程序实现电子书搜索与下载的功能。 2、技术栈 由于功能较为单一&#xff0c;因此前端使用原生的微信…