or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-execution.mdfem.mdframework-integration.mdindex.mdkernel-programming.mdoptimization.mdrendering.mdtypes-arrays.mdutilities.md

fem.mddocs/

0

# Finite Element Method (FEM)

1

2

Warp's finite element framework provides comprehensive tools for solving partial differential equations using the finite element method. It includes geometry definitions, function spaces, quadrature, field operations, and integration capabilities for numerical simulation of physical phenomena.

3

4

## Capabilities

5

6

### Geometry Types

7

8

Geometric domains for finite element discretization.

9

10

```python { .api }

11

class Grid2D:

12

"""Regular 2D grid geometry."""

13

14

def __init__(self, res_x: int, res_y: int):

15

"""Create 2D grid with specified resolution."""

16

17

class Grid3D:

18

"""Regular 3D grid geometry."""

19

20

def __init__(self, res_x: int, res_y: int, res_z: int):

21

"""Create 3D grid with specified resolution."""

22

23

class Tetmesh:

24

"""Tetrahedral mesh geometry."""

25

26

def __init__(self, vertices: array, indices: array):

27

"""

28

Create tetrahedral mesh from vertices and element connectivity.

29

30

Args:

31

vertices: Array of vertex positions

32

indices: Array of tetrahedron vertex indices

33

"""

34

35

class Hexmesh:

36

"""Hexahedral mesh geometry."""

37

38

def __init__(self, vertices: array, indices: array):

39

"""Create hexahedral mesh from vertices and connectivity."""

40

41

class Trimesh2D:

42

"""2D triangular mesh geometry."""

43

44

def __init__(self, vertices: array, indices: array):

45

"""Create 2D triangular mesh."""

46

47

class Trimesh3D:

48

"""3D triangular surface mesh geometry."""

49

50

def __init__(self, vertices: array, indices: array):

51

"""Create 3D triangular surface mesh."""

52

53

class Quadmesh2D:

54

"""2D quadrilateral mesh geometry."""

55

56

def __init__(self, vertices: array, indices: array):

57

"""Create 2D quadrilateral mesh."""

58

59

class Quadmesh3D:

60

"""3D quadrilateral surface mesh geometry."""

61

62

def __init__(self, vertices: array, indices: array):

63

"""Create 3D quadrilateral surface mesh."""

64

65

class Nanogrid:

66

"""Dense voxel grid for level set methods."""

67

68

def __init__(self, data: array, transform: transform = None):

69

"""Create nanogrid from voxel data."""

70

71

class AdaptiveNanogrid:

72

"""Adaptive sparse voxel grid."""

73

74

def __init__(self, field: Field, tolerance: float = 1e-6):

75

"""Create adaptive nanogrid from field with specified tolerance."""

76

```

77

78

### Function Spaces

79

80

Mathematical spaces defining basis functions and degrees of freedom.

81

82

```python { .api }

83

class FunctionSpace:

84

"""Function space defining basis functions over geometry."""

85

86

@property

87

def dimension(self) -> int:

88

"""Number of degrees of freedom."""

89

90

@property

91

def geometry(self) -> Geometry:

92

"""Underlying geometry."""

93

94

class BasisSpace:

95

"""Basis function space on geometry elements."""

96

97

class PointBasisSpace:

98

"""Point-based basis space for meshfree methods."""

99

100

def make_polynomial_space(geometry: Geometry,

101

degree: int,

102

dtype: type = float) -> FunctionSpace:

103

"""

104

Create polynomial function space of specified degree.

105

106

Args:

107

geometry: Geometric domain

108

degree: Polynomial degree (1=linear, 2=quadratic, etc.)

109

dtype: Scalar type for degrees of freedom

110

111

Returns:

112

Function space with polynomial basis functions

113

"""

114

115

def make_polynomial_basis_space(geometry: Geometry,

116

degree: int,

117

family: str = "lagrange") -> BasisSpace:

118

"""Create polynomial basis space with specified family."""

119

120

def make_collocated_function_space(geometry: Geometry,

121

shape: tuple,

122

degree: int = 1) -> FunctionSpace:

123

"""Create collocated vector/tensor function space."""

124

125

def make_covariant_function_space(geometry: Geometry,

126

degree: int = 1) -> FunctionSpace:

127

"""Create covariant (edge-based) function space."""

128

129

def make_contravariant_function_space(geometry: Geometry,

130

degree: int = 1) -> FunctionSpace:

131

"""Create contravariant (face-based) function space."""

132

```

133

134

### Fields

135

136

Field representations and operations over function spaces.

137

138

```python { .api }

139

class DiscreteField:

140

"""Field represented by discrete degrees of freedom."""

141

142

def __init__(self, space: FunctionSpace, dof_values: array = None):

143

"""

144

Create discrete field on function space.

145

146

Args:

147

space: Function space defining basis

148

dof_values: Degree of freedom values (allocated if None)

149

"""

150

151

class ImplicitField:

152

"""Field defined by implicit function."""

153

154

def __init__(self, func: Callable, space: FunctionSpace = None):

155

"""Create field from implicit function."""

156

157

class UniformField:

158

"""Field with constant value everywhere."""

159

160

def __init__(self, value, space: FunctionSpace = None):

161

"""Create uniform field with constant value."""

162

163

class NonconformingField:

164

"""Field with non-conforming discretization."""

165

166

def make_discrete_field(space: FunctionSpace,

167

dof_values: array = None) -> DiscreteField:

168

"""Create discrete field on function space."""

169

170

def make_test(space: FunctionSpace) -> DiscreteField:

171

"""Create test function for weak forms."""

172

173

def make_trial(space: FunctionSpace) -> DiscreteField:

174

"""Create trial function for weak forms."""

175

176

def make_restriction(field: Field, domain: Domain) -> Field:

177

"""Restrict field to subdomain."""

178

```

179

180

### Quadrature

181

182

Numerical integration schemes for finite element computations.

183

184

```python { .api }

185

class Quadrature:

186

"""Base class for quadrature rules."""

187

188

class RegularQuadrature:

189

"""Regular quadrature on structured grids."""

190

191

def __init__(self, geometry: Geometry, order: int):

192

"""

193

Create regular quadrature rule.

194

195

Args:

196

geometry: Geometric domain

197

order: Integration order (accuracy)

198

"""

199

200

class NodalQuadrature:

201

"""Quadrature using mesh nodes as integration points."""

202

203

def __init__(self, geometry: Geometry):

204

"""Create nodal quadrature rule."""

205

206

class PicQuadrature:

207

"""Particle-in-cell quadrature for particle methods."""

208

209

def __init__(self, positions: array, weights: array = None):

210

"""

211

Create PIC quadrature from particle data.

212

213

Args:

214

positions: Particle positions

215

weights: Particle weights (uniform if None)

216

"""

217

218

class ExplicitQuadrature:

219

"""Explicit quadrature with specified points and weights."""

220

221

def __init__(self, points: array, weights: array):

222

"""Create quadrature from explicit points and weights."""

223

```

224

225

### Domain and Topology

226

227

Domain definitions and topological operations.

228

229

```python { .api }

230

class GeometryDomain:

231

"""Geometric domain for finite element computations."""

232

233

def __init__(self, geometry: Geometry):

234

"""Create domain from geometry."""

235

236

class Cells:

237

"""Domain representing geometry cells/elements."""

238

239

class Sides:

240

"""Domain representing element faces/edges."""

241

242

class BoundarySides:

243

"""Domain representing boundary faces."""

244

245

class FrontierSides:

246

"""Domain representing interfaces between regions."""

247

248

class SpacePartition:

249

"""Partition of function space for parallel computation."""

250

251

class SpaceRestriction:

252

"""Restriction of function space to subdomain."""

253

254

class SpaceTopology:

255

"""Topological information for function space."""

256

257

def make_space_partition(space: FunctionSpace,

258

partitions: int) -> SpacePartition:

259

"""Partition function space for parallel computation."""

260

261

def make_space_restriction(space: FunctionSpace,

262

domain: Domain) -> SpaceRestriction:

263

"""Create space restriction to subdomain."""

264

```

265

266

### Integration and Interpolation

267

268

Core operations for finite element computations.

269

270

```python { .api }

271

def integrate(integrand: Callable,

272

domain: Domain,

273

quadrature: Quadrature = None,

274

output: Field = None) -> Field:

275

"""

276

Integrate function over domain using specified quadrature.

277

278

Args:

279

integrand: Function to integrate

280

domain: Integration domain

281

quadrature: Quadrature rule (default if None)

282

output: Output field (allocated if None)

283

284

Returns:

285

Integrated field values

286

"""

287

288

def interpolate(field: Field,

289

space: FunctionSpace,

290

domain: Domain = None) -> DiscreteField:

291

"""

292

Interpolate field onto function space.

293

294

Args:

295

field: Input field to interpolate

296

space: Target function space

297

domain: Interpolation domain (geometry if None)

298

299

Returns:

300

Discrete field on target space

301

"""

302

```

303

304

### Differential Operators

305

306

Operators for computing derivatives and differential operations.

307

308

```python { .api }

309

def grad(field: Field) -> Field:

310

"""Compute gradient of scalar field."""

311

312

def div(field: Field) -> Field:

313

"""Compute divergence of vector field."""

314

315

def curl(field: Field) -> Field:

316

"""Compute curl of vector field."""

317

318

def D(field: Field, direction: int) -> Field:

319

"""Partial derivative in specified direction."""

320

321

def grad_outer(field: Field) -> Field:

322

"""Outer product of gradient."""

323

324

def div_outer(field: Field) -> Field:

325

"""Outer divergence operation."""

326

327

def deformation_gradient(field: Field) -> Field:

328

"""Compute deformation gradient tensor."""

329

330

def grad_average(field: Field) -> Field:

331

"""Average gradient across elements."""

332

333

def grad_jump(field: Field) -> Field:

334

"""Jump in gradient across element boundaries."""

335

```

336

337

### Field Operations

338

339

Operations for manipulating and querying fields.

340

341

```python { .api }

342

def inner(a: Field, b: Field) -> Field:

343

"""Inner product of two fields."""

344

345

def outer(a: Field, b: Field) -> Field:

346

"""Outer product of two fields."""

347

348

def average(field: Field) -> Field:

349

"""Average field values across elements."""

350

351

def jump(field: Field) -> Field:

352

"""Jump in field across element boundaries."""

353

354

def lookup(field: Field, coordinates: array) -> array:

355

"""Evaluate field at specified coordinates."""

356

357

def partition_lookup(field: Field, partition: SpacePartition) -> Field:

358

"""Lookup field values in partitioned space."""

359

360

def at_node(field: Field, node_index: int):

361

"""Get field value at specific node."""

362

363

def measure(domain: Domain) -> Field:

364

"""Compute measure (area/volume) of domain."""

365

366

def measure_ratio(domain: Domain, reference: Domain) -> Field:

367

"""Ratio of domain measure to reference."""

368

369

def normal(domain: Domain) -> Field:

370

"""Outward normal vector on boundary."""

371

372

def position(domain: Domain) -> Field:

373

"""Position coordinates on domain."""

374

```

375

376

### Element Operations

377

378

Operations for working with individual elements.

379

380

```python { .api }

381

def cells(geometry: Geometry) -> Cells:

382

"""Get cells/elements of geometry."""

383

384

def element_coordinates(element: ElementIndex) -> Coords:

385

"""Get coordinates of element."""

386

387

def element_closest_point(element: ElementIndex, point: vec3) -> vec3:

388

"""Find closest point on element to query point."""

389

390

def node_count(element: ElementIndex) -> int:

391

"""Number of nodes in element."""

392

393

def node_index(element: ElementIndex, local_index: int) -> int:

394

"""Global node index from element and local index."""

395

396

def degree(space: FunctionSpace) -> int:

397

"""Polynomial degree of function space."""

398

399

def to_cell_side(side: int) -> int:

400

"""Convert side index to cell-relative index."""

401

402

def to_inner_cell(side: int) -> int:

403

"""Get inner cell adjacent to side."""

404

405

def to_outer_cell(side: int) -> int:

406

"""Get outer cell adjacent to side."""

407

```

408

409

### Caching and Memory Management

410

411

Utilities for managing temporary storage and caching.

412

413

```python { .api }

414

class TemporaryStore:

415

"""Storage manager for temporary arrays."""

416

417

def __init__(self, device: Device = None):

418

"""Create temporary storage on device."""

419

420

def borrow_temporary(shape: tuple,

421

dtype: type,

422

device: Device = None) -> array:

423

"""Borrow temporary array from pool."""

424

425

def borrow_temporary_like(arr: array,

426

dtype: type = None,

427

device: Device = None) -> array:

428

"""Borrow temporary array with same shape as existing array."""

429

430

def set_default_temporary_store(store: TemporaryStore) -> None:

431

"""Set default temporary storage."""

432

```

433

434

### Adaptivity

435

436

Adaptive mesh refinement and field operations.

437

438

```python { .api }

439

def adaptive_nanogrid_from_field(field: Field,

440

tolerance: float = 1e-6) -> AdaptiveNanogrid:

441

"""Create adaptive nanogrid from field with error tolerance."""

442

443

def adaptive_nanogrid_from_hierarchy(hierarchy,

444

level: int = -1) -> AdaptiveNanogrid:

445

"""Create adaptive nanogrid from mesh hierarchy."""

446

```

447

448

## Usage Examples

449

450

### Basic FEM Workflow

451

```python

452

import warp as wp

453

import warp.fem as fem

454

455

# Create geometry

456

grid = fem.Grid2D(res_x=32, res_y=32)

457

458

# Create function space

459

space = fem.make_polynomial_space(grid, degree=1)

460

461

# Create fields

462

u = fem.make_trial(space) # Solution field

463

v = fem.make_test(space) # Test function

464

465

# Define weak form for Poisson equation: ∫∇u·∇v dx = ∫f·v dx

466

@wp.kernel

467

def poisson_integrand(

468

coords: fem.Coords,

469

u: fem.Field,

470

v: fem.Field,

471

f: fem.Field

472

):

473

return fem.inner(fem.grad(u), fem.grad(v)) - f * v

474

475

# Integrate over domain

476

cells_domain = fem.cells(grid)

477

weak_form = fem.integrate(poisson_integrand, cells_domain)

478

```

479

480

### Working with Different Geometries

481

```python

482

# Tetrahedral mesh

483

vertices = wp.array([[0,0,0], [1,0,0], [0,1,0], [0,0,1]], dtype=wp.vec3)

484

tets = wp.array([[0,1,2,3]], dtype=wp.int32)

485

tet_mesh = fem.Tetmesh(vertices, tets)

486

487

# Function space on tetrahedral mesh

488

tet_space = fem.make_polynomial_space(tet_mesh, degree=2)

489

490

# Vector field

491

vector_space = fem.make_collocated_function_space(tet_mesh, shape=(3,), degree=1)

492

displacement = fem.make_discrete_field(vector_space)

493

```

494

495

### Quadrature and Integration

496

```python

497

# Custom quadrature

498

quadrature = fem.RegularQuadrature(grid, order=2)

499

500

# Integrate with specific quadrature

501

result = fem.integrate(

502

my_integrand_function,

503

fem.cells(grid),

504

quadrature=quadrature

505

)

506

507

# PIC quadrature for particle methods

508

particle_pos = wp.array([[0.1, 0.2], [0.8, 0.9]], dtype=wp.vec2)

509

particle_weights = wp.ones(2, dtype=float)

510

pic_quad = fem.PicQuadrature(particle_pos, particle_weights)

511

```

512

513

## Types

514

515

```python { .api }

516

# Core FEM types

517

Geometry = typing.Union[Grid2D, Grid3D, Tetmesh, Hexmesh, Trimesh2D, Trimesh3D, Quadmesh2D, Quadmesh3D]

518

Field = typing.Union[DiscreteField, ImplicitField, UniformField, NonconformingField]

519

Domain = typing.Union[GeometryDomain, Cells, Sides, BoundarySides, FrontierSides]

520

521

# Index types

522

ElementIndex = int

523

QuadraturePointIndex = int

524

NULL_ELEMENT_INDEX = -1

525

NULL_QP_INDEX = -1

526

527

# Coordinate types

528

Coords = vec3 # Element coordinates

529

530

# Sample type for field evaluation

531

class Sample:

532

element_index: ElementIndex

533

qp_index: QuadraturePointIndex

534

coords: Coords

535

536

def make_free_sample(coords: Coords) -> Sample:

537

"""Create sample at free coordinates."""

538

539

# DOF mapper for complex field structures

540

class DofMapper:

541

"""Maps between different DOF organizations."""

542

543

class SymmetricTensorMapper:

544

"""Maps symmetric tensor components to DOFs."""

545

546

class SkewSymmetricTensorMapper:

547

"""Maps skew-symmetric tensor components to DOFs."""

548

549

# Polynomial utilities

550

class Polynomial:

551

"""Polynomial representation for basis functions."""

552

553

def __init__(self, coefficients: array, degree: int):

554

"""Create polynomial from coefficients."""

555

```