我的构思是,我采样了2000组工况,每组工况下都提取了.csv表格,里面有每个节点的xyz坐标以及温...
Criado em: 26 de dezembro de 2025
Respondido usando GPT-5.2 Thinking por Chat01
Criado em: 26 de dezembro de 2025
Respondido usando GPT-5.2 Thinking por Chat01
pythonimport pandas as pd, os, numpy as np, textwrap, json, re, math path="/mnt/data/3D.csv" df=pd.read_csv(path) df.head(), df.shape, df.columns[:20]
pythonimport itertools, pandas as pd, numpy as np, re, os, math path="/mnt/data/3D.csv" # find line number of [Faces] faces_line=None with open(path,'r',errors='ignore') as f: for i,line in enumerate(f, start=1): if line.strip()=="[Faces]": faces_line=i break faces_line 123602
pythonimport pandas as pd, numpy as np nrows=123602-7 df_nodes=pd.read_csv(path, skiprows=5, nrows=nrows, skipinitialspace=True) df_nodes.head(), df_nodes.shape ( Node Number X [ m ] Y [ m ] Z [ m ] Bulk Temperature [ K ] 0 0 0.283122 0.002321 0.068789 726.500977 1 1 0.283122 0.002847 0.067341 726.790833 2 2 0.284000 -0.016653 0.125241 790.092224 3 3 0.284000 -0.018272 0.125241 790.110840 4 4 0.284295 -0.017976 0.124533 790.202209, (123595, 5))
pythonimport pandas as pd, numpy as np, re path="/mnt/data/3D.csv" faces=[] with open(path,'r',errors='ignore') as f: in_faces=False for line in f: s=line.strip() if s=="[Faces]": in_faces=True continue if not in_faces: continue if not s: continue # each face line: ints separated by comma parts=[p.strip() for p in s.split(',')] # some might have 3 or 4 nodes try: idx=[int(p) for p in parts if p!=''] except: continue faces.append(idx) len(faces), faces[0], set(map(len,faces)) (77717, [50213, 38683, 40594, 50219], {3, 4})
pythonfrom collections import defaultdict edges=set() for face in faces: m=len(face) # connect in cycle for i in range(m): a=face[i]; b=face[(i+1)%m] if a==b: continue if a<b: edges.add((a,b)) else: edges.add((b,a)) len(edges), list(edges)[:5] (130801, [(16623, 16624), (21356, 21358), (30232, 30233), (23589, 23659), (54816, 54826)])
pythonimport numpy as np deg=np.zeros(df_nodes.shape[0], dtype=np.int32) for a,b in edges: deg[a]+=1; deg[b]+=1 deg.min(), deg.max(), deg.mean(), np.percentile(deg,[50,90,99]) (0, 11, 2.1166066588454227, array([0., 6., 7.]))
pythonused_nodes=set() for face in faces: used_nodes.update(face) len(used_nodes), df_nodes.shape[0], len(used_nodes)/df_nodes.shape[0] (52894, 123595, 0.4279622962093936)
pythonN=df_nodes.shape[0] F=len(faces) tri=sum(1 for f in faces if len(f)==3) quad=F-tri used=len(used_nodes) E=len(edges) N,F,tri,quad,used,E (123595, 77717, 49266, 28451, 52894, 130801)
可以的,而且这是一个很常见、也很“省输出维度”的路线:POD(=PCA)先把每个工况的三维温度场压成少量系数,再用(图)网络去预测这些系数,最后用 POD 基底把温度场重构回 每个节点的三维分布。
我先基于你给的这个示例表格看了一下结构(它不是纯 CSV,而是带分段的导出格式):
[Data] 段:每行是一个节点 Node Number, X, Y, Z, Bulk Temperature(示例里约 123,595 个节点)[Faces] 段:每行是一张面(有三角形也有四边形),我这份里大概 77,717 个面(约 49,266 三角 + 28,451 四边形)重要提示:如果你用 Faces 建邻接,示例里只有约 52,894 个节点出现在 Faces 中(≈43%),意味着 其余节点在“Face-邻接图”里会是孤立点。
这不一定是错——但你要确认:你的 Faces 是否只包含“表面网格”,而你又希望预测“全体体网格节点”。如果是“体场”,通常需要 Elements(四面体/六面体单元连接),或改用 kNN/半径图 给全体节点补连边。
POD 的前提非常关键:
如果你确实需要“全体节点都有邻居”,而 Faces 又覆盖不全:
方案 A: 用 Elements(体单元)建连边(最物理)
方案 B: 对所有节点用 kNN / radius graph 建连边(工程上常用,MeshGraphNet 也常这么干)
把 2000 个工况的温度向量堆成快照矩阵:
做 SVD / snapshots 方法得到 POD 模态 ,并取能量累计(比如 99%)选择 r:
预测时重构:
工程细节(很关键)
你提到“把邻接矩阵输入网络”,那通常是 GNN 编码器:
xyz+adjacency 对所有工况都一样 → 网络无法区分工况,会学不出来两种常见建模方式:
预测得到的是每个节点温度 ,你已经有每个节点的 xyz 坐标,所以天然就是“三维场”(在离散节点上)。
如果你愿意,我可以直接按你这份文件格式给你一个可复用的数据读取/建图模板(把 [Data] 和 [Faces] 两段解析成 pos、T、edge_index),再给一个 POD(snapshots 法)+ 预测系数 + 重构 的训练骨架(PyTorch / PyG)。你把“工况输入是什么”(标量参数表?还是某些边界节点的值?)按你现有数据告诉我一句,我就按你的输入形式把网络那部分对上。
import pandas as pd
import numpy as np
import torch
import scipy.io as sio
import h5py
from sklearn.decomposition import PCA
from sklearn.decomposition import TruncatedSVD
def pca_reduction(data, n_components=2):
"""
使用PCA对数据进行降维
text:param data: 要降维的数据 [num_samples, num_features] :param n_components: 降维后的维度数 :return: 降维后的数据 """ pca = PCA(n_components=n_components) reduced_data = pca.fit_transform(data) return reduced_data
def pod_reduction(temperature_data, n_components=5):
"""
对温度数据进行POD降维。
text:param temperature_data: 每个节点的温度数据,假设是一个二维数组 [num_samples, num_features] :param n_components: 降维后的维度数 :return: 降维后的数据 """ return pca_reduction(temperature_data, n_components)
def svd_reduction(matrix, n_components=10):
"""
对邻接矩阵进行SVD降维
:param matrix: 邻接矩阵 [num_nodes, num_nodes]
:param n_components: 降维后的维度数
:return: 降维后的矩阵
"""
svd = TruncatedSVD(n_components=n_components)
reduced_matrix = svd.fit_transform(matrix)
return reduced_matrix
nodes = []
elems = []
index = []
num = sio.loadmat('index.mat')
num = num['index']
num=num.T.reshape(-1)
for i in num:
try:
CSV_FILE_PATH = 'H:\CASE\case' + str(i) + '\3D.csv'
df = pd.read_csv(CSV_FILE_PATH, header=3)
ind = df.iloc[:, 0] == '[Faces]'
elem_start = ind[ind.values==True].index
elem_start = elem_start[0]
node = df.iloc[:elem_start, 1:]
elem = df.iloc[elem_start+1:, :5]
textkk = pd.notnull(elem) tt = np.array(kk) ind_5 = np.where(tt[:, 4] == False)[0] ind_4 = np.where(tt[:, 3] == False)[0] if len(ind_4) == 0: elem = df.iloc[elem_start + 1:, :4] elems.append(np.array(elem, dtype=np.int32), ) nodes.append(np.array(node, dtype=np.float32)[:, (0, 1, 2, 3)], ) print(i) index.append(i) else: elem_5_end = ind_5[0] elem_4_end = ind_4[0] elem5 = elem.iloc[:elem_5_end, :] elem4 = elem.iloc[elem_5_end:elem_4_end, :4] elem3 = elem.iloc[elem_4_end:, :3] elems.append((np.array(elem5, dtype=np.int32), np.array(elem4, dtype=np.int32), np.array(elem3, dtype=np.int32))) nodes.append(np.array(node, dtype=np.float32)[:, (0, 1, 2, 3)], ) print(i) index.append(i) # CSV_FILE_PATH = 'H:\\case' + str(i + 1) + '\\dc-rfile.out' # df = pd.read_csv(CSV_FILE_PATH, header=3) # cl = df.iloc[:2] # # CSV_FILE_PATH = 'H:\\case' + str(i + 1) + '\\df-rfile.out' # df = pd.read_csv(CSV_FILE_PATH, header=3) # cd = df.iloc[:2] except: # nodes.append(np.zeros((num_node[j], 12), dtype=np.float32)) nodes.append([]) elems.append([]) continue
coordinates = np.concatenate([node[:, :3] for node in nodes], axis=0) # 提取所有节点的坐标
coordinates_reduced = pca_reduction(coordinates, n_components=2) # 将坐标降到2维
temperature_data = np.concatenate([node[:, 3:] for node in nodes], axis=0) # 提取所有节点的温度数据
temperature_reduced = pod_reduction(temperature_data, n_components=5) # 将温度数据降到5维
final_node_data = np.concatenate([coordinates_reduced, temperature_reduced], axis=1)
adj_matrix_reduced = svd_reduction(adj_matrix, n_components=10) # 进行SVD降维
torch.save({'nodes': nodes, 'elems': elems, 'index': index}, 'nodes-elem_0.25span_2000.pth')
上面是针对data_pro程序的修改,你看其他程序是否需要修改?降维,训练,再升维输出