import numpy as np from skfem import Mesh def get_element_midpoints(mesh: Mesh, transpose: bool = True) -> np.ndarray: midpoints = np.mean(mesh.p[:, mesh.t], axis=1) return midpoints.T if transpose else midpoints # 算三个顶点的mean/std/... def get_aggregation_per_element( solution: np.ndarray, element_indices: np.ndarray, aggregation_function_str: str = "mean", ) -> np.ndarray: vals = solution[element_indices] if aggregation_function_str == "mean": return vals.mean(axis=1) elif aggregation_function_str == "std": return vals.std(axis=1) elif aggregation_function_str == "min": return vals.min(axis=1) elif aggregation_function_str == "max": return vals.max(axis=1) elif aggregation_function_str == "median": return np.median(vals, axis=1) raise ValueError(f"Unknown aggregation function: {aggregation_function_str}") # 计算三角形面积 def get_triangle_areas_from_indices( positions: np.ndarray, triangle_indices: np.ndarray ) -> np.ndarray: i0, i1, i2 = triangle_indices[:, 0], triangle_indices[:, 1], triangle_indices[:, 2] return np.abs(0.5 * ( (positions[i1, 0] - positions[i0, 0]) * (positions[i2, 1] - positions[i0, 1]) - (positions[i2, 0] - positions[i0, 0]) * (positions[i1, 1] - positions[i0, 1]) )) # penalty:\alpha的采样方式 def sample_in_range(max_value: float, min_value: float, sampling_type: str) -> float: if sampling_type == "uniform": return np.random.uniform(min_value, max_value) elif sampling_type == "loguniform": return np.exp(np.random.uniform(np.log(min_value), np.log(max_value))) raise ValueError(f"Unknown sampling type: {sampling_type}") def construct_sizing_field_1d(x: np.ndarray, eps: float = 1e-4) -> np.ndarray: """Softplus 激活 → 目标网格面积 (numpy 版)。""" def _softplus(x): return np.log1p(np.exp(np.clip(x, -50, 50))) x = np.atleast_1d(np.asarray(x, dtype=np.float64)) return _softplus(x) + eps