of Abdominal Aortic Aneurysms with Fluid Boundary ... - OhioLINK ETD

48 downloads 50287 Views 4MB Size Report
AAAs can sometimes be detected as a throbbing mass in the abdomen or can be ...... Mail. Public Class Main. Private Sub Main_Load(ByVal sender As Object, ...
A Procedure for Generating Finite Element Models (FEM) of Abdominal Aortic Aneurysms with Fluid Boundary Conditions Derived from Magnetic Resonance Imaging (MRI) Velocimetry

M.S. Thesis

Presented in Partial Fulfillment of the Requirements for the Degree Master of Science in the Graduate School of The Ohio State University

By Mark Allen McElroy, B.S. Graduate Program in Mechanical Engineering

The Ohio State University 2010

Thesis Committee Samir N. Ghadiali, Advisor Orlando Simonetti

Copyright by Mark Allen McElroy 2010

Abstract

Abdominal Aortic Aneurysms (AAAs) are localized bulges in the lower aortic artery tissue. AAAs are prone to rupture, an extremely dangerous event, in which the aorta rips open and blood is allowed to flow freely into the body’s internal cavity. The fatality rate for ruptured AAAs is over 50% so preventative surgery is the preferred method of treatment. However many AAAs never rupture and the risks involved with preventative surgery are not negligible. Clinicians therefore must decide when the risks of AAA rupture outweigh those of preventative surgery.

The current clinical metric for determining the risk of AAA rupture is the transverse diameter. A 5.5 cm diameter is the suggested max allowable size. As many as 20-30% of AAAs below this threshold rupture and in practice, the operating surgeon must account for other risk factors too such as blood pressure and aneurysm shape. As a result, the decision is no more than an educated guess based on a series of known risk factors. There is a clinical desire for a more reliable and comprehensive AAA rupture risk metric Studies have shown that maximum arterial wall Von-Mises stress, calculated using patient-specific finite element (FE) models outperforms diameter with regards to predicting AAA rupture. Modern AAA FE models employ fully coupled dynamic fluidii

structure interaction (FSI) techniques in an effort to accurately measure max wall stress in-vivo and non-invasively. Published boundary conditions (BCs) for dynamic AAA model fluid domains typically involve standard flow rate and pressure conditions being applied at the inlet and outlet of the model respectively. Our lab proposes using in-vivo blood velocity measurements from phase-encoded velocimetry MRI scans to generate patient-specific fluid BCs. A patient-specific flow rate condition is applied at the inlet matching the velocimetry data read in at the inlet. A patient-specific downstream pressure is applied at the outlet. This pressure BC is derived from an optimization routine which seeks to match the modeled and measured outlet flow rates by altering the impedance at the outlet. To date, only one model has been run to convergence, due to a computation run time of over 1 month. While changes were made to the pressure condition at the outlet (a 14% increase in dynamic range) during optimization, these changes had almost no effect of the max arterial wall stress.

iii

Dedication

I would like to dedicate this work to my loving and supportive parents, Paul and Laura McElroy and to my brother, Matt McElroy

iv

Acknowledgments

I would like to acknowledge all those who have worked so hard to help bring this project to fruition. I would like to thank Dr. Yu Ding for aiding with the medical imaging aspects of this project, and Dr. Georgeta Mihai for working so hard on recruiting and scanning patients for this project. Thank you Dr. Sanjay Rajagopalan for providing a hands-on, clinical perspective to the project. Finally, thank you Dr. Orlando Simonetti and Dr. Samir Ghadiali for orchestrating and funding this project.

v

Vita

June 2004 ............................................................. Stow-Munroe Falls High School Fall 2006, Summer 2006, 2007, 2008 .................. Lexmark International March 2009 .......................................................... B.S. Mechanical Engineering, The Ohio State University June 2009 to present ........................................... Graduate Research Associate, Department of Biomedical Engineering, The Ohio State University

Fields of Study Major Field: Mechanical Engineering

vi

Table of Contents

Abstract ............................................................................................................................... ii Dedication .......................................................................................................................... iv Acknowledgments............................................................................................................... v Vita ..................................................................................................................................... vi Table of Contents .............................................................................................................. vii List of Tables ...................................................................................................................... ix List of Figures ...................................................................................................................... x Chapter 1: Abdominal Aortic Aneurysm Anatomy and Physiology .................................... 1 Chapter 2: Dealing with Abdominal Aortic Aneurysms Clinically ....................................... 5 Chapter 3: Abdominal Aortic Aneurysms from an Engineering Perspective ...................... 8 Chapter 4: In Depth Description of Models ...................................................................... 16 Chapter 5: Results ............................................................................................................. 39 Chapter 6: Future Work .................................................................................................... 52 References ........................................................................................................................ 56 Appendix A: How to Generate CAD data from MRI images ............................................. 59

vii

Appendix B: Generating a CAD model in Rhinoceros ....................................................... 71 Appendix C: Extracting Flow Rate Data from Velocimetry MRI Images ........................... 82 Appendix D: Putting it All Together in The Finite Element Model .................................... 86 Appendix E: The Optimization Routine and Running A Model ......................................... 94 Appendix F: Matlab Script Descriptions .......................................................................... 103 Appendix G: Visual Basic Script Descriptions .................................................................. 112 Appendix H: Utilizing the Ohio Supercomputing Center ................................................ 114 Appendix I: Helpful Contacts .......................................................................................... 115 Appendix J: Matlab Code ................................................................................................ 117 Appendix K: Visual Basic Code ........................................................................................ 176

viii

List of Tables

Table 1: Change in lumen volume with respect to sampling ......................................................... 21 Table 2: Important Dicom properties and descriptions................................................................. 64 Table 3: Suggested time stepping scheme .................................................................................... 91 Table 4: Required fields for settings structure .............................................................................. 95 Table 5: Required fields for ADINAwithMATLAB2 ......................................................................... 98 Table 6: Matlab Script Summary.................................................................................................. 103 Table 7: Visual Basic Script Summary .......................................................................................... 113

ix

List of Figures

Figure 1: Comparison of healthy and aneurismal aorta .................................................................. 1 Figure 2: The composition of a healthy aortic wall with no atherosclerosis ................................... 3 Figure 3: Simplified arterial cross section ........................................................................................ 3 Figure 4: Aortic Dissection ............................................................................................................... 5 Figure 5: Examples of the 2 preventative surgeries ........................................................................ 6 Figure 6: Force diagram for a pipe under pressure ......................................................................... 9 Figure 7: Example of axisymmetric geometry ............................................................................... 10 Figure 8: Modeled blood flow in AAA ............................................................................................ 12 Figure 9: Relationship between material stiffness, pressure and flow rate .................................. 15 Figure 10: Example MRI images ..................................................................................................... 17 Figure 11: The 2D image analysis process ..................................................................................... 20 Figure 12: Sampling artifacts in spline curves ................................................................................ 21 Figure 13: Sampling artifact in lofting ............................................................................................ 21 Figure 14: Initial data in Rhino ....................................................................................................... 23 Figure 15: Rhino processing ........................................................................................................... 23 Figure 16: The development of the blood domain ........................................................................ 23 Figure 17: The solid domain ........................................................................................................... 24 Figure 18: The ILT domain wall inner boundary ............................................................................ 24 x

Figure 19: Selecting a velocimetry region of interest .................................................................... 25 Figure 20: Comparison of flow rate data before and after processing ......................................... 26 Figure 21: Example of rough wall, ILT, and fluid mesh .................................................................. 30 Figure 22: Fluidic circuit diagram of the downstream impedance condition ................................ 31 Figure 23: Frequency response of 4-parameter Windkessel ......................................................... 32 Figure 24: The process for developing a pressure curve ............................................................... 33 Figure 25: Types of Nelder-Mead iterations shown in 2D ............................................................. 35 Figure 26: Convergence Chart........................................................................................................ 36 Figure 27: Iterative cycle for generating a patient specific impedance condition ........................ 37 Figure 28: Refined mesh used to generate mesh independent solutions ..................................... 38 Figure 29: Comparison of initial and final flow rate conditions for patient TK ............................. 40 Figure 30: Comparison of initial and final pressure conditions for Patient TK .............................. 40 Figure 31: Comparison of initial and final max stress values for Patient TK.................................. 41 Figure 32: Comparison of initial and experimental outlet flow rates for Patient MM .................. 42 Figure 33: Comparison of initial and experimental outlet flow rates for Patient AK .................... 42 Figure 34: Peak stress of initial and converged arterial wall ......................................................... 43 Figure 35: Artery wall stiffness variational study .......................................................................... 45 Figure 36: ILT stiffness variational study........................................................................................ 46 Figure 37: Impedance parameter R1 variational study ................................................................. 47 Figure 38: Impedance parameter L variational study .................................................................... 47 Figure 39: Impedance parameter R2 variational study ................................................................. 48 xi

Figure 40: Impedance parameter C variational study ................................................................... 48 Figure 41: Comparison of input function with impedance condition............................................ 50 Figure 42: Stress Maps for unconverged Patient MM and Patient AK models ............................. 51 Figure 43: The measured flow rate ................................................................................................ 52 Figure 44: Typical daw data set ..................................................................................................... 59 Figure 45: How to view data sets using a viewer program ............................................................ 61 Figure 46: A data set after being organized into folders ............................................................... 63 Figure 47: How to use the Crop GUI .............................................................................................. 66 Figure 48: How to use the Edging GUI ........................................................................................... 69 Figure 49: Fixing spline curves in Rhino ......................................................................................... 72 Figure 50: Generating surface A and the blood domain................................................................ 73 Figure 51: Generating surface B and surface C .............................................................................. 74 Figure 52: Rhino geometries .......................................................................................................... 75 Figure 53: How to create a cutting surface .................................................................................... 76 Figure 54: The cutting plane does not intersect across the whole surface. .................................. 76 Figure 55: The cutting planes. ........................................................................................................ 77 Figure 56: Rhino geometries .......................................................................................................... 78 Figure 57: Joining outwall surfaces ................................................................................................ 79 Figure 58: Dealing with problems during outerwall surface joining.............................................. 80 Figure 59: A typical velocimetry image and an image with a well defined lumen ........................ 83 Figure 60: Example region of interest ............................................................................................ 83 xii

Figure 61: Inlet and outlet flow rate data both before and after processing. ............................... 85

xiii

Chapter 1: Abdominal Aortic Aneurysm Anatomy and Physiology An aneurysm is the localized bulging of an artery. This bulge can include an enlarged blood cavity, a thickening of the artery wall, or both. Aneurysms can develop anywhere, but have strong tendencies towards specific locations, such as the aorta and brain [9]. The aorta is the largest artery in the

Figure 1: Comparison of healthy and aneurismal aorta. Reprinted from [2].

human body. It emerges directly from the top of the heart, curves downward in what is known as the aortic arch, and then proceeds through the thorax (or chest) to the abdomen. It terminates at the aortic bifurcation, located at the fourth lumbar vertebra, where it bifurcates into the right and left common iliac arteries [10]. Directly above the aortic bifurcation, at the end of the aorta is a common location for aneurysm development. Aneurysms in this abdominal section of the aorta are simply referred to as Abdominal Aortic Aneurysms (AAA). While a clear understanding of why AAAs develop is not well understood, the mechanism through which it occurs is. The bulge in the artery occurs due to the force of the blood flowing through it acting on damaged or diseased tissue. Known risk factors include aging, smoking, high blood pressure, atherosclerosis, and diseases that inflame blood vessels, such as vasculitis [9]. Males and elderly patients are at higher risk for developing AAAs. 1

Symptoms of an AAA include a throbbing in feeling in the abdomen, a deep pain in the back or side of the abdomen, or a gnawing pain in the abdomen that can last for hours or days. Many AAAs present no symptoms, and are instead detected during other medical procedures. AAAs can sometimes be detected as a throbbing mass in the abdomen or can be seen during abdominal imaging [9]. In order to discuss AAAs further, a clear understanding of the anatomy of an artery is necessary. A healthy arterial wall is composed of a series of layers. The adventitia, or outermost layer, is composed primarily of thick bundles of collagen fibrils in a helical structure. There is no definitive outer boundary to the adventitia. Instead the composition gradually becomes looser connective tissue [7]. The media, or middle layers of the wall, are composed of highly organized laminated layers of smooth muscle cells, elastin, and collagen fibril bundles. This is the primary load bearing tissue of the artery wall. Finally the intima, or inner most layer of the wall is an endothelial cell lining between the artery tissue and the lumen with a thin layer of helically oriented collagen fibrils backing them [7]. Many AAAs also develop intraluminal thrombus (ILT) which is a “fibrin structure of blood cells, platelets, blood proteins, and cellular debris” which attaches and buils on the lumen [11]. In many AAA this build up can dominate the crosssectional area of the artery wall. Over time calcium deposits can form both in the ILT and in atherosclerotic tissue between the media and intima of the wall as shown in Figure 3. These deposits are much stiffer than any surrounding tissue.

2

Figure 2: The composition of a healthy aortic wall with no atherosclerosis. It is divided into 3 sections: the intima (I), media (M) and adventitia (A). Reprinted from [7].

For simplification and modeling purposes these layers are often grouped into 3 separate materials that from here on will be referred to as wall tissue, ILT tissue, and calcified tissue. Wall tissue represents the adventia, media, and intima layers and is the primary load bearing surface. ILT is the blood clot like material buildup in the lumen and is relatively soft. The calcified tissue is the very stiff 3

Figure 3: Simplified arterial cross section. Reprinted from [6].

calcium deposits that form in ILT or artery wall as shown in Figure 3. This modeling ignores any heterogenatiy in these three materials.

4

Chapter 2: Dealing with Abdominal Aortic Aneurysms Clinically The reason aneurysms are a clinical concern, is that they are prone to dissection and rupture. Dissection occurs when a layer or a few layers of the artery wall tear, and blood begins flowing between the layers of the wall. Rupture is similar to dissection but in this case, the artery wall completely tears, and blood flows freely out of the artery and into the Figure 4: Aortic Dissection. Reprinted from [3].

internal cavities of the body. Both are very

serious, often proving fatal. We will discuss the implications of rupture only. Since AAAs occur in such a large artery, internal bleeding is extremely dangerous. The naturally occurring pressure and flow rate in the aorta are much higher than seen in smaller arteries and as a result victims can bleed out very quickly. Less than 50% of AAA rupture victims make it to the hospital before dying from this internal bleeding [12]. The speed at which AAA rupture can kill makes surgical repair an unreliable solution. Instead, a much safer course of action is to try to prevent AAA rupture before it occurs. Current medical practice is to perform preventative surgery when concern of AAA rupture arises. The goal of these preventative surgeries are to greatly reduce the chance of AAA rupture occurring, in hope of preventing rupture and thehigh mortality rate associated with it.

5

There are 2 preventative surgeries for AAA rupture – open repair and endovascular stent grafting. Open repair involves the abdomen being opened and the diseased AAA vessel being replaced with a synthetic artery. Endovascular stent grafting involves small incisions being made in the femoral artery so that the stent and surgical catheters may be inserted into the arterial tree downstream of the aneurysm. The stent is installed inside the lumen of the AAA to relieve

Figure 5: Examples of the 2 preventative surgeries. Open repair (left) and endovascular stent (right). Reprinted from [5].

pressure on the diseased wall tissue from the blood. Open repair is much more invasive, requiring more recovery time and is more prone to complications such as infection. Endovascular surgery is a quick and easy fix comparatively, but often requires recurring surgeries to make adjustments to the stent. With either method, the risk of complication is not negligible, and while AAA rupture is devastating, not all AAAs rupture. Performing either of these surgeries unnecessarily exposes the patient to unwarranted risk. Therefore, the question of when to perform preventative surgery must somehow be answered. In determining when surgery should be performed, the goal should be to minimize the total risk to the patient, in which case the moment the risk of AAA rupture outweighs the risks involved with surgery is the correct moment. Due to the somewhat unpredictable nature of AAA 6

rupture, there is no definitive way to answer this question. Experience and empirical evidence have produced AAA diameter as the clinically suggested method for gauging rupture risk. As the diameter of an AAA increases, evidence has shown that the chance of rupture does as well. Common practice is to hold off on preventative surgery until the diameter of the AAA exceeds 5.5cm, or the aneurysm is expanding faster than 0.5 – 1.0 cm/year [1, 6, 13-15]. If either of these values are exceeded, the risk of rupture is deemed to be greater than the risks involved with preventative surgery; if they are not exceeded, then surgery is deemed too risky and the usual recommendation is to wait and continue monitoring the aneurysm. Once an AAA is detected, patients are typically monitored yearly, or in some cases every 6 months, to ensure the AAA is relatively healthy and surgery is not necessary. The AAA is imaged, usually through ultrasound, and the diameter is approximated. While the 5.5cm and rapid expansion rules are considered a good rule of thumb, the final decision is up to the surgeon, who takes into account not only the diameter and growth rate, but other known risk factors such as blood pressure and age. The result is often more of an educated guess as to when it is appropriate to perform surgery, than a carefully evaluated risk assment. This subjectivity is necessary due to the weak correlation between aneurysm diameter and rupture risk. Studies by Simao da Silva, Darling, and Sterpetti all suggest that as many as 20 – 30% of AAAs with a diameter less than 5.5cm rupture before exceeding 5.5cm [16-18]. Furthermore, AAAs have been recorded to get as large as 17cm before rupturing [16].The clinical community is aware of the weakness of the diameter risk metric, and has expressed a desire for a better metric for determining AAA rupture risk [13, 19]. 7

Chapter 3: Abdominal Aortic Aneurysms from an Engineering Perspective

Rupture is a well documented and studied form of material failure in solid mechanics. There is general agreement in the engineering community that stress is the best way to determine if a material will fail. Stress is a measure of force per area in a material (such as lbs/ft2). While traditional stress values are directional, when analyzing material failure, often a scalar quantity known as von Mises stress, or effective stress is used. This is simply a way of incorporating the stress in all directions into one scalar quantity, which can be used to asses the total amount of stress a point is under independent of direction. Many materials have been noted to have critical amounts of von Mises stress they can withstand before they begin to fail. There are various definitions of material failure, but the first form, and the form that will be referred to in this paper involves a phenomenon known as yield. Yield occurs when a solid begins to permanently change shape. Up to a certain stress, solids will bounce back to their original shape when unloaded, but if loaded past their “yield stress” the solids will not return to their original shape naturally and instead returns to some new natural shape. While a material yielding does not necessarily mean it will break or rupture, no material can break without first reaching its yielding point. The statement “if the stress in an arterial wall is less than the wall’s yield stress, it will not rupture, but if the stress is greater than the yield stress, the artery has already begun to fail” is true by definition. This suggests that stress or perhaps the ratio of stress to yield stress would be an ideal metric for determining if an aneurysm might rupture [20].

8

While a correlation between diameter and AAA rupture does exist, it is relatively weak. 20 – 30% of aneurysms with a diameter under 5.5cm still rupture. Stress has the potential to be a much better indicator than diameter. In fact, diameter being correlated with rupture is firmly predicted within solid mechanics theory. The equation for stress in the wall of a thin walled pipe under constant pressure, often referred to in medicine as the Law of Laplace, is shown in Equation (1).

(1)

P is the pressure difference across the pipe wall, t is the thickness of the pipe wall, d is the internal diameter of the pipe, and σ is the stress in the wall. In this equation, the stress and diameter are proportional. This equation can be derived from the force diagram shown in Figure 6. The blue arrows represent pressure pushing the pipe apart, and the red arrows represent the stress in the pipe wall Figure 6: Force diagram for a pipe under pressure. As the diameter increases, so does the force from pressure, p. Modified from [4].

holding everything together. Unless the pipe breaks open, these forces must be in balance. As the

diameter of the pipe increases, the interior cross section of the pipe increases. Since the same internal pressure is acting on a larger area, the force exerted by the fluid, and thus the amount 9

of force the wall must exert to maintain balance increases. Since a larger force is required of the same amount of material in the wall, the stress (force/area) increases. While modeling an aneurysm as a thin walled pipe is an oversimplification, the logic relating diameter and stress is still intact. In both cases, when the amount of force required to contain the pressure becomes greater than what the material can provide (in other words when the stress exceeds the yield stress) it will rupture. While diameter and stress are related, diameter does not take into account as much information as stress does. Quantities such as blood pressure and variations in wall thickness, which are both clinically relevant risk factors, are ignored when using diameter to measure patient risk. However, stress can be used to capture all of these risk factors in one metric. It is generally agreed that stress would be a better metric for AAA rupture, however accurately measuring stresses in-vivo is a tricky problem that has not yet been perfected. While there are many solutions for simple geometry, such as the Law of Laplace, for more complex problems such as stress in an aneurysm, the solutions can be much more mathematically intense to derive. In order to better determine in-vivo stresses, researchers began constructing computer models of the artery mechanics to help calculate these stresses [8]. Using a Figure 7: Example of axisymmetric geometry. Reprinted from [8].

mathematical modeling technique known as 10

finite elements (FE), often used in engineering to determine stress, researches have begun modeling aneurysm mechanics. Early models were static with simplified axisymmetric geometry (see Figure 7), due largely to computational constraints [8]. With the concept proven, researches began to look for ways to improve upon these models. Many of the first improvements involved the material models used to describe the mechanical properties of arterial tissue. Mechanical material modeling involves creating a relationship between force and material deformation. Due to the highly heterogeneous, multiscale and largely varying properties of living tissue, modeling biological materials properly can be difficult. Clinical efforts are ongoing to properly define the properties and variations of arterial tissue [13, 21, 22]. Many computational models have been proposed [19, 23, 24]. The latest material models are anisotropic, meaning the artery tissue reacts differently when stressed circumferentially as opposed to longitudinally. This makes sense due to the organizational nature of tissue layers in the artery wall. However the most commonly used material model is the isotropic hyperelastic model first proposed by Raghavan in 2000 mostly due to the easy of application [24]. In 1999 David Vorp’s lab at the University of Pittsburgh made the jump to creating 3 dimensional patient-specific models [25-27]. This was a vast improvement over the previous, idealized, and often axisymmetric models. These models were generated using image analysis techniques to extract data from computed tomography (CT) scans.

11

The inclusion of the intraluminal thrombus (ILT) by Wang in 2002 proved to be a significant improvement [11]. As mentioned earlier, the intraluminal thrombus is a fatty buildup within the inner layers of the wall with vastly different material properties than the arterial wall tissue. While this tissue is usually considered unhealthy and related to atherosclerosis, FE models have shown it to help distribute forces uniformly through the wall and thus reduce peak stresses. Efforts soon followed to

Figure 8: Modeled blood flow in AAA. Reprinted from [1].

do the same with respect to calcium deposits in the tissue [6, 28]. There is currently no consensus on the effect of calcium deposits on wall stress. More recently a push has developed to improve the accuracy of the loading conditions. Past models have applied a uniform systolic pressure force normal to the surface of the lumen boundary. In reality, the abnormal geometry of aneurysms is known to often cause atypical blood flow patterns as shown in Figure 8 and these complex flow patterns can push harder on the artery wall in some places than in other. To capture these complex forces, the blood flow must be modeled in the lumen and allowed to exert force on the wall tissue, instead of applying loads directly to the inside of the wall. Computer models in which solid and fluid domains are allowed to interact with each other are known as fluid-structure interaction (FSI) models. Some of these models are static and solve for stresses assuming constant unchanging blood flow in 12

the artery [1, 29], while others model the flow dynamically, and as a result also capture changes in stress due to the dynamic fluctuations in the loads [14, 15, 30]. One of the problems with FSI modeling in-vivo is how much more information is required to model both the fluid and in some cases the dynamics. In dynamic models this additional information comes in the form of 2 fluid boundary conditions (BC). A standard cardiac flow rate curve for the aorta is applied at the inlet and a standard pressure curve is applied at the outlet. These are used to model the blood flow, which then exerts time varying and complex forces on the artery wall. These improvements have been vital in creating a more accurate model for predicting patient in-vivo stresses. In 2003 Fillinger showed that stress values in his models were 12% more accurate than diameter at predicting rupture [31]. While beating aneurysm diameter as a predictor is promising, the goal is to predict rupture and no model has yet proven itself able to distinguish between aneurysms near rupture and those that are not with any statistical significance. Therefore, the push to create a more accurate model continues. There are concerns that current FSI models don’t have enough measured data to validate their results and that until the stresses produced from FSI models can somehow be validated, they cannot be trusted to reflect the actual system. If the modeled blood flow is incorrect for some reason, the stresses the model predicts will be incorrect as well. In hopes of validating their fluid models, some researchers have begun coupling their FSI models with experiments to reproduce the flow in a laboratory environment, allowing the computational and experimental results to be compared [29, 32].

13

Our lab is looking for ways to further validate these FSI models computationally. By developing patient-specific fluid boundary conditions, assumptions regarding flow rate and pressure can be relaxed. MRI velocimetry data is utilized to measure the inlet and outlet flow rate of the modeled section of artery. A patient-specific impedance condition is then determined by selecting the impedance which maximizes the agreement between the modeled downstream flow rate and the flow rate measurement extracted from MRI velocimetry images at the downstream boundary. This impedance condition is then used to define what pressure the blood is under through the cardiac cycle at the outlet. One weakness of this approach is that changes to the material properties of the artery wall will directly affects the amount of pressure necessary to create a specific downstream flow rate. This requires the assumption that the patient-specific impedance condition is only patient-specific as long as the wall material properties are correct. As shown in Figure 9 varying the material properties will alter the downstream flow in the same way changing the pressure can. Therefore the amount of pressure required to produce a specific flow rate is dependant on the assumed material properties.

14

Figure 9: Relationship between material stiffness (A) and downstream pressure (B) with respect to downstream flow rate

15

Chapter 4: In Depth Description of Models The modeling procedure described below generates a computational finite element (FE) model that simulates the mechanics of an abdominal aortic aneurysm (AAA). It is a dynamic fully coupled fluid-structure interaction (FSI) model developed using patient-specific geometry and in-vivo blood velocity measurements from phase encoded velocimetry magnetic resonance imaging (MRI) scans. The arterial wall is subdivided into 2 different materials – arterial wall tissue and intraluminal thrombus (ILT), each with their own material models. The measured invivo velocity data is utilized along with the patient’s brachial diastolic blood pressure to generate a patient-specific downstream impedance condition relating the blood flow to pressure that can then be utilized in modeling the blood flow. The procedure begins with a series of MRI scans, lasting approximately 1½ hours. The MRI machine is a 1.5T strength MRI capable of achieving 1x1x1 mm spatial resolution and performing phase contrast acquisition. A T1 weighted 3D anatomical scan is performed over the diseased section of the artery. Also, using MRI phase contrast data, the in-vivo velocity is measured at the upstream and downstream boundaries of the anatomical data. The location of a given velocity measurement within the cardiac cycle is measured by recording the amount of time after the patients R-wave the image was taken. The R-wave is the electrocardiogram signal which signifies the beginning of ventricular contraction in the heart.

16

It is important that the velocimetry data be taken as close to the boundaries of the model as possible, as this is where they will be applied. Also, the phase shift between the 2 velocity data sets, resulting from the time it takes for pressure waves to propagate down the modeled section of aorta is important in the optimization of the impedance condition. Typically, the velocity is measured in the 2 in-plane directions of the image as well as in the out of the plane direction. Due to noise, only the out-ofplane data is utilized, so the velocimetry images should also be taken as orthogonal to the direction of flow as possible. Since inplane motion is ignored, efforts should be made to measure the velocity in a location where there are no flow artifacts that might produce excessive in-plane motion, such as circular flows. The patient’s brachial diastolic

Figure 10: MRI images. (A) is a slice of the anatomical scan. (B) is the out-of-plane velocity map. (C) is an inplane velocity map in the anterior-posterior direction

17

pressure is also taken during this time. Efforts must be made to record an appropriate brachial pressure, as patients might suffer from stress induced high blood pressure during testing. Once all the required data is collected, construction of the model can begin. The anatomical MRI data is run through an in-house image analysis program created using Matlab, which walks the user through the image analysis procedure. It begins with capturing the luminal opening using edge detection. The program first performs some preliminary 3D median pre-filtering (Figure 11.2). During this process each voxel is assigned a value equal to the median value of all the voxels within its 3D neighborhood. In this case, the neighborhood is defined to be a 3x3x3 pixel volume. Then, a series of 2D image analysis procedures for detecting a 2D edge are implemented as shown in Figure 11. The 2D process begins by enlarging the images using bicubic interpolation (Figure 11.3) and applying a 2D median filter to the image (Figure 11.4). The filter neighborhood in this case is a 2D square of pixels. The size is defined by the user. Edge detection is performed using the Canny algorithm (Figure 11.5). This algorithm utilizes 2 different thresholds. The main or primary threshold defines how much of a change in pixel intensity is required before an edge exists. The lower the primary threshold, the more edges will be detected in an image. The secondary threshold also detects edges, however any edge detected using the secondary threshold is only kept as an edge if it touches an existing primary edge. In this way, the secondary threshold can control how long a detected edge is or how many times it branches off. The lower the secondary threshold, the longer and more complex edges appear. After edge 18

detection is performed, a morphological closing operation is implemented on the 2D image (Figure 11.6). This procedure, also referred to as a flood-fill procedure, increases the thickness of all the detected lines a user specified amount, and then erodes the added pixels away again. Anywhere where 2 edges were joined during the flood, they will remain joined after the pixels are eroded away. This helps ensure that the edges detected are closed and define a body of points. The parameters in each of these process steps (magnification, filter neighborhood size, edging thresholds, closure radius) can be altered in real time by the user and an image of the detected edges overlaid onto the pre-filtered image is available to check the accuracy of the detected lumen (Figure 11 .7). Once a series of 2D bodies have been defined, the user is asked to select the body in each image which represents the artery lumen (Figure 11.8).

19

Figure 11: The 2D image analysis process. Raw (1). Pre-filtered (2). Enlarged (3). Filtered (4). Edge detected (5). Closed (6). Overlay (7). Final lumen body (8)

Once the lumen has been completely defined, the next step is to define the outer boundary of the artery wall. The anatomy of an artery is such that the outer edge of an artery is poorly defined and cannot be automatically extracted using any type of edge detection. Therefore, the user is prompted to hand draw the outer boundary for a subset of the slices. Both the luminal and outer boundaries are recorded as a series of points. These points are then written to a Rhinoceros command file in such a way that only every 4th slice is considered and 20

the points in each slice are connected using a closed 6th order spline curve. The reduced sampling and high order spline curves were determined empirically in order to prevent high frequency oscillations in the surface that are obvious artifacts of the sampling. Figure 12 shows this sampling artifact in the spline curves, and Figure 13 shows it when the curves are lofted together. Table 1 has data regarding the change in volume of the models with regards to slice sampling. The change to the model volume as a result of this resampling is only about 1%.

Figure 12: Sampling artifacts in spline curves

Table 1: Change in lumen volume with respect to sampling

1 for 1 1 for 2 1 for 4

Figure 13: Sampling artifact in lofting. (A) 1 for 1 sampling. (B) 1 for 2 sampling. (C) 1 for 4 sampling

21

Lumen Volume (cm3) 14.88 14.94 15.03

% Change in Volume 0.00 0.39 1.02

Rhinoceros is a computer aided design (CAD) package based on nonuniform rational B-splines (NURBS) instead of line segments like traditional CAD packages. As a result, Rhino is excellent for smoothing out digitized geometry extracted from the MRI scans into smooth and continuous shapes. In Rhinoceros, the command file exported from Matlab is read in as a stack of 2 dimensional spline curves a shown in Figure 14. The lumen boundary curves are lofted together and then caped at the ends to form the fluid domain. Due to the resolution of the MRI, many defining features of the wall cannot be resolved such as calcium deposits or the boundary between the artery wall and intraluminal thrombus (ILT). For that reason, the thickness of the arterial wall

Figure 16: The development of the blood domain

Figure 14: Initial data in Rhino

Figure 15: Offsetting the outer surface 1.8mm (center) and subtracting the blood domain (right)

23

tissue is assumed to be 1.8mm. The arterial wall spline curves are lofted together and the resulting surface is offset inwards 1.8mm. The inset wall surface and lumen surface then act as the outer and inner boundaries of the intraluminal thrombus (ILT). To ensure the wall has uniform thickness, the outermost boundary of the combined fluid and ILT domains is then offset 1.8mm out. The arterial wall is defined as the body between these 2 surfaces. Since the outer boundary of the ILT was defined to be 1.8mm in from the defined arterial wall curves, the majority of the arterial wall is exactly the Figure 18: Both the ILT domain (left) same as the surface generated from the hand drawn outer boundary. Wherever the

and wall inner boundary (right) are derived from combinations of the lumen boundary and inset outer boundary

fluid domain extends through the ILT layer, however, the artery wall is expanded slightly past this surface to ensure a 1.8mm thick boundary around these protrusions. Once the 3 domains (blood, ILT, and wall) are defined, the solid and fluid domains of the model are exported from Rhinoceros separately as parasolid files (.x_t).

Figure 17: The solid domain. The thick spots are places where the surface was deemed too thin

24

In order to obtain flow rate data from the MRI velocimetry images, the images are loaded into another in-house image analysis program written in Matlab. This program prompts the user to select a region of interest (ROI) at each end. It then records the flow rate through that region for each image in the stack by averaging the velocity over the region and multiplying it by the area. The trigger time property, recorded in the Dicom images, is

Figure 19: Selecting a region of the velocimetry image to calculate the flow rate through

used to place each data point in time. This property records how long after the trigger event, in this case the patient’s R-wave, the image was taken. Doing this for the inlet and outlet of the model results in flow rate vs. time curve defined at both ends of the model. To enforce a steady state flow, the period and flow volume per cycle of the outflow is scaled to match the inlet flow. This prevents the volume of model from slowly changing across many cardiac cycles. Also, a running average is applied to the data to help dampen out noise. Figure 20 compares these raw and processed flow curves.

25

Experimental Flow Rate Data 50

Flow Rate in Z-direction (cm 3/s)

0

-50

-100

inlet (raw) inlet (processed) outlet (raw) outlet (processed)

-150

-200

0

0.1

0.2

0.3

0.4

0.5 0.6 Trigger Time (s)

0.7

0.8

0.9

1

Figure 20: Comparison of flow rate data before and after processing

The next step is to bring the CAD geometry into the finite element (FE) program ADINA. ADINA works with solid and fluid models separately. This is why the models were exported from Rhino separately. There is error introduced in assuming that the imaged geometry is the natural shape of the artery because in fact the artery was under pressure when imaged. Since the stress of the material during imaging is not known this pre-stress must be ignored, and the imaged geometry is assumed to be the arteries unstressed state. In the fluid model, the blood is modeled as a simple Newtonian fluid with a viscosity of 3.5cP (3.5*10^-3 Pa*s) and density of 1035 kg/m^3 [15]. The flow is assumed to be laminar. This would typically be an unrealistic assumption since abdominal aortic flow is known to be 26

transitory (meaning it is sometimes laminar and sometimes turbulent). This affect the fluid flow because turbulent flow dissipates kinetic energy through the use of eddies while laminar flow does not. While the flow could be modeled as turbulent, this is ill advised due to a lack of information regarding the amount of energy being dissipated. To combat this flaw flowcondition-based interpolation (FCBI) elements are used instead of traditional finite fluid elements. FCBI elements are a hybrid between the finite element and finite volume mathematical techniques for solving fluids models [33]. They utilize the Petrov-Galerkin finite element formulation Equations (2)-(3) to solve the incompressible Navier-Stokes Equations.

(2)

(3)

The Petrov-Galerkin method is a virtual work method for finding the minimum energy solution to a given energy equation. In this case v and p represent a descretized and interpolated solution for the real velocities and pressures of the solution while w and q represent small changes to the velocity and pressure solution. The energy will be minimized when infinitely small changes in either of the imaginary variables have no effect on the energy. In variational calculus, this is known as a stationary point and it signifies a maximum or minimum. When dealing with energy functions, there is typically no maximum value, and so this is equivalent to solving for a minimum. Typically the interpolation equation used to represent v is also used to represent w. This is known as the Bubnov-Galerkin method. In the case of FCBI elements, 27

however, the v function contains exponential terms dependent upon the Reynolds number and the w function is defined as a step function. During the solution process, the exponential terms allow the solution to automatically account for upwinding effects, while the discontinuous virtual velocity function ensures that interpolation between nodes perfectly captures the function shape. This results in conservation of both mass and momentum at the element scale. By enforcing conservation laws and accounting for upwinding effects, FCBI elements can model highly turbulent flows well without the use of a turbulence model [34]. At the inlet to the fluid domain a velocity boundary condition (BC) is chosen to produce the measured inlet flow rate for the given area of the inlet. This is done simply because ADINA does not support a flow rate BC. Applying a uniform velocity across the opening assumes the flow can be modeled as plug flow. A pressure BC is applied to the outlet. The source of this pressure BC comes from the downstream impedance condition and the downstream flow rate velocimetry data. The remaining surfaces are constrained by the solid domain through a fully coupled FSI BC. This BC actually incorporates kinematic, velocity and stress requirements shown in Equations (4)-(6) all into one BC.

(4) (5) (6)

28

The kinematic constraint requires the fluid and solid surfaces remain fixed to one another and displace together. The velocity BC is the no-slip condition, specifying the velocity of the fluid at the wall to be 0, and the stress BC requires the stress to be continuous across the boundary. When the solid model is loaded into ADINA, there will be 2 separate bodies – the wall and the ILT. At the shared surface between these 2 bodies, they must be linked together, physically attaching them to one another. If this were not true, the wall and ILT would be able to slide against one another. The arterial wall tissue is modeled using the Mooney-Rivlin hyperelastic material model proposed by Raghavan [24].

(7)

Where W is the strain energy and I1 is the first invariant of the left Cauchy-Green tensor. α and β are empirical values derived from uniaxial tensile loading of AAA wall tissue excised during surgical repair equal to 174 kPa and 372 kPa respectively. The ILT tissue is modeled using the linear elastic model developed by Di Martino [30, 35], where the Young’s Modulus is 110 kPa and the material is incompressible (Poisson’s Ratio = 0.49). Other than the FSI BC on the inner surface of the combined solids the only other BCs are at the upper and lower ends of the model. At the top surfaces of the model, both bodies are fully constrained. While this is admittedly nonrealistic, it is required to enforce the fluid flow rate BC at the inlet. Since the flow rate BC is defined as a velocity BC (because ADINA does not support flow rate BCs) it requires the area of the inlet to remain constant. Otherwise, the velocity BC will no longer represent the desired 29

flow rate. At the outlet, the bodies are only constrained in the out-of-plane direction. This is commonly referred to as being longitudinally tethered in the literature and is a better reflection of the true boundary. No BC is applied to the outer surface of the model. This assumes any stabilizing effects from the loose connective tissue surrounding the aorta are negligible. The fluid and solid models are solved using a direct FSI algorithm. Each body is meshed using linear elements at a density of about 2 mm. This mesh is optimized for speed, not accuracy, and does not claim to be mesh independent. Once a model converges to an impedance condition, the mesh can be refined to eliminate mesh dependence, and then rerun through the optimization routine. This speeds up the procedure by minimizing the number of times a dense mesh required to generate a mesh independent solution is run. The mesh initially used is shown in Figure 21. It consists of 34k 1st order fluid elements, 25k 1st order arterial wall elements and 33k 1st order ILT elements. Once the FE models are constructed, the downstream impedance condition can be considered. The downstream impedance condition is a time varying relationship between the amount of blood leaving the model (outlet flow rate) and the amount of resistance to that blood flow (downstream pressure). This complex 30

Figure 21: Example of rough wall, ILT, and fluid mesh (left to right) used during optimization

relationship results from the network of arteries downstream of the model. Each artery, like a pipe, resists fluid flow. This resistance is related to the length and diameter of each artery in the network. Because the arteries are compliant the artery diameter is related to pressure and the artery material properties too and so the impedance condition depends not only on length and diameter of every downstream artery, but also pressure and compliance. The actual impedance condition

Figure 22: Fluidic circuit diagram of the downstream impedance condition

for an arterial tree is therefore much too complex to derive directly. Instead simplifications are made. The Windkessel 4 parameter model is a common way to approximate the impedance condition in large arteries [36]. Mathematically it is represented by the transfer function shown in Equation (8).

(8)

Where R1, R2, L, and C are 4 constants, j is the imaginary number, and ω is the frequency of the input. Using the electrical-fluid flow analogy, this impedance condition can also be depicted using as shown in Figure 22, where the parameters of each component correspond to the 31

constants in Equation (8). R1 and Bode Diagram 200

which the gain is determined by R1 and the cut-off frequency is

Magnitude (dB)

L represent a low-pass filter in

150

100

50

0 270

way, R2 and C represent a high-

225

pass filter in which the gain is determined by R2 and the cut-off

Phase (deg)

determined by L. In a similar

180 135 90 -8 10

-6

10

-4

10

-2

10

0

10

2

10

Frequency (rad/sec)

frequency is determined by C. The

Figure 23: Frequency response of 4-parameter Windkessel

result of combining these 2 effects is a notch filter, which attenuates signals within the 2 cut-off frequencies while amplifying high frequency signals by R1 and low frequencies by R2 as shown by the bode plot in Figure 23. One of the downsides to this method of creating a pressure curve is that it can only react to changes in flow rate and cannot detect any type of baseline pressure. The pressure curve resulting from the Windkessel model assumes the pressure is zero when the flow rate is zero. In order to sidestep this pitfall, the patient’s brachial diastolic pressure is added to the pressure curve, making the pressure equal to the brachial diastolic pressure when the flow rate is zero and preserving the dynamic pressure trends. This of course assumes that the artery is at diastole when the flow rate is zero, and that diastole in the aorta is the same pressure as diastole in the brachial artery. Since the outlet flow rate is known from MRI velocimetry images, 32

outlet pressure curves can be derived through transforming the flow rate to a pressure using the Windkessel model

Flow Rate (cm3/s)

Experimental Flow Rate 200 150 100 50 0 -50

0

and then adding the measured

0.5

1

1.5

Impedance Transformed Pressure Curve

diastolic pressure to the resulting pressure curve as

Pressure (kPa)

1

shown in Figure 24. Note that

0.5 0 -0.5 -1

0

0.5

1

1.5

Final Offset Pressure Curve

changing the 4 parameters of the Windkessel model will alter the final pressure curve independent of the measured

Pressure (kPa)

11.5 11 10.5 10

0

0.5

1

1.5

Time (s)

flow rate data. This process is totally automated using in-house

Figure 24: The process for developing a pressure curve. Transform the experimental flow rate (middle) and then add the diastolic pressure (bottom)

Matlab code. In order to calibrate the impedance condition to the patient, an outlet pressure curve is derived from an initial guess of the correct impedance condition. The pressure BC is imported into the ADINA FE model and the model is run to completion. Once the model has completed running, the downstream flow rate vs. time curve from the model is exported to Matlab where it is compared with the MRI velocimetry measured flow rate vs. time curve. The error in agreement between the curves is measured as the total area between the curves squared. This 33

error in flow rate agreement is then minimized by varying the 4 impedance parameters. The optimization routine systematically selects values for the 4 parameters of the impedance model, derives pressure curves based on those selected impedance parameters, and then runs a FE model with that pressure curve to completion. Once completed, the error in flow rate agreements is calculated for that specific model. This process is repeated until the functional value has converges to some minimum amount of error. Once the model is converged, the impedance condition is said to be calibrated to the patient. This process is automated using a series of custom made Matlab and Visual Basic programs. The optimization routine used is the Nelder-Mead simplex method which is a nongradient method. This routine makes decisions regarding which impedance parameters to evaluate next by considering a simplex of points (in this case a simplex is 5 points). At the beginning of each iteration, the largest functional valued point in the simplex is reflected across the centroid of the remaining simplex points. Based on the evaluation of this point, a decision is made regarding which point to try next. The method chooses to either end the iteration, expand, contract inside, contract outside or shrink [37].

34

If the reflected point is not as good as the best point, but better than the 2nd worst point, the reflected point is chosen to replace the worst point in the active simplex and the iteration ends. If the new point is less than the lowest value in the simplex, expansion is attempted. A point is calculated which lies further in the same direction than the reflected point did. If the expansion point is less than the reflected point it replaces the largest point in the simplex, otherwise, the reflected point replaces the largest point. If the reflected point is better than the worst point in the simplex but not better than any others, an outside contraction is performed. Another point is evaluated closer to the simplex than the initial reflected point. The best point between these 2 replaces the worst point in the simplex. If the reflected point is worse than any point currently in the simplex, a contract inside operation is performed. During this step, a point close to the centroid is evaluated. If the new point is better than the worst point in the simplex, replace the worst point with it. If the new point is still not better than current worst point, a shrink operation is performed. This means that all of the current points in the

35

Figure 25: Types of NelderMead iterations shown in 2D. From top to bottom: reflection, expansion, contract outside, contract inside, shirnk.

simplex (except the best

-11

10

x 10

Convergence Chart for Unconstrained Optimization of Patient TK

one) are brought towards 9.5

A proper convergence criterion for

Error (m3/entire model)

the best simplex point. 9

8.5

the optimization routine has 8

not yet been decided. 7.5

Convergence is currently

0

10

20

30

40

50 Iteration

60

70

80

90

100

Figure 26: Convergence Chart

declared when the lowest 5 function values (the active simplex) are all within 10-15 of each other. This was chosen based on an observed lack of improvement in the functional values at this point as shown in Figure 26, and an r2 value greater than 0.995. The impedance parameters were still steadily changing value at this point which suggest that while the function “appears” to be close to convergence, it is not, by definition converged. Due to the large r2 value, an argument can be made that the functional value is close to convergence, however, the impedance parameters cannot be referred to as patient-specific until they also converge. Since the functional value is of primary importance, this is acceptable, however in order to develop a patient-specific impedance condition, more iterations would be necessary. Initial attempts at optimization utilized the Broyden-Fletcher-Goldfarb-Shanno (BFGS) gradient based method. Gradient based methods such as BFGS determine the direction of 36

steepest decent by calculating the gradient at the operating point, usually through a finite difference scheme. They then move in that direction towards a minimum value before recalculating the gradient and changing the direction of search. Gradient methods traditionally outperform non-gradient methods in most cases. They can however become unstable when dealing with signal noise and discontinuous functions due to the impact these have on calculating a reliable gradient value. Reliably calculating a gradient value was the reason the Nelder-Mead method was eventual chosen over the BFGS method despite BFGS’s better rate of convergence. Since each function evaluation requires running a complex FE simulation, the whole optimization routine has proven very computationally expensive and can require literally hundreds of FE models to run before convergence is reached. Optimization Routine Selects an Impedance Condition

The Modeled Flow Rate is Used to Calculate the Error

A Pressure Curve that matches that Impedance Condition is Generated

The Outlet Flow Rate is Extracted From The Model Results

The FE Model is Modified to Include the New Pressure Curve

The FE Model is Run to Completion

Figure 27: Iterative cycle for generating a patient specific impedance condition. Red denotes steps taken in Matlab, while blue represents steps in ADINA

37

Once the model has converged using a minimalistic mesh, the mesh must be refined to assure a mesh independent solution. Figure 28 shows the refined mesh used after the impedance was optimized. This improved mesh contains 111k 1st order fluid elements, 58k 1st order wall elements, and 117k 1st order ILT elements.

Figure 28: Refined mesh used to generate mesh independent solutions

38

Chapter 5: Results In application, deriving a patient-specific impedance condition has proven time consuming. Once the images are received, generating a model ready to be used in the optimization routine takes anywhere from 4 hours to a couple days depending on what type of problems are encountered, usually with regards to the validity of the geometry in Rhino, or the linking of the two solid bodies in ADINA. With more practice and experience, this will likely drop considerably Each Finite Element (FE) model then takes approximately 5-7 hours to run when given two 3 GHz, 64-bit processing nodes, and requires about 2 Gb of RAM. Since this large computation time results more from the FSI iterations and time steps than from the number of degrees of freedom in the model, a large diminishing return is seen when parallelizing these models across many cores. The Patient TK model required 161 models to be evaluated before converging (functional simplex range less than 10-15). The model therefore required approximately 1000 hours (41 days) of run time to converge starting from a standard Windkessel impedance value for the abdominal aorta [36]. Figure 29 compares the initial and final modeled flow rates with the experimentally measured one, and Figure 30 shows the initial and final outlet pressure boundary condition applied to the model. Figure 31 then compares the calculated max stress values of the converged and unconverged models.

39

Comparision of Outlet Flow Rates 200 Experimental Standard Converged

Outlet Flow Rate (cm 3/s)

150

100

50

0

-50

0

0.5

1

1.5

Time (s)

Figure 29: Comparison of initial and final flow rate conditions for patient TK Downstream Pressures Derived from Impedance Conditions 12 Standard Converged

11.8

Downstream Pressure (kPa)

11.6 11.4 11.2 11 10.8 10.6 10.4 10.2 10

0

0.5

1

1.5

Time (s)

Figure 30: Comparison of initial and final pressure conditions for Patient TK

40

Max Stress Values Before and After Convergence 160

Max Von Mises Stress (kPa)

140 120 100 80

Initial Converged

60 40 20 0 Wall

ILT

Figure 31: Comparison of initial and final max stress values for Patient TK

While solid conclusions cannot be drawn from a single data set, the data comparing the converged and initial conditions for Patient TK suggests that generating a patient-specific downstream impedance condition has almost no impact on the calculated maximum wall stress. While the range of dynamic pressures increased by about 200 Pa (14%) the max wall stress changed by less than 0.1%. While a much larger change in the ILT stress (15%) occurred, the stress experienced by the ILT is not typically considered when predicting AAA rupture. Figures 32 and 33 compares experimental outlet flow rate with the standard outlet flow rate generated by using a typical impedance condition for 2 other patients. When compared with Patient TK’s

41

initial data, both of these data sets show more potential for improvement through the derivation of a patient-specific boundary than Patient TK did.

Comparision of Outlet Flow Rate for Patient MM 120 Experimental Standard

Outlet Flow Rate (cm 3/s)

100

80

60

40

20

0

-20

0

0.5

1

1.5

Time (s)

Figure 32: Comparison of initial and experimental outlet flow rates for Patient MM Comparision of Outlet Flow Rates for Patient AK 180 Experimental Standard

160

Outlet Flow Rate (cm 3/s)

140 120 100 80 60 40 20 0 -20

0

0.2

0.4

0.6

0.8

1 1.2 Time (s)

1.4

1.6

1.8

2

Figure 33: Comparison of initial and experimental outlet flow rates for Patient AK

42

Figure 34: Peak stress of initial (left) and converged (right) arterial wall

The mapped stress values for the converged and unconverged Patient TK models during their peak stress values are shown in Figure 34. While the peak values themselves did not increase much, the amount of total strain the wall is experiencing is slightly larger. This suggests that the increased load is being distributed across a larger area of wall by the ILT. This behavior allows the total load to increase, while not increasing the maximum wall stress values. It is of note that Patient TK has a very large amount of ILT tissue when compared to the other patients, and having less ILT would likely increase the sensitivity of the maximum stress to changes in the

43

fluid load. If this is the case, patient-specific impedance conditions could have a more dramatic effect on max stress values in other patient geometries. At the initial “standard” impedance value, a parametric study of the wall stiffness and optimization parameters was performed on Patient TK with the goal of better understand the effects of the material properties and optimization parameters on these peak stress values. Figure 35 shows the results of varying the stiffness of the wall material over 2 decades. Because the artery wall is a hyper-elastic material, its stiffness changes as a function of deformation. The presented wall stiffness values represent the stiffness of the material only while completely undeformed.

44

Effects of Artery Wall Initial Stiffness on Max Stress

Max Von Mises Stress (kPa)

150

100

50

0 2 10

3

4

10 10 ILT Young's Modulus (kPa)

5

10

Figure 35: Artery wall stiffness variational study

The astricks markers represent the operating point, in this case the assumed material properties. The ILT shows to be very sensitive to changes in the wall stress. The wall itself shows significant change in max stress as well, though not at the operating point since the astricks is nearly a minimum. If the operating point were moved up to about 6*103 kPa, the sensativity would be about 30 kPA/decade. Figure 36 shows similar results in which the stiffness of the ILT was varied over about 1 decade. Since the ILT is a linear elastic model, the stiffness is constant and equivalent to the Young’s Modulus.

45

Effects of ILT Stiffness on Max Stress 140

Max Von Mises Stress (kPa)

120

100

80

60

40

20

0 1 10

2

3

10 10 ILT Young's Modulus (kPa)

4

10

Figure 36: ILT stiffness variational study

Changes to the stiffness of the ILT affect wall stress significantly more (approximately 110 kPa/decade at the operating point). This helps validate the theory that the ILT is helping distribute forces over the artery wall. Figures 37 – 40 show the impact of independently varying the 4 impedance parameters around the initial assumed impedance condition.

46

Effects of the R1 Impedance Parameter on Max Stress 140

Max Von Mises Stress (kPa)

120 Wall ILT 100

80

60

40

20 5 10

6

7

10

8

10

10

5

Fluid Resistance (Ns/m )

Figure 37: Impedance parameter R1 variational study Effects of the L Impedance Parameter on Max Stress 120 110 Wall ILT

Max Von Mises Stress (kPa)

100 90 80 70 60 50 40 30 20 4 10

5

6

10

10

Fluid Inertance (m 8/kgs)

Figure 38: Impedance parameter L variational study

47

7

10

Effects of the R2 Impedance Parameter on Max Stress 120 110 Wall ILT

Max Von Mises Stress (kPa)

100 90 80 70 60 50 40 30 20 -5 10

0

5

10

10

10

15

10

10

20

10

5

Fluid Resistance (Ns/m )

Figure 39: Impedance parameter R2 variational study Effects of the C Impedance Parameter on Max Stress 140 Wall ILT

Max Von Mises Stress (kPa)

120

100

80

60

40

20 -5 10

0

5

10

10 Compliance (m 5/N)

Figure 40: Impedance parameter C variational study

48

10

10

The max stresses do not appear to be as sensitive to changes in the impedance model as they are to changes in the material models. This suggests that the optimization routine might be better implemented, if a downstream boundary condition was assumed and patient specific material properties were generated using the optimization routine. Due to the nature of the routine, this should be a generally easy change to make. The lack of change in functional value with respect to the R2 and C parameters is a result of the assumed impedance condition used. As mentioned, the R2 and C parameters act as a lowpass filter, allowing only low frequency components of the outlet flow rate data through, while attenuating higher frequencies. The C value defines what a low frequency is, by affecting the location of the cutoff frequency (the point at which the filter begins attenuating signals). Under the assumed impedance condition, the experimental flow rate curve, which acts as the input to the impedance condition has no “low-frequency" components, as shown in Figure 41, where the impedance condition and input flow rate data are compared in the frequency domain. As shown in Figure 40, if the capacitance value were changed enough to include components of the input signal on the low-frequency side of the notch filter, then both C and R2 would have an effect on the stresses.

49

-5

Frequency Analysis of Outlet Flow Rate

Magnitude (abs)

x 10 6 4 2 0 -4 10

-3

-2

10

-1

10

10

0

10

1

10

2

10

Impedance Condition Frequency Response

Magnitude (dB)

150

100

50

0 -4 10

-3

10

-2

10

-1

10

0

10

1

10

2

10

Frequency (Hz)

Figure 41: Comparison of input function with impedance condition validating why R2 and C have no effect on the pressure curve

As the Patient TK model converged, the notched bandwidth actually moves further to the left. If the input frequencies from the outlet flow rate data are found to always lie entirely on the high frequency region of the impedance condition, the low-pass filter components would be unnecessary, and removing them will reduce the degrees of freedom being optimized, thus increasing the rate of convergence. This also explains a phenomenon encountered during the optimization in which the R2 parameter value varies wildly. During these swings in R2 value often attempts negative

50

resistance values, which make no physical sense. The optimization routines erratic behavior with respect to the R2 parameter is a result of the functions complete lack of dependence on R2. While the bulk of data collected so far has been with the Patient TK data set, other models have been generated and proven to work using these techniques. While these models work, they have not yet been run to convergence, and so they do not represent patient-specific impedance data sets. Figure show examples of other geometries and mapped stress that have been successfully calculated using the techniques presented.

Figure 42: Stress Maps for unconverged Patient MM (left) and Patient AK (right) models

51

Chapter 6: Future Work While the optimization tool developed appears to work well, more data is necessary before any firm conclusions can be made with regards to its significants. Also, there is need for some further validation such as proving the solution is independent of the selected time stepping scheme and creating a more physically significant definition of convergence. With respect to the tool itself, experience suggests it would be a more accurate strategy to define an average velocity from the MRI velocimetry images instead of a flow rate. This would allow the region of interest defined during velocimetry image processing to be placed well within the visible lumen barrier instead of on it. The lumen cross sectional area varies by as much as 20% through the cardiac cycle and attempting to define a stationary boundary of

Figure 43: The measured flow rate is determined by integrating the velocity over a specified ROI. By measuring average velocity instead of flow rate, the ROI could be shrunk to easily fit in the lumen with out introducing error.

the artery over which to calculate flow rate is an exercise in futility. If too large a region of interest (ROI) is selected unwanted noise is introduced from periphery pixel values. Declaring too small a ROI and artificially reducing the measured flow rate by not integrating over the whole cross sectional area of the lumen. While 52

calculating the average velocity requires the flow be modeled as plug flow (uniform velocity cross section), this assumtion is already made during modeling, based on how the boundary conditions are introduced. Another possible improvement to the current system would be the development of an ADINA flow rate boundary condition (BC) so that the solid BC on the inlet side can be relaxed to longitudinally tethered instead of being fully constrained. The development of such a BC can be done through the use of the user-defined BC options in ADIANA. This would require a fortran file to be constructed which reacts with the back-end of ADINAs solver. Improving the upstream BCs should prevent the non-physiological stress concentrations at the top of the model which are currently often the location of maximum ILT stress values. The goal of genrating a “push button” operation that can easily walk medical personel with no engineering experience through the process of designing, running and analysising a model has not yet been reached. While many sections, such as image analysis and optimization have been well packaged, the CAD and FE modeling has not. Now that a foundation has been laid regarding the operation of this AAA modeling tool, efforts could begin to package it into be more user-friendly “push button” operation. While the above improvements would be beneficial, the primary question when facing the future of this project involves its current inability to decouple fluid force and material stiffness. There are an infinite number of combinations or impedance condition and material properties which can generate a given flow rate. As long as the “patient-specific” impedance 53

parameter requires assumed material properties to be correct, it cannot be referred to as patient-specific in the true sense of the word. In order to combat this, a different method for determining either downstream pressure or material properties would be required, such as tabulated clinical data. Some might suggest pulse wave velocimetry (PWV) as one possibility for generating this type of data. While it is possible PWV could work, the theory behind PWV is closely tied in with the deformation of the artery, so it is questionable if any more data would be included in a PWV measurement than all ready exists. Also, PWV cannot be used to completely define either the downstream flow rate or the material stiffness. Instead it can provide the dynamic range of the pressure values or the average stiffness of the artery at the operating pressure independant of position or material type. Both the wall and ILT would be averaged together in this arterial stiffness value. However, if empirical data were collected and tabulated in such a way that educated guesses could be made regarding either wall stiffness or downstream pressure based off of a series of indicators (age, PWV, sex, etc.) the amount of error introduced through the assumed value could be reduced. Increasing the accuracy of the assumed value, in conjunction with generating a patient-specific pressure or stiffness condition (depending on which data is tabulated) will validate the procedure. Another possible improvement could be the introduction of variable arterial wall thickness and calcified tissue to the models. To include these details, the resolution of the anatomical data must be increased by about 3 orders of magnitude (from 1x1x1 mm to 54

0.1x0.1x0.1 mm) this desired level of resolution is impossible to obtain using an MRI. Computer Tomography (CT) is a much better imaging technique for achieving this resolution. Also, calcified tissue is easily distinguishable from ILT in CT scans. One of the possible challenges with incorporating CT scans into the procedure will involve properly registering the new anatomical CT images with the still required MRI velocimetry images. As mentioned earlier, the velocimetry data must be well registered with the anatomical data or else it could negatively affect the optimization routine by altering the phase shift between the velocity curves.

55

References

1.

2. 3. 4.

5.

6.

7.

8.

9.

10. 11.

12. 13. 14.

Bluestein, D., et al., Intraluminal thrombus and risk of rupture in patient specific abdominal aortic aneurysm - FSI modelling. Computer Methods in Biomechanics and Biomedical Engineering, 2009. 12(1): p. 73-81. Union Memorial Hospital. Aneurysms. [cited 2010 Aug. 13]; Available from: http://www.unionmemorial.org/body.cfm?id=555789. Cardiolabel Worldwide. Types of Aneurysm. May 1, 2010 [cited 2010 Aug. 26]; Available from: http://www.cardiolabel.eu/Types%20of%20Aneurysm.html. University of Nebraska: Department of Engineering Mechanics. Pressure Vessels. 2000 [cited 2010 Aug. 16]; Available from: http://emweb.unl.edu/negahban/em325/18pressure-vessels/pressure%20vessels.htm. Society of Vascular Surgery. Abdominal Aortic Aneurysm. Vascular Web 2010 Jan. 19, 2010 [cited 2010 Aug. 13]; Available from: http://www.vascularweb.org/vascularhealth/Pages/AbdominalAorticAneurysm.aspx. Maier, A., et al., Impact of calcifications on patient-specific wall stress analysis of abdominal aortic aneurysms. Biomechanics and Modeling in Mechanobiology, 2010: p. 1-11. Gasser, T.C., R.W. Ogden, and G.A. Holzapfel, Hyperelastic modelling of arterial layers with distributed collagen fibre orientations. Journal of the Royal Society Interface, 2006. 3(6): p. 15-35. Mower, W.R., L.J. Baraff, and J. Sneyd, STRESS DISTRIBUTIONS IN VASCULAR ANEURYSMS - FACTORS AFFECTING RISK OF ANEURYSM RUPTURE. Journal of Surgical Research, 1993. 55(2): p. 155-161. U.S. Department of Health & Human Services, National Institutes of Health, and National Heart Lung and Blood Institute. Aneurysm. 2009 April 2009 [cited 2010 August 13]; Available from: http://www.nhlbi.nih.gov/health/dci/Diseases/arm/arm_what.html. aortic bifurcation, in Stedman's Medical Dictionary. 2006, Lippincott Williams & Wilkins. Wang, D.H.J., et al., Effect of intraluminal thrombus on wall stress in patient-specific models of abdominal aortic aneurysm. Journal of Vascular Surgery, 2002. 36(3): p. 598604. Thomas, P.R. and R.D. Stewart, Abdominal aortic aneurysm. Br J Surg, 1988. 75(8): p. 733-6. Thubrikar, M.J., et al., Mechanical properties of abdominal aortic aneurysm wall. Journal of Medical Engineering & Technology, 2001. 25(4): p. 133-142. Scotti, C.M., et al., Wall stress and flow dynamics in abdominal aortic aneurysms: finite element analysis vs. fluid-structure interaction. Computer Methods in Biomechanics and Biomedical Engineering, 2008. 11(3): p. 301-322. 56

15.

16. 17. 18. 19.

20.

21. 22. 23. 24.

25. 26.

27. 28.

29.

30.

Rissland, P., et al., Abdominal Aortic Aneurysm Risk of Rupture: Patient-Specific FSI Simulations Using Anisotropic Model. Journal of Biomechanical Engineering-Transactions of the Asme, 2009. 131(3). da Silva, E.S., et al., Morphology and diameter of infrarenal aortic aneurysms: a prospective autopsy study. Cardiovascular Surgery, 2000. 8(7): p. 526-532. Darling, R.C., et al., Autopsy Study of Unoperated Abdominal Aortic-Aneurysms - Case for Early Resection. Circulation, 1977. 56(3): p. 161-164. Sterpetti, A.V., et al., Factors Influencing the Rupture of Abdominal Aortic-Aneurysms. Surgery Gynecology & Obstetrics, 1991. 173(3): p. 175-178. Raghavan, M.L., M.W. Webster, and D.A. Vorp, Ex vivo biomechanical behavior of abdominal aortic aneurysm: Assessment using a new mathematical model. Annals of Biomedical Engineering, 1996. 24(5): p. 573-582. Geest, J.P.V., et al., A biomechanics-based rupture potential index for abdominal aortic aneurysm risk assessment - Demonstrative application, in Abdominal Aortic Aneurysm: Genetics, Pathophysiology and Molecular Biology, M.D. Tilson, H. Kuivaniemi, and G.R. Upchurch, Editors. 2006, Blackwell Publishing: Oxford. p. 11-21. Santelices, L.C., et al., Relative Contributions of Age and Atherosclerosis to Vascular Stiffness. Cts-Clinical and Translational Science, 2008. 1(1): p. 62-66. Stalhand, J., Determination of human arterial wall parameters from clinical data. Biomechanics and Modeling in Mechanobiology, 2009. 8(2): p. 141-148. Geest, J.P.V., et al., The effects of anisotropy on the stress analyses of patient-specific abdominal aortic aneurysms. Annals of Biomedical Engineering, 2008. 36(6): p. 921-932. Raghavan, M.L. and D.A. Vorp, Toward a biomechanical tool to evaluate rupture potential of abdominal aortic aneurysm: identification of a finite strain constitutive model and evaluation of its applicability. Journal of Biomechanics, 2000. 33(4): p. 475482. Sacks, M.S., et al., In vivo three-dimensional surface geometry of abdominal aortic aneurysms. Annals of Biomedical Engineering, 1999. 27(4): p. 469-479. Raghavan, M.L., et al., Wall stress distribution on three-dimensionally reconstructed models of human abdominal aortic aneurysm. Journal of Vascular Surgery, 2000. 31(4): p. 760-769. Smith, D.B., et al., Surface geometric analysis of anatomic structures using biquintic finite element interpolation. Annals of Biomedical Engineering, 2000. 28(6): p. 598-611. Speelman, L., et al., Effects of wall calcifications in patient-specific wall stress analyses of abdominal aortic aneurysms. Journal of Biomechanical Engineering-Transactions of the Asme, 2007. 129(1): p. 105-109. Dorfmann, A., et al., Evaluating patient-specific abdominal aortic aneurysm wall stress based on flow-induced loading. Biomechanics and Modeling in Mechanobiology, 2010. 9(2): p. 127-139. Papaharilaou, Y., et al., A decoupled fluid structure approach for estimating wall stress in abdominal aortic aneurysms. Journal of Biomechanics, 2007. 40(2): p. 367-377. 57

31.

Fillinger, M.F., et al., Prediction of rupture risk in abdominal aortic aneurysm during observation: Wall stress versus diameter. Journal of Vascular Surgery, 2003. 37(4): p. 724-732. 32. Yang, A.S., C.Y. Wen, and L.Y. Tseng, In vitro characterization of aortic flow using numerical simulation, phase-contrast magnetic resonance imaging, and particle tracking images. Proceedings of the Institution of Mechanical Engineers Part C-Journal of Mechanical Engineering Science, 2008. 222(12): p. 2455-2462. 33. Bathe, K.J. and H. Zhang, A flow-condition-based interpolation finite element procedure for incompressible fluid flows. Computers & Structures, 2002. 80(14-15): p. 1267-1277. 34. Bathe, K.J. and J.P. Pontaza, A flow-condition-based interpolation mixed finite element procedure for higher Reynolds number fluid flows. Mathematical Models & Methods in Applied Sciences, 2002. 12(4): p. 525-539. 35. Di Martino, E., et al., Biomechanics of abdominal aortic aneurysm in the presence of endoluminal thrombus: experimental characterisation and structural static computational analysis. Eur J Vasc Endovasc Surg, 1998. 15(4): p. 290-9. 36. Hlavac, M. and J. Holcik, Windkessel Model Analysis in Matlab, Brno University of Technology FEEC Brno University of Technology Department of Biomedical Engineering: Brno. 37. Lagarias, J.C., et al., Convergence properties of the Nelder-Mead simplex method in low dimensions. Siam Journal on Optimization, 1998. 9(1): p. 112-147.

58

Appendix A: How to Generate CAD data from MRI images

When a data set is received, it usually contains 1 file called DICOMDIR and then a serialized list of files as shown. None of these files will have file extensions. These files are called DICOM images. DICOM is a universal medical imaging format that is becoming popular for transferring medical image files between doctors and hospitals.

Figure 44: Typical raw data set

59

In order to view these images, a DICOM viewer such as MicroDicom will be necessary. In order to open a data set, only the DICOMDIR file needs to be opened in the viewer. This file is a catalog of all the images and how they are organized. Upon opening the data set, the file structure will become much more obvious. Each image is organized in a tree, similar to how windows explorer lays out folders. The most general tier specifies the patient. The next tier identifies which study the image belongs to, and the last tier is which series the image was taken in. The first couple series of any set are known as the localizers. These provide a general map of where the body is in the machine so that the MRI technician can determine where they need to image further. The localizers are of no concern during modeling. In fact, there are only 2 types of series of interest to the modeler: anatomical and velocimetry. Both of these will appear as images taken in the transverse plane of the body.

60

Figure 45: How to view data sets using a viewer program

The velocimetry data is the easiest to spot. It always consists of 4 sequential series, the last 3 of which just look like static. The 3 static looking series are maps of the velocity at a stationary slice position during different times. The series measure velocity in the X, the Y, and the Z directions respectfully. The series preceding these 3 velocity maps, which should look much more normal is the image generated while creating the 3 velocity maps, and is of no real importance other than matching the position of the images to the anatomical data. 61

The anatomical images are all within 1 series and look very similar to the 1st velocimetry image series except with better contrast. Each image is taken at a different location, so when viewing a series of these images you are moving superiorly or inferiorly through space instead of time. There is always another series that looks very similar to the anatomical series towards the beginning. This is one of the localizer series. It covers a larger area and has more distance between the slices than the anatomical data. Notice that each one of the images in the viewer is actually the title of one of the serialized files in the data set. Whatever the numbering scheme for these images is, it becomes quickly apparent that it is not designed allow easy differentiation of image series. In fact, the numbers in each series appear randomly organized. This can make reading specific image series into Matlab very tedious. To work around this a Matlab script (DicomSort.m) was created that breaks these image files into folders based on their place in the organizational hierarchy. Once the images are split up and reorganized, they will no longer be able to be opened in the Dicom viewer, but it will become much easier to locate all the images in a specific series through file browsing.

62

Figure 46: A data set after being organized into folders

To begin extracting the anatomical data go to the anatomical Matlab folder (D:\mark\Aortic Wall Imaging\Matlab Programs\clean-up\Anatomical Data). In this folder are all the scripts needed to extract the anatomical data and write the Rhino command file. The file entitled “BATCH_FILE.m” is simply a list of commands that must be run to perform the whole process. These commands can be performed one at a time to become familiar with the process and how it works, or the script can be run directly and will walk the user through the whole process. It is nice to understand each step of the batch file so that if mistakes are made midprocess the process can be stopped, the mistake can be fixed, and then the process can be resumed from where it was left off.

63

When dealing with Dicom images in Matlab there are 2 commands of interest: dicomread and dicominfo. The first reads the image in exactly like imread does. The second reads in a large structure or other data recorded in the Dicom format. While many of these values are not that important or self-explanatory, others are can be cryptic and are necessary to properly extract data from the images. Table 2 lists some of these fields and what they mean. Table 2: Important Dicom properties and descriptions

Field Name

Data Type

Description

SequenceName

String

In velocimetry images, the velocity conversion is the number buried in this string. (ex: if 75 is in the string, then max pixel intensity = 75 cm/s and min pixel intensity = -75 cm/s)

SliceThickness

Number

The thickness of each image out-of-plane(mm)

SpacingBetweenSlices

Number

The percent of slice thickness that is not imaged between each slice in a 3D stack. (ex: SliceThickness=1, SpaceingBetweenSlices=10, therefore 0.1mm are skipped between each image)

ImagePositionPatient

Vector

global XYZ coordinates of the upper left (1,1) pixel (mm)

Continued

64

Table 2 Continued

Field Name

Data Type

Description

PixelSpacing

Vector

size of each pixel in the local xy directions (mm)

ImageOrientationPatient Vector

The first 3 values are a unit vector in the local x direction in terms of global XYZ coordinates. The last 3 are a unit vector in the local y direction in terms of global XYZ coordinates.

TriggerTime

Number

In velocimetry images, the amount of time after the triggering event the image was taken (ms)

The image analysis begins with all the images from the anatomical data series being read into Matlab. Then a GUI aids the user in cropping the MRI images of the whole chest down to a localized area around the aorta. Properly cropping down the image will save a lot of computational time during image processing, but will also avoid introducing edge effects in the region of interest, caused by the filter neighborhood falling off the edge of the image. During cropping, if there are images at the beginning or end of the series that need to be taken out, they can be removed using the Remove button, however, if they are in the middle of the series, they should not be removed, because the program will assumes even spacing between all the images. The images can be cropped repeatedly in one run if necessary, but remember to hit the crop button before exiting, otherwise the image will not be cropped.

65

Figure 47: How to use the Crop GUI

After cropping, the data is pre-filtered using a 3x3x3 neighborhood median filter. The command used to do this is medfilt3 which is not a packaged Matlab command but can be downloaded for free. When an image is filtered with a median filter, the new pixel value is defined as the median value of all the pixels in its neighborhood on the original image. The benefit of a median averaging filter over a more traditional mean averaging filter is that a

66

median filter does a better job at preserving edges, whereas mean averaging will erode edges in an image. After the pre-filter, the edging GUI is loaded. The edging GUI handles the magnification, filtering, edging, and closing operations. The magnification operation enlarges the images by interpolating more pixel values using bicubic interpolation. The level of magnification can be controlled using the textbox labeled “Magnification”, however in practice this appears to be unnecessary and the default (4x) works very well. After being magnified, a 2D median filter is applied to each slice. The filtering helps eliminate noise during the edging operation. The filter neighborhood is always assumed to be square and the size can be controlled by using either the slider or text box in the “Filtering” group. While not prevented, using even numbered neighborhood sizes is ill advised because there should always be a central pixel in the filtering neighborhood. While the median filter does attempt to preserve the lumen edge, an excessively large neighborhood will shift the edge inward do to its naturally convex shape. Therefore it is advised to keep the median filter size relatively small unless necessary. The filtered image is then passed to the Canny edging algorithm. This algorithm utilizes 2 different thresholds, each with their own slider and textbox located in the “Edging” button group. The main or primary threshold defines how much of a change in pixel value is required before an edge is declared to exist. The lower the primary threshold, the more edges will be detected in an image. The secondary threshold also detects edges, however any edge detected 67

using the secondary threshold is only kept as an edge if it touches an existing primary edge. In this way, the secondary threshold can control how long an edge is or how many times it branches off. The lower the secondary threshold, the longer and more complex edges will appear. The secondary threshold must always be lower than or equal to the primary threshold. Once the appropriate edging thresholds are set for an image, a morphological closure operation is performed on the edged image. This means that all the edges are thickened by the closure radius, and then eroded back to their original size with the caveat that any edges that were connected during the thickening process (usually referred to as a flooding operation) remain connected when the lines are eroded back down. The result is that any small holes in the boundary are filled in and connected. The amount of flooding performed can be controlled using the textbox labeled “Closure Radius”. Each image can be viewed at any step along this process by using the radio buttons located at the bottom of the GUI. This is extremely useful for determining exactly why an edge doesn’t look right and what should be changed to make it better. The “Unaltered” option shows the raw image as it was read into the GUI, after the pre-filtering. The “Magnified” button shows the image after being refined through interpolation. “Filtered” is the image after being run through the median filter. “Edged” is the results after the edge detection algorithm has run. “Closed” looks very similar to edge usually, but it is actually the image after the morphological flood/fill operations were used to help close the lumen boundary. The “Overlay” option is very

68

helpful for validation because it plots the final detected boundary on top off the original image, to quickly ensure that the detected edge is correct.

Figure 48: How to use the Edging GUI

After exiting the edging GUI the boundaries are used to define filled bodies and the user is prompted to select the body which represents the artery in each image. Once the correct body is selected, it is eroded back down to an outer edge. The user is then prompted to draw a closed polygon on a series of slice images to define the artery outer boundary. These hand drawn points, as well as the points determined to be lumen edges are exported to Rhino. 69

The .txt file exported from Matlab is not just data, but actually a list of commands to be executed in Rhino’s command terminal. Upon opening Rhino, all of the Matlab data can be input by going to Tools>Commands>Read from File… and selecting the Matlab outputted file.

70

Appendix B: Generating a CAD model in Rhinoceros Generating the CAD model in Rhino is a less structured step in the process. Each geometry is different and different problems are encountered when attempting to model it. The overall goal in Rhino is to take the spline curve data loaded in from Matlab and generate 3 closed bodies representing the blood, the ILT, and the wall. As you will see when you load the data into Rhino, everything in Rhino is organized into layers. The command file creates a new layer for each spline curve it loads in. The layers are designated either “Fluid Domain #”, for spline curves representing the lumen boundary, or “Outer Wall #” for spline curves representing the outer boundary of the artery. The first thing is to look through the data loaded into Rhino and correct any obvious errors, such as the spline curve connecting through points in the incorrect order. To correct an obvious error, activate and show only the layer containing that curve. Then delete the undesired points and recreate the spline curve as shown in Figure 49.

71

Figure 49: Fixing spline curves in Rhino

Once you are happy with the imported data you can begin developing it into solid bodies. I usually start with the inner most layer and work my way out. Create a new layer (surface A), and generate a surface that is all of the lumen slices lofted together. Then create another layer (Blood Domain) and copy the surface you just created into it (Ctrl-C, Ctrl-V, Edit>Layers>Change Object Layer). Cap the ends. Your fluid domain is done. 72

Figure 50: Generating surface A and the blood domain

The next step is to create the ILT domain. The outer wall is assumed to be 1.8 mm thick and so the outer boundary of the ILT should be 1.8mm in from what was determined to be the outer boundary of the wall. Create a new layer (surface B) and loft together the outer wall spline curves using the same procedure used to create surface A, except instead of using a loose loft, as done before, Use a tight loft. Then in another new layer (surface C), offset surface B inwards 1.8mm. 73

Figure 51: Generating surface B and surface C

Surface C then represents the inner boundary of the artery wall and Surface A represents the outer boundary of the fluid domain. Therefore the ILT should occupy the space between these 2 surfaces. In many cases these surfaces will overlap one another in a few spots. In these places there is assumed to be no ILT. Create a layer (ILT domain) and make copies of both surface A and surface C in it. In order to develop a solid body from these two overlapping surfaces, the sections where the fluid domain is outside the wall domain must be deleted. The most dependable way to do this is to use the split command. Split the surface A duplicate in the ILT 74

domain using surface C and split the surface C duplicate in the ILT domain using surface A. The result should be that wherever the 2 surfaces cross each other, they have been divided into separate surfaces. Then simply delete all the patches of unwanted surface to get 2 surfaces similar to those shown in Figure 52.

Figure 52: (left) Surface C after split operation. (right) A split surface A and surface C after the extra material was deleted.

Once these surfaces are caped and joined, the ILT solid will be complete. However, using the “OffsetSrf” command causes the edges of surface C to no longer be planar. In order to cap an object the surfaces must be made planar at the ends. To do this, create a new layer (end 75

surfaces). Unhide a spline curve at each end of the model (it can be a fluid domain or outer wall curve. It doesn’t matter because they should both be in the same plane). Create a plane from each of the spline curves. These planes will be used to define the ends of your surfaces.

Figure 53: How to create a cutting surface

Figure 54: The cutting plane does not intersect across the whole surface.

When the planar surface is shown with the ILT geometry, notice that some of the ILT surface doesn’t reach the end plane, meaning a cut will still not create a planar surface yet. There are 2 solutions to this. The first is to bring the end plane in a little using “OffsetSrf”. The second is to extend the ILT surface using the “ExtendSrf” command. The second is preferred because as it doesn’t change the overall length of the model. Once one of these options is performed, the surfaces can be cut (“BooleanDifference” or “Split” commands) to produce 76

planar ends, and then can be easily capped to produce the ILT body. If the “Cap” command is having difficulties, “PlanarSrf” combined with “Join” works well also. The only remaining body is the artery wall. While the drawn in slices are meant to represent the outer boundary of the artery wall, there is also a desire to prevent stress concentrations caused by non-existent thin spots in the artery wall. Therefore, the wall is not assumed to end at surface B, but instead at a uniform 1.8mm from the outer boundary of the combined blood and ILT domains. Anywhere that the ILT exists, a 1.8mm offset will be equivalent to using surface B because the outer boundary of the ILT is defined to be a 1.8mm offset of surface B. However, in areas where the fluid domain was closer than 1.8 mm to the defined outer wall boundary (places with no ILT) wall material is added until the wall is exactly 1.8mm. In order to create the wall domain in Rhino, create a new layer (surface D). As done with the ILT, copy surface A and surface C into this layer and split each surface. In this case, however, do not delete the spots where the fluid domain overtakes the ILT and instead delete the inner most surface. In most places, this should be surface A, but in the small patches where surface A is outside of surface C, it will become surface C. Once this is done, join all the surfaces together to get the inner boundary of the artery wall. Figure 55: The cutting planes.

77

Figure 56: The finished ILT domain (left) and surface D (right). Both are built from surface A and surface C but with different parts of each.

Since the artery wall is defined as being 1.8mm thick, the outer boundary is found by offsetting surface D 1.8mm outward. This is done in its own layer (surface E). When the poly surface is offset, it will be exploded into each component surface and then those components will be offset individually. The result is a collection of surfaces that all have a small amount of

78

overlap that must be removed before they can be rejoined. Split each overlapping surface with the other and delete the extra length. This must be done for both surfaces at each overlap.

Figure 57: The surfaces will initially overlap (A). Both surfaces will need to be split so that the overlap from the buldge (B) and from the main surface (C) can both be deleted. Once this is done, the 2 surfaces should easily join (D).

If you’re having difficulties getting the surfaces to split, use the “intersect” command to make sure there is a closed intersection curve dividing each surface in two. In the example above there wasn’t originally a closed intersection and the main surface was extended to close it. In

79

some cases the surfaces will fail to split when the intersection curve is closed. This almost always occurs when dealing with polysurfaces and can be worked out by exploding the polysurface in surfaces and using the closed intersection line to split each surface individually. If all else fails and there are still difficulties with combining the surfaces, the “JoinEdge” command can be used. This command is somewhat of a built in cheat which can cause problems later on, because Rhino will still not have a good understanding of the geometry, even though its closed.

Figure 58: Initially these surfaces did not divide themselves into 2 parts. The intersection curve was not closed (A). The ExtendSrf command was used on the main surface to create a closed intersection curve.

Once the outer surface is completely joined together into one polysurface assembly of the arterial wall solid body can begin. Create a new layer (wall domain) and copy surface D and surface E into it. Trim the ends of the surfaces as was done with the ILT (the same cutting planes can be used) and cap it to generate a solid model of your surface. At this point, the whole CAD model should exist in Rhino. The next step is exporting the data out of Rhino and into ADINA. ADINA can accept either IGIS or parasolid files. Between these 2 choices of file format, parasolid 80

is by far a superior format. However, the parasolid compiler in Rhino is problamatic and often produces invalid parasolid files. To work around this, export the geometry (File>Export Selected) from Rhino in two seperate step files (.stp) – one with the blood domain, and another with the ILT and artery wall domains. Then open each file in SolidWorks and immediately save them (just use “save as”) again as a parasolid file (.x_t).

81

Appendix C: Extracting Flow Rate Data from Velocimetry MRI Images In order to extract the flow rate data from the MRI velocimetry images, returning to Matlab. All the programs required to perform this task are in the folder “D:\mark\Aortic Wall Imaging\Matlab Programs\clean-up\Experimental Data”. Also in this folder is a script called BATCH_FILE.m. As before, this is simply a list of commands to run through in order to extract the flow rate information from the images. They can be run sequentially in the command window, or the script itself can be executed and will walk the user through the process. The process begins with reading the velocimetry images at the inlet in the Z-direction (the out-of plane direction) into Matlab. As mentioned earlier, the velocity scaling information is buried in a string “SequenceName” located in the Dicom file information. This scalar is extracted from all the images, to ensure there are no problems with getting this data out of the images later and to ensure the correct images were selected. Then, the same cropping GUI that was used with the anatomical data is used again to crop down the images around the area of interest. In this case, the cropping is only used to shrink the images so that the region of interest can be magnified.

82

Figure 59: A typical velocimetry image (left) and an image with a well defined lumen (right)

In Figure 59 notice that the artery geometry can only be resolved when the blood velocity is high enough to get the lumen out of the noise level of the image. During the cropping operation, make sure to note the slice number of a slice with an easily definable lumen. The next step is to select the area that should be averaged over. The user will be prompted to enter the slice number of a slice with a definable lumen cavity, and then draw an ellipse representing the lumen area on that slice. This ellipse defines the area over which the flow rate will be measured. When happy with the ROI, hit enter to move on. The flow rate is calculated by multiplying the velocity value of each pixel within the ROI by the pixel area, to get the flow rate of that specific pixel, and then summing these pixel scale flow rate values for all the pixels in the ROI. During this process, the area of the Figure 60: Example region of interest (ROI)

83

ROI is also calculated. Despite the integration of data over the area, the noise level of the resulting curve can be quite high. A running average of the flow rate is then taken to help eliminate noise. It is typically over 5 points, but can easily be changed if necessary. While averaging the data does attenuate the large pulsitile spike in flow rate, it also eliminates a lot of noise and has proven much more stable in the model. To prevent the averaging from introducing phase shift, the running averaged is taken with the pixel being averaged in the center of its neighborhood. This process is then repeated for the downstream boundary. After a flow rate has been calculated for the upstream and downstream boundaries they must be normalized to one another. Since these are separate experimental data sets, they are not guaranteed to have the same period or flow rate/cycle. In reality these values must be the same for both sets or else the artery will steadily inflate or deflate over many cycles as more blood is allowed to enter than exits or vice versa. To this end, the user is asked to input the area of the model inlets and outlets. Since the flow rate is defined over the ROI selected in the image, any difference in area between the model opening and the ROI will affect the measured flow rate. To track this error, the difference in area between the given model opening, and the selected ROI is reported. At the inlet, a velocity is defined which provides the measured flow rate over the given model inlet area. The outlet flow rate is then, first normalized to the period of the inlet flow rate. This is done simply by multiplying the outlet time values by the ratio of the inlet period to the outlet period. The ratio multiplier is displayed so the user knows how much the data is being manipulated. But the difference is usually less than 10%. The outlet flow rate is then normalized to the inlet flow rate too. Both the inlet and outlet flow rates are integrated 84

over their cycle to determine a flow per cycle. The ratio of these flows is then used to scale the outlet flow data in the same way the outlet time data was scaled. This flow rate modifier quantity is again displayed for the user, and is often closer to 20%. Once the period and flow per cycle of the outlet data has been set equal to those of the inlet data, these data sets can be applied to a model without integrating error over each cycle modeled. While there are concerns over manipulating the experimental data so much, it is necessary and anatomically correct for these 2 data sets to have identical period and, assuming there are no other outlet arteries, identical flow per cycle.

Experimental Flow Rate Data 50

Flow Rate in Z-direction (cm 3/s)

0

-50

-100

inlet (raw) inlet (processed) outlet (raw) outlet (processed)

-150

-200

0

0.1

0.2

0.3

0.4

0.5 0.6 Trigger Time (s)

0.7

0.8

0.9

Figure 61: Inlet and outlet flow rate data both before and after processing.

85

1

Appendix D: Putting it All Together in The Finite Element Model Once both the experimental data and the CAD model have been generated, the mechanical model can be constructed. The mechanical model is generated using finite elements in a software package called ADINA. ADINA models the fluid and solid domains separately, but then will solve them together in a fluid-structure interaction solver. The list below will walk the user through generating the models in ADINA. Solid Domain 1) Set Environment - ADINA Structures - Dynamics-Implicit - FSI

Control>Degrees of Freedom… turn off rotational DOFs Control>Analysis Assumptions>Kinematics large strains large stresses

2) Import Wall and ILT geometry 3) "facelink "

ex: facelink 1 1 3 2 6

86

facelink 2 1 6 2 3

If that doesn‟t work, here are some other techniques Rigid Links After everything is meshed create a node set of the slave surface without the nodes on the end (slave nodes cannot have constraints applied to them)

Meshing>Nodes>Node Set Node Set 1 -

“from geometry line/edge”

-

Select all edges on the slave body (ILT) that are both linked with the master body (Wall) and on a surface with boundary conditions (the ends)

Node Set 2 -

“from geometry surface/face”

-

Select all faces on the slave body that are linked with the master body

Node Set 3 -

“subtract sets”

-

Subtract node set 1 from node set 2

Node Set 4 -

“from geometry surface/face”

-

Select all faces on the master body that contact the slave body

87

Model>Constraints>Rigid Links -

Make Node Set 3 (ILT) slave and Node Set 4 (wall) the master

Rigid Link (nodes) The program “MatchNodeSets_RigidLinks.m” written by Francis Sheer can be used to identify a series of nodes to be connected to the closest node of in another set of nodes. The paired data is then exported as a text file to be imported into ADINAs Rigid Link (nodes) options

Glue Mesh Create the 2 meshes, but ensure that Coincident checking is turned off for both meshes. Then utilize the Glue Mesh command to fix the 2 surfaces to each other.

4) Define Materials Material 1 - Artery Wall Mooney-Rivlin Density = 1000 Bulk Modulus = 174000000 C1=174000 C3=1881000 Material 2 - ILT Elastic Isotropic Density = 1000

88

E=0.11e6 nu=0.49

5) Define Element Groups EG 1 - 3D Solid Default Material = 1 EG 2 - 3D Solid Default Material = 2

6) Define Skew System Model>Skew Systems>Define Normal System # 1

Model>Skew System>Apply Faces Select End Faces Select Skew System 1 Set Normal Direction to “Aligned with Axis „A‟” In a skew system, the ABC directions replace XYZ, so this is equivalent to setting X to the normal direction

7) Apply BCs Fix All DOFs at upper faces Define FIX_NORM as fixing X-TRANSLATION

89

Apply FIX_NORM at lower faces Model>BCs>FSI BC

8) Generate Mesh Subdivide Bodies length ~0.002 Create Mesh>Body 4 element nodes

Fluid Domain 1) Set Environment - ADINA CFD - Transient - FSI - Incompressible

FSI Options FSI Solution Coupling = direct Maximum Number of FSI Iterations = 25 Analysis Options Automatic Time-Stepping = On Maximum Subdivisions Allowed = 10 Controlled By = Subdivision Procedure

90

Model>Flow Assumptions Include Heat Transfer = Off Flow Model = Laminar Control>Solution Process FCBI Elements = Yes Control>Time Steps Table 3: Suggested time stepping scheme

Number of Steps

Step Size

10

0.0001

1

0.039

1

0.16

4

0.2

(Period of Cardiac Cycle)*2/0.01

0.01

2) Import Geometry 3) Define Material Material 1 - Incompressible Constant Viscosity = 3.5e-3 Density = 1035

4) Define Element Group EG 1 - 3D fluid

5) Apply Fixities

91

Model>Special Boundary Conditions Condition 1 - Fluid-Structure Interface

Import Inflow Velocity to Time Function 1 Import Pressure to Time Function 2 (if using optimization routine, just put filler) Apply Velocity BC Define Load as 1 in the Z direction Apply load to inlet face with time function 1 Apply Nodal Pressure BC Define Load as 1 Apply load to outlet face with time function 2

6) Generate Mesh Subdivide Bodies length ~0.002 Meshing>Create Mesh>Body

Applying a “facelink” to the solid geometry rarely works, but is a better and simpler way of combining the 2 solid bodies. The solid materials are assumed to be as dense as water. This is due to a lack of data regarding arterial wall tissue densities. The mesh density is a suggestion based on convergence alone. A mesh convergence study is still required in order to validate the model results. The time steps are also only a suggestion and might need to be varied slightly between models. Typically, the first second is designated as ramp-up, and I suggest this be kept as it is hardwired into much of the analysis code. After the first step, the model should run for at

92

least 2 complete cycles to avoid unwanted transient effects in the first cycle. Since each patient will have a different cardiac cycle period, each model will need to be run a different amount of time to complete 2 full cycles. This can be done by varying the number of time steps or the length of the time steps. The example shows varying the number of time steps, but either way is acceptable.

93

Appendix E: The Optimization Routine and Running A Model Once the mechanical model is complete, the last step is setting up an optimization routine that uses the finite element model for function evaluation. This routine is charged with finding the impedance condition parameters for which the model outlet flow rate has the best agreement with the measured velocimetry outlet flow rate. Since ADINA has no built-in optimization abilities, a process had to be constructed to systematically select an impedance condition, incorporate that condition into the ADINA models, run the models to completion, and then extract data from the models and evaluate the level of agreement between the flow rate data. The first tendency to construct such a process, to perform the same task repeatedly between programs, would be a batch file. Batch files are lists of commands meant to be run like a program in the operating system. The problem with using a batch file in this case is the length of time over which each step can take. For example, the program cannot attempt to extract data until after the model has run to completion. While there are ways in batch file programming to ask the execution of the file to wait until the above commands are complete, problems arise due to the construction of the ADINA executable files. ADINA, like many other programs for Windows, is constructed such that the executable file (the file used to begin an instance of the program) is only a launcher program, and closes quickly after opening the files which will actually remain open. This prevents batch files from easily determining if the file is still running, because it only knows to monitor the launch executable, which quickly closes. 94

To work around this problem, a Visual Basic Program was developed (ADINAwithMATLAB2). This program automates the whole optimization routine by timing the running of both Matlab and ADINA off of each other. Before running ADINAwithMATLAB2, it is important that a Matlab structure variable be saved with the fields below that also matches with the data asked for in the program’s GUI. Table 4: Required fields for settings structure

Field Name

Variable Type

Description

experimental_t

nx1 vector of doubles

Time component of experimental outlet flow rate data (sec)

experimental_outflow nx1 vector of doubles

Flow rate component of experimental outlet flow rate data (m3/s)

diastolic

double

Diastolic brachial blood pressure (mmHg)

x0

4x1 vector of doubles

The initial impedance condition parameters. The design vector, x is defined as x=[C; L; R1; R2], where each parameter is as referenced in Figure 22.

Continued

95

Table 4 continued

Field Name

Variable Type

Description

waveform_cycles

double

Determines the number of cardiac cycles which will be read into the ADINA model before it is run

outletfacenumber

double

The number of the face that represents to outlet in the ADINA fluid model

IDBfile

string

The full path of the fluid internal database (.idb) file

fluidDATfile

string

The full path of the fluid database (.dat) file

solidDATfile

string

The full path of the solid database (.dat) file

INfile

string

The full path of the input (.in) file generated by Matlab to change the pressure function being applied to the model

Continued

96

Table 4 continued

Field Name

Variable Type

Description

PLOfile

string

The full path of the plot (.plo) file generated by Matlab to extract the outlet flow rate from the model

PORfile

string

The full path of the portal (.por) file that contains data for the solved model.

log_file

string

The full path of the function evaluation log file. This file is generated by Matlab and is used to store function evaluation quantities each time a model is completed. Each row is an evaluation. The first 4 numbers are the x vector quantities and the last number is the function quantity.

FlowrateFile

string

The full path of the ADINA output file containing the outlet flow rate data for a completed model.

97

On top of this data all being loaded into a structure called settings and saved as a .mat Matlab workspace file, The fields in the VB script must also be completed. These values are explained below. Table 5: Required fields for ADINAwithMATLAB2

Text Box Title

Description

Matlab Active Directory

Full path of the directory containing all the Matlab code that will be run including the .mat file with the settings structure

Matlab Command

Whatever you would like to run in Matlab. Can be used exactly as the Matlab Command Console. Typically contains “Optimize(‘MATFILE’)” where MATFILE is the name of the .mat file containing the settings structure

ADINA AUI executable file

Fill path of ADINA AUI executable. Typically can be left as default value.

ADINA FSI Solver executable

Fill path of ADINA FSI solver executable. Typically can be left as default value.

ADINA IN file

The full path of the input (.in) file generated by Matlab to change the pressure function being applied to the model. Must match .mat file.

Continued

98

Table 5 continued

Text Box Title

Description

ADINA PLO file

The full path of the plot (.plo) file generated by Matlab to extract the outlet flow rate from the model. Must match .mat file.

Fluid DAT file

The full path of the fluid database (.dat) file. Must match .mat file

OUT file

The full path of the fluid output (.out) file.

Solid DAT file

The full path of the solid database (.dat) file. Must match .mat file

Preprocessing Wait Time

Number of minutes to wait after initiating the IN file before proceeding.

Processing Wait Time

Number of minutes the OUT file must remain unchanged before proceeding

# of Processors

Number of processors the FSI solver is allowed to allocate.

Mem Usage

Amount of memory the FSI solver is allowed to allocate

Postprocessing Wait Time

Number of minutes to wait after initiating the PLO file before proceeding.

99

When executed, ADINAwithMATLAB2 runs as follows. 1. Opens Matlab. Changes the active directory as specified. Then executes any commands in the Matlab command text box. Automatically detects when Matlab closes. Once Matlab closes, it proceeds to the next step. The optimization Matlab script ends with a “quit” command unless the model has converged, causing the program to proceed as soon as Matlab has completed its commands. a. During the running of “Optimize” in Matlab, the optimization routine will be run from the initial point x0. Function values will be returned from the log file until one of two things happens – the model converges, or a function value is requested which is not given in the log file. When the model converges, Matlab will remain open, stopping the routine from running, with a message declaring the model converged. If a function value is requested for which there is no known solution in the log file, Matlab will generate 2 text files – the IN file, and the PLO file. The IN file opens the fluid IDB model file and changes the pressure condition. It then generates a new DAT file, and closes the AUI. The PLO file opens the fluid POR file of a solved model, and outputs the flow rate across the face specified by outletfacenumber. 2. Once Matlab has closed, the VB program will instantly open the AUI and execute the IN file that Matlab just generated. Since the VB script cannot determine when ADINA has completed running the IN file, it will wait for a designated amount of time before doing anything else. During this time, the interface of the VB program will appear crashed. 100

This is because the program was not multi-threaded and does not mean the program has crashed. 3. After waiting the prescribed amount of “preprocessing” time the VB program will open the ADINA FSI solver and begin solving the solid and fluid DAT files. It will do nothing but monitor the size of the fluid OUT file every minute until it has not changed in file size for the prescribed amount of “processing” time. 4. Once the OUT file has stopped growing for a time, the VB program will again open the AUI, this time running the PLO file. It will again wait the specified “postprocessing” time in order to give the PLO file time to run its course. During this time, the user interface of the VB script will not refresh and appear crashed, as during the preprocessing. 5. After the OUT file has been run, Matlab will be opened as before, restarting the cycle. The first thing Matlab attempts to do is read the FlowrateFile exported during the PLO file’s run, and add that entry to the function evaluation log file. That way, when the Optimization routine starts again, it will proceed a step further before encountering another unknown function value.

Obviously problems will be encountered if any of the data fields in the settings Matlab structure variable or the ADINAwithMATLAB2 program fields is incorrect. Another problem area can be the 3 waiting times that must be specified. If any of these times are too short, steps will be taken before appropriate. For example, the model could begin to solve before the pressure condition has been changed. In this case, it will result in incorrect function evaluation values. In 101

other cases, such as if it believes the solver has completed before it has, the process will most likely incorrectly work itself all the way around to opening the solver again, and then will error out because the DAT files it wishes to access are already in use. In most cases, once the program is stopped, errors can be easily corrected by deleting the FlowrateFile, to ensure no extra data is incorrectly read in, and deleting the unwanted or incorrect function evaluation lines from the log file.

102

Appendix F: Matlab Script Descriptions Table 6 is a brief description of all the Matlab scripts utilized in this process. Some of these files are used during the process, while others are sometimes helpful for debugging or otherwise visualizing the data. Table 6: Matlab Script Summary

Name

Location

Description

AdinaTimeVar2Matlab.m

D:\mark\Aortic Wall

Opens ADINA exported variable

Imaging\Matlab

files and exports the data within,

Programs\clean-up\Model

including the title of each variable

Calibration Procedure

extracted

D:\mark\Aortic Wall

Checks the function evaluation log

Imaging\Matlab

file for a requested impedance

Programs\clean-up\Model

vector x. If the value is listed it

Calibration Procedure

returns that the value was found

CheckLog

and what the value is. Continued

103

Table 6 continued

Name

Location

Description

ExportWaveform

D:\mark\Aortic Wall

Writes the request impedance

Imaging\Matlab

condition vector, x into the log file,

Programs\clean-up\Model

without a function evaluation, and

Calibration Procedure

then generates an ADINA IN file which includes the correct pressure curve for the given impedance.

GetFunc

D:\mark\Aortic Wall

Checks the log file to see if a

Imaging\Matlab

requested impedance condition

Programs\clean-up\Model

has already been evaluated. If not,

Calibration Procedure

runs the ExportWaveform script and returns that no function evaluation exists. Can be set to penalize negative impedance parameters, thus creating a constrained optimization routine or can allow for negative parameters

Continued

104

Table 6 continued

Name

Location

Description

ImportWaveforms

D:\mark\Aortic Wall

Reads the flow rate file data, and

Imaging\Matlab

adds the appropriate functional

Programs\clean-up\Model

evaluation to the end of the log file.

Calibration Procedure Optimize

D:\mark\Aortic Wall

Opens the .mat variable data with

Imaging\Matlab

the settings structure within, and

Programs\clean-up\Model

then begins the optimization

Calibration Procedure

routine. If the routine requires a function evaluation to proceed, the file prepares the VB script to run one then closes Matlab. Otherwise it runs until converged, and then displays a message to the user. The optimization procedure is also constructed to produce a convergence chart which is saved as Convergence_Chart.fig in the active Matlab directory.

Continued

105

Table 6 continued

Name

Location

Description

BATCH_FILE

D:\mark\Aortic Wall

List of commands that walk

Imaging\Matlab

through the anatomical image

Programs\clean-

analysis procedure

up\Anatomical Data Crop_GUI

D:\mark\Aortic Wall

GUI for defining the desired section

Imaging\Matlab

of an image stack. Is identical to

Programs\clean-

the one used in velocimetry.

up\Anatomical Data DicomCrop

DicomDrawBoundary

D:\mark\Aortic Wall

Crops data off of a Dicom image. In

Imaging\Matlab

addition to altering the image, the

Programs\clean-

information within the Dicom

up\Anatomical Data

image must also be updated.

D:\mark\Aortic Wall

Prompts the user to draw in

Imaging\Matlab

polygons around a series of images

Programs\clean-

in a stack. Used to define the outer

up\Anatomical Data

boundary of the artery.

Continued

106

Table 6 Continued

Name

Location

Description

DicomMagnify

D:\mark\Aortic Wall

Interpolates more image points in a

Imaging\Matlab

Dicom image. Also, updates the

Programs\clean-

extra information in the Dicom

up\Anatomical Data

image

D:\mark\Aortic Wall

Exports a list of 3 dimensional data

Imaging\Matlab

points from a black and white

Programs\clean-

image, where each white pixel is

up\Anatomical Data

defined as a point.

D:\mark\Aortic Wall

GUI for handling the image

Imaging\Matlab

processing of the anatomical lumen

Programs\clean-

data

DicomPic2Pts

Edging_GUI

up\Anatomical Data GetBody_GUI

D:\mark\Aortic Wall

Goes through a stack of black and

Imaging\Matlab

white images, and prompt the user

Programs\clean-

to select the white body which

up\Anatomical Data

represents the aorta

Continued

107

Table 6 continued

Name

Location

Description

GetDicomStack

D:\mark\Aortic Wall

Prompts the user to select a series

Imaging\Matlab

of Dicom images to read in and

Programs\clean-

then reads both the image and

up\Anatomical Data

information in and sorts both by either height or time

Slice2Rhino

D:\mark\Aortic Wall

When given a series of 3D data

Imaging\Matlab

points organized into slices,

Programs\clean-

generates a Rhino command file to

up\Anatomical Data

read those data points in as a series of spline curves

BATCH_FILE

D:\mark\Aortic Wall

List of commands that walk

Imaging\Matlab

through the velocimetry image

Programs\clean-

analysis procedure

up\Experimental Data Crop_GUI

D:\mark\Aortic Wall

Same as Crop_GUI for anatomical

Imaging\Matlab

data

Programs\cleanup\Experimental Data Continued

108

Table 6 continued

Name

Location

Description

DicomCrop

D:\mark\Aortic Wall

Same as DicomCrop for anatomical

Imaging\Matlab

data

Programs\cleanup\Experimental Data DisectSequenceName

D:\mark\Aortic Wall

Removes the velocity scaling data

Imaging\Matlab

buried within the SequenceName

Programs\clean-

property of a Dicom stack

up\Experimental Data ExtractFlowrate

D:\mark\Aortic Wall

Measures the flow rate through a

Imaging\Matlab

region of interest defined by the

Programs\clean-

user for a set of velocimetry images

up\Experimental Data GetDicomStack

D:\mark\Aortic Wall

Same as GetDicomStack for

Imaging\Matlab

anatomical data

Programs\cleanup\Experimental Data Continued

109

Table 6 continued

Name

Location

Description

Replicate

D:\mark\Aortic Wall

When given the data for 1 period of

Imaging\Matlab

a periodic cycle, will repeat this

Programs\clean-

data as many times as needed to

up\Experimental Data

generate data covering more than 1 period

SortDicom

D:\mark\Aortic Wall

Used to sort the series of raw

Imaging\Matlab

Dicom images into folders for

Programs\clean-up\Other

easier manipulation

Nice Functions Velocity

D:\mark\Aortic Wall

Can read in all the velocimetry data

Imaging\Matlab

provided (including the XYZ

Programs\clean-up\Other

directions) and generate a vector

Nice Functions

field of data that can be viewed in Tecplot

Continued

110

Table 6 continued

Name

Location

Description

DicomGetAbsLocation

D:\mark\Aortic Wall

Reads one image and allows the

Imaging\Matlab

user to select one pixel in that

Programs\clean-up\Other

image. Then outputs the global XYZ

Nice Functions

coordinates of the pixel.

D:\mark\Aortic Wall

Tries to define a 3D body from only

Imaging\Matlab

1 selected point. While sound,

Programs\clean-up\Other

sometimes screws up and the

Nice Functions

benefit was deemed usually not

bw3select

worth the hassle. medfilt3

viewer3d

C:\Documents and

Used to implement 3D median

Settings\Mark\My

filtering on images. Written by

Documents\MATLAB

Damien Garcia.

C:\Documents and

Very cool program. Allows the user

Settings\Mark\My

to visualize 3D image stacks in

Documents\MATLAB

Matlab. Written by Dirk-Jan Kroon

111

Appendix G: Visual Basic Script Descriptions These Visual Basic Programs were written on a 32-bit computer in Microsoft Visual Basic 2010 Express. Each project is on the “Data_Transfer” drive located on the Seagate BlackArmor network drive. They are located in the folder “Visual Basic Programs”. To install any of these programs, go to the “publish” folder within the specific project and use the setup.exe file. To uninstall any of these programs from your computer use “Add or Remove Programs” located in the Windows Control Panel.

Table 7 is a list and brief description of the Visual Basic scripts.

112

Table 7: Visual Basic Script Summary

Name

Description

ADINA Batch

Allows multiple ADINA models to be run sequentially. Once the list is completed, the user can choose to be emailed. Current only written to support the FSI solver, but is setup for more to be easily added. Monitors models by detecting changes in the size of the fluid out file.

ADINAwithMATLAB

Used during the optimization routine. Runs commands in Matlab, then executes an IN file in the ADINA AUI. Waits a designated amount of preprocessing time, before then starting the ADINA FSI solver. Monitors the fluid .out file size, until it stops growing, and then executes a PLO file in the ADINA AUI before returning to the beginning of the cycle and running Matlab again. It continues this cycle indefinitely.

Console Model

Sends an email when the selected file stops changing size. Must be

Notifier

run in the command console, and requires mailsend.exe to be placed in the computers path. This program has been dated by the GUI version and could probably be avoided.

GUI Model Notifier

Sends an email when the selected file stops changing size.

113

Appendix H: Utilizing the Ohio Supercomputing Center The Ohio Supercomputing Center (OSC) has the potential to significantly improve the throughput of this project by providing a significant number of additional computational resources. Hopefully these resources will not only reduce the amount of time required to run each model to convergence, but also allow for many more models to be run simultaneously. First, an account must be made for the user. If ADINA is to be used on the OSC, the user must be list under Dr. Ghadiali’s account because the ADINA license is in his name. Connecting to the OSC can be done through an SSH client such as "Putty". Once connected to the OSC, the interface is a text only UNIX command console. A text editor will be necessary to view and edit any text files on the system. “Vi” is a common choice that seems to work very well once you get the hang of it. Another important function will be transferring files back and forth between the workstation and the OSC account. “Pscp” is a command line function that is supported by Putty and can be downloaded from their web site, which can be used to transfer files both from and to the OSC account. To utilize multiple processors, jobs must be submitted in batch mode. The OSC website has some information regarding how to use their batch file software. In order to run ADINA on the OSC computer, it must be transferred over using pscp and then installed. Once installed use lsmon to specify the license server. >cd $ADINA/slm >./lsmon license2.osce.edu The files to run ADINA are then located at $ADINA/tools. The OSC does not support ADINA and are providing the ADINA license server for us as a courtesy. Don’t expect large amounts of help from the OSC with regards to ADINA, but any questions regarding ADINA at the OSC should be directed to Sid Samsi, who was kind enough to set up the license server. Also, .dat files created in a windows version of ADINA cannot be run directly on the Linux version of ADINA located at the OSC. In order to run models at the OSC, .in files should be created on a windows system with a graphical interface and then a .idb file can be generated from the .in file on the OSC system. Using the linux version of the .idb file, will allow you to generate proper .dat files to be run. The optimization software should should not be affected by any of these changes.

114

Appendix I: Helpful Contacts Dr. Samir Ghadiali Department of Biomedical Engineering Davis Heart and Lung Research Institute Department of Mechanical Engineering

The Ohio State University

[email protected] Columbus, OH

The Ohio State University

Columbus, OH

The Ohio State University

Columbus, OH

Project coordinator, Modeling expert

Dr. Orlando Simonetti Davis Heart and Lung Research Institute Department of Internal Medicine and Radiology

The Ohio State University

[email protected] Columbus, OH

The Ohio State University

Columbus, OH

Project coordinator, Medical imaging expert

Dr. Sanjay Rajagopalan Davis Heart and Lung Research Institute Department of Internal Medicine and Radiology

The Ohio State University

[email protected] Columbus, OH

The Ohio State University

Columbus, OH

Surgeon, AAA expert

Dr. Georgeta Mihai Davis Heart and Lung Research Institute

The Ohio State University

[email protected] Columbus, OH

Medical imaging expert, Clinical liaison

ADINA Troubleshooting

[email protected]

ADINA modeling help. They usually respond within a day. 115

OSC Troubleshooting

[email protected]

For help using the OSC. Any questions regarding running ADINA on the OSC should be directed to Sid Samsi, but still through the above email.

116

Appendix J: Matlab Code

AdinaTimeVar2Matlab function [data,Variables]=AdinaTimeVar2Matlab(data_name) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% % % Converts the text file exported from ADINA containing variable data % versus time (in which there is only one value per time) into Matlab % variables % % data_name = path of the ADINA exported text file % % data = cell array of variable values. Each cell is a different variable % Variables = the name of the cell arrays in order %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% if nargin~=1 %Get file paths [data_name, data_path]=uigetfile('*.txt','Select Data File'); data_name=[data_path data_name]; end %Read in variable data file_str=fileread(data_name); %Extract variable names pos_vars=regexp(file_str,'TIME','once'); pos_endvars=pos_vars+regexp(file_str(pos_vars:length(file_str)),'\n','o nce'); var_str=file_str(pos_vars:pos_endvars); i=1; done=0; while done~=1 try done=1; var(i)=textscan(var_str,'%s %*[^\n]'); pos_vars=regexp(var_str,var{i},'once'); var_str=var_str(pos_vars{1}+length(var{i}{1}):length(var_str)); i=i+1;

117

done=0; end end for i=1:length(var)-1 Variables{i}=var{i}{1}; end %Read in variable data data_format='%f'; for i=2:length(Variables) data_format=[data_format ' %f']; end pos_data=pos_endvars; pos_enddata=pos_data + regexp(file_str(pos_data:length(file_str)),'***','once')-1; data=textscan(file_str(pos_data:pos_enddata),data_format);

118

CheckLog function [exists,func]=CheckLog(x,settings) %checks the logfile for the given "x" and returns whether it exists and its %value try log=csvread(settings.log_file,0,0); catch button=questdlg('Log File Does Not Exist. Would you like to create one?'); if strcmp(button,'Yes'); fid=fopen(settings.log_file,'w'); fclose(fid); end exists=0; func=NaN; return end %search for entry containing the desired x value results=log; for i=1:length(x) if isempty(results) break; end search_id=find(results(:,i)==x(i)); results=results(search_id,:); end %make sure only 1 entry is found if size(results(:,1))>1 warning('Non-unique X values found in the log'); end %return values if isempty(results) exists=0; func=NaN; else exists=1; func=results(length(x)+1); end

119

ExportWaveform function ExportWaveform(x,settings) %exports a text file ready to import into adina %read log file and determine next entry number try log=csvread(settings.log_file,0,0); entry_num=size(log,1)+1; catch entry_num=1; end

%set up windkessel model %-----------------4 Element Windkessel Model------------------C=x(1); L=x(2); R1=x(3); R2=x(4); num=[R1*R2*L*C (R1+R2)*L R1*R2]; den=[R2*L*C R1*R2*C+L R1]; TransFunc=tf(-1*num,den); omega_n=sqrt(R1/(R2*L*C)); zeta=(R2*C+L/R1)/2*omega_n; t_steadystate = 4.6/(zeta*omega_n); % (+/-)1% error %-------------------------------------------------------------%% convert flowrate to pressure t=settings.experimental_t; q=settings.experimental_outflow; %make the sampling uniformly spaced pp=spline(t,q); t_resampled=linspace(min(t),max(t),length(t))'; q_resampled=ppval(pp,t_resampled); %ensure sampling reaches steady state t_rep=t_resampled; q_rep=q_resampled; while max(t_rep)handles.x1 temp=handles.x1; handles.x1=handles.x2; handles.x2=temp; clear temp end if handles.y20) % scroll down for i=1:evnt.VerticalScrollCount if handles.selected+1 > handles.list_length handles.selected=1; else handles.selected=handles.selected+1; end end else % scroll up for i=1:abs(evnt.VerticalScrollCount) if handles.selected == 1 handles.selected=handles.list_length; else handles.selected=handles.selected-1; end

134

end end set(handles.listbox1,'Value',handles.selected); guidata(gcf, handles); refresh_axes(handles)

135

DicomCrop function [new_data, new_info]=DicomCrop(data,info,win) %Crop down Dicom Images while maintaing the validity of their info file. % %Inputs: % % data - uncropped image stack % info - cell array where each cell i corresponds to image data(:,:,i) % win - structure defining a cropped window of pixels. % feilds: xmin, xmax, ymin, ymax, zmin, zmax % % %Outputs: % % new_data - cropped image stack % new_info - info array modified to match the cropped images new_data=data(win.ymin:win.ymax , win.xmin:win.xmax , win.zmin:win.zmax); new_info=cell((win.zmax - win.zmin)+1,1); for i=1:(win.zmax - win.zmin)+1 new_info{i}=info{win.zmin+i-1}; end for i=1:length(new_info) xscale=info{i}.PixelSpacing(2); yscale=info{i}.PixelSpacing(1); pos=info{i}.ImagePositionPatient;

%mm/pixel %mm/pixel %mm

xvect=info{i}.ImageOrientationPatient(1:3); yvect=info{i}.ImageOrientationPatient(4:6); zvect=cross(xvect,yvect); T=[xvect yvect zvect]; %transform from xyz to XYZ shift_xyz=[(win.xmin-1)*xscale; (-1)*(win.ymin-1)*yscale; 0]; shift_XYZ=T*shift_xyz; pos_new=pos+shift_XYZ; new_info{i}.ImagePositionPatient=[pos_new];

136

end

137

DicomDrawBoundary function %Prompts Then %exports %array. %Exports

[X,Y,Z]=DicomDrawBoundary(all_pic,all_surf,all_info,numslice) the user to draw in the artery wall for a number of slices. an array of points coorosponding to the artery wall in a cell cell arrays of points. Each cell is from a single slice.

zcoord=round(linspace(1,length(all_pic(1,1,:)),numslice)); pic=all_pic(:,:,zcoord); count=0; for i=zcoord count=count+1; [r,c]=find(all_surf(:,:,i)~=0);%%%%%%%%%%%%%%%%%%%% surf{count}=[r c];%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% info{count}=all_info{i}; end X=cell(0); Y=cell(0); Z=cell(0); %draw in outer wall points h=figure; for i=1:length(info) xscale=info{i}.PixelSpacing(2); yscale=info{i}.PixelSpacing(1); base_XYZ=info{i}.ImagePositionPatient;

%mm/pixel %mm/pixel %mm

xvect=info{i}.ImageOrientationPatient(1:3); yvect=info{i}.ImageOrientationPatient(4:6); zvect=cross(xvect,yvect); T=[xvect yvect zvect]; %transform from xyz to XYZ imshow(pic(:,:,i),[],'InitialMagnification','fit'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% hold on for j=1:length(surf{i}(:,1)) plot(surf{i}(j,2),surf{i}(j,1),'.r') end title('Draw In Outerwall of Artery')%%%%%%%%%%% hold off %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% line=impoly();

138

pos=getPosition(line); x=pos(:,1); y=pos(:,2); for j=1:length(x); shift_xyz=[x(j)*xscale; (-1)*y(j)*yscale; 0]; shift_XYZ=T*shift_xyz; XYZ=(base_XYZ+shift_XYZ)*.001; X{i}(j)=XYZ(1); Y{i}(j)=XYZ(2); Z{i}(j)=XYZ(3); end end close(h)

139

%converts to meters

DicomMagnify function [new_info]=DicomMagnify(info,mag) %Corrects a stack of DICOM info files after the data has been resized % %Inputs: % % info - cell array of dicom information structures % mag - the rescalling factor or magnification % % new_info - corrected cell array of dicom information new_info=cell(length(info),1); for i=1:length(info) new_info{i}=info{i}; new_info{i}.PixelSpacing=new_info{i}.PixelSpacing/mag; end

140

DicomPic2Pts function [X,Y,Z]=DicomPic2Pts(img,info) %Exports cell arrays of points. Each cell is from a single slice X=cell(0); Y=cell(0); Z=cell(0); for i=1:length(info) xscale=info{i}.PixelSpacing(2); yscale=info{i}.PixelSpacing(1); pos=info{i}.ImagePositionPatient;

%mm/pixel %mm/pixel %mm

xvect=info{i}.ImageOrientationPatient(1:3); yvect=info{i}.ImageOrientationPatient(4:6); zvect=cross(xvect,yvect); T=[xvect yvect zvect]; %transform from xyz to XYZ [r,c]=find(img(:,:,i)); for j=1:length(r); shift_xyz=[c(j)*xscale; (-1)*r(j)*yscale; 0]; shift_XYZ=T*shift_xyz; pos_new=(pos+shift_XYZ)*.001; X{i}(j)=pos_new(1); Y{i}(j)=pos_new(2); Z{i}(j)=pos_new(3); end end

141

%converts points to meters

Edging_GUI function varargout = Edging_GUI(varargin) % EDGING_GUI M-file for Edging_GUI.fig % EDGING_GUI, by itself, creates a new EDGING_GUI or raises the existing % singleton*. % % H = EDGING_GUI returns the handle to a new EDGING_GUI or the handle to % the existing singleton*. % % EDGING_GUI('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in EDGING_GUI.M with the given input arguments. % % EDGING_GUI('Property','Value',...) creates a new EDGING_GUI or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before Edging_GUI_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to Edging_GUI_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @Edging_GUI_OpeningFcn, ... 'gui_OutputFcn', @Edging_GUI_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout

142

[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin[4]); else gui_mainfcn(gui_State, varargin[4]); end % End initialization code - DO NOT EDIT function Edging_GUI_OpeningFcn(hObject, eventdata, handles, varargin) %#ok h=waitbar(0,'Initializing GUI'); %initialize inputs handles.img_raw=varargin{1}; handles.zlength=length(handles.img_raw(1,1,:)); handles.ylengthr=length(handles.img_raw(:,1,1)); handles.xlengthr=length(handles.img_raw(1,:,1)); defaults=varargin{2}; %initialize default data if length(defaults.size)==1 handles.size=defaults.size*ones(length(handles.img_raw(1,1,:)),1); else handles.size=defaults.size; end if length(defaults.rad)==1 handles.rad=defaults.rad*ones(length(handles.img_raw(1,1,:)),1); else handles.rad=defaults.rad; end handles.mag=defaults.mag; handles.xlength=handles.xlengthr*handles.mag; handles.ylength=handles.ylengthr*handles.mag; %get initial thresholds if isfield(defaults,'thresh') if length(defaults.thresh)==1 handles.thresh=cell(1,zlength); for i=1:zlength handles.thresh{i}=defaults.thresh; end else handles.thresh=defaults.thresh; end else

143

for i=1:handles.zlength img_interp=imresize(handles.img_raw(:,:,i),handles.mag); img_filt=medfilt2(img_interp,handles.size(i)*[1 1]); [img_edge,handles.thresh{i}]=edge(img_filt,'canny'); end end %initialize GUI strings=cell(handles.zlength,1); for i=1:handles.zlength strings{i}=['Slice ' num2str(i)]; end set(handles.listbox1,'String',strings) handles.selected=1; handles.plot='closed'; set(handles.edit_mag,'String',num2str(handles.mag)); set(handles.edit_rad,'String',num2str(handles.rad(handles.selected))); set(handles.uipanel3,'SelectionChangeFcn',@plot_options); close(h) guidata(hObject, handles); refresh(handles); uiwait(handles.figure1); function varargout = Edging_GUI_OutputFcn(hObject, eventdata, handles) h=waitbar(0,'Compiling Images...'); %create analysed images img_close=zeros(handles.ylength,handles.xlength,handles.zlength); for i=1:handles.zlength img_interp=imresize(handles.img_raw(:,:,i),handles.mag); img_filt=medfilt2(img_interp,handles.size(i)*[1 1]); img_edge=edge(img_filt,'canny',handles.thresh{i}); img_close(:,:,i)=imclose(img_edge,strel('disk',handles.rad(i))); end %export desired values varargout{1}=img_close;

144

settings.size=handles.size; settings.thresh=handles.thresh; settings.mag=handles.mag; settings.rad=handles.rad; varargout{2}=settings; close(hObject) close(h);

function listbox1_CreateFcn(hObject, eventdata, handles) %#ok % Hint: listbox controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end function edit_size_CreateFcn(hObject, eventdata, handles) % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end function slider_size_CreateFcn(hObject, eventdata, handles) % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end function edit_prime_CreateFcn(hObject, eventdata, handles) % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end function slider_prime_CreateFcn(hObject, eventdata, handles) % Hint: slider controls usually have a light gray background.

145

if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end function edit_second_CreateFcn(hObject, eventdata, handles) % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end function slider_second_CreateFcn(hObject, eventdata, handles) % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end function edit_mag_CreateFcn(hObject, eventdata, handles) % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end function edit_rad_CreateFcn(hObject, eventdata, handles) % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end

function listbox1_Callback(hObject, eventdata, handles) %Update handles and refresh handles.selected=get(hObject,'Value'); guidata(hObject, handles); refresh(handles); function edit_size_Callback(hObject, eventdata, handles)

146

try %#ok %Check that new value is an integer > 0 if str2double(get(handles.edit_size,'String'))>0 str=get(handles.edit_size,'String'); value=round(str2double(str)); %if > max_slider disable the slider bar /if < max_slider active the slider bar slider_max=get(handles.slider_size,'Max'); if value>slider_max set(handles.slider_size,'Value',slider_max); set(handles.slider_size,'Enable','off'); else set(handles.slider_size,'Enable','on'); end %Update handles and refresh handles.size(handles.selected)=value; guidata(hObject, handles); refresh(handles) end end function slider_size_Callback(hObject, eventdata, handles) value=round(get(handles.slider_size,'Value')); %Update handles and refresh handles.size(handles.selected)=value; guidata(hObject, handles); refresh(handles) function edit_prime_Callback(hObject, eventdata, handles) try %#ok %Check that new value is a number >0 and < secondary threshold if str2double(get(handles.edit_prime,'String'))>0 str=get(handles.edit_prime,'String'); value=str2double(str); if value >= handles.thresh{handles.selected}(2) warning('Primary Threshold must be less than Secondary Threshold'); %#ok value=handles.thresh{handles.selected}(2)-.01; end %Update handles and refresh handles.thresh{handles.selected}(1)=value; guidata(hObject, handles);

147

refresh(handles) end end

function slider_prime_Callback(hObject, eventdata, handles) value=get(handles.slider_prime,'Value'); %Check value is not less than secondary value if value >= handles.thresh{handles.selected}(2) warning('Primary Threshold must be less than Secondary Threshold'); %#ok value=handles.thresh{handles.selected}(2)-.01; end %Update handles and refresh handles.thresh{handles.selected}(1)=value; guidata(hObject, handles); refresh(handles) function edit_second_Callback(hObject, eventdata, handles) try %#ok %Check that new value is a number primary threshold if str2double(get(handles.edit_second,'String'))>0 str=get(handles.edit_second,'String'); value=str2double(str); if value 0 str=get(handles.edit_mag,'String'); value=round(str2double(str)); end %Clear previous image data since it is now the wrong dimension handles.img_interp=[]; handles.img_filt=[]; handles.img_edge=[]; handles.img_close=[]; %Update handles and refresh handles.mag=value; guidata(hObject, handles); refresh(handles) end

function edit_rad_Callback(hObject, eventdata, handles) try %#ok %Check that new value is an integer > 0 if str2double(get(handles.edit_rad,'String'))>0 str=get(handles.edit_rad,'String'); value=round(str2double(str)); %Update handles and refresh handles.rad(handles.selected)=value; guidata(hObject, handles); refresh(handles) end end

149

function plot_options(hObject,eventdata) handles=guidata(gcf); handles.plot=get(eventdata.NewValue,'Tag'); guidata(gcf, handles); refresh(handles) function button_apply_all_Callback(hObject, eventdata, handles) doit=questdlg('Are you sure you want to overwrite all slice settings?','WARNING','Yes','No','No'); if strcmp(doit,'Yes') a=handles.selected; mag=handles.mag(a); size=handles.size(a); thresh=handles.thresh{a}; rad=handles.rad(a); for i=1:handles.zlength handles.mag(i)=mag; handles.size(i)=size; handles.thresh{i}=thresh; handles.rad(i)=rad; end end function button_detect_thresh_Callback(hObject, eventdata, handles) img_interp=imresize(handles.img_raw(:,:,handles.selected),handles.mag); img_filt=medfilt2(img_interp,handles.size(handles.selected)*[1 1]); [x,handles.thresh{handles.selected}]=edge(img_filt,'canny'); guidata(gcf, handles); refresh(handles)

function button_done_Callback(hObject, eventdata, handles) uiresume();

function refresh(handles)

150

a=handles.selected; %Synchronize sliders and text boxes set(handles.edit_size,'String',num2str(handles.size(a))); set(handles.slider_size,'Value',handles.size(a)); set(handles.edit_prime,'String',num2str(handles.thresh{a}(1))); set(handles.slider_prime,'Value',handles.thresh{a}(1));

set(handles.edit_second,'String',num2str(handles.thresh{a}(2))); set(handles.slider_second,'Value',handles.thresh{a}(2)); set(handles.edit_rad,'String',num2str(handles.rad(a))); %Plot the requested image switch handles.plot case 'unaltered' imshow(handles.img_raw(:,:,a),[]); case 'magnified' handles.xlength=handles.xlengthr*handles.mag; handles.ylength=handles.ylengthr*handles.mag;

img_interp=imresize(handles.img_raw(:,:,a),handles.mag); imshow(img_interp,[]); case 'filtered' handles.xlength=handles.xlengthr*handles.mag; handles.ylength=handles.ylengthr*handles.mag;

img_interp=imresize(handles.img_raw(:,:,a),handles.mag); img_filt=medfilt2(img_interp,handles.size(a)*[1 1]); imshow(img_filt,[]); case 'edged' handles.xlength=handles.xlengthr*handles.mag; handles.ylength=handles.ylengthr*handles.mag;

img_interp=imresize(handles.img_raw(:,:,a),handles.mag); img_filt=medfilt2(img_interp,handles.size(a)*[1 1]); img_edge=edge(img_filt,'canny',handles.thresh{a}); imshow(img_edge); case 'closed'

151

handles.xlength=handles.xlengthr*handles.mag; handles.ylength=handles.ylengthr*handles.mag;

img_interp=imresize(handles.img_raw(:,:,a),handles.mag); img_filt=medfilt2(img_interp,handles.size(a)*[1 1]); img_edge=edge(img_filt,'canny',handles.thresh{a}); img_close=imclose(img_edge,strel('disk',handles.rad(a))); imshow(img_close); case 'overlay' handles.xlength=handles.xlengthr*handles.mag; handles.ylength=handles.ylengthr*handles.mag;

img_interp=imresize(handles.img_raw(:,:,a),handles.mag); img_filt=medfilt2(img_interp,handles.size(a)*[1 1]); img_edge=edge(img_filt,'canny',handles.thresh{a}); img_close=imclose(img_edge,strel('disk',handles.rad(a))); overlay=-0.75*double(img_close)+1; image=double(imresize(handles.img_raw(:,:,a),handles.mag,'nearest')); plot=overlay.*image; imshow(plot/max(plot(:)),[]); end

function figure1_WindowScrollWheelFcn(hObject, eventdata, handles) if (eventdata.VerticalScrollCount>0) % scroll down for i=1:eventdata.VerticalScrollCount if handles.selected+1 > handles.zlength handles.selected=1; else handles.selected=handles.selected+1; end end else % scroll up for i=1:abs(eventdata.VerticalScrollCount) if handles.selected == 1 handles.selected=handles.zlength; else handles.selected=handles.selected-1;

152

end end end set(handles.listbox1,'Value',handles.selected); guidata(hObject, handles); refresh(handles)

153

GetBody_GUI function [bod]=GetBody_GUI(img) h=figure; for i=1:length(img(1,1,:)) imshow(img(:,:,i),'InitialMagnification','fit') title('Select Body') [c,r]=ginput(1); bod(:,:,i)=bwselect(img(:,:,i),c,r,4); end close(h);

154

GetDicomStack function [img info]=GetDicomStack(FilterSpec,DialogTitle,DefaultName,Sort) if nargin= NextModelPointer Then ListBox_FluidDAT.DoDragDrop(ListBox_FluidDAT.Text, DragDropEffects.All) End If End Sub Private Sub ListBox_FluidDAT_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox_FluidDAT.DragOver e.Effect = DragDropEffects.Move End Sub

184

Private Sub ListBox_FluidDAT_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox_FluidDAT.DragDrop Dim DragPoint As Integer Dim Destination As Integer Dim Source As Integer DragPoint = ListBox_FluidDAT.IndexFromPoint(ListBox_FluidDAT.PointToClient(New Point(e.X, e.Y))) If DragPoint -1 Then Source = ListBox_FluidDAT.SelectedIndex Destination = ListBox_FluidDAT.IndexFromPoint(ListBox_FluidDAT.PointToClient(New Point(e.X, e.Y))) If Source < Destination Then FluidDATFiles.Insert(Destination, FluidDATFiles(Source)) FluidDATFiles.RemoveAt(Source) FluidDAT_FilesOnly.Insert(Destination, FluidDAT_FilesOnly(Source)) FluidDAT_FilesOnly.RemoveAt(Source) Else FluidDATFiles.Insert(Destination, FluidDATFiles(Source)) FluidDATFiles.RemoveAt(Source + 1) FluidDAT_FilesOnly.Insert(Destination, FluidDAT_FilesOnly(Source)) FluidDAT_FilesOnly.RemoveAt(Source + 1) End If ListBox_FluidDAT.Items.Clear() ListBox_FluidDAT.Items.AddRange(FluidDAT_FilesOnly.ToArray) End If End Sub

'''''''''''''''''''''Solid Text Box''''''''''''''''''''''' Private Sub Button_GetSolidDAT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_GetSolidDAT.Click OpenFileDialog1.InitialDirectory = My.Settings.DATFolder OpenFileDialog1.Filter = "DAT File (*.dat) |*.dat" OpenFileDialog1.Title = "Open Solid .DAT Files" OpenFileDialog1.Multiselect = True OpenFileDialog1.ShowDialog() My.Settings.DATFolder = Path.GetDirectoryName(OpenFileDialog1.FileName) SolidDATFiles.AddRange(OpenFileDialog1.FileNames) SolidDAT_FilesOnly.AddRange(OpenFileDialog1.SafeFileNames) ListBox_SolidDAT.Items.Clear() ListBox_SolidDAT.Items.AddRange(SolidDAT_FilesOnly.ToArray) End Sub

185

Private Sub ListBox_SolidDAT_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ListBox_SolidDAT.KeyUp 'deletes selected file if delete is pressed If e.KeyData = Keys.Delete And ListBox_SolidDAT.SelectedIndex -1 Then If ListBox_SolidDAT.SelectedIndex < NextModelPointer Then MsgBox("ERROR: Cannot delete run/running models from list") End If SolidDATFiles.RemoveAt(ListBox_SolidDAT.SelectedIndex) SolidDAT_FilesOnly.RemoveAt(ListBox_SolidDAT.SelectedIndex) ListBox_SolidDAT.Items.Clear() ListBox_SolidDAT.Items.AddRange(SolidDAT_FilesOnly.ToArray) End If End Sub Private Sub ListBox_SolidDAT_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ListBox_SolidDAT.DrawItem e.DrawBackground() For i = 0 To RunningIndex.Length - 1 If e.Index = RunningIndex(i) Then e.Graphics.FillRectangle(Brushes.LightGreen, e.Bounds) End If Next If e.Index -1 Then Using b As New SolidBrush(e.ForeColor) e.Graphics.DrawString(ListBox_SolidDAT.GetItemText(ListBox_SolidDAT.Items(e.Index) ), e.Font, b, e.Bounds) End Using End If e.DrawFocusRectangle() End Sub Private Sub ListBox_SolidDAT_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox_SolidDAT.MouseDown If ListBox_SolidDAT.SelectedIndex >= NextModelPointer Then ListBox_SolidDAT.DoDragDrop(ListBox_SolidDAT.Text, DragDropEffects.All) End If End Sub Private Sub ListBox_SolidDAT_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox_SolidDAT.DragOver e.Effect = DragDropEffects.Move End Sub Private Sub ListBox_SolidDAT_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox_SolidDAT.DragDrop Dim DragPoint As Integer

186

Dim Destination As Integer Dim Source As Integer DragPoint = ListBox_SolidDAT.IndexFromPoint(ListBox_SolidDAT.PointToClient(New Point(e.X, e.Y))) If DragPoint -1 Then Source = ListBox_SolidDAT.SelectedIndex Destination = ListBox_SolidDAT.IndexFromPoint(ListBox_SolidDAT.PointToClient(New Point(e.X, e.Y))) If Source < Destination Then SolidDATFiles.Insert(Destination, SolidDATFiles(Source)) SolidDATFiles.RemoveAt(Source) SolidDAT_FilesOnly.Insert(Destination, SolidDAT_FilesOnly(Source)) SolidDAT_FilesOnly.RemoveAt(Source) Else SolidDATFiles.Insert(Destination, SolidDATFiles(Source)) SolidDATFiles.RemoveAt(Source + 1) SolidDAT_FilesOnly.Insert(Destination, SolidDAT_FilesOnly(Source)) SolidDAT_FilesOnly.RemoveAt(Source + 1) End If ListBox_SolidDAT.Items.Clear() ListBox_SolidDAT.Items.AddRange(SolidDAT_FilesOnly.ToArray) End If End Sub

'''''''''''''''''''Execute Commands''''''''''''''''''' Private Sub Button_Run_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button_Run.Click Timer1.Interval = CInt(60000 * My.Settings.SampleRate) Timer1_Tick(sender, e) 'Initialize() Timer1.Enabled = True End Sub

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick For i = 0 To RunningIndex.Length - 1 If RunningIndex(i) -1 Then FileLength2(i) = FileLength1(i) FileLength1(i) = FileLen(RunningOutFiles(i)) If FileLength1(i) - FileLength2(i) = 0 Then

187

RunningIndex(i) = -1 End If End If Next 'Add models to the que If FluidDATFiles.Count > SolidDATFiles.Count Then ListLength = SolidDATFiles.Count Else ListLength = FluidDATFiles.Count End If If NextModelPointer < ListLength Then Initialize() Exit Sub End If 'check if done For i = 0 To RunningIndex.Length - 1 If RunningIndex(i) -1 Then Exit Sub End If Next If My.Settings.SendNotification Then Dim mail As New MailMessage() Dim smtp As New SmtpClient() Try mail = GenMailVariable() Catch MsgBox("ERROR: Failed to construct mail object. Check settings.") Exit Sub End Try Try smtp = GenSMTPVariable() Catch MsgBox("ERROR: Failed to initialize SMTP server. Check settings.") Exit Sub End Try Try smtp.Send(mail) Catch MsgBox("ERROR: Failed to send e-mail.") Exit Sub End Try End If Me.Close()

188

End Sub Sub Initialize() Dim ModelDone As Boolean Dim Index As Integer Index = 0 While Index RunningIndex.Length If RunningIndex(Index) = -1 And NextModelPointer < ListLength Then ModelDone = True Exit While End If Index = Index + 1 End While 'MsgBox(CStr(RunningIndex(0) & " " & RunningIndex(1) & " " & RunningIndex(2) & " " & RunningIndex(3))) 'MsgBox(CStr(RunningIndex(0))) If ModelDone Then RunningIndex(Index) = NextModelPointer NextModelPointer = NextModelPointer + 1 RunningOutFiles(Index) = Replace(FluidDATFiles(RunningIndex(Index)), ".dat", ".out") FileLength1(Index) = 0 Dim Command As String Command = Chr(34) & My.Settings.ADINAFSIexe & Chr(34) & " -b -s -mm " & CStr(My.Settings.NumMemory) & "mb -t " & CStr(My.Settings.NumProc) & " " & Chr(34) & FluidDATFiles(RunningIndex(Index)) & Chr(34) & " " & Chr(34) & SolidDATFiles(RunningIndex(Index)) & Chr(34) Shell(Command) 'refresh listboxs ListBox_FluidDAT.Items.Clear() ListBox_FluidDAT.Items.AddRange(FluidDAT_FilesOnly.ToArray) ListBox_SolidDAT.Items.Clear() ListBox_SolidDAT.Items.AddRange(SolidDAT_FilesOnly.ToArray) End If End Sub Public Function GenMailVariable() As MailMessage Dim mail As New MailMessage() mail.To.Add(My.Settings.EmailTo) mail.From = New MailAddress(My.Settings.EmailFrom) mail.Subject = My.Settings.EmailSubject mail.Body = My.Settings.EmailMessage Return mail End Function

189

Public Function GenSMTPVariable() As SmtpClient Dim smtp As New SmtpClient() smtp.Host = My.Settings.EmailSMTP smtp.Port = My.Settings.EmailPort If My.Settings.EmailAuthentication Then smtp.Credentials = New NetworkCredential(My.Settings.EmailUsername, My.Settings.EmailPassword) End If If My.Settings.EmailTLS Then smtp.EnableSsl = True End If Return smtp End Function End Class

190

ADINAwithMATLAB (Form1.vb) Imports System.Diagnostics Public Class Form1 Dim FileLen1 As Integer Dim FileLen2 As Integer Dim FileChg As Integer = 0 Dim TimeLimit As Integer = 10 'minutes measured every minute 'Dim ActiveDIR As String = "C:\Documents and Settings\Mark\Desktop\Automated Testing\Matlab" 'Dim MatlabCmd As String = "Optimize('test.mat')" 'Dim ADINA_AUI As String = "C:\ADINA86\bin\aui.exe" 'Dim ADINA_FSI As String = "C:\ADINA86\bin\adfsi.exe" 'Dim INfile As String = "C:\Documents and Settings\Mark\Desktop\Automated Testing\RunFolder\INfile.in" 'Dim PLOfile As String = "C:\Documents and Settings\Mark\Desktop\Automated Testing\RunFolder\PLOfile.plo" 'Dim DATfile1 As String = "C:\Documents and Settings\Mark\Desktop\Automated Testing\RunFolder\fluid.dat" 'Dim DATfile2 As String = "C:\Documents and Settings\Mark\Desktop\Automated Testing\Models\solid.dat" 'Dim OUTfile As String = "C:\Documents and Settings\Mark\Desktop\Automated Testing\RunFolder\fluid.out" Dim Running As Boolean = False Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If Not Running Then Running = True Button1.Text = "Stop" PrepWork() Else Running = False Button1.Text = "Start" End If End Sub Public Sub PrepWork() Dim ProcProp1 As New ProcessStartInfo ProcProp1.FileName = "matlab" ProcProp1.Arguments = "-sd " & Chr(34) & My.Settings.MatDir & Chr(34) & " -r " & Chr(34) & My.Settings.MatCmd & Chr(34) & " -nosplash -wait" Dim Proc1 As Process = Process.Start(ProcProp1) Proc1.WaitForExit()

191

If Running Then PreProcess() End If End Sub Public Sub PreProcess() Dim ProcProp2 As New ProcessStartInfo ProcProp2.FileName = Chr(34) & My.Settings.ADINA_AUI & Chr(34) ProcProp2.Arguments = Chr(34) & My.Settings.ADINA_IN & Chr(34) Dim Proc2 As Process = Process.Start(ProcProp2) Threading.Thread.Sleep(60000 * My.Settings.PreProcWait) If Running Then Solver() End If End Sub Public Sub Solver() Dim ProcProp3 As New ProcessStartInfo ProcProp3.FileName = Chr(34) & My.Settings.ADINA_FSI & Chr(34) ProcProp3.Arguments = "-b -s -mm " & CStr(My.Settings.MemUsage) & "gb -t " & CStr(My.Settings.NumProc) & " " & Chr(34) & My.Settings.FluidDAT & Chr(34) & " " & Chr(34) & My.Settings.SolidDAT & Chr(34) Dim Proc3 As Process = Process.Start(ProcProp3) FileLen1 = 0 Timer.Interval = 60000 '1 minute Timer.Enabled = True End Sub

Private Sub Timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer.Tick 'Re-evaluate file size FileLen2 = FileLen1 FileLen1 = FileLen(My.Settings.ADINA_OUT) If FileLen2 - FileLen1 = 0 Then 'If file doesnt change size flag it FileChg = FileChg + 1 If FileChg >= My.Settings.SolverThresh Then Timer.Enabled = False If Running Then PostProcess() End If End If Else 'if program changes in size reset flag FileChg = 0

192

End If End Sub Public Sub PostProcess() Dim ProcProp4 As New ProcessStartInfo ProcProp4.FileName = Chr(34) & My.Settings.ADINA_AUI & Chr(34) ProcProp4.Arguments = Chr(34) & My.Settings.ADINA_PLO & Chr(34) Dim Proc4 As Process = Process.Start(ProcProp4) Threading.Thread.Sleep(60000 * My.Settings.PostProcWait) If Running Then PrepWork() End If End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load TextBox_MatDir.Text = My.Settings.MatDir TextBox_MatCmd.Text = My.Settings.MatCmd TextBox_AUI.Text = My.Settings.ADINA_AUI TextBox_FSI.Text = My.Settings.ADINA_FSI TextBox_IN.Text = My.Settings.ADINA_IN TextBox_OUT.Text = My.Settings.ADINA_OUT TextBox_PLO.Text = My.Settings.ADINA_PLO TextBox_FluidDAT.Text = My.Settings.FluidDAT TextBox_SolidDAT.Text = My.Settings.SolidDAT TextBox_PreProcWait.Text = CStr(My.Settings.PreProcWait) TextBox_PostProcWait.Text = CStr(My.Settings.PostProcWait) TextBox_SolverThresh.Text = CStr(My.Settings.SolverThresh) TextBox_NumProc.Text = CStr(My.Settings.NumProc) TextBox_MemUsage.Text = CStr(My.Settings.MemUsage) End Sub Private Sub TextBox_MatDir_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_MatDir.TextChanged Try My.Settings.MatDir = TextBox_MatDir.Text Catch ex As Exception Beep() End Try TextBox_MatDir.Text = My.Settings.MatDir End Sub Private Sub TextBox_MatCmd_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_MatCmd.TextChanged Try My.Settings.MatCmd = TextBox_MatCmd.Text Catch ex As Exception Beep()

193

End Try TextBox_MatDir.Text = My.Settings.MatDir End Sub Private Sub TextBox_AUI_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_AUI.TextChanged Try My.Settings.ADINA_AUI = TextBox_AUI.Text Catch ex As Exception Beep() End Try TextBox_AUI.Text = My.Settings.ADINA_AUI End Sub Private Sub TextBox_FSI_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_FSI.TextChanged Try My.Settings.ADINA_FSI = TextBox_FSI.Text Catch ex As Exception Beep() End Try TextBox_FSI.Text = My.Settings.ADINA_FSI End Sub Private Sub TextBox_IN_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_IN.TextChanged Try My.Settings.ADINA_IN = TextBox_IN.Text Catch ex As Exception Beep() End Try TextBox_IN.Text = My.Settings.ADINA_IN End Sub Private Sub TextBox_PLO_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_PLO.TextChanged Try My.Settings.ADINA_PLO = TextBox_PLO.Text Catch ex As Exception Beep() End Try TextBox_PLO.Text = My.Settings.ADINA_PLO End Sub Private Sub TextBox_OUT_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_OUT.TextChanged Try My.Settings.ADINA_OUT = TextBox_OUT.Text Catch ex As Exception Beep()

194

End Try TextBox_OUT.Text = My.Settings.ADINA_OUT End Sub Private Sub TextBox_FluidDAT_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_FluidDAT.TextChanged Try My.Settings.FluidDAT = TextBox_FluidDAT.Text Catch ex As Exception Beep() End Try TextBox_FluidDAT.Text = My.Settings.FluidDAT End Sub Private Sub TextBox_SolidDAT_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_SolidDAT.TextChanged Try My.Settings.SolidDAT = TextBox_SolidDAT.Text Catch ex As Exception Beep() End Try TextBox_SolidDAT.Text = My.Settings.SolidDAT End Sub Private Sub TextBox_PreProcWait_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_PreProcWait.TextChanged Try My.Settings.PreProcWait = CInt(TextBox_PreProcWait.Text) Catch ex As Exception Beep() End Try TextBox_PreProcWait.Text = CStr(My.Settings.PreProcWait) End Sub Private Sub TextBox_SolverThresh_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_SolverThresh.TextChanged Try My.Settings.SolverThresh = CInt(TextBox_SolverThresh.Text) Catch ex As Exception Beep() End Try TextBox_SolverThresh.Text = CStr(My.Settings.SolverThresh) End Sub Private Sub TextBox_NumProc_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_NumProc.TextChanged Try My.Settings.NumProc = CInt(TextBox_NumProc.Text) Catch ex As Exception Beep()

195

End Try TextBox_NumProc.Text = CStr(My.Settings.NumProc) End Sub Private Sub TextBox_MemUsage_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_MemUsage.TextChanged Try My.Settings.MemUsage = CInt(TextBox_MemUsage.Text) Catch ex As Exception Beep() End Try TextBox_MemUsage.Text = CStr(My.Settings.MemUsage) End Sub Private Sub TextBox_PostProcWait_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox_PostProcWait.TextChanged Try My.Settings.PostProcWait = CInt(TextBox_PostProcWait.Text) Catch ex As Exception Beep() End Try TextBox_PostProcWait.Text = CStr(My.Settings.PostProcWait) End Sub End Class

196

Console Mode Notifier (Module1.vb) Imports System.Threading Module Module1 Dim file_location As String Dim sampling_min As Integer Dim sampling_ms As Integer Dim threshold As Integer executing Dim DOScommand As String Dim Dim Dim Dim Dim

'location of file being checked for size 'sample rate in minutes 'sample rate in miliseconds 'number of consecutive positve samplings before 'command to be executed when file stops growing

fileinfo1 As System.IO.FileInfo fileinfo2 As System.IO.FileInfo sizechange As Integer consecutive As Integer = 0 testrun As String

Sub Main() System.Console.Write("Locate File: ") file_location = System.Console.ReadLine System.Console.Write("Sample Rate (min): ") sampling_min = System.Console.ReadLine sampling_ms = sampling_min * 60000 System.Console.Write("How Many Positive Samples Before Executing: ") threshold = System.Console.ReadLine System.Console.Write("DOS Command to execute at completion:") DOScommand = System.Console.ReadLine System.Console.Write("Test command? (y/n)") testrun = System.Console.ReadLine If testrun = "y" Then System.Console.WriteLine("Performing Test Run...") Shell(DOScommand) End If System.Console.WriteLine("Beginning File Monitoring at " & Now) fileinfo1 = My.Computer.FileSystem.GetFileInfo(file_location) Thread.Sleep(sampling_ms) Do fileinfo2 = fileinfo1 fileinfo1 = My.Computer.FileSystem.GetFileInfo(file_location) sizechange = fileinfo2.Length - fileinfo1.Length If sizechange = 0 Then

197

consecutive = consecutive + 1 System.Console.WriteLine(Now & " File Unchanged for " & consecutive * sampling_min & " minute(s)") If consecutive >= threshold Then System.Console.WriteLine("Threshold Reached. Executing Command and Terminating") Shell(DOScommand) Exit Do End If Else consecutive = 0 End If Thread.Sleep(sampling_ms) Loop Until False Thread.Sleep(60000) System.Console.WriteLine("Finished!") System.Console.Read() End Sub End Module

198

GUI Model Notifier (Form1.vb) Imports System.Net.Mail Imports System.Net

Public Class Form1 Dim mail As New MailMessage() Dim smtp As New SmtpClient() Dim FileLen1 As Integer Dim FileLen2 As Integer Dim Change As Integer Dim Consecutive As Integer = 0

Private Sub Form1_HandleCreated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.HandleCreated FileLocation.Text = My.Settings.FileLoc SampRate.Text = My.Settings.SampRate SampThresh.Text = My.Settings.SampThresh ToBox.Text = My.Settings.EmailTo FromBox.Text = My.Settings.EmailFrom SubBox.Text = My.Settings.EmailSub MessBox.Text = My.Settings.EmailMess TestBox.Checked = My.Settings.EmailTest SMTPBox.Text = My.Settings.EmailSMTP PortBox.Text = My.Settings.EmailPort TLSBox.Checked = My.Settings.EmailTLS AuthBox.Checked = My.Settings.EmailAuth UserBox.Text = My.Settings.EmailUser PassBox.Text = My.Settings.EmailPass CloseBox.Checked = My.Settings.CloseProg End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BrowseButton.Click OpenFileDialog1.InitialDirectory = My.Settings.FileLoc OpenFileDialog1.Title = "Select file to monitor" OpenFileDialog1.ShowDialog() FileLocation.Text = OpenFileDialog1.FileName End Sub Private Sub AuthBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AuthBox.CheckedChanged If AuthBox.Checked = True Then UserBox.Enabled = True PassBox.Enabled = True Else

199

UserBox.Enabled = False PassBox.Enabled = False End If End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RunButton.Click 'Check inputs for errors If Dir(FileLocation.Text) = "" Then MsgBox("ERROR: Monitored File Does Not Exist") Exit Sub End If If Val(SampRate.Text) Mod 1 0 Or Val(SampRate.Text) = Val(SampThresh.Text) Then 'if flags exceed threshold execute command LogBox.Text = LogBox.Text & vbNewLine & "Threshold reached. Executing..." LogBox.SelectionStart = LogBox.Text.Length LogBox.ScrollToCaret() LogBox.Refresh() smtp.Send(mail) Timer.Enabled = False 'close application If CloseBox.Checked = True Then Application.Exit() Else Consecutive = 0 LogBox.Text = LogBox.Text & vbNewLine & "Done!" & vbNewLine & vbNewLine LogBox.SelectionStart = LogBox.Text.Length LogBox.ScrollToCaret() LogBox.Refresh() End If End If Else 'if program changes in size reset flag Consecutive = 0 End If End Sub End Class

202