In the current implementation, the experiment (that includes the definition of geometry, initial and boundary conditions, materials) is strongly linked to the implementation (currently dolfin), e.g. the mesh is stored as a dolfin mesh including the bc. This certainly has several benefits in particular when only a single solver is used. However, we currently try to restructure that to migrate to dolfinx. In that case, there might be a benefit of actually trying to circumvent the solver specific implementation in the definition of the experiment. The question to be discussed would be what could/should be stored, and how this could be structured. Currently, this concerns primary the mesh and the boundary conditions.
Mesh
One option is that each experiment provides an export2xdmf_via_gmsh function, that exports the mesh, internally calling gmsh and meshio for a conversion to xdmf. These steps could also be done as external steps (the solver would first call export_to_gmsh (from the experiment), then gmsh (for meshing the resulting geo file) and finally meshio for conversion to xdmf. The solver that implements one experiment would then call this export2xdfm_gmsh method from the experiment and read in the resulting mesh.
A second option is to "hide" the mesh generation in the solver, such that meshing is actually done in the solver for that experiment (so the export2mesh function is not part of the experiment, but also implemented in the solver that directly takes the parameters (length, height) stored in the experiment to create the mesh. However, this approach would not allow to take multiple experiments that are pretty similar (tension test for a cube or cylinder) with the same solver interface.
Boundary conditions
I could imagine having a base class and special implementations e.g.
The solver would then loop over the list of bc, and based on the type (e.g. DirichletNode) would implement fixing a single node at a prescribed coordinate (coming from the solver independent definition). As for the surfaces, there could be multiple options by either using something like top/bottom/left/right (where we then just extract max_x and define that as right), or prescribe planes (e.g. xy plane at z=10) or even use the gmsh functionality to define these surfaces.
In the current implementation, the experiment (that includes the definition of geometry, initial and boundary conditions, materials) is strongly linked to the implementation (currently dolfin), e.g. the mesh is stored as a dolfin mesh including the bc. This certainly has several benefits in particular when only a single solver is used. However, we currently try to restructure that to migrate to dolfinx. In that case, there might be a benefit of actually trying to circumvent the solver specific implementation in the definition of the experiment. The question to be discussed would be what could/should be stored, and how this could be structured. Currently, this concerns primary the mesh and the boundary conditions.
Mesh
One option is that each experiment provides an export2xdmf_via_gmsh function, that exports the mesh, internally calling gmsh and meshio for a conversion to xdmf. These steps could also be done as external steps (the solver would first call export_to_gmsh (from the experiment), then gmsh (for meshing the resulting geo file) and finally meshio for conversion to xdmf. The solver that implements one experiment would then call this export2xdfm_gmsh method from the experiment and read in the resulting mesh. A second option is to "hide" the mesh generation in the solver, such that meshing is actually done in the solver for that experiment (so the export2mesh function is not part of the experiment, but also implemented in the solver that directly takes the parameters (length, height) stored in the experiment to create the mesh. However, this approach would not allow to take multiple experiments that are pretty similar (tension test for a cube or cylinder) with the same solver interface.
Boundary conditions
I could imagine having a base class and special implementations e.g.
The solver would then loop over the list of bc, and based on the type (e.g. DirichletNode) would implement fixing a single node at a prescribed coordinate (coming from the solver independent definition). As for the surfaces, there could be multiple options by either using something like top/bottom/left/right (where we then just extract max_x and define that as right), or prescribe planes (e.g. xy plane at z=10) or even use the gmsh functionality to define these surfaces.