# -*- python -*-

# This software was produced by NIST, an agency of the U.S. government,
# and by statute is not subject to copyright in the United States.
# Recipients of this software assume all responsibilities associated
# with its operation, modification and maintenance. However, to
# facilitate maintenance we ask that before distributing modified
# versions of this software, you first contact the authors at
# oof_manager@nist.gov. 

from ooflib.tutorials import tutorial
TutoringItem = tutorial.TutoringItem
TutorialClass = tutorial.TutorialClass

TutorialClass(
    subject = "Nonrectangular Domain",
    ordering=5,
    lessons = [
    
    TutoringItem(
    subject="Introduction",
    comments=
"""Meshes (Skeletons) that are generated by OOF2 are always RECTANGULAR.  However, it doesn't mean that you're limited only to a rectangular domain.
    
OOF2 allows you to simulate arbitrarily shaped problem domains by selectively assigning materials to a Microstructure.

In this tutorial, we will cover this topic in detail. """
    ),

    TutoringItem(
    subject="Microstructure",
    comments=
"""Open a graphics window, if none has been opened yet, with the <b>Graphics/New</b> command in the <b>Windows</b> menu.  In its <b>Settings</b> menu, set <b>New Layer Policy</b> to <b>Single</b>.

Locate the file <tt>el_shape.png</tt> within the share/oof2/examples directory in your OOF2 installation.
    
Open the <b>Microstructure</b> page and click <b>New from Image File</b> to create a new microstructure.  In the file selection dialog box, navigate to <b>el_shape.png</b>.  Click <b>OK</b> to load the Image and create the Microstructure. """,
    ),
    
    TutoringItem(
    subject="Categorizing Pixels",
    comments=
"""The microstructure features <b>green</b> and <b>ivory</b> regions. We're interested only in the <b>green</b> region -- our problem domain will be an <b>L</b>-shaped bracket, so to speak.

To categorize pixels automatically, open the <b>Image</b> page and click the <b>Group</b> button.
    
Go back to the <b>Microstructure</b> page and you will see that <b>2</b> pixel groups have been created for the microstructure. """
    ),

    TutoringItem(
    subject="Pixel Group",
    comments=

"""Now, we'll change names of pixel groups for our convenience.

Go to the <b>Microstructure</b> page and select the first pixel group, "#00ff00", which contains the <b>green</b> pixels.  Click the <b>Rename</b> button.

Replace the old name with "green".  (Triple-clicking on the old name in the dialog box will select the whole name, making it easier to replace.)

Don't bother with the other pixel group, since we're not going to use it. """,
    ),

    TutoringItem(
    subject="Material",
    comments=
"""Open the <b>Materials</b> page. Create a new material by clicking on the <b>New</b> button in the <b>Material</b> pane.

Tgype <b>green-material</b> in the text entry field.  Click <b>OK</b>.  """,
    ),

    TutoringItem(
    subject="Property",
    comments=
"""Start creating a property for <b>green-material</b> by selecting <b>Isotropic</b> from <b>Mechanical:Elasticity</b> in the property hierarchy.

Click <b>Copy</b> and check the box to give it a user-defined name.

Tgype in <b>green_elasticity</b>. Click <b>OK</b>.""",
    ),

    TutoringItem(
    subject="Parametrizing Property",
    comments=
"""Select <b>green_elasticity</b> from the Property hierarchy and either double click it or click the <b>Parametrize...</b> button to input actual values.

The elasticity parameters can be entered in a variety of formats. The default format is <b>Cij</b>.  Change it to <b>E and nu</b> with the pull down menu at the top of the Parametrize dialog box.

Set the modulus of elasticity (<b>young</b>) to 1.0 and Poisson's ratio (<b>poisson</b>) to 0.3.

Click <b>OK</b> to finish up. """,
    ),

    TutoringItem(
    subject="Adding Property to Material",
    comments=
"""Select <b>green_elasticity</b> from the Property tree.

Click <b>Add Property to Material</b> from the bottom of the <b>Property</b> pane to add the Property to the Material.

The addition should immediately appear in the <b>Material</b> pane, in the list of Properties below the Material selector. """,
    ),

    TutoringItem(
    subject="Assigning Material to Pixels",
    comments=
"""Select the material <b>green-material</b> and click on the button labelled <b>Assign Material to Pixels...</b> in the <b>Material</b> pane.

The pop-up window lets you choose the Microstructure to which the Material will be assigned (currently we only have one, "el_shape.png"), and the pixels within the Microstructure.  Choose the pixel group <b>green</b> in the <b>pixels</b> pull-down menu.

Click <b>OK</b> to finish.

We will NOT do anything for the <b>ivory</b> pixels. """,
    ),

    TutoringItem(
    subject="Skeleton",
    comments=
"""Go to the <b>Skeleton</b> page. Click <b>New...</b> to create an initial skeleton.

Use these  values for the initial skeleton: <b>x_elements</b> = 20, <b>y_elements</b> = 20, and <b>skeleton_geometry</b>=QuadSkeleton. Click <b>OK</b> to create the Skeleton. """,
    ),

    TutoringItem(
    subject="Boundary Modification",
    comments=
"""Since we're only interested in the <b>green</b> portion of the Skeleton, we're going to modify the existing boundaries.  The existing boundaries include edges of non-green elements.
    
We will modify two edge boundaries, <b>top</b> and <b>right</b>, so that only the segments from the <b>green</b> elements will be part of them.  Advance to the next slide for real action.  """
    ),

    TutoringItem(
    subject="Boundary Modification 1",
    comments=
"""Go to the <b>Skeleton Boundaries</b> page. Select the <b>top</b> boundary from the <b>Boundaries</b> pane. Now, if you go to the graphics window, you will see that the selected edge boundary is displayed.  What we're going to do is to remove segments from the <b>ivory</b> elements from this boundary.

Open the <b>Skeleton Selection</b> toolbox in the graphics window. Select <b>Segment</b> from the selection modes. Choose <b>Rectangle</b> for the selection method. Now, try to select all the segments that belong to <b>ivory</b> elements from the <b>top</b> boundary by click-and-dragging the mouse.

Selected segments appear as thick <b>green</b> lines.  Go back to the <b>Skeleton Boundaries</b> page and click the <b>Modify...</b> button. Select <b>Remove segments</b> for the modifying method and select <b>&lt;selection&gt;</b> for <b>group</b>.  Click <b>OK</b>. You should see the immediate change in the <b>Boundary data</b> pane and in the graphics window. 

(Depending on the size of your graphics window, the arrows drawn on the selected boundary may obscure the view.  Select <b>List All Layers</b> from the <b>Settings</b> menu in the graphics window. Double click on <b>SkeletonSelectedBoundaryDisplay</b>, and set <b>arrowsize</b> to something small.  Click <b>OK</b>.  You may want to unset <b>List All Layers</b> when you're done.) """,
    ),

    TutoringItem(
    subject="Boundary Modification 2",
    comments=
"""We'll do a similar thing for the <b>right</b> edge boundary. Select the <b>right</b> boundary from the <b>Boundaries</b> pane.

Go to the graphics window and try to select all the segments that belong to <b>ivory</b> elements from the <b>right</b> boundary.

Go back to the <b>Skeleton Boundaries</b> page and click the <b>Modify...</b> button. Select <b>Remove segments</b> for the modifying method and select <b>&lt;selection&gt;</b> for the <b>group</b>. Click <b>OK</b>.

Now, we're ready to create a Mesh from this Skeleton. """,
    ),
    
    TutoringItem(
    subject="Finite Element Mesh",
    comments=
"""Open the <b>FE Mesh</b> page.

Click the <b>New</b> button to get a dialog box for creating a new Mesh.  Here you must specify which types of mesh elements to use for triangular (<b>element3</b>) and quadrilateral (<b>element4</b>) skeleton elements and their orders.

Use these values, <b>mapping order</b> = 2, <b>interpolation order</b> = 2, <b>3-sided element</b> = T6_6, <b>4-sided element</b> = Q8_8 to create a quadratic Mesh.

Click <b>OK</b>.

As you recall, we didn't assign any material to the <b>ivory</b> elements.  These elements will be dummies, which makes the Mesh (even if it's rectangular) an effective L-shaped domain.  If you hide or delete the <b>Skeleton</b> layer in the <b>Graphics</b> window, you'll see that Mesh elements are drawn only where a Material has been assigned.

Now, let us solve a problem using this Mesh. """,
    ),

    TutoringItem(
    subject=" Field",
    comments=
"""Proceed to the <b>Fields &amp; Equations</b> page.
    
Check all <b>three</b> boxes for the <b>Displacement</b> field.

Check the <b>active</b> box for the <b>Force Balance</b> equation. """,
    ),

    TutoringItem(
    subject="Boundary Conditions",
    comments=
"""Go to the <b>Boundary Conditions</b> page.

The boundary conditions (all <b>Dirichlet</b>) we're going to apply are:

<b>1.</b> u_x = 0 on the <b>left</b> side
    
<b>2.</b> u_y = 0 on the <b>left</b> side

<b>3.</b> u_x = 0 on the <b>top</b> side

<b>4.</b> u_y = 0 on the <b>top</b> side

<b>5.</b> u_y = -2 on the <b>right</b> side"""
    ),

    TutoringItem(
    subject="Boundary Condition 1",
    comments=
"""Click the <b>New...</b> button from the <b>Condition</b> pane to bring up a boundary condition builder.  The pull-down menu at the top of the dialog box allows you to choose the type of boundary condition.  Set it to <b>Dirichlet</b>, which gives associated Fields fixed values at the boundaries.
    
Since only one Field is defined and only one Equation is active, the <b>field</b> and <b>equation</b> menus have only one choice each.  Leave them set to <b>Displacement</b> and <b>Force_Balance</b>.
 
The first B.C. deals with displacement in the <b>x</b>-direction, so select <b>x</b> for both <b>Displacement</b> and <b>Force_Balance</b>.

The <b>profile</b> is the functional form of the Field along the boundary.  Set <b>profile</b> to <b>Constant Profile</b> with <b>value</b> = 0.

Choose the <b>boundary</b> to which this condition should be applied (<b>left</b>) and click <b>OK</b>. """,
    ),

    TutoringItem(
    subject="Boundary Condition 2-5",
    comments=
"""Create the rest of Boundary Conditions as you did for the first one. You can always go back to previous slides to check some numbers and stuff by clicking on the <b>Back</b> button. BUT, make sure to create all the BCs before you move on to the next slide.

(If you get back to this page and discover that the <b>Next</b> button is disabled, just edit one of the boundary conditions.  You don't actually have to change it, you just have to trick the tutorial machinery into thinking you've changed something.)""",
    ),

    TutoringItem(
    subject="Solution",
    comments=
    
"""Open the <b>Solver</b> page.

In the <b>Solvers</b> box, select the <b>default</b> subproblem and click <b>Set Solver</b>.  Click <b>OK</b> to accept the default values (<b>solver_mode</b>=Basic, <b>time_stepper</b>=Static, etc).

Click <b>Solve</b>.  The deformed Mesh will be displayed in the graphics window.

By default, OOF2 doesn't display elements with no material defined in the output, which explains what you're seeing now.

We've covered how you simulate arbitrary problem domains by selectively assigning Materials so far.
    
Thanks for following the tutorial!"""
    )
    
    ])
