From 50c0e31de504f3e447736b5c2d2994d197f4bfd2 Mon Sep 17 00:00:00 2001
From: Rafael Ravedutti <rafael.r.ravedutti@fau.de>
Date: Mon, 22 Jul 2024 17:52:46 +0200
Subject: [PATCH] Update README.md

Signed-off-by: Rafael Ravedutti <rafael.r.ravedutti@fau.de>
---
 README.md | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/README.md b/README.md
index f59b97f..52f753b 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,109 @@
 # P4IRS - Parallel and Performance-Portable Particles Intermediate Representation and Simulator
+
+P4IRS is an open-source, stand-alone compiler and domain-specific language for particle simulations which aims at generating optimized code for different target hardwares.
+It is released as a Python package and allows users to define kernels, integrators and other particle routines in a high-level and straightforward fashion without the need to implement any backend code.
+
+## Build instructions
+
+There is a Makefile which contains configurable environment variables such as `TESTCASE` compiler parameters evaluate P4IRS performance on different scenarios.
+`TESTCASE` refers to any of the files within the example directory, such as `md` and `dem`.
+
+## Usage
+
+To load P4IRS, it is necessary to install it as a Python package and import it with:
+
+```python
+import pairs
+```
+
+Particle interactions and specific routines to update each particle individually through the usage of Python methods, and these can make use of defined properties, given parameters and intrinsic methods from P4IRS:
+
+```python
+def lennard_jones(i, j):
+    sr2 = 1.0 / squared_distance(i, j)
+    sr6 = sr2 * sr2 * sr2 * sigma6[i, j]
+    apply(force, delta(i, j) * (48.0 * sr6 * (sr6 - 0.5) * sr2 * epsilon[i, j]))
+
+
+def initial_integrate(i):
+    linear_velocity[i] += (dt * 0.5) * force[i] / mass[i]
+    position[i] += dt * linear_velocity[i]
+
+
+def final_integrate(i):
+    linear_velocity[i] += (dt * 0.5) * force[i] / mass[i]
+```
+
+After defining the methods, it is necessary to setup the P4IRS simulations:
+
+```python
+# Simulation setup
+psim = pairs.simulation(
+  "md", # Simulation identifier
+  [pairs.point_mass()], # List of shapes
+  timesteps=200, # Number of time-steps
+  double_prec=True) # Use double-precision
+
+# Particle properties
+psim.add_position('position')
+psim.add_property('mass', pairs.real(), 1.0)
+psim.add_property('velocity', pairs.vector())
+psim.add_property('force', pairs.vector(), volatile=True)
+
+# Features and their properties
+psim.add_feature('type', ntypes)
+psim.add_feature_property('type', 'epsilon', pairs.real(), [...])
+psim.add_feature_property('type', 'sigma6', pairs.real(), [...])
+
+# Simulation domain
+psim.set_domain([xmin, ymin, zmin, xmax, ymax, zmax])
+
+# Initial state
+psim.read_particle_data(
+  "data/copper_fcc_lattice.input",
+  ['type', 'mass', 'position', 'velocity'],
+  pairs.point_mass())
+```
+
+Then the optimization strategies and visualization settings to use:
+
+```python
+# Optimization settings
+psim.reneighbor_every(20)
+psim.compute_half()
+psim.build_neighbor_lists(cutoff_radius + skin)
+psim.vtk_output("output/md", every=20)
+```
+
+Then, all defined particle routines defined must be scheduled for computation:
+
+```python
+# Kernels to compute
+psim.compute(lennard_jones, cutoff_radius)
+psim.compute(euler, symbols={'dt': dt})
+```
+
+And finally, it is necessary to define the target and trigger the code generator:
+
+```
+# Target hardware
+if target == 'gpu':
+  psim.target(pairs.target_gpu())
+else:
+  psim.target(pairs.target_cpu())
+
+psim.generate()
+```
+
+## Citations
+
+TBD
+
+## Credits
+
+P4IRS is developed by the Erlangen National High Performance Computing Center
+([NHR@FAU](https://hpc.fau.de/)) at the University of Erlangen-Nürnberg.
+
+## License
+
+[MIT](https://i10git.cs.fau.de/software/pairs/-/blob/master/LICENSE)
-- 
GitLab