Kratos Multiphysics is now on cloudHPC: validated on the Turek–Hron FSI benchmark

Published by Ruggero Poletto on

FSI2 animation

TL;DR

  • New solver on cloudHPC: Kratos Multiphysics 10.4.2 (KratosMultiphysics-10.4.2). Upload a folder with ProjectParameters.json, the .mdpa mesh and the materials file, pick an instance and run: structural, fluid, FSI, DEM, MPM, convection–diffusion and co-simulation applications are ready to use, with no installation and no compilation.
  • To validate it we ran the Turek–Hron fluid–structure interaction benchmark with the official example mesh. Against the refined reference values (Turek et al., 2010), the flag-tip amplitudes are within 1 % on CSM3 and FSI2, and within 3 % (transverse) and 6.4 % (streamwise) on FSI3, where the frequency is also 3.3 % low (no mesh study: this is the FSI2 example mesh used on FSI3).
  • The raw drag and lift are noisy from one time step to the next. After low-pass filtering well above the flapping frequency, FSI2 forces are within 1.7 % of the reference and FSI3 forces within 6.5 %. Switching the fluid scheme from Bossak to BDF2 reduces the noise but does not remove it.
  • On the preCICE perpendicular flap, Kratos’ tip peaks are within −2.4 % to +0.3 % of OpenFOAM + CalculiX and OpenFOAM + code_aster, with the same period. Kratos is the lowest of the four codes on the 1st and 3rd peak; solids4foam is the highest.
  • More OpenMP threads did not make these 2D cases faster: 2 vCPU is the cheapest choice. The six production runs cost €8.05 in total.

New on cloudHPC: Kratos Multiphysics 10.4.2

Kratos Multiphysics is an open-source (BSD-4) C++/Python finite-element framework developed at CIMNE in Barcelona. One code covers structures, fluids, particles and their coupling, all driven by the same JSON input (ProjectParameters.json) and .mdpa mesh format.

From today you can run it on cloudHPC as KratosMultiphysics-10.4.2, next to the other open-source solvers already on the platform. The build includes these applications:

Kratos applicationWhat you can simulate
StructuralMechanics, ConstitutiveLaws, ContactStructuralMechanicsLinear and non-linear statics and dynamics, large displacements, solids/shells/beams, contact
FluidDynamicsIncompressible flow (VMS and other stabilised FE formulations), Bossak and BDF2 time integration
FSI, MeshMoving, MappingFluid–structure interaction in one framework, with mesh motion and non-matching interface mapping
DEMDiscrete element method for granular materials
MPMMaterial point method for very large deformations (soils, granular flows, impacts)
ConvectionDiffusionHeat transfer and scalar transport
CoSimulationCoupling of Kratos solvers with each other (multi-physics, multi-stage)
LinearSolvers, MetisAMGCL and direct solvers, mesh partitioning

How it runs on cloudHPC:

  • Input: the case folder with ProjectParameters.json, the .mdpa mesh(es) and the materials .json. Several cases can go in subfolders and run one after another; a relaunch skips the cases that already completed.
  • Parallelism: OpenMP, one thread per physical core (no MPI, no GPU). Use highcore or hypercore instances.
  • Output: VTK/GiD results, .dat probes and forces and log.kratos, packed in KRATOS.tar.gz.
  • Cost: the whole validation below (six production runs on 2-vCPU instances) cost €8.05.

Where Kratos fits among the cloudHPC solvers

Kratos doesn’t replace the codes many of you already run on cloudHPC; it adds a third way to do FSI and a single-framework option for DEM and MPM.

PhysicsSolvers on cloudHPCWhat Kratos adds
CFDOpenFOAM (ESI and openfoam.org), foam-extend, SU2, code_saturne, DAFoam, OpenLB, Palabos, DualSPHysics, T-FlowsStabilised finite-element CFD on unstructured meshes
Structures (FEA)code_aster, CalculiX, Elmer, FEniCSx, FreeFEM, OpenRadioss / OpenCourantNon-linear structures in the same input format as the fluid
FSIpreCICE (OpenFOAM + CalculiX or code_aster)FSI in one code, one input file, no external coupling library
ParticlesLIGGGHTS, LAMMPSDEM and MPM in the same framework (and input format) as the fluid and structure solvers
FireFDS (6.7.0 to the latest)—
Buildings, coastal, environmentEnergyPlus, CONTAM, openTELEMAC, SWAN, XBeach—

Why we validated it on FSI first

FSI is where Kratos differs most from what was already on the platform. It couples its own fluid, structure and mesh-motion solvers in one framework and one input file. The coupling itself is still partitioned (fluid and structure solved one after the other, iterating within each time step), but there is no second code and no external coupling library, unlike a multi-code workflow such as OpenFOAM + CalculiX through preCICE.

In October we presented a new open-source preCICE connector for code_aster and compared it with CalculiX and solids4foam on the preCICE perpendicular-flap tutorial. That raised an obvious question: how does a single-framework FSI code do, on a case with published reference values and on a case where we already have three other solvers?

This post answers it with two test families:

  1. Turek–Hron (Turek & Hron, 2006): the standard 2D FSI benchmark. An elastic flag is attached behind a cylinder in a channel. We ran the structural test (CSM3) and two fully coupled versions (FSI2, FSI3). The reference values are high-resolution numerical results, not experiments. We compare against the refined values published in 2010 by the same group (finest mesh, smallest time step) and also show the original 2006 values.
  2. preCICE perpendicular flap: a flap clamped to the floor of a channel, compared with our October runs of OpenFOAM + CalculiX, OpenFOAM + code_aster and solids4foam.

Results at a glance

CaseQuantityKratos 10.4.2Reference 2010vs 2010vs 2006
CSM3tip ux [mm] [Hz]−14.16 ± 14.16 [1.099]−14.305 ± 14.305 [1.0995]−1.0 %same reference
CSM3tip uy [mm] [Hz]−63.18 ± 64.86 [1.098]−63.607 ± 65.160 [1.0995]−0.5 %same reference
FSI2tip ux [mm] [Hz]−14.95 ± 12.76 [3.854]−14.85 ± 12.70 [3.86]+0.5 %+2.6 %
FSI2tip uy [mm] [Hz]1.17 ± 82.07 [1.927]1.30 ± 81.6 [1.93]+0.6 %+1.8 %
FSI2drag [N/m], filtered 20 Hz217.4 ± 79.0215.06 ± 77.65mean +1.1 %, amp. +1.7 %mean +4.1 %, amp. +7.1 %
FSI2lift [N/m], filtered 20 Hz0.7 ± 240.70.61 ± 237.8amp. +1.2 %amp. +2.8 %
FSI3tip ux [mm] [Hz]−3.08 ± 2.89 [10.56]−2.88 ± 2.72 [10.93]+6.4 %+14.4 %
FSI3tip uy [mm] [Hz]1.05 ± 36.05 [5.28]1.47 ± 34.99 [5.46]+3.0 %+4.9 %
FSI3drag [N/m], filtered 50 Hz464.4 ± 28.7460.5 ± 27.74mean +0.8 %, amp. +3.4 %mean +1.5 %, amp. +26.6 %
FSI3lift [N/m], filtered 50 Hz5.1 ± 144.02.50 ± 153.91amp. −6.5 %amp. −3.9 %
Flap1st peak tip x [mm]194.2 at 0.71 sno reference; CalculiX 198.3 · code_aster 199.0 · solids4foam 203.9 (−2.1 % / −2.4 % / −4.8 %)

Values are mean ± amplitude [frequency], as in the Turek–Hron papers. All FSI values are from the BDF2 runs. “vs” columns give the amplitude error unless stated. Forces are low-pass filtered at 20 Hz (FSI2) and 50 Hz (FSI3); see “The force noise” below. The mean lift is close to zero, so its percentage error is not meaningful and isn’t shown.

Amplitude error of Kratos vs the Turek–Hron reference

How the runs were set up

  • Solver: Kratos Multiphysics 10.4.2 (KratosMultiphysics-10.4.2 on cloudHPC), applications FSI, FluidDynamics, StructuralMechanics, MeshMoving, Mapping, LinearSolvers.
  • Turek–Hron meshes: the official FSI2 case from the Kratos Examples repository (fluid_structure_interaction/validation/fsi_turek_FSI2): 29,926 linear triangles for the fluid (VMS stabilisation) and 2,625 quadrilaterals for the flag (Total Lagrangian, Saint Venant–Kirchhoff, plane strain). The same meshes are used for CSM3 and FSI3, with the material and inflow changed.
  • Coupling: partitioned Dirichlet–Neumann with MVQN acceleration (the Kratos default for this example), structural-similarity mesh motion. Fluid time integration: Bossak (the default) in a first series and BDF2 in a second one. The tables use BDF2.
  • Time steps: 0.005 s (CSM3), 0.002 s (FSI2), 0.001 s (FSI3); simulated time 10 s, 15 s and 10 s (the example runs FSI2 to 20 s; 15 s is already well into the periodic regime). Statistics are taken over the last periodic window: CSM3 5–10 s, FSI2 11–15 s, FSI3 7–10 s.
  • Machine: 2 vCPU hypercore, regular instance. Kratos has no restart on cloudHPC, so a spot pre-emption would lose the run.
  • Changes vs the Kratos example: VTK output instead of GiD, a point probe at A = (0.6, 0.2), body-fitted drag and lift on the cylinder and the flag, and AMGCL block size 2 for the mesh solver (this only removes a warning).

Case 1 — CSM3: the flag alone under gravity

Turek–Hron set-up

CSM3 removes the fluid: the flag (ρs = 1000 kg/m³, E = 1.4 MPa, ν = 0.4) falls under a gravity of 2 m/s² and oscillates around its sagged position. It tests the structural solver and the large-displacement formulation on their own.

CSM3: Kratos vs reference

Kratos reproduces both components within 1 % in amplitude, and the oscillation frequency (1.099 Hz) matches the reference 1.0995 Hz within 0.2 %.

What we learned: the structural side of Kratos is accurate on this geometrically non-linear test. That matters because everything else builds on it.

Case 2 — FSI2: large flapping, heavy flag

FSI2 uses a heavy flag (ρs = 10,000 kg/m³) at mean inflow 1 m/s (Re = 100). After a 2 s ramp the flag settles into a large flapping motion of about ±80 mm at the tip.

FSI2 animation
FSI2: Kratos vs reference
  • Displacements: amplitude error +0.5 % (ux) and +0.6 % (uy); frequencies 3.854 Hz and 1.927 Hz against 3.86 and 1.93 Hz (−0.2 %).
  • Forces (filtered): drag 217.4 ± 79.0 N/m against 215.06 ± 77.65; lift 0.7 ± 240.7 against 0.61 ± 237.8.
  • Bossak vs BDF2: the displacement statistics agree to within 0.1 %. The two curves are not identical point by point (they drift slightly in phase over the run, up to about 1.3 mm), but mean, amplitude and frequency are the same.

What we learned: with the standard example mesh, Kratos is within 2 % of the refined reference for every FSI2 quantity, once the forces are filtered (next section).

The force noise: what it is and what it isn’t

The raw drag and lift written by Kratos flip up and down from one time step to the next. In FSI2 with the default Bossak scheme, the lift changed direction at 85 % of consecutive steps, with jumps up to 1,146 N/m between two steps, on a signal whose amplitude is about 238 N/m. Taking max/min of the raw signal gives +69 % on the drag amplitude and +150 % on the lift amplitude.

We checked three things:

  1. Is it the force post-processing? No. We integrated the fluid traction (pressure + viscous stress) directly from the saved velocity and pressure fields on the deformed mesh. At t = 14.0 s that gives 140.2 / 131.7 N/m (drag / lift) against 143.8 / 132.4 N/m from Kratos’ own output, including the same dip. The noise is in the pressure field itself.
  2. Is it the time scheme? Partly. With BDF2 instead of Bossak, the largest FSI2 lift jump went from 1,146 to 428 N/m and the raw amplitude errors fell to +24 % (drag) and +71 % (lift). In FSI3, BDF2 cut the raw drag amplitude by 21 % but barely changed the lift: 83 % of steps still reverse direction (87 % with Bossak).
  3. Does it hide the physics? No. The noise lives at the time-step scale (hundreds of Hz), while the flag moves at 2–11 Hz. With everything above 20 Hz (FSI2) or 50 Hz (FSI3) removed, Bossak and BDF2 give the same forces within 0.3 %. Doubling the cut-off changes the FSI2 amplitudes by less than 0.5 %, and the FSI3 drag amplitude by 4 %.
FSI2 forcesBossak rawBDF2 rawFiltered 20 Hz (BDF2)Reference 2010
drag [N/m]247.2 ± 131.0231.4 ± 96.1217.4 ± 79.0215.06 ± 77.65
lift [N/m]−97.3 ± 595.09.2 ± 405.90.7 ± 240.70.61 ± 237.8
lift reversals between steps85 %76 %——

What we learned: if you post-process forces from a Kratos FSI run, filter them, check that the result doesn’t depend on the cut-off, and say what you did. Don’t read amplitudes off the raw signal. The displacements are smooth and need no filtering.

Case 3 — FSI3: faster and lighter

FSI3 doubles the inflow (2 m/s, Re = 200) and uses a lighter, stiffer flag (ρs = 1000 kg/m³, E = 5.6 MPa). The flag flaps at about 5.3 Hz, roughly 2.7 times faster than in FSI2, with a smaller amplitude.

FSI3: Kratos vs reference
  • Transverse motion uy: +3.0 % in amplitude; frequency 5.28 Hz against 5.46 Hz (−3.3 %).
  • Streamwise motion ux: +6.4 % in amplitude, on a motion of under 6 mm peak to peak; frequency −3.4 %.
  • Forces (filtered at 50 Hz): drag 464.4 ± 28.7 N/m against 460.5 ± 27.74 (mean +0.8 %, amplitude +3.4 %); lift amplitude −6.5 %.

The reference matters here. Against the original 2006 values the drag amplitude looks 27 % too high and ux 14 % too high; against the refined 2010 values (finer mesh, smaller time step) those become +3.4 % and +6.4 %. The 2010 reference also moved the frequency from 5.3 to 5.46 Hz, so Kratos’ 5.28 Hz, which matched the 2006 value, is now 3.3 % low.

What we learned: FSI3 is the harder test for the FSI2 example mesh and time step. The largest deviations are ux amplitude (+6.4 %), lift amplitude (−6.5 %) and frequency (−3.3 %). We didn’t run a mesh or time-step study, so we can’t say which of the two limits the result. If you need FSI3-level accuracy, that study is the next step.

Case 4 — perpendicular flap vs CalculiX, code_aster and solids4foam

Perpendicular-flap set-up

We rebuilt the preCICE perpendicular-flap tutorial in Kratos with the same blockMesh layout and grading (5,580 triangles) and the same settings:

  • initial and inlet velocity: 10 m/s;
  • fluid: ρ = 1 kg/m³, ν = 1 m²/s;
  • solid: ρ = 3000 kg/m³, E = 4 MPa, ν = 0.3, linear elastic, 360 quads;
  • time step: 0.01 s, for 5 s.

The other three results come from our October runs: OpenFOAM v2506 + CalculiX 2.20.1 and OpenFOAM v2506 + code_aster 17.3.17, both through preCICE 3.3.1, and solids4foam v2.3 (OpenFOAM v2412).

Flap tip displacement: four codes
Tip x [mm]Kratos 10.4.2OpenFOAM + CalculiXOpenFOAM + code_astersolids4foam
1st peak194.2 at 0.71 s198.3 at 0.74 s199.0 at 0.75 s203.9 at 0.72 s
2nd peak183.9 at 2.37 s183.3 at 2.31 s186.0 at 2.38 s189.3 at 2.35 s
3rd peak171.3 at 3.91 s174.7 at 3.94 s174.0 at 3.99 s177.1 at 3.97 s
Minima−7.3 / 2.3 / 18.7−1.7 / 10.5 / 24.3−1.3 / 10.8 / 21.0−14.6 / −1.6 / 9.7
RMS difference vs CalculiX13.2—2.914.9

There is no reference solution for this tutorial, so this is a code-to-code comparison.

  • Peaks: Kratos is within −2.4 % to +0.3 % of the two preCICE runs. It is the lowest of the four codes on the 1st and 3rd peak and close to CalculiX on the 2nd. solids4foam is 1.4–3.3 % above the preCICE runs.
  • Period: all four codes oscillate with a period of about 1.6 s.
  • Minima: this is where the codes differ most. Kratos and solids4foam swing back further than the two preCICE runs, solids4foam the most.

The two preCICE runs agree within 2.9 mm RMS because they share the same OpenFOAM fluid, mesh and coupling and differ only in the structural solver. Kratos and solids4foam differ from them by 13–15 mm RMS. Kratos changes the fluid discretisation (finite elements instead of finite volumes), the structural solver and the coupling all at once. solids4foam keeps an OpenFOAM finite-volume fluid but changes the solid solver and the coupling. With these four runs alone we can’t separate those effects.

What we learned: a single-framework code (Kratos), a single-toolbox code (solids4foam) and multi-code couplings through preCICE give the same flap response within a few percent on the peaks and the same period. The differences show up mainly in the minima.

Failures on the way (and how we fixed them)

  • Flap: MVQN coupling diverged. With Kratos’ default MVQN accelerator, the FSI iterations per step grew from the start of the flap run and reached 26 at t = 0.08 s. The coupling stopped converging at 0.15 s and the run produced NaN from 0.16 s. Switching to Aitken relaxation ("solver_type": "Relaxation", "w_0": 0.5) gave a stable run at about 5 iterations per step.
  • Flap: starting from rest. The OpenFOAM tutorial starts with 10 m/s everywhere. Starting Kratos from rest with only the inlet at 10 m/s gives a much harder impulsive start, so we matched the tutorial’s initial condition.
  • Point probe not found. A = (0.6, 0.2) is not a node of the example mesh: the point_output_process needs "entity_type": "element" to interpolate.
  • Renamed process. In Kratos 10.4.2 the force output is compute_body_fitted_flow_forces_and_moments_process (older examples use compute_body_fitted_drag_process).
  • Empty VTK files. VTK output only writes the variables listed in nodal_solution_step_data_variables; with an empty list you get geometry only.
  • A first launch that never ran Kratos. The first test on cloudHPC ended “COMPLETED” with Kratos Python environment not found in the log. The image was fixed the same day, but it’s a reminder to always read the log, not just the status.

Run times and costs

RunSimulatedStepsBilled wall timeCost
CSM310 s2,00013 min€0.09
FSI2, Bossak15 s7,5003 h 33 min€1.56
FSI2, BDF215 s7,5003 h 44 min€1.64
FSI3, Bossak10 s10,0005 h 36 min€2.47
FSI3, BDF210 s10,0005 h 02 min€2.21
Perpendicular flap5 s50110 min€0.07
Total€8.05

All runs on 2 vCPU hypercore, regular instances. Billed time includes boot, end-of-run detection and result upload (about 10 minutes per run). Costs per row are rounded; the total is the exact sum.

More cores didn’t help here

Kratos is parallelised with OpenMP on cloudHPC. We ran the first 100 FSI2 steps (inside the inflow ramp) on 2, 4, 8 and 16 vCPU, one run each:

OpenMP scaling on FSI2
vCPU (hypercore)24816
Solver time, 100 steps1.9 min2.1 min2.0 min2.5 min
Speed-up vs 2 vCPU1.000.900.950.76
Billed cost€0.09€0.17€0.33€0.64

From 2 to 8 vCPU the solver times differ by at most 0.2 minutes, too little to rank them with single runs and a log resolution of 0.1 minutes; 16 vCPU was slower. The cost, on the other hand, doubles with every step up. With 30,000 fluid elements, extra threads don’t pay off: use 2 vCPU for 2D Kratos FSI cases of this size, and test a few sizes before large 3D runs.

How to run these cases on cloudHPC

  1. Put ProjectParameters.json, the .mdpa meshes and the materials .json files in one folder. Several cases can go in subfolders, one per ProjectParameters.json; they run one after another.
  2. Choose KratosMultiphysics-10.4.2, 2 vCPU hypercore, and a regular instance for anything longer than a few minutes: Kratos runs don’t restart after a spot pre-emption.
  3. MainKratos.py is not executed: the platform reads the analysis from it (or from "analysis_stage" in the parameters file) and runs the standard Kratos analysis. Custom Python stages are ignored.
  4. "parallel_type": "MPI" runs in OpenMP (Trilinos is not available); use OpenMP linear solvers such as amgcl.
  5. Results come back in KRATOS.tar.gz: VTK/GiD output, .dat probes and forces, and log.kratos. The small .dat files and the log also stay in the folder for quick download.
  6. If a case needs a Kratos application that isn’t in the build (see the table at the top), the run stops with a clear message: ask cloudHPC support. CoSimulation set-ups that launch external programs and restarts from multistage checkpoints are not allowed.
  7. Read log.kratos, not only the run status: a run can end “COMPLETED” even if Kratos stopped with an error.

The input files for all cases in this post are in the downloadable package (cases/).

FAQ

Can I run Kratos Multiphysics in the cloud? Yes. Kratos Multiphysics 10.4.2 is available on cloudHPC as KratosMultiphysics-10.4.2, with the structural, fluid, FSI, DEM, MPM, convection–diffusion and co-simulation applications. Upload the folder with ProjectParameters.json, the .mdpa mesh and the materials file, choose a highcore or hypercore instance and launch; nothing needs to be installed or compiled.

Is Kratos Multiphysics good for fluid–structure interaction? On the Turek–Hron benchmark, Kratos 10.4.2 with the official example mesh reproduces the flag motion within 1 % on CSM3 and FSI2 and within 3–6.4 % on FSI3, against the refined 2010 reference. Drag and lift need low-pass filtering because of time-step-scale noise in the fluid pressure.

What is the Turek–Hron FSI benchmark? A 2D test proposed by Turek and Hron in 2006: an elastic flag attached to a cylinder in a laminar channel flow. CSM3 tests the structure alone, CFD1–3 test the fluid alone, and FSI1–FSI3 test the coupled problem, with reference values for tip displacement, drag and lift. Refined reference values were published in 2010.

How does Kratos compare with OpenFOAM + preCICE and solids4foam? On the preCICE perpendicular flap, Kratos’ tip-displacement peaks are within −2.4 % to +0.3 % of OpenFOAM + CalculiX and OpenFOAM + code_aster; solids4foam is 1.4–3.3 % above them. All four codes have the same period of about 1.6 s.

How many cores should I use for Kratos? For 2D cases of about 30,000 elements, 2 vCPU: 4 and 8 vCPU gave the same run time at higher cost, and 16 vCPU was slower. Larger 3D models may scale better, but test first.

Why are my Kratos drag and lift so noisy? In these FSI runs the fluid pressure oscillates from step to step. It’s not a post-processing error (integrating the stresses gives the same values), and BDF2 only reduces it. Low-pass filter well above the physical frequency and check that the result doesn’t depend on the cut-off.

References

  • S. Turek, J. Hron (2006). Proposal for numerical benchmarking of fluid-structure interaction between an elastic object and laminar incompressible flow. In H.-J. Bungartz, M. Schäfer (eds.), Fluid-Structure Interaction, Lecture Notes in Computational Science and Engineering 53, Springer, pp. 371–385. doi:10.1007/3-540-34596-5_15
  • S. Turek, J. Hron, M. Razzaq, H. Wobker, M. Schäfer (2010). Numerical benchmarking of fluid-structure interaction: a comparison of different discretization and solution approaches. In H.-J. Bungartz, M. Mehl, M. Schäfer (eds.), Fluid Structure Interaction II, Lecture Notes in Computational Science and Engineering 73, Springer, pp. 413–424. doi:10.1007/978-3-642-14206-2_15
  • FEATFLOW FSI benchmark pages and reference data, TU Dortmund. Link
  • P. Dadvand, R. Rossi, E. Oñate (2010). An object-oriented environment for developing finite element codes for multi-disciplinary applications. Archives of Computational Methods in Engineering 17(3), 253–297. doi:10.1007/s11831-010-9045-2
  • Kratos Multiphysics: source code and examples.
  • G. Chourdakis et al. (2022). preCICE v2: A sustainable and user-friendly coupling library. Open Research Europe 2:51. doi:10.12688/openreseurope.14445.2
  • preCICE perpendicular-flap tutorial. Link
  • P. Cardiff et al. (2018). An open-source finite volume toolbox for solid mechanics and fluid-solid interaction simulations. arXiv:1808.10736
  • precice_aster — open-source preCICE connector for code_aster (CFD FEA SERVICE). GitHub

CloudHPC is a HPC provider to run engineering simulations on the cloud. CloudHPC provides from 1 to 224 vCPUs for each process in several configuration of HPC infrastructure - both multi-thread and multi-core. Current software ranges includes several CAE, CFD, FEA, FEM software among which OpenFOAM, FDS, Blender and several others.

New users benefit of a FREE trial of 300 vCPU/Hours to be used on the platform in order to test the platform, all each features and verify if it is suitable for their needs


Categories: Kratos