Skip to content

schmaeke/APSiS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Caution

While this repository remains unarchived, I do not plan to continue development. Java, is not the optimal tool for this project. The code is available for anyone interested in exploring or building upon it.

APSiS - Advanced Physics Simulation Software

APSiS logo

Overview

APSiS was initially developed as a personal project to aid my coursework, leveraging Java as the language I was most familiar with at the time. This software was never meant to be a comprehensive, production-level solution but rather a functional exploration of advanced computational physics concepts.

Key Features

  • Element Topologies: Line, quadrilateral, and hexahedron.
  • Efficient Mapping: Utilizes axis-aligned bounding boxes for fast Jacobian evaluations and high-order Lagrange interpolation for complex shapes.
  • Polynomial Approximation: Anisotropic high-order polynomial approximation up to $p = 62$ based on integrated Legendre polynomials.
  • Adaptive Mesh Refinement: Supports arbitrary local $h$-refinements using the multi-level hp method.
  • Advanced Quadrature: Implements quadrature rules suitable for immersed boundary computations as outlined in the Finite Cell Method.

Limitations

  • Boundary Conditions: Lacks weak boundary condition implementations for Dirichlet constraints within elements.
  • Mesh I/O: Does not include mesh input/output capabilities, as FCM does not require them.
  • PDE Solvers: APSiS is a framework for implementing PDE solvers but does not include any pre-built equations.

Selected Results

Immersed Boundary Methods High-Order Elements Adaptive Mesh Refinement
Immersed aluminum foam High-order elements Shock wave

Compilation Guide

Requirements

  • JDK: OpenJDK version 21 or higher.
  • Build Tool: gradle version 8.6 or higher.

Build Instructions

gradle build

No third-party libraries are required.

Example Usage: Solving the Poisson Equation on a Unit Square

This example demonstrates how to use APSiS to solve the Laplace equation on a unit square $\Omega = [0, 1]^2$.

Mathematical Formulation

Solve:

$$\nabla^2 u = 0 \quad \forall \boldsymbol{x} \in \Omega$$

with boundary conditions:

  • Homogeneous Dirichlet conditions on the left, right, and bottom.
  • $u = \sin( \pi,x_0 )$ on the top boundary for $x_1 = 1$.

Code Implementation

  1. Define the Domain:
final var no_elements_x = 3;
final var no_elements_y = 3;
final var domain = new RectDomain(no_elements_x, no_elements_y, 0.0, 0.0, 1.0, 1.0);
  1. Create the Approximation Field:
final var element_degree_x = 8;
final var element_degree_y = 8;
final var element_degrees = new int[][] { { element_degree_x, element_degree_y } };
final var field_u = new PieceWiseHighOrder("u", domain, 1, 1, true, element_degrees);
  1. Apply Dirichlet Boundary Conditions:
final var dirichlet = new DirichletGlobalL2Projection();
dirichlet.apply(field_u, x -> new Vector(0.0), domain.boundary(RectDomain.LEFT), 0);
dirichlet.apply(field_u, x -> new Vector(0.0), domain.boundary(RectDomain.BOTTOM), 0);
dirichlet.apply(field_u, x -> new Vector(0.0), domain.boundary(RectDomain.RIGHT), 0);
dirichlet.apply(field_u, x -> new Vector(Math.sin(x.component(0) * Math.PI)), domain.boundary(RectDomain.TOP), 0);
  1. Define the Bilinear Form:
final Bilinear bilinear = (v, u, x, q, Q, JxW, s) -> s[0][0] += v.gradient(q).dot(u.gradient(q)) * JxW;
  1. Set Up Integration:
final var integrator = new BasicGaussLegendre(domain, element_degree_x + 1, element_degree_y + 1);
integrator.generate_quadrature_points();
  1. Create Local System of Equations:
final var local_soe = new LocalSOE(field_u, StorageScheme.SYMMETRIC_DENSE);
integrator.integrate(bilinear, local_soe);
  1. Assemble the Global System:
field_u.create_dof_enumerator();
field_u.dof_enumerator().enumerate();
final var N = field_u.dof_enumerator().no_unconstrained_dofs();
final var A = new SparseMatrix(N, N);
final var b = new Vector(N);
final var x = new Vector(N);
local_soe.assemble_system_matrix(A, false, false);
local_soe.assemble_system_vector(b, false, true);
  1. Solve the System:
final var precond = new JacobiPreconditioner();
final var solver = new SolverPCG(1000, 1E-12, true, precond);

if (!solver.solve(A, b, x)) {
    throw new RuntimeException("Solver did not converge!");
}
field_u.insert_solution(x);
  1. Post-Process Results:
final var vtu_post = new VTUPostProcessor(domain, Math.max(element_degree_x, element_degree_y), 1, false, true, "solution.vtu");
vtu_post.add_point_processor(new SolutionProcessor(field_u));
vtu_post.add_point_processor(new SolutionGradientProcessor(field_u));
vtu_post.post_process();

Example solution
Solution warped by factor 0.5 normal to the surface.

  1. Compute solution’s relative energy error:
final var reference_energy = 1.576674047468559;
final var numeric_energy = local_soe.energy();
final var relative_energy_error = sqrt(abs(reference_energy - numeric_energy) / abs(reference_energy)) * 100.0;

For the given parameters this evaluates to

$$||e||_E = \sqrt{\frac{|\Pi_\text{num} - \Pi|}{|\Pi|}} \cdot 100\% = 8.7 \cdot 10^{-4} \%$$

About

A small finite element library wirtten in Java. Implements high order elements with multi-level hp refinements.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages