BAMresearch / fenics-constitutive

Complex constitutive models beyond the FEniCS UFL.
https://bamresearch.github.io/fenics-constitutive
MIT License
12 stars 2 forks source link

Mixed problems #20

Closed TTitscher closed 8 months ago

TTitscher commented 2 years ago

The current focus of the module is on mechanics problems that solve for the displacement field. More exciting problems often have a coupling to another physical or numerical quantity like:

In my previous work with gradient damage, I was able to seamlessly integrate the nonlocal strain field in an existing mechanics problem, because I solved monolitally (fully coupled) and additional field only required Neumann=0 boundary conditions which are automatically fulfilled.

I already know from @eriktamsen that his implementation of a thermo-mechanics problem decouples both problems (first solve u, then solve T, iterate) and requires boundary conditions for the temperature T field.

How would a consistent solution look like?

eriktamsen commented 2 years ago

My current (personal) solution for solving two separate temperature and displacement problems together, is to have a problem class, which initiates two distinct NonLinearProblems. I like the current setup, as I can organize the solvers etc on the problem level and define the materials in the nonlinear problems. In addition, this would make my suggestion from #24, to measure sensors after solving the problem, easy. I would therefore suggest to have an analogue implementation in our module, however I am open to other suggestions.

ajafarihub commented 2 years ago

IMO, integrating specific problems into the module is a valid desire, however, I find the "solution scheme" quite out of the scope; i.e. any problem might need its adjusted solver. So, I would suggest: 1- we try to come up with a set of appropriate attributes/methods that look to be common among a range of problems we are going to deal with, and based on that we define a BaseClass. For example: BaseClass.solve(t, logger) BaseClass.get_solution_field # main field, either coupled or not BaseClass.get_solution_space # main space, either coupled or not BaseClass.get_field(field_name) # for a particular field_name BaseClass.get_space(field_name, collapse=False) # for a particular field_name BaseClass.set_BC(field_name, bc) # for instance BaseClass.add_sensor(...) # maybe ? .... 2- Based on BaseClass, we can subclass different problems: Elastic, Gradient Damage, Thermo-elastic, plastic, etc. And of course, any has its own implementation of solve() for instance.

So, maybe this issue goes down to figuring out a good design for the BaseClass.

eriktamsen commented 2 years ago

At first glance, I would generally agree with your suggestion. I am not sure when you would need the function of "get_main_field", as I would assume all direct output will go through a sensor, which will need to know what kind of fields they are using. I do not fully understand what you mean with "I find the "solution scheme" quite out of the scope". I think my suggestion and yours could both be applied, without making it too complex.

The important thing is that this mixed problem/multi physics thing is not just some nice feature but very relevant for my simulation, therefore I would like to make sure this is possible with our module, otherwise I will not be able to use it.

ajafarihub commented 2 years ago

It might be that I have a missunderstanding of what is aimed by the module, and therefore, I was thinking handling of the particular solver that is needed for a mixed-problem would be a bit too detailed (at least at this stage). It looks to me crucial to first have a common definition of what really the "scope" of the module should/could be. For example, do we want to put all structural/thermal/mixed/coupled/decoupled ... problems in one module? How; e.g. all in one class or in different classes? What are typical boundary conditions, initial conditions, solvers and solve_options for each problem? How and to which extend can we merge the similarities possibly existing in each of those aspects; i.e. solver, BCs, ICs, etc. ?

I would say, for MixedProblem, we can probably first subclass two other classes from the BaseClass: MixedCoupledProblem(BaseClass) --> for example, Gradient Damage is of this kind MixedDecoupledProblem(BaseClass)

I think, an easy way to go is having/implementing different classes for different problems, but it would be nice to come up with some common attributes/methods with certain input arguments. The list I wrote in my last message (e.g. get_main_field that @eriktamsen asked about) is just a first suggestion and can be discussed in more details. But maybe a first step is to come up with a list of different problems, each of which together with a list of attributes/methods/options needed for defining/solving/inferring it.

joergfunger commented 2 years ago

I would also agree that is totally fine to have multiple modules for different purposes (e.g. one for pure mechanical models, and then maybe another one that does thermomechanics,..). The goal would be to have easy to use interfaces, e.g. there is a CreateCubeMesh, or Create3PointBendingMesh (length, width, thickness, dimension2D/3D, load position (to have a node there). This creates a meshfile that you can then input into a fenics_constitutive model that takes e.g. as input a (general) geometry file, and a constitutive model assuming a single materials (so just the stress-strain function either as a cpp file or python) and some bc (and that list of bc must not cover all cases, but could be e.g. (Dirichlet=0 in some box, or Neumann along a line in some directions). These moduls are then published (e.g. on git) and anyone can use those. And if you need to change something just copy the existing one and create a new one. If you realize at some point that you could generalize two into something that is more general (e.g. including pure mechanics and thermal into a single modul) that would then also be great. And if we then have a module that gets a fenics_constitutive simulation model with some sensors and compare/calibrate that given another data module (that gets the same sensors as the simulation model and outputs the exp. data) that would be even greater. The important point is that each module has a specific set of inputs/and outputs and it should then be working for all possible combinations. That means, if the input to a fenics_constitutive is really a general mesh file, then it should work for all mesh files. On the other hand, if it is just for a compression test and you can only change the height, width and mesh density then those should be the inputs (instead of a general mesh file).