Biotissue MCTK to APF Refactor

From ScorecWiki

Jump to: navigation, search



The Biotissue Project is currently undergoing revisions to remove use of the old MCTK libraries and toward use of the newly-developed APF library. This change is predominantly motivated by APFs more straightforward field management interface and lighter memory footprint and (hopefully) better runtime speed.

Macro MCTK to APF

The refactor of the macroscale analysis to the APF library is predominantly complete, evaluation and testing in order to arrive at a suitable level of nonlinear convergence is all that remains, and this is predominantly unrelated to the overall switch to APF.

Micro_fo MCTK To APF

The Micro_fo source didn't use much of the MCTK library's functionalities, predominantly only functions relating to querying the parametric coordinates of Gaussian integration points were used. The need for these functions was submitted to the APF project developer who added them in without any difficulty.

Micro_fm MCTK to APF

The Micro_fm source uses a great deal of the old MCTK library's functionalities. As such this space will be used for notes on the functionality and revisions made during the refactoring process.

A majority of the functions implemented in the FibMtx.h and Micro.h primary classes are overwritten in the NonLinFibMtx.h primary class, as such that is where initial refactoring is taking place, and the class has been made a direct subclass of FiniteElementAnalysis.h's namesake class. Any functionalities implemented in FibMtx or Micro needed by NonLinFibMtx will be absorbed into that single class. At a later date the functions specific to these two classes may be spun out of NonLinFibMtx and the subclass hierarchy restores, but at the moment the separation of concerns for these three classes is unclear at best.

Many of the functions in NonLinFibMtx need to be not only refactored in order to replace MCTK calls with equivalent apf calls, but also revised for coding style and computational complexity. Several location have already been refactored where a multitude of unnecessary calls or inneficient order-of-operations is used. Most recently, in GetBoundaryFiberEdges(), in order to conduct a search for elements in a list, the list was simply iterated over... potentially four times in this instance. This has been replaced with three uses of a search function in order to remove the O(n) worst case scenario and simply have O(lg n) average case complexity.

The GetAverageFiberStress() function has been refactored, but may still need revision. Currently it makes use of the force vector assembly process of the analysis in order to calculate the average fiber stress (which also does not appear to be averaged... though perhaps there is a subtlety being missed somewhere). There should hopefully be a different method rather than assembling the global force vector in order to calculate these values. Just prior to printing the total traction values at the end of the function, all mesh regions were iterated over and their volumes retrieved from the meshing database... though this value is not used in any way. As such this section of the function has been removed. Perhaps this had to do with the averaging implied in the title.

GetMeshVtxOnGeomFace() is entirely unnecessary as it can simply be replaced by a single call to Model_GetClassifiedEntities() to retrieve the mesh vertices... for some reason a call was made to retrieve the faces, iterate over the faces, iterate over the face's vertices, determine if the vertex had already been inserted into a list ( a O(n lg n) process which is completely unnecessary... could be worse but still not good), and return said list. As such the function has been removed from the class.

initial_guess() currently uses hardcoded guesses for specific test cases, which need to be changed and the code recompiled between test cases... something more general is required. Probably solving a linear version of the problem or something to that effect to generate an initial guess as in the macroscale analysis, or at the very least something general. At the end of the function there is a note about needing to place the initial guess and essential boundary conditions into the history of the dof... this will likely need to be accomplished in apf be using multiple fields on the mesh (the displacement solution field and one or more displacement history fields), though talking to Dan about this need might lead to a better solution). It only needs the previous displacement, so whatever the previous displacement is, simply add the current dof values (the function has been renamed AccumulateDisplacements() as well). This implementation seems like it will accumulate the fixed boundary conditions as well...

The MoveMesh() function is identical to the Analysis_UpdateMesh function implemented in the NonLinTissue macro class, since both of these classes (NonLinFibMtx and NonLinTissue are subclasses of FiniteElementAnalysis, the Analysis_UpdateMesh() function is being pulled out of these classes and into an independent function declared in the FiniteElementAnalysis.h file and implemented in with the function signature Mesh_UpdateWithDispField(apf::Field*), the apf Field is enough to retrieve the apf mesh and some casting of mesh entities allows access to the unerlying simmetrix entities to retrieve and update their associated coordinates.

Functions Taken From FibMtx or Micro into NonLinFibMtx

  • FibMtx
    • void setBdryFaces() -> void SetBoundaryGeomFaces()
Personal tools