Demo 3: Moving Fins =================== The following example demonstrates how to use pyCart and Cart3D to analyze a configuration with moving components. The example is similar to :ref:`pycart-ex-arrow`, except that the fins go inside the body of the bullet. .. figure:: fins01.png :width: 4in Example showing fin 4 deflected 15 degrees after intersecting with body This allows for the fins to be rotated about some hinge axis, and then once the fins are in the correct position, Cart3D's ``intersect`` tool can be used to transform this self-intersecting surface into a single water-tight geometry. To get started, clone this repo and run the following easy commands: .. code-block:: console $ git clone https://github.com/nasa-ddalle/pycart03-fins.git $ cd pycart03-fins $ ./copy-files.py $ cd work/ This will copy all of the files into a newly created ``work/`` folder. Follow the instructions below by entering that ``work/`` folder; the purpose is that you can easily delete the ``work/`` folder and restart the tutorial at any time. Let's run a case to see how this works. .. code-block:: none $ pycart -f fins.json -I 7 Case Config/Run Directory Status Iterations Que CPU Time ---- -------------------------------------- ------- ----------- --- -------- 0 poweroff_d2+05_d4-15/m1.75a1.0r30.0 --- / . Group name: 'poweroff_d2+05.0d4-15.0' (index 4) Preparing surface triangulation... Reading tri file(s) from root directory. Writing triangulation: 'Components.tri' Writing triangulation: 'Components.c.tri' > autoInputs -r 8 -t Components.tri -maxR 10 > intersect -i Components.tri -o Components.o.tri Writing triangulation: 'Components.i.tri' > cubes -pre preSpec.c3d.cntl -maxR 10 -reorder -a 10 -b 2 > mgPrep -n 3 Using template for 'input.cntl' file Starting case 'poweroff_d2+05.0d4-15.0/m1.75a1.0r30.0'. > flowCart -his -clic -N 200 -y_is_spanwise -limiter 2 -T -cfl 1.1 -mg 3 -binaryIO -tm 0 Submitted or ran 1 job(s). ---=1, The output is pretty similar to a case without the fin deflections, but there are a few differences that are helpful to explain. The first is the name of the case, ``poweroff_d2+05_d4-15/m1.75a1.0r30.0``, which is especially different in that the name of the folder contains the fin deflections. That is all controlled in the pyCart input file ``fins.json``, and we will discuss it shortly. This example is configured with the fin deflections in the folder name because each set of cases with same fin positions can use the same mesh. The next difference is that pyCart reports writing two triangulation files, ``Components.tri`` and ``Components.c.tri``, instead of the usual ``Components.i.tri``. The reason for this pair of files is that ``intersect`` requires each body to have a single component ID, which destroys the surface component naming that is defined in our inputs (like splitting off the nose cap, body, and base of the bullet shape into separate components). So ``Components.tri`` has only five components (the bullet shape and one for each fin) while ``Components.c.tri`` has seven components. Then ``intersect`` is run with the command run above, which generates ``Components.o.tri``. This file also has only five component IDs, and these are mapped back into the original component ID numbering by comparing to ``Components.c.tri`` to generate the final triangulation ``Components.i.tri`` with its seven component IDs. Otherwise, the solution proceeds in the same manner as a non-intersecting case. Let's take a closer look at the ``"Mesh"`` and ``"RunMatrix"`` sections of the pyCart input file ``fins.json`` to explain how this was set up. .. code-block:: javascript "Mesh": { // Intersect "intersect": true, // Surface triangulation "TriFile": [ "inputs/bullet.tri", "inputs/fin1.tri", "inputs/fin2.tri", "inputs/fin3.tri", "inputs/fin4.tri" ] }, The ``"Mesh"`` section is relatively simple but contains a little bit more information than the default section. The individual water-tight volumes are split into separate ``tri`` files, which provides pyCart two layers of information about how to split up the surface. Each ``tri`` file may contain multiple component IDs (in this case, only ``bullet.tri`` contains more than one component ID), but each file should contain a single closed surface. Then pyCart combines all these triangulations before intersecting them. If *intersect* is not set to ``true``, using multiple triangulation files has little effect. .. code-block:: javascript // RunMatrix (i.e. run matrix) description "RunMatrix": { // Global run matrix definitions "Keys": ["Mach", "alpha_t", "phi", "d2", "d4"], "File": "inputs/matrix.csv", "GroupMesh": true, "GroupPrefix": "poweroff", // Customized key definitions "Definitions": { // Rotate fin 2 "d2": { "Group": true, "Type": "rotation", "CompID": "fin2", "Vector": [[7.2,0,0], [7.2,-1,0]], ++"Value": "float", "Format": "%+03i_" }, // Rotate fin 4 "d4": { "Group": true, "Type": "rotation", "CompID": "fin4", "Vector": [[7.2,0,0], [7.2,1,0]], "Value": "float", "Format": "%+03i" } } } The ``"RunMatrix"`` section, which defines the run matrix input variables, is more interesting, so let's go through the settings one-by-one. The *Keys* input sets the list of input variables. The first three are common variables for many configurations and as such are automatically recognized by pyCart. The *File* parameter simply points to a file that contains the values of each input variable at which to run the configuration. Setting *GroupMesh* to true tells pyCart that the run matrix can be split into groups of cases such that each case in one group can use the same mesh, and *GroupPrefix* sets the base name of the group folders. The last parameter, *Definitions*, is the interesting part of this example. Because *Mach*, *alpha_t*, and *phi* are such common input variables (called "trajectory keys" in CAPE terminology) that we can rely on the default definitions. (Default trajectory key definitions can be altered by editing the file ``$CAPE/pycart/options/pyCart.default.json``.) The other two parameters are fin rotations, which require customization. The trajectory key *d2* is set up to rotate fin #2. We set *Group* to ``true`` because cases with the same fin deflections can use the same mesh. The *Type* is set to ``"rotation"``, which pyCart recognizes and reduces some of our work in defining it here. We set *CompID* to ``"fin2"``, which tells pyCart to rotate any triangles in the component defined as ``"fin2"`` in the ``Config.xml`` file. Then *Vector* gives a list of two points that define a vector about which to rotate the points. Finally, *Format* sets a ``printf`` style format string for how the value is printed in the folder name. It's set to integer in this example, which would create problems for fin deflection angles like ``2.1``. Anyway, this example shows how to set up general component rotations very quickly.