Giter VIP home page Giter VIP logo

pygeo's People

Contributors

a-cgray avatar akleb avatar anilyil avatar arshsaja avatar bbrelje avatar bernardopacini avatar camader avatar daburdette avatar denera avatar eirikurj avatar ewu63 avatar eytanadler avatar friedenhe avatar gawng avatar gjkennedy avatar gkenway avatar godotmisogi avatar hajdik avatar joanibal avatar jrram avatar justinsgray avatar lambe avatar lamkina avatar lvzhoujie avatar marcomangano avatar nbons avatar neysecco avatar sseraj avatar timryanb avatar xiaosong2105 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pygeo's Issues

writeRefAxis is midly broken

Description

DVGeometry.writeRefAxes appears to have broken midly due to a change in OrderedDict(). It should be reg tested but currently is not

Steps to reproduce issue

  1. Call writeRefAxes in the normal manner

Current behavior

Raises the following error:

Traceback (most recent call last):
  File "runFFDExample.py", line 50, in <module>
    DVGeo.writeRefAxes('local_refaxes.dat')
  File "/home/ben/packages/pygeo/pygeo/DVGeometry.py", line 2066, in writeRefAxes
    print(self.points.keys()[0])
TypeError: 'odict_keys' object is not subscriptable

Expected behavior

Should not do that

Child FFD deltas not calculated with the same point set as parent.

Previously known issue written here for documentation.

The Problem

When working with a child FFD embed in a parent FFD, a sub set of the points embedded in the parent will also be embed in the child. When calculating the additional movement of embed points due to the modification of the child FFD, the child FFD will first update the points embed inside of itself according to how the control points of the child were moved when the parent deformed. However, updating the points according to how the control points of the child were moved will not produce a point set identical to those embed in the parent! So when the child calculates deltas (additional position modifications) and they are added to the modifications caused by the motion of the parent FFD, the deltas will not have the intended geometric effect. For example in cases where the parent FFD does shape modifications and the child rotates a subset of these points (think morphing LE/TE), the rotation will skew the shape modifications. An example of this is shown in the picture below.
shapeModificationsSkewed

When it's an Issue

  • when combining parent shape variables with child shape deformation that isn't uniform for each point (child shape variables and rotation will cause issues, but translation will not).
  • Especially apparent when using large child FFD modifications

Work Around

  • use a linear spline surface for the Child FFD (works well for rotations, but not for child shape variables)

long term fix

  • change the data structure for child FFDs so that it references the same point set as the parent (same object in memory) but only works with a sub set of these points (the ones inside the child FFD). This way the points that the child FFD uses to calculate its additional modifications will always be the same as the points warped by the parent deformation.

MPhys wrapper: Standardize and cleanup the pygeo wrapper

Description of feature

the pygeo wrapper can be cleaned up substantially and we can also make the integration with the new api smoother.

In particular, during reverse mode derivative computations, it does unnecessary work when we have many thickness constraints, but pygeo still evaluates the full jacobian including the cfd surface nodes even though their seeds are zero.

Moved the issue from the mphys repo: OpenMDAO/mphys#62

Potential solution

The symmPlane argument does not work with all of the feature set in DVGeo.

Description

To automatically convert a half-body parameterization with a half body FFD into a full body parameterization that also creates a mirrored FFD block, DVGeo has an optional argument called symmPlane. This option enables some functionality to automatically mirror an FFD; however, not all features of this approach works. Specifically, users should be careful about how the reference axes are handled, as well as linking both sides of the FFD volumes.

I do not have a specific example right now, but this capability should be tested and debugged before it is ready for production cases.

Complex cast in pyNetwork

Type of issue

What types of issue is it?
Select the appropriate type(s) that describe this issue

  • Bugfix (non-breaking change which fixes an issue)

Description

Running any ASO will cause the following warning:

$HOME/mdolab/pygeo/pyNetwork.py:147: ComplexWarning: Casting complex values to real discards the imaginary part
  self.curves[icurve].coef[i] = self.coef[ii]

To reproduce, run then ASO script in MACH-Aero-tutorial.

PlanarityConstraint creates redundant pointsets

Description

The planarity constraint class is added using a pre-defined DVGeo pointset. However, at the time the constraint is created, an exact duplicate pointset is added to DVGeo creating unnecessary overhead.

Steps to reproduce issue

See TODO in PlanarityConstraint init method

Current behavior

Creates duplicate pointset and adds to DVGeo

Expected behavior

Should use original pointset in DVGeo

MPhys DVCon derivatives are incorrect with multiple processors

Description

Related issues have be a reoccurring topic in MPhys. I think for DVCon the issue is still unresolved, but I not in the loop on this type of issue.

Steps to reproduce issue

Run the following script

import numpy as np
import openmdao.api as om
import pyspline
from mphys.multipoint import Multipoint

from pygeo.mphys import OM_DVGEOCOMP
from pygeo.constraints.thicknessConstraint import ThicknessConstraint
from collections import OrderedDict

class Top(Multipoint):
    def setup(self):
        self.add_subsystem("dvs", om.IndepVarComp(), promotes=["*"])
        self.dvs.add_output("scale_section", val=np.ones(2) * 1.0)
        
        self.add_subsystem("geometry", OM_DVGEOCOMP(file="cube_ffd.xyz", type="ffd"))

    def configure(self):
        # add ref axis
        center_line_cords = np.array(
            [
                [-1.0, 0.0, 0.0],
                [1.0, 0.0, 0.0],
            ]
        )
        c0 = pyspline.Curve(X=center_line_cords, k=2)
        self.geometry.nom_addRefAxis(
             name="centerline", curve=c0, axis=np.array([1.0, 0.0, 0.0]),
        )

        # add design variables
        def scale_sections(val, geo):
            for i in range(geo.scale["centerline"].coef.size):
                geo.scale["centerline"].coef[i] = val[i]

        self.geometry.nom_addGlobalDV(
            "scale_section",
            np.ones(2) * 1.0,
            scale_sections,
        )

        # add contraint
        pts = np.array(
            [
                [0.0, -0.5, 0.0],
                [0.0, 0.5, 0.0],
            ]
        )

        typeName = "thickCon"
        conName = "thickness"
        lower = 0.0
        upper = 2.0
        scaled = True
        scale = 1.0

        self.geometry.DVCon.constraints[typeName] = OrderedDict()
        self.geometry.DVCon.constraints[typeName][conName] = ThicknessConstraint(
            conName, pts, lower, upper, scaled, scale, self.geometry.DVCon.DVGeometries["default"], True, None
        )
        self.geometry.add_output(conName, val=np.ones(pts.shape[0] // 2))


        # connect dvs to geometry
        self.connect("scale_section", "geometry.scale_section")
        # add design variables and contraints to the problem
        self.add_design_var("scale_section",)
        self.add_constraint("geometry.thickness", lower=lower, upper=upper, scaler=1.0)
        
prob = om.Problem()
prob.model = Top()
prob.setup(mode="rev")
om.n2(prob, show_browser=False, outfile="mphys_con_error.html")
prob.run_model()
prob.check_totals(step=3e-3)

on 1 processor I get

-----------------
Total Derivatives
-----------------

  Full Model: 'geometry.thickness' wrt 'dvs.scale_section'
    Analytic Magnitude: 7.071068e-01
          Fd Magnitude: 7.071068e-01 (fd:None)
    Absolute Error (Jan - Jfd) : 8.038873e-14

    Relative Error (Jan - Jfd) / Jfd : 1.136868e-13

    Raw Analytic Derivative (Jfor)
[[0.5 0.5]]

    Raw FD Derivative (Jfd)
[[0.5 0.5]]
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

on 2 I get

-----------------
Total Derivatives
-----------------

  Full Model: 'geometry.thickness' wrt 'dvs.scale_section'
    Analytic Magnitude: 3.535534e-01
          Fd Magnitude: 0.000000e+00 (fd:None)
    Absolute Error (Jan - Jfd) : 3.535534e-01 *

    Relative Error (Jan - Jfd) / Jan : 1.000000e+00 *

    MPI Rank 1

    Raw Analytic Derivative (Jfor)
[[0.25 0.25]]

    Raw FD Derivative (Jfd)
[[0. 0.]]
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-----------------
Total Derivatives
-----------------

  Full Model: 'geometry.thickness' wrt 'dvs.scale_section'
    Analytic Magnitude: 3.535534e-01
          Fd Magnitude: 7.071068e-01 (fd:None)
    Absolute Error (Jan - Jfd) : 3.535534e-01 *

    Relative Error (Jan - Jfd) / Jfd : 5.000000e-01 *

    MPI Rank 0

    Raw Analytic Derivative (Jfor)
[[0.25 0.25]]

    Raw FD Derivative (Jfd)
[[0.5 0.5]]
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Expected behavior

I would expect the derivatives to be correct on all procs or at least the root proc

Code versions

I'm running this in the stable public docker container

  • Operating System:
  • Python:
  • OpenMPI:
  • CGNS:
  • PETSc:
  • Compiler:
  • This repository: latest commit (b7f1bfb)

DVGeo does not use original FFD coef values when complex-stepping user functions

Description

When we implement our own functions for span, sweep, chord etc variables, they almost always look something like this:

def span(val, geo):
    C = geo.extractCoef("wing") # Get coeffs for the baseline FFD
    C = f(C, val) # Change the values of C based on val
    geo.restoreCoef(C, "wing") # Set coeffs to new value

This form relies on the assumption that every time this function is called, geo.extractCoef will return the coefficient values for the baseline FFD configuration. This is true the function is called to update the FFD coordinates, but when DVGeo comes to complex-step over the function, geo.extractCoef instead returns the updated coefficient values.

Effectively then, when DVGeo updates the geometry, it is calling something that behaves like C_new = f(C_orig, val) whereas when it does the complex-stepping it is instead calling f(C_new, val+dh*j), a different function.

See https://github.com/mdolab/private-MACH-tutorial/pull/83 for an example of how this can lead to issues.

Most of the time we get away with this because our DV's only add or subtract from coefficients (e.g C += val), in which case the derivatives do not depend on C.

Steps to reproduce issue

  1. Put a breakpoint in one of your DVGeo functions
  2. Run a script where you run an analysis on a deformed geometry and then compute derivatives
  3. Compare the values returned by geo.extractCoef when your DVGeo function is called to update the geometry vs when it is called to compute derivatives.

Current behavior

geo object passed to DVGeo functions during complex-stepping process is not the baseline geometry

Expected behavior

geo object passed to DVGeo functions during complex-stepping process should always be the baseline geometry

OpenVSP is not deterministic in spanwise distribution of parametric coordinates on blended wings.

Description

OpenVSP has a bug, where it can give two different spanwise parametric coordinate distributions on blended wings. The code seems to "lock" onto an execution path during initialization, and is consistent with design changes after initialization. However, we run multiple instances of OpenVSP on multiple procs, as a result, it is highly likely that the different instances running on different procs do not agree on the spanwise parametric coordinates. Even though the actual differences are small, this introduces very large errors when we do parallel finite-differencing. Currently, the code avoids this issue by doing the FD computations completely (base and perturbed) on the proc that perturbs the DV, instead of doing the base evaluation on the proc that owns the point, and the perturbed evaluation on the proc that perturbs the DV.

OpenVSP version of at least 3.21.1

I have a test script for this bug. I will check with all versions of OpenVSP and try to see if they ended up fixing it in a recent release. If not, I will contact the dev team (again) and point them towards the issue.

DVGeometry allows ref axis to be added after a finalize is called

Description

DVGeometry will allow the user to addRefAxis() following a finalize call without raising an error or warning. Instead, an obscure error is raised, e.g.

Traceback (most recent call last):
  File "runFFDExample.py", line 43, in <module>
    stlmesh.vectors[:,1,:] = DVGeo.update('mesh_v1')
  File "/home/ben/packages/pygeo/pygeo/DVGeometry.py", line 1281, in update
    self._complexifyCoef()
  File "/home/ben/packages/pygeo/pygeo/DVGeometry.py", line 2746, in _complexifyCoef
    self.rot_x[key].coef = self.rot_x[key].coef.astype('D')
AttributeError: 'DVGeometry' object has no attribute 'rot_x'

Steps to reproduce issue

  1. Create a DVGeometry object
  2. Add a pointset
  3. Update the pointset
  4. Add a ref axis
  5. Try to update again

Current behavior

Raises obscure error potentially much later than when the refAxis is added

Expected behavior

Should raise error at the time the ref axis is added if the system is finalized

FIXED FFD POINTS FOR AN OPTIMIZATION

Hi, I would like to use pygeo for the parameterization of my geometry which is an airfoil. My optimization problem is optimizing a morphing airfoil vertically but I need to put a local contraints on 4 FFD point of my box and impose that they will not move during the optimization.
Is it possible do it with pygeo? Searching in the documentation I have not understand if there is a DVconstraints that adress this requirment

Thanks in advanced

DVGeometryVSP parallel finite difference has stochastic error on Ubuntu builds

Description

DVGeometryVSP parallel finite diff derivatives should have zero error compared to doing the same finite differences in serial. However, due to a bug in VSP, some processor's VSP models randomly have slightly different underlying parametric representations of each surface. The result is that doing parallel finite differences will sometimes produce a different Jacobian than doing the same in serial on the root processor.

DVGeoVSP test 2 documents the issue. The tolerance on the test, 5e-5, is much higher than we would like. We sometimes see errors in the 1e-5 or higher range. However, for unknown reasons, this only happens on Ubuntu-based containers. The CentOS images have zero error to machine precision.

Current behavior

Parallel finite differences using OpenVSP on Ubuntu creates random errors that are larger than we'd hope

Expected behavior

Parallel FD has zero error (to machine precision) compared to serial FD

Once this bug (on the OpenVSP side) is fixed the tolerance in test_2 should be tightened to 1e-16

Design variables not correctly reset after running `demoDesignVars`

Description

After running demoDesignVars, the pyGeo design variables appear to be left in whatever state they were in the last written frame. This is an issue because if you then run ADflow, you will be not be the running the baseline geometry you think you are.

Steps to reproduce issue

  1. Setup an ADflow/pyaerostructure case with a DVGeo object
  2. Run demoDesignVars
  3. Run ADflow/pyaerostructure and look at the result in tecplot (the result shown below is from the private MACH tutorial)

Current behavior

Geometric DV's remain in their last perturbed state.

Screenshot_20220126_183702

Expected behavior

Geometric DV's should be reset to their original values at the end of demoDesignVars

I don't understand how this is happening as the DV's appear to be correctly reset in all the intermediate frames, it's only the final perturbed state that is not.

Reorganize the repo

Description

There are several unnecessarily large files in this repo:

  • DVConstraints.py has 6468 lines
  • DVGeometry.py has 4541 lines
  • geo_utils.py has 4509 lines

We should move some code into new files. For example, we should have separate files for separate constraint and DV classes instead of having them all in the same file. These files can be stored in separate directories.

RuntimeWarning in `rotation.py`

Description

When running MACH-Aero optimizations, a lot of warnings are printed:

pygeo/pygeo/geo_utils/rotation.py:10: RuntimeWarning: invalid value encountered in cdouble_scalars
  theta = theta * np.pi / 180

The same warning is also printed for lines 17 and 24.

Steps to reproduce issue

  1. Run MACH-Aero: mpirun -n 8 python aero_opt.py
  2. Look at the terminal output before any ADflow iterations

Current behavior

Many runtime warnings are printed

Expected behavior

There should be no runtime warnings

Code versions

  • Python: 3.9.7
  • Numpy 1.19.2
  • scipy 1.7.3

Sensitivities discrepancies with `rotType=7`

Description

In some corner parametrization cases we have observed that when swtiching to rotType=7 (instead of using rotType=0), the total derivatives become unusable, despite the geometry deformations being consistent and the FD test showing negligible changes in value.

Posting to make the user base aware of potential issues with this setting, I apologize for posting such a general statement here.

Steps to reproduce issue

This is actually the hardest part of the issue.. this has been only observed on some wind turbine sensitivity studies I carried out for this dev PR using another (at the time of writing) unmerged ADflow bugfix.
Unfortunately I do not have the bandwidth and the necessary implementation understanding to figure out where this error is coming from, but I am leaving this here for reference. There is probably some non-linearity or "non-commutativeness" coming from the operations within rotType=7 that was exacerbated by my sensitivity studies.
Hope to come back on this some time soon.

Current behavior

An example of how off the derivatives can be:

FD derivative - step 1e-2: 115540.23375306278
adjoint derivative (optimization-safe): 119087.22965122
adjoint derivative (rotType=7): 196336.67968909

Expected behavior

The derivatives should be consistent with the reference values!!

Code versions

pyGeo v 1.4.0

Update `childIdx` to use a string rather than just an index

Type of issue

What types of issue is it?
Select the appropriate type(s) that describe this issue

  • New feature (non-breaking change which adds functionality)

Description

Currently, childIdx has to be an integer which refers to the index of the child FFDs (by the order in which they are created in the script). It should be updated to use a more descriptive string which is associated to each FFD. Maybe we should add a name field to each FFD or something?

Rename some modules

Description of feature

The names in pygeo are terrible. There's a module called pygeo inside pygeo which only does surface generation, and DVCon isn't really for constraining DVs directly.

Here is a list of things I would like to rename, together with suggestions.

  • DVGeometry -> add FFD to the name to make it explicit
  • DVGeometryMulti -> something MultiFFD
  • rename DVGeometry prefix for the other parameterizations
  • DVConstraints -> geoConstraints
  • pyGeo the module must be renamed

Few other things to consider:

  • These changes are large enough that I think we should consider a major version bump
  • Maybe move the 3 files (pyGeo, pyNetwork, pyBlock) to their own module

Please comment below with your suggestions.

MPhys wrapper: Move dvcon to a matrix-based API for partials

Description of feature

With DVConstraints, and possibly with DVGeometry wrapper as well, we compute and store a full Jacobian internally using complex step or parallel finite differences. However, we have been using the matrix-free Jacobian vector product API in OpenMDAO instead of the matrix-based API.

Our approach is not well suited with the mat-free API; we end up either needing to do full jacobian computations each time mat-free API is called, or we need to keep track of design changes and update the Jacobians once and re-use them for subsequent mat-free API calls.

Matrix-based API is the way to go here: OpenMDAO would automatically update the matrix-based Jacobians when the design is changed. The only work we need to do here is to expose our Jacobians to OpenMDAO in the correct format for each DV and output/constraint.

Moved from the MPhys repo: OpenMDAO/mphys#69

Create a library of FFD operations

Write generic FFD functions and put them as a library. Make them customizable, so that people can import instead of writing their own twist functions etc. every time they want to run an optimization.

List of functions:

  • twist
  • shape
  • chord (w/ and w/o Yehudi)
  • span
  • sweep
  • dihedral
  • tail rotation?

Broken `writePlot3dCoef()` with numpy >=1.18

Type of issue

  • Bug

Description

The function writePlot3dCoef() in pyBlock.py is broken when numpy==1.18 is used.
It looks like the function numpy.flatten() now only requires a string input to define the flattening order, and not an integer as we are currently doing (see lines 660, 662, 664 of pyBlock.py).

I believe the issue is generated by this deprecated module

Steps to reproduce issue

  1. pip install numpy==1.18
  2. Run a script that uses DVGeometry.writePlot3d()

Current behavior

Broken function, the run crashes throwing the following value error:

Traceback (most recent call last):
  File "Analysis.py", line 239, in <module>
    DVGeoc1.writePlot3d(outputDirectory + "/ffd_deformed_P%.0f.xyz" % (args.pitch))
  File "/home/mmangano/miniconda3/envs/pygeo-dev/lib/python3.8/site-packages/pygeo/DVGeometry.py", line 2113, in writePlot3d
    self.FFD.writePlot3dCoef(fileName)
  File "/home/mmangano/miniconda3/envs/pygeo-dev/lib/python3.8/site-packages/pygeo/pyBlock.py", line 660, in writePlot3dCoef
    vals[:, :, :, 0].flatten(1).tofile(f, sep="\n")
ValueError: Non-string object detected for the array ordering. Please pass in 'C', 'F', 'A', or 'K' instead

Expected behavior

The function should replicate the behavior tested with numpy 1.16 and output a coordinate file with the correct ordering.

Code version

pygeo: 1.2.0

Python version: 3.8

External dependencies: numpy 1.18.5

Better pyGeo description

Update the README.md file description of pyGeo to be more descriptive. Ideally, it would be on par with pyOptsparse

Formatting

Description

Once #52 and #28 are merged, the code should be formatted and all linting errors fixed.

Remove the duplicate tolerance when embedding points.

Description of feature

Once the PR mdolab/pyspline#47 is merged, the pyspline projection will use the same tolerance used to check if a point is inside the volume or not. With this change, we can remove the additional embTol in the attachPoints method in pyBlock: https://github.com/mdolab/pygeo/blob/main/pygeo/pyBlock.py#L775

Potential solution

We can default to just using eps both in the projection solver and for checking if a point successfully projected or not.

DVConstraints test currently fails due to no numpy-stl installation

Description

Numpy stl not found during Azure tests

Steps to reproduce issue

Make a PR
The tests fail on DVConstraints because stl cannot be found

Current behavior

Expected behavior

pip install -e .[testing] installs the optional numpy-stl dependency

@nwu63 or someone, do you know why the Azure transition changed the way pygeo is installed on the machine during reg tests?

Typo in VSP wrapper

Description

I believe there is a typo here, and that the actual subroutine of interest is pySpline.libspline.adtprojections.searchquads.

Colinearity and PlanarityConstraint derivatives incorrect for exactly zero input values

Description

The way the Colinearity and PlanarityConstraints compute derivatives causes incorrect / spurious nonzero derivative values to appear if inputs (e.g. points, axes) contain true zero values.

The problem is this line which appears in two places in DVConstraints
/(2.0*numpy.sqrt(tmpX[i]))

Steps to reproduce issue

Turn derivative checking back on in test_DVConstraints tests 9 and 13b. It is currently turned off in the baseline case because the derivatives will contain different values depending on whether pyspline is compiled using Intel or GCC (produces near-zero floats in different places which causes the derivatives to be different)

Proposed fix

Instead of checking whether tmpX is exactly zero, check if it is nearly zero to within some tol
Or deprecate these constraints if nobody is using them.

Discussion: Get the derivative of the dXpt/dDV and the DVConstraint.

Hi, I am new to pygeo. The provided jacobian from pygeo is in CSR format for TACS. How can I just get the jacobian matrices for each of the pointset and the DVs and DVconstraint. The tutorial for this is lacking compared to others.

Context: To pass the DXpt/dDV to openMDAO in the compute_partial method.

DVGeometryCST import fails silently due to dependency not described in the docs

Description

If a user does not have prefoil installed, importing DVGeometryCST at pygeo init will fail silently and produce a "ImportError: cannot import name 'DVGeometryCST' from 'pygeo'" error message when the module is actually used. This hides the underlying cause, which is that prefoil is not installed. The prefoil dependency is not described, as far as I can tell, anywhere in the docs or installation instructions.

Steps to reproduce issue

Install pygeo 1.12.2 on ubuntu-like system
Try to use DVGeometryCST (e.g. from cmplxfoil)

Current behavior

Error message hides reason for import error

Expected behavior

Error message ought to describe the missing dependency
Docs ought to describe prefoil depedency

Code versions

  • Operating System: Ubuntu 20
  • Python: 3.8.5
  • OpenMPI: n/a
  • CGNS: n/a
  • PETSc: n/a
  • Compiler: n/a
  • This repository: 1.12.2

Prefoil dependency

Description

#141 added a hard prefoil dependency but setup.py was not updated to account for this. All tests that import pyGeo fail if you do not also have prefoil installed (which includes some ADflow tests).

At the very least, prefoil should be added in install_requires. However, I don't see much use in making everyone who wants to use pyGeo install prefoil. I would prefer if DVGeometryCST was imported like the other classes that have non-standard dependencies:

pygeo/pygeo/__init__.py

Lines 11 to 22 in d786ca8

try:
from .parameterization import DVGeometryVSP
except ImportError:
pass
try:
from .parameterization import DVGeometryESP
except ImportError:
pass
try:
from .parameterization import DVGeometryMulti
except ImportError:
pass

Similarly, if DVGeometryCST cannot be imported, we should skip its tests.

We can use this issue to discuss what the best approach is.

LocationConstraints1D returns NaN when polyline point values are zero and scaling is on

Description

LocationConstraints1D returns NaN when polyline point values are zero and scaled=True

For example,

Steps to reproduce issue

Please provide a minimum working example (MWE) if possible
Run Test 12 in test_DVConstraints, but turn scaled=True

Current behavior

NaN is returned if the original point location had a coordinate value of 0.0

Expected behavior

Should produce value 1.0 if the point is unchanged from its original location.
Or deprecate this if nobody is using it

Code versions

List versions only if relevant

  • Python

Extract airfoil data from a geometry model

Hi, I am sorry to bother your guys.

I am trying to generate a wing by using pyGeo('liftingSurface',...).
But the first thing I met is how to get the airfoil data from the existing geometry model.

So I am trying to ask for a suggestion that
Is there a way to extract airfoil data from several sections in an existing geometry model?

Again, sorry for this issue and many thanks.

Importing mpi4py Unnecessarily when Importing pygeo.geo_utils

Description

When scripting together a bunch of runs its is useful to be able to call os.system or subprocess.run on mpirun commands. During the setup up for various runs when grids are created pygeo cannot currently be used to correct or modify geometries because it will break any calls to command line mpirun. I think this is due to pygeo importing all of its modules whenever it is called, which in some cases also imports mpi4py. System calls cannot be made that use mpirun if mpi4py was previously imported. I am not too familiar with the pygeo structure, but there may be other submodules that this sort of thing also applies to.

Steps to reproduce issue

The steps are pretty much as follows, an example script is seen directly below the steps

  1. import something from pygeo
  2. try to run either os.system("mpirun hostname") or subprocess.run("mpirun hostame", shell=True)
>>> from pygeo.geo_utils import *
>>> import subprocess
>>> print(subprocess.run("mpirun hostname", shell=True))

Current behavior

The current behavior returns a non-zero error code on any system calls with mpirun calls. For the attached script this looks like:

$ python test.py 
CompletedProcess(args='mpirun hostname', returncode=1)

Expected behavior

For the sample script the expected behavior is a list of all of the processors on your machine. For my 24 core workstation it looks like this:

$ python test.py 
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
akleb-workstation
CompletedProcess(args='mpirun hostname', returncode=0)

Increase 'nIter' for 'attachPoints' in 'pyBlock.py'

Description of feature

When using DVGeo, pyBlock.py is used in the background. In the function attachPoints(...) found here the iterations-limit nIter is hardcoded to 100.

I encountered a problem where 100 is not enough.

Potential solution

Either increase the default value or make it adjustable through the regular DVGeo-wrapper.

Is there a way to link design variables of shared nodes in multi block FFDs?

If an FFD box is composed of multiple blocks with shared nodes, addLocalDV will assign a degree of freedom to each of the shared nodes. Perturbations to the local design variables will thus "break" the connection of the previously shared nodes. It would be useful to assign a single degree of freedom to each of the shared nodes so that they move in unison. Is there a feature to preserve the connection of shared nodes across blocks?

I suppose that this could be achieved with addShapeFunctionDV, but I'm wondering if this can be achieved with addLocalDV directly.

Rename `addGeoDV` functions

Type of issue

What types of issue is it?
Select the appropriate type(s) that describe this issue

  • Refactor

Description

I propose that we change some of the function names, which are unnecessarily verbose:

  • addGeoDVGlobal -> addGlobalDV
  • addGeoDVLocal -> addLocalDV
  • addGeoDVSectionLocal -> addSectionLocalDV

Nondeterministic test failure

Description

Sometimes when you run the tests, test_DVGeometry.py:RegTestPyGeo.test_21 will randomly fail. The nature of the failure is that some entries in the numpy array in the dictinoary dIdx: mainAxis: x_axis are swapped. It's unclear why or how, but maybe it has to do with the way we loop over dictionary keys or something.

Steps to reproduce issue

Unfortunately not reliably reproducible :( but this happened on some of the CI runs of #88 and was observed previously by @eirikurj.

Local DVs are not consistent with in-plane section rotations

Description

pyGeo users should be aware of an inconsistency in the way local design variables are implemented.
Any time the full set of design variables is updated, pyGeo will first update the global design variables, then apply individual FFD displacements.
The problem stems from the fact that DVs added with addLocalDV can only be displaced along the global reference axes.

This implies that when local design variable displacements occur after a section has been twisted, shape variables will "ignore" this rotation and will just be displaced over the user-defined axis, eg."y".
Such an issue is barely noticeable for regular aircraft applications, where twist is limited to a few degrees, but if you for example have large pitch deformations + shape variables on a wind turbine model, this happens:

As I was digging through, I realized that addLocalSectionDV should be intended also for this purpose and not solely "winglet" handling, but switching to this different DV type did not change the behavior. I tested displacements along different axes to verify that the way I was calling the DV was correct, so I assume that addLocalSectionDV either:

  • does not work with children FFD or
  • ignores in-plane rotations of the FFD section

Even if LocalSectionDV gets fixed or extended to cover this case, I feel that having local DVs to follow the local section rotations should be the default behavior, instead of being enabled by an "exotic" DV.
I don't see any point in having the current behavior shown above as default!

Proposed fix

The order of DVs update should be changed, with local DVs going first and global DVs being updated at the last step.
The main challenge I see is that we need to update the links_x attributes of the refAxis (see sketch below) for this to work.

These vectors connect the intersection of the refAxis with the FFD section plane (whose coordinates are handled by user-implemented DVs by using extractCoef() and restoreCoef()). Any rotation or scaling operation relies on these links to appropriately update the control points location.
The logical steps for the updated code to work would be:

  1. initialize the FFD object, including the refAxis and it's links to the FFD coefficients
  2. apply shape DVs and re-compute all the links
  3. apply global DVs using the updated links

I assume the original developers had a reason to implement geometry manipulation operations in this order, but I feel we should refactor at least this section of pyGeo as soon as possible.

Steps to reproduce issue

I have just tried this on my cases, but someone should also try this to replicate the issue

  1. Take a simple 3D case - e.g. the MACH-Aero tutorial
  2. set some very high twist value, and set a large displacement of one or two design variables
  3. run an analysis and write the deformed DVs or use DemoDesignVars

Current behavior

See fist pic above

Expected behavior

Shape vars should be displaced perpendicularly to the "chord axis" of the rotated FFD section.

DVConstraints evalFunctions inconsistent passing of references + values

Description

When evalFunctions and evalFunctionsSens is called for each type of constraint, one of two things happens. Either a fresh set of values is returned back to the dict() with all the constraints in it, or a reference to an existing array (which may have been present at previous iterations).

For example, the ThicknessConstraint always passes a reference to a FRESH array of values, whereas the CircularityConstraint passes a reference to the same array each time. If the dict() is manipulated outside, it can affect the internal values. Alternatively, a user may inadvertently save a result from a previous iteration without realizing it's a live reference which can be changed later on. I discovered this will writing reg tests for the circularity constraint.

Should probably be made consistent but this may produce breaking behavior in very few edge cases where people are relying on the current reference behavior.

Code versions

List versions only if relevant

  • Python

Tests fail due to skipped tests

Description

PR #170 added tests that are skipped if run in parallel. This breaks the tests and the docker nightly integration tests as the EXTRA_FLAGS='--disallow_skipped' is set.

The tests have parallel tests defined, e.g.,

test_params = [
    # # Tutorial scalar JST
    {"N_PROCS": 1, "name": "serial"},
    {"N_PROCS": 4, "name": "parallel_4procs"},
]

but they also have,

# we skip parallel tests for now
if not train and self.N_PROCS > 1:
    self.skipTest("Skipping the parallel test for now.")

Steps to reproduce issue

Run tests with testflo -v -n 1 --disallow_skipped

Current behavior

The tests that are skipped are the following:

The following tests were skipped:
test_DVGeometryESP.py:TestPyGeoESP_BasicCube_1_parallel_4procs.test_composite
test_DVGeometryVSP.py:RegTestPyGeoVSP_1_parallel_4procs.test_2
test_DVGeometryVSP.py:RegTestPyGeoVSP_1_parallel_4procs.test_3

Expected behavior

No tests should be skipped

Code versions

Current mdolab/private:u20-gcc-ompi-stable docker image

Possible solution

Two options

  1. If there is no need for a parallel run, then remove test_params and define N_PROCS = 1
  2. Remove the if check and allow running in parallel.

Define base classes to unify the various DVGeo modules

Description

Currently, DVGeoVSP and DVGeoESP do not share any code with DVGeo, but mimics its API. This results in potential inconsistencies such as #124.

The solution is probably to define the API via an abstract base class, which is then inherited by all the various modules.

issue using addLocalDV

Hi,
few days ago I have created an issue to understand how to fix some point of my FFD box since I want to optimize a morphing airfoil and I need to fix a "box" as a constrain. To do it I opted for geo_utils.PointSelect as following:
`

FFDFile = "ffd.xyz"

DVGeo = DVGeometry(FFDFile)
##MY MODIFICATION
pts= DVGeo.getLocalIndex(0)

indexList = pts[:,:,:].flatten() #all the FFD nodes of the box pre-defined

fixed = []
for i in np.array([2,7]):
for j in np.array([0,1]):
for k in np.array([0,1]):
#for visualization purposes
fixed.append(DVGeo.getLocalIndex(0)[i, j, k])

moved = [ix for ix in indexList if ix not in fixed]

PS_fixed = geo_utils.PointSelect('list', fixed)
PS_moved = geo_utils.PointSelect('list', moved)
PS_total = geo_utils.PointSelect('list', indexList)

DVGeo.addLocalDV("shape", lower=-0.05, upper=0.05, axis="y", scale=1.0, pointSelect = PS_moved)

DVGeo.addLocalDV("fix", lower=1, upper=1, axis = 'y', scale=1.0, pointSelect = PS_fixed)`

Than I added the same constraints of the airfoil optimization tutorial https://mdolab-mach-aero.readthedocs-hosted.com/en/latest/machAeroTutorials/airfoilopt_singlepoint.html
Therefore I run the code but it return the following error:

------------------------------------------------------------------------------+
| pyOptSparse Error: The 'lower' argument to addCon or addConGroup is |
| invalid. It must be None, a scalar, or a list/array or length nCon=16. |
+------------------------------------------------------------------------------+

In my opinion the error is in the definition of addLocalDV. How can I fix it?

Refactor handling of multiple DVGeo objects with DVCon

Description of feature

The PR #52 introduces a way to use multiple DVGeometry objects with a single DVConstraints object. So far, only @bbrelje uses these. There is a separate development of DVGeometryMulti that is used to handle intersecting components. I also implemented a similar functionality but in a different way. In that work, DVGeometryMulti class handles multiple component DVGeometries, and adjusts the naming for pyoptsparse etc.

Ideally we want to have a consistent implementation so both approaches can function together.

Potential solution

Around April 2021, we will refactor the pygeo code with @bbrelje to fix this consistency issue. At the same time, I will also merge the outstanding work in my development branch: https://github.com/anilyil/pygeo/tree/dev The main addition will be the DVGeometryMulti code, but there are other minor API changes for other pygeo classes.

The underlying SVD for definition of sectional DVs can give inconsistent results.

Description

SVD (U \Sigma V^T = A) is used to figure out a local coordinate frame. This is done by looking at the columns of the U matrix. The first column is a best fit line through the points that define that FFD section. The second column is the next best fit that is orthogonal to the first one; this ends up being the second vector that defines the section tangents (although not exactly). Then the third one is the last orthogonal vector that spans the 3 dimensional space, and that ends up being orthogonal to the section surface itself.

The SVD is only unique up to a sign change of these vectors in the U and V matrices. So while the U1 U2 and U3 vectors’ orientations are correct, their “sense” (what way the arrow is pointing to) can vary based on what machine its running on.
I realized that the sectional DVs on the dlr f6 case ended up getting a wrong direction on some of the sections when I ran it on docker, vs natively on the same computer. So far, seems like the SVD has been giving consistent results for everyone, but it can totally flip direction if not careful. I think even if you provide an “orient0" direction, the other two directions can still flip. If you do not provide any orient directions, then all 3 vectors can flip either way.

The method to create sectional DVs: https://github.com/mdolab/pygeo/blob/master/pygeo/DVGeometry.py#L689

During its setup, it calls https://github.com/mdolab/pygeo/blob/master/pygeo/DVGeometry.py#L3407 to figure out the sectional coordinates.

Here is the SVD where we take the U matrix from: https://github.com/mdolab/pygeo/blob/master/pygeo/DVGeometry.py#L3505

The sectionFrame method can take in an optional argument orient0, which is a way to correctly orient the first basis vector. However, this does not fully fix the solution as the other two vectors can still flip among themselves. If orient0 is not provided, then all 3 vectors can flip direction.

Suggested Solution

My suggested solution is to make sure we align these vectors with some of the directions introduced by the FFD. So I am proposing computing the “finite difference” version of these vectors with the FFD, and then using the sign of the dot product of these FFD vectors with the SVD vectors to flip the SVD vectors if required.

At least for Ney’s F6 stuff, this fix flips the direction of the sectional DV changes. However, this fix does make it consistent between my native and docker runs.

My suggested solution will most likely break the runscripts that have been using this in the past.

Steps to reproduce issue

I am attaching a simple FFD box and a python test script. There are 16 total FFD control points we select and we define normal DVs using these. When run with the current default branch of pygeo (commit: f8176b0) the control points on the upper side ends up flipping in direction when I run it natively on my mac vs docker running on my mac.

pygeo_sectional_test.zip

Current behavior

The SVD can result in vectors that change in sense between computers, and this can lead to "flipping" of design variable directions.

Expected behavior

The local coordinate system computed for FFD sections should be unique.

Update tests

Description

  • Update tests to use testflo
  • Add coverage report since this is pure Python

Issue with determining interior points

Description

I made a multi-block FFD box that completely encloses a geometry. However, when I add the point set (an .stl file), I get a warning that a number of points are not projected to the tolerance. I believe this warning is given when an FFD box does not fully enclose the geometry. However, that isn't the case here, the FFD box does in fact enclose the geometry.

Any suggestions on a work around would be very appreciated.

I've prepared a minimum working example with a simplified geometry:
MWE.zip

Steps to reproduce issue

  1. python MWE.py
  2. Open the paraview file to see the FFD box, initial geometry, and "clipped" geometry

Current behavior

Points in the geometry are clipped even though the geometry is fully enclosed by the FFD box. In the image attached, the blue surface is the original geometry and the white surface is the "clipped" geometry.
MWE_picture

Expected behavior

The geometry should not be altered

Code versions

Using the MDO Lab's docker image

mpi4py installation requirement

Type of issue

  • Maintenance

Description

pygeo uses mpi4py, but it's not listed in install_requires in setup.py.
It might worth putting it there, though most of the MACH users should already have it installed. (I realized this issue when running OAS tests, which just use pyGeo but no other MACH repositories.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.