FVM in CFD 学习笔记_第7章_OpenFOAM和uFVM中的有限体积网格

article/2025/10/22 13:21:53

学习自F. Moukalled, L. Mangani, M. Darwish所著The Finite Volume Method in Computational Fluid Dynamics - An Advanced Introduction with OpenFOAM and Matlab
Chapter 7 The Finite Volume Mesh in OpenFOAM and uFVM

OpenFOAM是强大高效的开源代码,而uFVM则侧重教育学习(便于理解却丧失效率),本章着重讲解OpenFOAM的网格文件格式,以及uFVM的网格数据结构是如何架构的,可见uFVM与OpenFOAM的实现细节是非常类似的,可以作为学习OpenFOAM的先导。

1 uFVM

1.1 OpenFOAM测试算例

uFVM代码是直接读入OpenFOAM的算例配置文件的,所以先要理解OpenFOAM的算例是如何设置的,下图展示了一个名为cavity的算例,其设置文件全部放在cavity文件夹下面。

在这里插入图片描述

在cavity文件夹下,有三个文件夹:

其中文件夹0下面存放的是初始物理场(含内部量与边界量)的信息,即初始速度场U和初始压力场p存放在0/P和0/U文件中。一旦计算开始后,若设置了输出间隔,则会生成对应时刻标号的文件夹,其里面存放着对应时刻的流场变量。

在文件夹system中存放的是与FVM算法相关的三个设置文件:controlDict是计算的控制参数,如模拟的开始和结束时间、使用的时间步长、数据输出间隔等信息;fvSchemes是定义离散格式的,比如梯度格式、插值格式等;fvSolution则定义的是求解算法(求解Ax=b方程的法子,如共轭梯度、多重网格等)、松弛因子、收敛指标等信息。

在const文件夹中,transportProperties文件存放的是相关物理特性,如粘性系数;polyMesh中则存放着描述网格信息的文件points、faces、owner、neighbour、boundary共5个文件。有人可能会很好奇,那个blockMeshDict是干啥的?它其实是用来剖分分块结构网格的配置文件,里面大概是写每个块的角点以及划分单元数目和单元长度增长比率的信息,写好后,用blockMesh命令就能生成较为简单的分块结构网格了,也就是前面提到的那5个文件信息了。实际上,如果网格不是用blockMesh工具来划分的,而是由别的格式的非结构网格转化而来的,那么在polyMesh文件夹下就见不到这个blockMeshDict文件了。

下面咱们看看polyMesh文件夹中这5个文件是如何给出网格信息的。

1.2 polyMesh文件夹

在这里插入图片描述

如上图所示(来自OpenFOAM开发者Hrvoje Jasak大神的博士论文),OpenFOAM中的单元是任意多面体,而每个面可以由任意多边形构成,所以非常灵活通用,当然结构网格是这种多面体网格的一种特例。

OpenFOAM中只处理3维网格,如果是2维问题,把它沿着展向拉伸一层网格让它变成3维网格,同时把展向两端的边界面定义成empty就可以了。

points

points文件存放的是角点的坐标 ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi)列表,注意,这些角点,既是单元的角点,也是面的角点。标识为0的角点(第1个角点)坐标存放在第1行,标识为1的角点(第2个角点)坐标存放在第2行。注意:由于C++中的数组标识是从0开始而非从1开始的,所以第1个量的标识是0,而如果有N个量,则第N个量的标识是N-1(有点反人类,跟自然数到底是从0开始还是从1开始有点像哈)。这个points文件的格式如下

#number of points
(
(#x #y #z)
......
)

看看points文件的范例,共有1074个角点:

1074
(
(32 16 0.9377383239)
(33.9429245 16.11834526 0.9377383239)
(35.84160614 16.46798134 0.9377383239)
(37.67648315 17.04080009 0.9377383239)
(39.42799377 17.82870483 0.9377383239)
(41.07658768 18.82359314 0.9377383239)
(...)
...
)

faces

也是个列表,存放的是构成面的角点标识列表,同样,第1行是0号标识面的所有角点标识,第2行是1号表示面的所有角点标识。faces文件的格式如下

#number of faces
(
#number of points for face 1 (#p1 #p2 #p3 ...... )
#number of points for face 2 (#p1 #p2 #p3 ...... )
......
)

faces文件的范例如下,有3290个面(所有面=内部面+边界面),这里每个面由4个角点组成

3290
(
4(36 573 589 52)
4(41 578 634 97)
4(44 81 618 581)
4(30 82 619 567)
4(121 50 587 658)
4(39 120 657 576)
......
)

owners

owners文件存储着面的所属(owner)单元标识,即,标识为0的第1个面的owner单元标识存放在第一行,标识为1的第2个面的owner单元标识存放在第2行,以此类推。注意:owner单元的数目等于面的总数目,即内部面数目+边界面数目。
单元的数目等于owner的最大值+1(因为标识从0开始的)。
owners文件的格式如下

#number of owners
(
#owner of face1
#owner of face2
......
)

owners文件范例如下

3290
(
0
1
2
3
4
5
6
......
)

单元总数也可以从owners文件的头部信息行中获取,nCells后面跟的就是单元数目

    note        "nPoints:1074  nCells:918  nFaces:3290  nInternalFaces:1300";

neighbours

neighbours文件存放的是面的邻居单元(neighbour)标识列表,注意邻居单元的数目等于内部面的数目,因为边界面只有一个单元,就是own单元,边界面是没有neighbour单元的。

neighbours文件的格式为

#number of neighbour
(
#neighbour of face1
#neighbour of face2
......
)

neighbours文件的范例为

1300
(
22
68
29
96
31
34
......
)

boundary
boundary文件存放的是计算域的边界列表,每个边界类型所含的面将作为一个patch存在,并赋予名字。每个边界patch的类型将用其所含面的总数(nFaces)和起始面标识(startFace)来指定。换言之,对于面而言,首先标识的是内部面,然后再标识外部边界面,而每个boundary patch上的面将被连续标识,以便在boundary中指定名字与类型。

boundary patch的格式为

#boundary patch name
{
type #patchtype;
nFaces #number of face in patch set;
startFace #starting face index for patch;
}

boundary patch的范例如下,即从1300号到1399号面命名为wall-4,其边界类型为壁面。

wall-4
{
type wall;
nFaces 100;
startFace 1300;
}

有人可能会很好奇?为啥没有单元的面标识列表呢?因为完全不需要,owners和neighbours就完全标清楚了面和单元的编码关系,由这些关系就足以得到element-faces的标识关系,没必要再多此一举地整上一个单元所含面标识的列表文件出来。而且,FVM的计算中大多是做面循环,而较少会用到单元循环,所以以面为基础的数据架构是很实用的。

1.3 uFVM网格

uFVM读入的是OpenFOAM的网格文件,用的是cfdOpenFoamMesh(2018年V1.5版本中是cfdReadPolyMesh)函数,这个函数依次去读取points、faces、owner、neighbour、boundary文件信息,并后处理来获得额外的elements、points的拓扑信息。

网格读取并重构拓扑关系成功后,将存储在一个结构体当中,以elbow算例为例,完成cfdOpenFoamMesh后,mesh的信息如下(注意,在V1.5版本的uFVM中是把这些几何信息和拓扑信息全部一股脑地存放在global变量Region的mesh中,而在老版本中(书上那样子)是分开来分别存放在mesh下面的nodes、faces、elements和boundaries里面,这里还是以书本为例把,毕竟分开存放更便于理解数据架构,虽然寻访的时候要两层剥离稍微麻烦点)。mesh的详情如下

m = cfdReadOpenFoamMesh('elbow')
m =nodes: [1x1074 struct]		% 1074个节点的信息列表numberOfNodes: 1074 				% 节点总数为1074caseDirectory: 'elbow'				% 算例名字elblownumberOfFaces: 3290				% 面总数为3290numberOfElements: 918					% 单元总数为918 faces: [1x3290 struct]		% 3290个面的信息列表numberOfInteriorFaces: 1300				% 内部面总数为1300boundaries: [1x6 struct]		% 6个boundary patch的信息列表numberOfBoundaries: 6					% 边界的数目为6(这个量好像跟下面的重复了!)numberOfPatches: 6					% 边界patch的数目为6elements: [1x918 struct]		% 918个单元的信息列表numberOfBElements: 1990				% 边界单元数目为1990numberOfBFaces: 1990				% 边界面的数目为1990,这个与边界单元的数目是一致的

这个网格可以用cfdPlotMesh函数将其可视化
在这里插入图片描述

在nodes列表中,每个元素为一个结构体,代表着第i个节点的信息(注意不同于c++,matlab列表的下标是从1开始算的),那么第1个节点的信息如下

n1= m.nodes(1)
n1 =centroid: [3x1 double]							% 节点形心坐标,即节点的坐标x,y,zindex: 1										% 节点整体标识(编号,编码)iFaces: [172 328 1355 1386 1677 1891 1893]	% 节点被哪些面所享有,这些面的标识列表iElements: [112 219 220]							% 节点被哪些单元所享有,这些单元的标识列表

在faces列表中,每个元素为一个结构体,代表着第i个面的信息,以第3个面为例

m.faces(3)
ans =iNodes: [45 82 619 582]	% 构成该面的节点列表index: 3					% 该面的标识iOwner: 3					% 该面owner单元标识iNeighbour: 30					% 该面neighbour单元标识(若为边界面,则该标识为-1)centroid: [3x1 double] 		% 该面形心坐标x,y,zSf: [3x1 double]		% 该面的面积矢量Sx,Sy,Szarea: 5.3046				% 该面的面积SCN: [3x1 double]		% 该面所属单元形心到该面形心的距离矢量CfgeoDiff: 4.5940				% ?面几何扩散系数 gDiff_f = Ef / CF,见第8章T: [3x1 double]		% 面所属单元和邻近单元形心之间的距离矢量CF?(感觉更像是Tf=Sf-CF为非正交修正矢量,见第8章内容)gf: 0.4226				% 面插值中的几何权重系数gfwalldist: 0					% 面所属单元形心到壁面的垂直距离(某些湍流模型中会用到)iOwnerNeighbourCoef: 1					% ?iNeighbourOwnerCoef: 1					% ?

在elements列表中,每个元素为一个结构体,存放着第i个单元的信息,以第20个单元为例

m.elements(20)
ans =index: 20						% 该单元标识iNeighbours: [100 103]				% 该单元的邻近单元(与该单元共享面的那些单元)标识列表iFaces: [33 34 1317 1493 1494]  % 构成该单元的面标识列表iNodes: [168 79 616 705 617 80] % 构成该单元的节点标识列表volume: 3.2484					% 该单元体积faceSign: [1 1 1 1 1]				% 该单元的构成面是否为其owner面(==1)或neighbour(==-1)numberOfNeighbours: 2						% 该单元邻近单元数目centroid: [3x1 double]			% 该单元的形心坐标x,y,z

注意,单元标识和面标识是统一的,以保证两者间在逻辑上的属从关系,边界面是在内部面之后才开始编号的。可以用cfdPlotElements来标明特定的单元,如

cfdPlotElements([20 300])

在这里插入图片描述

m.elements(300)
ans =index: 300iNeighbours: [278 302 590]iFaces: [407 435 436 2053 2054]iNodes: [283 820 679 142 290 827]volume: 1.9083faceSign: [-1 1 1 1 1]numberOfNeighbours: 3centroid: [3x1 double]

20单元位于左上角蓝色的,300单元位于右下角红色的表示。20单元确实有两个邻近面,有5个构成面(2维网格展向拉伸成3维后,展向前后还有俩面);300单元有3个邻近面,有5个构成面,其体积是小于20单元的;与前面给出的信息是一致的。

最后给出的是boundary patches的信息,存放在boundaries列表中,每个元素为一个结构体,存放着第i个边界片的信息,以第1个边界片为例

>> m. boundaries(1)
ans =userName: 'wall-4'	% 该边界片的名字(用户随便起的名字)index: 1			% 该边界片的标识type: 'wall'		% 该边界片的类型(物理类型,这里是壁面)numberOfBFaces: 100			% 该边界片的面总数为100个startFace: 1301		% 该边界片的起始面标识为1301

也就是说,第1-1300都是内部面,而从1301开始的后面那些面都是边界面(再啰嗦一句,C++下标从0开始,matlab下标从1开始,所以这里uFVM中是1301,而OpenFOAM中是1300),那么咱们看下1301号面这个边界面的信息是什么

>> m.faces(1301)
ans =iNodes: [38 53 590 575]index: 1301iOwner: 1iNeighbour: -1centroid: [3x1 double]Sf: [3x1 double]area: 3.7510CN: [3x1 double]geoDiff: 5.6264T: [3x1 double]gf: 1walldist: 0.6667iOwnerNeighbourCoef: []iNeighbourOwnerCoef: []

这些信息中可以发现边界面与内部面的不同之处,即边界面的neighbour单元是没有的(标识为-1),边界面的几何权重系数gf为1。

那么,如果要对对某个边界patch做循环的话,该如何处理呢?对这个边界patch的起始面和终止面循环就好了,比如要对boundary patch的第2个patch的面做循环,可以这样子

theMesh = cfdGetMesh;
iPatch = 2;
iBFaces = cfdGetFaceIndicesForBoundaryIndex(iPatch)
for iBFace = iBFacestheBFace = theMesh.faces(iBFace);disp(theBFace) %display theBFace internal fields
end

cfdGetFaceIndicesForBoundaryIndex是这样定义的

theIndices = cfdGetFaceIndicesForBoundaryIndex(theBoundaryIndex)
%
theBoundary = cfdGetBoundary(theBoundaryIndex);
theNumberOfBFaces = theBoundary.numberOfBFaces; 				% 该片边界所含面的数目
theStartFace = theBoundary.startFace;							% 起始面标识
theIndices = [theStartFace:theStartFace+theNumberOfBFaces-1];	%  起始面标识 到 起始面标识+边界片的面总数-1
%
end

最后,再看下新版本(2018 V1.5版本)uFVM中的mesh信息,其实和上面是一样的,只是糅一起了。

global Region
>> Region.meshans = nodeCentroids: [1074x3 double]numberOfNodes: 1074faceNodes: {3290x1 cell}numberOfFaces: 3290owners: [3290x1 double]numberOfInteriorFaces: 1300numberOfBFaces: 1990neighbours: [1300x1 double]numberOfElements: 918numberOfBElements: 1990cfdBoundaryPatchesArray: {6x1 cell}numberOfBoundaryPatches: 6closed: 0elementNeighbours: {918x1 cell}elementFaces: {918x1 cell}elementNodes: {918x1 cell}upperAnbCoeffIndex: [1300x1 double]lowerAnbCoeffIndex: [1300x1 double]nodeElements: {1074x1 cell}nodeFaces: {1074x1 cell}elementCentroids: [918x3 double]elementVolumes: [918x1 double]faceCentroids: [3290x3 double]faceSf: [3290x3 double]faceAreas: [3290x1 double]faceWeights: [3290x1 double]faceCF: [3290x3 double]faceCf: [3290x3 double]faceFf: [3290x3 double]wallDist: [3290x1 double]wallDistLimited: [3290x1 double]

1.4 uFVM Geometric Field(不同几何位置上的变量场)

在FVM的求解的过程中,已知变量、待求变量、中间变量的信息经常被存放在不同的地方,如单元形心、面形心、角点(节点)处,而变量的类型又有标量、向量、矢量之分,因此便有了位于单元、面、节点处的标量、向量、矢量场这么众多不同类型的场。

1.4.1 Element Fields(存储在单元上的场)

单元场可以用如下函数来定义

cfdSetupMeshField(theUserName, theLocale, theType, theTimeStep)

其中theUserName为该场的名字,theLocale为该场在几何意义上的存储位置(Elements, Faces, Nodes),即存放在单元、面还是节点上,theType为存放变量的类型(Scalar或Vector),标量还是矢量,最后的theTimeStep表明该场的不同时刻(Step0, Step1, 等),例如

>> UField = cfdSetupMeshField('U:water','Elements','Vector','Step0')
UField =userName: 'U:water'name: 'U_fluid01'type: 'Vector'locale: 'Elements'phi: [2908x3 double]

便定义了一个存储在单元形心上的矢量场,其存储的时间步是Step0,即,当前时间步。

在这里插入图片描述

如上图,该变量数组的长度是NumberOfElements + NumberOfBoundaryFaces,即,单元数目 + 边界面数目。也就是说,虽然是存储在单元上的场,但是把边界面也当成一种特殊类型的单元,所以单元场上存的变量值,既有每个单元上的值,**也有边界面上的值,边界面的值是作为单元场的边界条件存在的!**它们是按照先单元后边界面的顺序排列的。

那么,如果要把UField在patch1上的边界值设成[1 0 0]该如何做呢?如下

% get the mesh
theMesh = cfdGetMesh;						% 提取网格
% get information about the boundary patch	% 提取boundary patch信息
theBoundary = theMesh.boundaries(iPatch);	% 拿出第iPatch个boundary patch的信息
numberOfElements = theMesh.numberOfElements;			% 整体单元数目
numberOfInteriorFaces = theMesh.numberOfInteriorFaces;	% 整体内部面数目
numberOfBFaces = theBoundary.numberOfBFaces;			% 整体边界面数目
% Starting face
iFaceStart = theBoundary.startFace;						% 第iPatch个boundary patch的起始面标识% get information about starting and ending elements
% 第iPatch个boundary patch在Element Fields中,起始单元标识的计算为
% 起始单元标识 = 整体单元数目 + (第iPatch个边界patch的开始面标识 - 内部面数目)
iElementStart = numberOfElements+iFaceStart-numberOfInteriorFaces;% 第iPatch个boundary patch在Element Fields中,结束单元标识的计算为
% 结束单元标识 = 起始单元标识 + (第iPatch个边界patch的面数目 - 1)
iElementEnd = iElementStart+numberOfBFaces-1;% define the indices as an index array
iBElements = iElementStart:iElementEnd;	% 起始单元标识 到 结束单元标识
>> UField.phi(iBElements,:) =
cfdComputeFormulaAtLocale('[1;0;0]','BPatch1','Vector')
ans =1    0    01    0    01    0    0
......

其中的

cfdComputeFormulaAtLocale(theFormula,theLocale,theType)

计算在theLocale处的theFormla的值,并且返回特定长度的theType(Scalar 或 Vector)数组。

1.4.2 Face Fields(存储在面上的场)

面场是存储位置在面上的场,即theLocale设置为’Faces’的场

cfdSetupMeshField(theUserName, theLocale, theType, theTimeStep)

在这里插入图片描述这里,数组的长度就是整体面的数目了,即内部面数目 + 外部边界面数目,即numberOfFaces = numberOfInteriorFaces + numberOfBoundaryFaces

对于某个边界片boundary patch的边界面的访问方法如下

theMesh = cfdGetMesh; 									% 提取网格
numberOfElements = theMesh.numberOfElements; 			% 整体单元数目
numberOfInteriorFaces = theMesh.numberOfInteriorFaces; 	% 内部面数目
theBoundary = theMesh.boundaries(iPatch); 				% 提取出第i个边界片boundary patch
numberOfBFaces = theBoundary.numberOfBFaces; 			% 第i个boundary patch(该片边界)的边界面数目
%
iFaceStart = theBoundary.startFace;		% 该片边界的开始边界面标识
iFaceEnd = iFaceStart+numberOfBFaces-1; % 该片边界的结束边界面标识 = 起始面标识 + 边界面总数 - 1
iBFaces = iFaceStart:iFaceEnd;			% 该片边界面标识范围
%
iElementStart = numberOfElements+iFaceStart-numberOfInteriorFaces; 	% 该片边界的起始单元标识
iElementEnd = iElementStart+numberOfBFaces-1;						% 该片边界的结束单元标识
iBElements = iElementStart:iElementEnd;								% 该片边界的单元范围
thBFaces = theMesh.faces(iBFaces)		% 取出该片边界的边界面信息(几何与拓扑信息)

如果要取出该片边界boundary patch的边界单元值,则可用(phi是单元场)

phi_b = phi[iBElements];

1.4.3 Node Fields (存储在节点上的场)

这个比较简单,就是在节点上存放的变量场,数组的长度就是节点的整体数目,节点也不用区分什么内部边界外部边界的,所以没啥好赘述的。
在这里插入图片描述

1.5 uFVM网格的对应操作

在离散和求解过程中,最常见的操作莫过于对单元、内部面、边界面、边界单元、或边界片(boundary patch)的循环遍历操作了。那么它们要如何实现呢?

1.5.1 单元循环遍历

做单元标识从1到numberOfElements(0到numberOfElements-1)的循环就好了,不管是对单元几何拓扑信息的提取,还是对单元场变量的提取,都是一样的,如下

for iElement=1:numberOfElementstheElement = theMesh.elements(iElement) % 取出第iElement个单元的拓扑几何信息phi(iElement) % this is field phi at centroid of element iElement	% 取出第iElement个单元形心上存放的物理量phi值....
end

如果要对边界单元做循环处理,如下

% 对于边界单元(只有单元场才有边界单元的概念)做循环
% 循环范围从 整体单元数目+1 到 整体单元数目 + 边界面数目(边界面数目等于边界单元的数目)
for iBElement = numberOfElements + 1: numberOfElements + numberOfBFacesphi(iBElement) = 0;			% 将边界单元上的phi值设为0
end

1.5.2 面循环遍历

面的编码是先做内部面编码,然后再依次对边界面做编码,因此,若对内部面做循环,只需要从1到numberOfInteriorFaces循环就好了,即

for iFace=1:numberOfInteriorFacestheFace = theMesh.faces(iFace)	% 取出第iFace个面的几何拓扑信息
end

如果要对边界面做循环,则

for iBFace= numberOfInteriorFaces+1:numberOfFacestheBFace = theMesh.faces(iBFace)
end

如果要对特定某片的boundary patch的边界面做循环,则

startFace = theMesh.boundaries(n).startFace	% 第n个boundary patch的起始面标识
nFaces = theMesh.boundaries(n).nFaces		% 第n个boundary patch的边界面数目 
for iBFace = startFace: startFace+nFaces-1	% 循环范围从起始面 到 起始面+该片边界面总数目-1 即可...
end

当然,可以用函数cfdGetFaceIndicesForBoundaryIndex直接获得循环范围startFace: startFace+nFaces-1。

1.6 计算Gauss Gradient

在uFVM中,对于单元形心处梯度值的计算是在函数CFDComputerGradientGauss0中进行的,0表示没有非正交修正操作,具体细节可以参考函数代码,由于这部分内容和第9章的梯度计算是重复的,而第9章中除了提及单元中心梯度,还讲了面中心梯度,节点梯度的算法,所以直接参考第9章的代码讲解就好了。

2 OpenFOAM

to be continued…


http://chatgpt.dhexx.cn/article/Wsi8U02y.shtml

相关文章

fvm操作多个flutter的安装和使用教程

win下使用fvm实现多个Flutter版本的切换 配置前说明:Win环境下,下载FVM时,需要先配置一个Dart环境,因为用到 dart pub命令 1. 配置Dart环境 a. 方式一:可以去Dart官网下载安装 官网地址:https://…

使用fvm管理多个flutter版本

安装独立的dart环境 官方安装方法:https://dart.dev/get-dart brew tap dart-lang/dart brew install dart更新dart版本: brew upgrade dart重新安装dart: brew reinstall dart查看当前dart版本: $ dart --version Dart SDK vers…

fvm管理多个Flutter版本(Win10安装记录)

文章目录 FVM官网参考1.安装2.配置FVM环境变量3.修改一下fvm文件缓存地址,以免以后下载的flutter sdk下载到C盘4. 默认fvm的下载地址是在C盘,修改fvm缓存地址5.下载安装Flutter SDK6. 将原来电脑上的SDK复制到E:\Flutter\FlutterSDK\ 下改名为版本号7.系…

Flutter FVM 版本管理

Fvm 安装 尝试方案 目前可行性的方案 中间可能失败的原因 尝试过四套博客上的方案,最终只有上面哪一个成功了,后来总结了一下那些方案的套路都是一样的,而且应该都是可行的(因为其他同事都成功了)例如:…

使用FVM管理Flutter SDK版本切换

window下配置fvm版本切换工具,管理flutter sdk版本的切换 一、配置flutter dart环境 使用前需要先配置flutter dart环境,才能下载jvm 已经配置好环境的,在命令框中输入dart --version验证是否安装成功 C:\Users\topqizhi>dart --versi…

基于FVM的应力求解

FVM:有限体积法,作为一种有限元处理方法,在弹性力学领域得到了广泛应用。该方法主要利用Navier-Stocks方程对多面体(polyhedral)网格进行空间离散。本文旨在针对线弹性材料边界应力问题进行分析。 本文主要解决单一材料…

【Flutter】macOS从零开始使用FVM搭建Flutter开发环境

前言 本文为个人记录macOS系统使用fvm从零开始搭建flutter开发环境到项目运行的过程,非教程性质,仅供参考,如有疑问或建议,欢迎大家在评论区留言 附上开发设备配置 一、安装vscode 以vscode为编码工具 下载地址:Do…

flutter fvm 版本控制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EjoR1x37-1626914814179)(https://ducafecat.tech/2021/07/22/translation/version-management-in-flutter/2021-07-22-08-39-22.png)] 老铁记得 转发 ,猫哥会呈现更多 Flutter 好文~~~~ …

Flutter之fvm管理版本

对于flutter SDK版本,相信很多人都有深有体会,项目多了以后,可能每个项目使用的SDK都不同。 我个人的经历是:官方从2.12版本推出空安全版本,由于最初的项目用的空安全之前版本,老项目无法尽数适配空安全&a…

flutter版本控制工具 `FVM`

文章目录 FVM 切换VSCode 的Flutter版本在windows上安装fvm方法一:先安装 choco检查安装是否成功 常用指令接下来安装fvm方法二:pub方式安装 fvmVSCode配置安卓studio Flutter版本切换项目缓存目录列出配置 设置缓存路径配置 常用命令安装删除列出releas…

flutter 版本控制fvm

1先安装 choco powershell 管理员身份运行 不会的话,先打开一个powershell 窗口 ,然后右击任务栏,选择第一个,即可进入 输入命令 Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::Securi…

FVM - Mac上管理 Flutter 多版本的神奇

随着flutter2.0的发布,相信很多同学都是激动的心,颤动的手,想快速尝试一波,做一个吃螃蟹的人,本人也是怀揣着这样的心情,头脑一热的将本地的flutter版本更新到2.0了,螃蟹吃完了,但是…

官方蓄力已久,FVM虚拟机将使IPFS激励层生态迎来加速爆发期?

VM(Virtual Machine)指虚拟机,简单来说就是智能合约的执行引擎。 FVM指IPFS激励层公链上的虚拟机。 10月27日,胡安在万向峰会上做主题演讲时提及FVM,将社区内对于FVM的讨论推上了新顶峰。IPFS激励层官方对虚拟机的部署由来已久,社区方面也在积极讨论,此前在IPFS激励层周年…

FVM初启,Filecoin生态爆发着力点在哪?

Filecoin 小高潮 2023年初,Filecoin发文分享了今年的三项重大变更,分别是FVM、数据计算和检索市场的更新,这些更新消息在发布后迅速吸引了市场的广泛关注。 特别是在3月14日,Filecoin正式推出了FVM,这一变革使得Filec…

一篇弄懂 offsetWidth、offsetHeight、offsetleft、offsetTop和offsetParent的区别!(1)

快速理解offset之间的区别 1.offsetWidth与offsetHeight2.offsetParent3.offsetleft、offsetTop 以下代码均在Chrome浏览器中测试 1.offsetWidth与offsetHeight 1.offsetWidth:元素的布局宽度。   2.offsetHeight:元素的布局高度。   offsetWidth、o…

搞清楚 clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop

网页可见区域高:document.body.clientHeight 网页正文全文高:document.body.scrollHeight 网页可见区域高(包括边线的高):document.body.offsetHeight 网页被卷去的高:document.body.scrollTop 屏幕分辨率…

使用TS中元素使用offsetHeight,offsetTop,offsetLeft报错

使用ts后,可以使用scroll家族和client家族,但使用offset家族会报错但也能运行 报错 类型“Element”上不存在属性“offsetHeight” 原因:ts中Element类型上没有定义offsetHeight,解决如下:通过as HTMLDivElement解决…

彻底搞懂offsetHeight,clientHeight,scrollHeight,scrollTop,offsetTop

offsetHeight和clientHeight都是获取dom元素自身的高度的,它们之间的区别在于: offsetHeight:获取的高度除了自身高度外,还包含了padding和border clientHeight:获取的高度除了自身高度外,还包含了padding …

正文内容过长时,offsetHeight的获取和监听变化

正文内容过长时,超过4行隐藏,点击全部展开,可视高度(可见高度)offsetHeight的获取和监听变化_无围之解的博客-CSDN博客 核心逻辑代码 mounted() {this.$nextTick(() > {this.h1 this.$refs.div11.offsetHeight;});…

offsetHeight及其他

网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWidth (包括边线的宽) 网页可见区域高:document.body.offsetHeight (包括边线的宽) 网页正文全文宽&a…