R8-c: the 3D flag's interface — deformed-plate body (host + device φ/ub) and the conservative load transfer onto a Hex20 plate
- embedded3/plate.rs: PlateSurface (mid-surface on span stations) and the host evaluation of DeviceSdf (phi_host / velocity_host / is_flag_host), expression for expression e3_geom.cu; a span-uniform plate is the polyline capsule to the bit; first-order spanwise-slope correction. - e3_geom.cu / device/geom.rs: plate branch of geom_phi_at and body_velocity (nst = 0 keeps the polyline path unchanged). - cutwall.rs / exchange.rs: the load loops observed through a sink (sums unchanged); interface.rs: Mask::cut_wall_loads (every summand of cut_wall_force with its foot), HexPlate (R8-b's Hex20 lattice numbering), consistent point-force transfer conserving force and moment to round-off, locate() for the transpose, mid_surface() for the fluid body. - flag test: RTX_E3_FLAG_BODY=plate, _STATIONS, _TWIST, _TRANSFER(_EVERY, _CSV, _NODAL); all default off. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d63806c0e6
commit
9c2ae32061
@@ -24,6 +24,7 @@ struct GeomSdf {
|
||||
double fillet; /* root fillet radius (0: min) */
|
||||
int cyl_cut, flag_cut; /* cut to the span */
|
||||
int npts; /* polyline points (x, y interleaved) */
|
||||
int nst, ns; /* R8-c plate: stations and points per station (nst 0: the polyline) */
|
||||
};
|
||||
|
||||
struct GeomGrid {
|
||||
@@ -45,15 +46,107 @@ __device__ __forceinline__ double span_cut(double d2, double z, const GeomSdf& s
|
||||
return outside + rs_min(rs_max(q1, q2), 0.0) - r;
|
||||
}
|
||||
|
||||
/*
|
||||
* R8-c: the deformed plate (`plate.rs`, the host twin expression for
|
||||
* expression): `poly` holds the stations' rows (x, y interleaved, row-major
|
||||
* by station) followed by the stations' z. The stations bracketing z are
|
||||
* interpolated linearly into one polyline (outside their range: the end
|
||||
* station as it is), the in-plane closest point taken as the polyline's,
|
||||
* the distance corrected for the spanwise slope d / sqrt(1 + (e·c)²);
|
||||
* with `vel`, the velocity at the closest point the same way.
|
||||
*/
|
||||
__device__ double plate_dist(double x, double y, double z, const GeomSdf& s,
|
||||
const double* __restrict__ P, const double* __restrict__ V,
|
||||
double* vx, double* vy)
|
||||
{
|
||||
int nst = s.nst, ns = s.ns;
|
||||
const double* Z = P + 2 * (long long) nst * ns;
|
||||
int k = 0, interp = 0;
|
||||
double w = 0.0;
|
||||
if (nst > 1) {
|
||||
if (z <= Z[0]) {
|
||||
k = 0;
|
||||
} else if (z >= Z[nst - 1]) {
|
||||
k = nst - 2;
|
||||
} else {
|
||||
while (k + 1 < nst && Z[k + 1] <= z) ++k;
|
||||
if (k > nst - 2) k = nst - 2;
|
||||
}
|
||||
interp = 1;
|
||||
w = (z - Z[k]) / (Z[k + 1] - Z[k]);
|
||||
/* beyond the end stations: at most half an interval extrapolated */
|
||||
if (w < -0.5) w = -0.5;
|
||||
if (w > 1.5) w = 1.5;
|
||||
}
|
||||
const double* R0 = P + 2 * (long long) k * ns;
|
||||
const double* R1 = interp ? R0 + 2 * ns : R0;
|
||||
double best = 1.0 / 0.0, ub = 0.0, qbx = 0.0, qby = 0.0;
|
||||
int mb = 0;
|
||||
for (int m = 0; m + 1 < ns; ++m) {
|
||||
double ax, ay, bx, by;
|
||||
if (interp) {
|
||||
ax = R0[2 * m] + w * (R1[2 * m] - R0[2 * m]);
|
||||
ay = R0[2 * m + 1] + w * (R1[2 * m + 1] - R0[2 * m + 1]);
|
||||
bx = R0[2 * m + 2] + w * (R1[2 * m + 2] - R0[2 * m + 2]);
|
||||
by = R0[2 * m + 3] + w * (R1[2 * m + 3] - R0[2 * m + 3]);
|
||||
} else {
|
||||
ax = R0[2 * m]; ay = R0[2 * m + 1];
|
||||
bx = R0[2 * m + 2]; by = R0[2 * m + 3];
|
||||
}
|
||||
double ex = bx - ax, ey = by - ay;
|
||||
double l2 = ex * ex + ey * ey;
|
||||
double u = ((x - ax) * ex + (y - ay) * ey) / l2;
|
||||
if (u < 0.0) u = 0.0;
|
||||
if (u > 1.0) u = 1.0;
|
||||
double px = ax + u * ex, py = ay + u * ey;
|
||||
double qx = x - px, qy = y - py;
|
||||
double d = sqrt(qx * qx + qy * qy);
|
||||
if (d < best) {
|
||||
best = d;
|
||||
mb = m;
|
||||
ub = u;
|
||||
qbx = qx;
|
||||
qby = qy;
|
||||
}
|
||||
}
|
||||
if (interp && best > 0.0) {
|
||||
double dz = Z[k + 1] - Z[k];
|
||||
double cax = R1[2 * mb] - R0[2 * mb], cay = R1[2 * mb + 1] - R0[2 * mb + 1];
|
||||
double cbx = R1[2 * mb + 2] - R0[2 * mb + 2], cby = R1[2 * mb + 3] - R0[2 * mb + 3];
|
||||
double cx = (cax + ub * (cbx - cax)) / dz;
|
||||
double cy = (cay + ub * (cby - cay)) / dz;
|
||||
double qn = (qbx * cx + qby * cy) / best;
|
||||
best = best / sqrt(1.0 + qn * qn);
|
||||
}
|
||||
if (V) {
|
||||
const double* V0 = V + 2 * (long long) k * ns;
|
||||
const double* V1 = interp ? V0 + 2 * ns : V0;
|
||||
double avx, avy, bvx, bvy;
|
||||
if (interp) {
|
||||
avx = V0[2 * mb] + w * (V1[2 * mb] - V0[2 * mb]);
|
||||
avy = V0[2 * mb + 1] + w * (V1[2 * mb + 1] - V0[2 * mb + 1]);
|
||||
bvx = V0[2 * mb + 2] + w * (V1[2 * mb + 2] - V0[2 * mb + 2]);
|
||||
bvy = V0[2 * mb + 3] + w * (V1[2 * mb + 3] - V0[2 * mb + 3]);
|
||||
} else {
|
||||
avx = V0[2 * mb]; avy = V0[2 * mb + 1];
|
||||
bvx = V0[2 * mb + 2]; bvy = V0[2 * mb + 3];
|
||||
}
|
||||
*vx = avx + ub * (bvx - avx);
|
||||
*vy = avy + ub * (bvy - avy);
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
__device__ double geom_phi_at(double x, double y, double z, const GeomSdf& s, const double* __restrict__ poly)
|
||||
{
|
||||
/* the circle */
|
||||
double ex0 = x - s.cx, ey0 = y - s.cy;
|
||||
double dc = sqrt(ex0 * ex0 + ey0 * ey0) - s.rc;
|
||||
if (s.cyl_cut) dc = span_cut(dc, z, s);
|
||||
/* the capsule: distance to the polyline */
|
||||
/* the capsule: distance to the polyline (or the plate, R8-c) */
|
||||
double best = 1.0 / 0.0;
|
||||
for (int m = 0; m + 1 < s.npts; ++m) {
|
||||
if (s.nst > 0) best = plate_dist(x, y, z, s, poly, nullptr, nullptr, nullptr);
|
||||
else for (int m = 0; m + 1 < s.npts; ++m) {
|
||||
double ax = poly[2 * m], ay = poly[2 * m + 1];
|
||||
double bx = poly[2 * m + 2], by = poly[2 * m + 3];
|
||||
double ex = bx - ax, ey = by - ay;
|
||||
@@ -299,7 +392,8 @@ __device__ double body_velocity(double x, double y, double z, int c, const GeomS
|
||||
const double* __restrict__ poly, const double* __restrict__ vel)
|
||||
{
|
||||
double best = 1.0 / 0.0, vx = 0.0, vy = 0.0;
|
||||
for (int m = 0; m + 1 < s.npts; ++m) {
|
||||
if (s.nst > 0) best = plate_dist(x, y, z, s, poly, vel, &vx, &vy);
|
||||
else for (int m = 0; m + 1 < s.npts; ++m) {
|
||||
double ax = poly[2 * m], ay = poly[2 * m + 1];
|
||||
double bx = poly[2 * m + 2], by = poly[2 * m + 3];
|
||||
double ex = bx - ax, ey = by - ay;
|
||||
|
||||
Reference in New Issue
Block a user