BAMresearch / FenicsConcrete

FE model representing the hardening of concrete
MIT License
1 stars 1 forks source link

Paraview Sensor #3

Closed eriktamsen closed 1 year ago

eriktamsen commented 2 years ago

Currently the paraview output is defined in the material class, it would be nice to have a sensor to which the problem object is passed and from that triggers a paraview output. I see problems with the plots, as somehow the sensor needs to know which problem has which fields to plot.

joergfunger commented 2 years ago

If you define a paraview sensor, that gets that information as input e.g. a dictionary with all the information (e.g. name of the field, name of the function space, name of the function space it is projected onto, ...). You could then (internally in each call of evaluating the sensor) store all the information, and then (at the end), output the paraview file.

eriktamsen commented 2 years ago

This is certainly possible. That will either make the definition of the sensor super cumbersome and error-prone (typos), or you will have to define what is plotted again in the material model as a list/dictionary, which is similar how it is now, but it will move some of the code to the sensor definition. There are a few things where I am not sure how I would technically be able to implement this, but I guess there are solutions for those questions as well.

I am not sure what you mean with storing it internally and having the output at the end. You can just use the same paraview file and write the output of each time step.

TTitscher commented 2 years ago

Assuming the solution fields (e.g. displacements and temperature) are stored in problem.u and problem.T respectively. How about the API

f = dolfin.XDMFFile("my_solution_fields.xdmf", ...)
sensor1 = FieldSensor(f, problem.u, name="displacements")
sensor2 = FieldSensor(f, problem.T, name="temperature")
# ...
for t in time_steps:
   problem.solve(t)
   problem.update_history(...) # ?
   sensor1(t) # postprocessing...
   sensor2(t)   

and this Sensor.__call__ is then just something like

def __call__(self, t):
   self.xdmf_file.write(self.field, t)

Note that the setup of the specific sensors for a given problem could be automated in a problem.define_sensors_for_all_fields(xdmf_file_name).

PS I find "paraview sensor" misleading as paraview is the program to show the actual output files...

joergfunger commented 2 years ago

I'm fine with field sensor or xdmf (since this is what the sensor "outputs"). In the interface, it might be nice to include also derived fields (such as the strain/stress/Mises stress/principal stress) and the corresponding function space it is projected onto. As for the separate interface with sensor1 and sensor2, I would have probably made the loop over the two fields in the FieldSensor (which means the fields and names would have to be provided in the constructor), but that is a minor detail. Maybe this separate approach allows to easily add other sensors with the same XDMFfile without changing the FieldSensor class.

TTitscher commented 2 years ago

As usual in this pattern, the __call__ method of the sensors should have a common interface, e.g. only getting the current time stamp and the rest would be passed via __init__. Following your suggestion, one could think of a

sensors =  []
sensors.append(DerivedFieldSensor(f, form=problem.strain_in_ufl, V=TensorFunctionSpace(problem.mesh,...)))
sensors.append(DerivedFieldSensor(f, form=problem.mises_stress, V=FunctionSpace(problem.mesh,...)))
# ...
for t in ts:
   for sensor in sensors:
       sensor(t)

In that case it IMO makes sense to directly write the xdmf file within the sensor. When the sensor measures scalars (or generally fewer values) it may come handy to separate the measurement from the storage. My idea was a MeasurementSystem that automatically loops over previously added sensors. Not sure, how the XDMF export fits in this concept though...

eriktamsen commented 2 years ago

This measurement system idea is basically how the sensors are implemented now, just without the need of an extra class, as the sensors are added to the problem https://github.com/BAMresearch/FenicsConcrete/blob/7a086d7767e20bd111cc7b05e5aa742d7e5ff47c/fenics_concrete/material_problems/concrete_thermo_mechanical.py#L130-L133

joergfunger commented 2 years ago

@eriktamsen But the sensor only provides pointwise information, using the sensor does not allow to export to xdmf, correct?

eriktamsen commented 2 years ago

I did not completely follow what you want with xdmf, you mean the paraview file, or do you want to export something else? The sensor can do what ever you implement in the measure function, currently its mostly point data, but also a scalar value of an integral, or the maximum/minimum of a field, as that is what I needed up to now.

joergfunger commented 2 years ago

So some sensor might output e.g. the temperature at some point (the result of the sensor is a data table of time vs T). Why couldnt't we interpret the xdmf file as a sensor output (the sensor measures xdmf with certain parameters to be passed to the sensor that defines what exactly is measured (stress, displacements) and on what function space those are to be projected. In a similar way, we could define a VMAP "sensor" that stores all results in VMAP to be postprocessed afterwards.

eriktamsen commented 2 years ago

I am certain we can do that, and I will do it if it is wanted, I am not certain this is the most practical or logical way. I personally would rather have flags that are turned on or off depending if you want a Paraview/VMAP output or not and use the sensors to get specific output to be used for e.g. calibration. In the long run the direct Paraview output will be obsolete anyways as the VMAP to Paraview export is being developed, therefore it might not be useful to spend too much thought on it now.

joergfunger commented 2 years ago

But the VMAP to paraview would similarly be a sensor (at least from my point of view). The advantage is that the postprocessing is outsourced (not hardcoded in the actually library that does the computation). Thus, e.g. the VMAP sensor would rather be independent (only requiring some standardized information from the FEniCS problem). So changing from paraview sensor to VMAP sensor would not require any changes in the library.

eriktamsen commented 2 years ago

It would be great if we only have to pass the problem to the VMAP wrapper without any changes to the code, I do not want to promise that right now, but I agree that that would be ideal :) I would have said the VMAP to Paraview would be a separate step in a workflow, unrelated to fenics or this specific code/package. I guess concerning these exports my personal concept of sensor differs from yours, but this is just wording.

eriktamsen commented 1 year ago

will be addressed in fenicsXconcrete