Esempio n. 1
0
        /// <summary>
        /// Finds the boundary evaluator (<see cref="AppControl.BoundaryValues"/>)
        /// associated with <paramref name="fieldName"/> for the condition
        /// <paramref name="boundaryValues"/>.
        /// </summary>
        /// <param name="boundaryValues">The boundary condition</param>
        /// <param name="fieldName">The id of the boundary in question</param>
        /// <returns>
        /// The evaluator stored in <see cref="AppControl.BoundaryValues"/>
        /// for a boundary with id <paramref name="fieldName"/>.
        /// </returns>
        private static Func <double[], double, double> GetBoundaryValueFunction(AppControl.BoundaryValueCollection boundaryValues, string fieldName)
        {
            Func <double[], double, double> boundaryValue = null;

            TryGetBoundaryValueFunction(boundaryValues, fieldName, out boundaryValue);

            if (boundaryValue == null)
            {
                throw new ArgumentException(
                          "Missing boundary specification for field '" + fieldName + "'",
                          "condition");
            }

            return(boundaryValue);
        }
Esempio n. 2
0
        /// <summary>
        /// Retrieves the configured boundary condition for a given
        /// <paramref name="edgeTagName"/>.
        /// </summary>
        /// <param name="edgeTagName">The name of the edge</param>
        /// <returns>
        /// The boundary condition that has been assigned to edges with
        /// name <paramref name="edgeTagName"/>
        /// </returns>
        public virtual BoundaryCondition GetBoundaryCondition(string edgeTagName)
        {
            AppControl.BoundaryValueCollection boundaryValues =
                GetConfiguredBoundaryValues(edgeTagName);

            var key = boundaryValueMap.Keys.SingleOrDefault(tag => edgeTagName.StartsWith(tag, StringComparison.InvariantCultureIgnoreCase));

            if (key == null)
            {
                throw new NotImplementedException("Unknown edge tag name \"" + edgeTagName + "\"");
            }
            else
            {
                return(boundaryValueMap[key](control, boundaryValues));
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Searches the boundary config (<see cref="AppControl.BoundaryValues"/>)
        /// for a definition of a set of boundary values for an edge with name
        /// <paramref name="edgeTagName"/>.
        /// </summary>
        /// <param name="edgeTagName">
        /// The id of the boundary in question
        /// </param>
        /// <returns>The boundary values specified in the control file</returns>
        private AppControl.BoundaryValueCollection GetConfiguredBoundaryValues(string edgeTagName)
        {
            AppControl.BoundaryValueCollection boundaryValues = null;
            foreach (var tagConditionPair in control.BoundaryValues)
            {
                if (edgeTagName.StartsWith(tagConditionPair.Key, StringComparison.InvariantCultureIgnoreCase))
                {
                    boundaryValues = tagConditionPair.Value;
                }
            }

            if (boundaryValues == null)
            {
                throw new ArgumentException(
                          "Unable to find a definition for boundary conditions for edges of type '" + edgeTagName + "'",
                          "edgeTagName");
            }

            return(boundaryValues);
        }
Esempio n. 4
0
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="grdDat"></param>
        /// <param name="_bndy"></param>
        /// <param name="bndFunctionNames">
        /// all names of boundary functions that should be parsed for, see <see cref="bndFunction"/>
        /// </param>
        public BoundaryCondMap(IGridData grdDat, IDictionary <string, AppControl.BoundaryValueCollection> _bndy, params string[] bndFunctionNames)
        {
            var bndy = new Dictionary <string, AppControl.BoundaryValueCollection>(_bndy, new StringIgnoreCaseEq());

            m_grdDat = grdDat;
            //m_grid = grdDat.Grid;
            //var grid = m_grid;

            // verify Boundary Condition Type Enum
            // ====================================
            {
                Type tT = typeof(BCType);
                if (!tT.IsEnum)
                {
                    throw new ApplicationException("generic type argument must be an enumeration.");
                }

                var consts = tT.GetMembers();

                foreach (var c in consts)
                {
                    try {
                        BCType val;
                        val = (BCType)Enum.Parse(tT, c.Name); // if we pass this line, we've found a constant of the enum

                        BoundaryCondTypes.Add(c.Name, val);
                    } catch (Exception) {
                        // some other member, e.g. Equals(),...
                    }
                }
            }

            // verify boundary function names
            // ==============================

            foreach (string s in bndFunctionNames)
            {
                Func <double[], double, double>[] vals = new Func <double[], double, double> [GridCommons.FIRST_PERIODIC_BC_TAG];
                //ArrayTools.Set(vals, Zero);
                for (int ii = 0; ii < vals.Length; ii++)
                {
                    vals[ii] = Zero;
                }

                bndFunction.Add(s, vals);
            }


            // verification: test if EdgeTagsNames and EdgeTags in control file and in grid match
            // ==================================================================================

            //int D = grid.SpatialDimension;
            {
                List <string> Problems = new List <string>();


                // 1st: look if all EdgeTagsNames in the Grid have a corresponding entry in the control file
                foreach (byte EdgeTag in grdDat.EdgeTagNames.Keys)    // loop over all edge tag names in grid ...
                {
                    string EdgeTagName = grdDat.EdgeTagNames[EdgeTag];
                    if (EdgeTagName.Length <= 0)
                    {
                        Problems.Add("Found an empty EdgeTagName in the grid. (EdgeTag = " + EdgeTag + ").");
                    }

                    if (EdgeTag == 0)
                    {
                        // must not be in the control file

                        foreach (string edgetagname in bndy.Keys)
                        {
                            if (edgetagname.Equals(EdgeTagName, StringComparison.InvariantCultureIgnoreCase))
                            {
                                Problems.Add("Illegal specification for boundary condition on internal edge: (EdgeTagName = '" + EdgeTagName + "', Edgetag = " + EdgeTag + ".");
                            }
                        }
                    }
                    else if (EdgeTag >= GridCommons.FIRST_PERIODIC_BC_TAG)
                    {
                        // must not be in the control file

                        foreach (string edgetagname in bndy.Keys)
                        {
                            if (edgetagname.Equals(EdgeTagName, StringComparison.InvariantCultureIgnoreCase))
                            {
                                Problems.Add("Illegal specification for boundary condition on periodic edge: (EdgeTagName = '" + EdgeTagName + "', Edgetag = " + EdgeTag + ".");
                            }
                        }
                    }
                    else
                    {
                        // must be contained in the control file

                        int found = 0;
                        foreach (string edgetagname in bndy.Keys)
                        {
                            if (edgetagname.Equals(EdgeTagName, StringComparison.InvariantCultureIgnoreCase))
                            {
                                found++;
                            }
                        }

                        if (found > 1)
                        {
                            Problems.Add("Boundary condition in control file is specified more than once (" + found + " times) (EdgeTagName = '" + EdgeTagName + "', Edgetag = " + EdgeTag + ".");
                        }

                        if (found == 0)
                        {
                            Problems.Add("EdgeTagName = '" + EdgeTagName + "', Edgetag = " + EdgeTag + " is specified in the grid, but not in control file.");
                        }
                    }
                }

                // 2nd: look if all boundary conditions in the control file can be found in the grid.
                foreach (string edgetagname in bndy.Keys)   // loop over all boundary conditions in control file
                {
                    if (edgetagname == null || edgetagname.Length <= 0)
                    {
                        Problems.Add("found some boundary condition with zero-length name");
                    }

                    if (!grdDat.EdgeTagNames.Values.Contains(edgetagname, new StringIgnoreCaseEq()))
                    {
                        Problems.Add("some boundary condition for '" + edgetagname + "' is specified in control file, but there is no corresponding EdgeTagName in the grid.");
                    }
                }



                // 3rd: test if all boundary conditions can be interpreted
                foreach (var bc in bndy)
                {
                    string edgetagname  = bc.Key;
                    string _EdgeTagName = edgetagname.ToLowerInvariant();
                    string ttt          = bc.Value.type;

                    int interptret = 0;
                    foreach (string bctype in this.BoundaryCondTypes.Keys)
                    {
                        string _bctype = bctype.ToLowerInvariant();

                        if (ttt != null && ttt.Equals(bctype, StringComparison.InvariantCultureIgnoreCase))
                        {
                            interptret++;
                            continue;
                        }

                        if (ttt == null && _EdgeTagName.Contains(_bctype))
                        {
                            interptret++;
                            continue;
                        }
                    }

                    if (interptret <= 0)
                    {
                        Problems.Add("unable to interpret boundary condition for name '" + edgetagname + "': no fitting boundary condition type found;");
                    }
                    if (interptret > 1)
                    {
                        Problems.Add("unable to interpret boundary condition for name '" + edgetagname + "': not unique; ");
                    }
                }

                // throw an exception, if there are any problems
                if (Problems.Count > 0)
                {
                    StringWriter stw = new StringWriter();

                    stw.WriteLine("Found " + Problems.Count + " problem(s) with boundary condition specification.");
                    foreach (string s in Problems)
                    {
                        stw.WriteLine(s);
                    }

                    stw.Write("(EdgeTagNames in the grid are: ");
                    int cnt = 0;
                    foreach (string s in grdDat.EdgeTagNames.Values)
                    {
                        cnt++;
                        stw.Write("'" + s + "'");
                        if (cnt < grdDat.EdgeTagNames.Count)
                        {
                            stw.Write(", ");
                        }
                    }
                    stw.Write(")");


                    throw new ApplicationException(stw.ToString());
                }
            }

            // test edges
            // ==========

            // loop over all edges ...
            int E = grdDat.iGeomEdges.Count;

            for (int e = 0; e < E; e++)
            {
                //foreach (byte EdgeTag in grdDat.EdgeTags) {
                byte EdgeTag = grdDat.iGeomEdges.EdgeTags[e];

                if (EdgeTag == 0)
                {
                    if (grdDat.iGeomEdges.CellIndices[e, 1] < 0)
                    {
                        // unspec. EdgeTag on boundary -> error
                        throw new ApplicationException("Error in Grid: found at least one edge without EdgeTag;");
                    }
                    else
                    {
                        // inner edge: nothing to do;
                        continue;
                    }
                }

                if (EdgeTag >= GridCommons.FIRST_PERIODIC_BC_TAG)
                {
                    continue; // do nothing for periodic edges
                }
            }


            // build the EdgeTag -> BoundaryCondType -- Mapping
            // ================================================

            foreach (byte EdgeTag in grdDat.EdgeTagNames.Keys)
            {
                string EdgeTagName = grdDat.EdgeTagNames[EdgeTag];
                if (EdgeTag == 0 || EdgeTag >= GridCommons.FIRST_PERIODIC_BC_TAG)
                {
                    continue;
                }

                AppControl.BoundaryValueCollection bc = bndy[EdgeTagName];


                {
                    // these problems should have been detected prevoiusly...

                    if (bc == null)
                    {
                        throw new ApplicationException("unable to find definition for boundary in control file; " +
                                                       "From Gird: EdegTag = " + EdgeTag + ", EdgeTagName = " + EdgeTagName + "; ");
                    }
                    if (EdgeTagName == null || EdgeTagName.Length <= 0)
                    {
                        throw new ApplicationException("EdgeTagName is not defined: must be defined either in grid or within control-file; EdgeTag = " + EdgeTag);
                    }
                }

                // set boundary condition
                // ----------------------
                {
                    string _EdgeTagName = EdgeTagName.ToLowerInvariant();
                    string type         = bc.type;
                    if (type == null)
                    {
                        type = "";
                    }
                    if (type.Length > 0)
                    {
                        // specification of type overrules the name
                        _EdgeTagName = "";
                    }

                    bool found = false;
                    foreach (string bctype in this.BoundaryCondTypes.Keys)
                    {
                        if (type.Equals(bctype, StringComparison.InvariantCultureIgnoreCase) || _EdgeTagName.Contains(bctype.ToLowerInvariant()))
                        {
                            EdgeTag2Type[EdgeTag] = this.BoundaryCondTypes[bctype];
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        throw new ApplicationException("unable to determine boundary condition type:" +
                                                       " EdgeTagName: \"" + EdgeTagName + "\": " +
                                                       "EdgeTagName or type must contain either with \"Wall\", \"Velocity_inlet\", or \"Pressure_Outlet\", or \"Outflow\" (case insensitive) to be identified by this version of the Navier-Stokes solver.");
                    }


                    foreach (var kv in bc.Evaluators)
                    {
                        string DesiredFieldName = kv.Key;
                        Func <double[], double, double> f_bnd = kv.Value;

                        if (!bndFunction.Keys.Contains(DesiredFieldName))
                        {
                            //string allNmn = "";
                            //foreach (var ss in bndFunction.Keys)
                            //    allNmn += ss + " ";
                            //throw new ApplicationException("boundary function '" + val.DesiredFieldName + "' is not supported by the application (must be one of: " + allNmn+");");

                            // there may be some other BoundaryConditionMap which uses this name
                        }
                        else
                        {
                            bndFunction[DesiredFieldName][EdgeTag] = f_bnd;
                        }
                    }
                }
            }

            // define which boundary condition types are used in the actual grid !!!
            // =====================================================================

            foreach (BCType bct in this.BoundaryCondTypes.Values)
            {
                int cnt = 0;

                // loop over all edges ...
                E = grdDat.iGeomEdges.Count;
                for (int e = 0; e < E; e++)
                {
                    //foreach (byte EdgeTag in grdDat.EdgeTags) {
                    byte EdgeTag = grdDat.iGeomEdges.EdgeTags[e];

                    if (EdgeTag == 0)
                    {
                        continue;
                    }

                    if (EdgeTag >= GridCommons.FIRST_PERIODIC_BC_TAG)
                    {
                        continue; // do nothing for periodic edges
                    }
                    if (EdgeTag2Type[EdgeTag].Equals(bct))
                    {
                        cnt++;
                    }
                }

                int GlobCnt = 0;
                unsafe
                {
                    csMPI.Raw.Allreduce((IntPtr)(&cnt), (IntPtr)(&GlobCnt), 1,
                                        csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.SUM, csMPI.Raw._COMM.WORLD);
                }

                BCTypeUseCount.Add(bct, GlobCnt);
            }

            // additional info
            // ===============
            {
                var _EdgeTag2EdgeTagName = new Dictionary <byte, string>();
                var _EdgeTagName2EdgeTag = new Dictionary <string, byte>();

                foreach (var kv in grdDat.EdgeTagNames)
                {
                    _EdgeTag2EdgeTagName.Add(kv.Key, kv.Value);
                    _EdgeTagName2EdgeTag.Add(kv.Value, kv.Key);
                }
                EdgeTag2EdgeTagName = _EdgeTag2EdgeTagName;
                EdgeTagName2EdgeTag = _EdgeTagName2EdgeTag;
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Version of <see cref="GetVelocityBoundaryValueFunction"/> which
        /// supports optional vector fields.
        /// </summary>
        /// <param name="boundaryValues">
        /// <see cref="GetBoundaryValueFunction"/>
        /// </param>
        /// <returns>
        /// A list of length
        /// <see cref="CNSEnvironment.NumberOfDimensions"/> of boundary
        /// values as returned by <see cref="GetBoundaryValueFunction"/>.
        /// </returns>
        private static Func <double[], double, double>[] GetOptionalVelocityBoundaryValueFunction(AppControl.BoundaryValueCollection boundaryValues)
        {
            int numberOfDimensions = CNSEnvironment.NumberOfDimensions;

            // First check x-component only
            Func <double[], double, double> boundaryValue;
            bool found = TryGetBoundaryValueFunction(boundaryValues, "u0", out boundaryValue);

            // If x-component is missing, assume no velocity
            if (!found)
            {
                return(null);
            }

            Func <double[], double, double>[] result = new Func <double[], double, double> [numberOfDimensions];
            result[0] = boundaryValue;

            // If x-component is present, _all_ other components have to be
            // there, too
            for (int i = 1; i < numberOfDimensions; i++)
            {
                result[i] = GetBoundaryValueFunction(boundaryValues, "u" + i);
            }

            return(result);
        }
Esempio n. 6
0
        /// <summary>
        /// Vector version of <see cref="GetBoundaryValueFunction"/> for the
        /// velocity components
        /// </summary>
        /// <param name="boundaryCondition">
        /// <see cref="GetBoundaryValueFunction"/>
        /// </param>
        /// <returns>
        /// A list of length
        /// <see cref="CNSEnvironment.NumberOfDimensions"/> of boundary
        /// values as returned by <see cref="GetBoundaryValueFunction"/>.
        /// </returns>
        private static Func <double[], double, double>[] GetVelocityBoundaryValueFunction(AppControl.BoundaryValueCollection boundaryCondition)
        {
            Func <double[], double, double>[] result = GetOptionalVelocityBoundaryValueFunction(boundaryCondition);

            if (result == null)
            {
                throw new Exception(String.Format(
                                        "Missing definition of velocity component for boundary condition"));
            }

            return(result);
        }
Esempio n. 7
0
 /// <summary>
 /// Finds the boundary evaluator (<see cref="AppControl.BoundaryValues"/>)
 /// associated with <paramref name="fieldName"/> for the condition
 /// <paramref name="boundaryValues"/>.
 /// </summary>
 /// <param name="boundaryValues">
 /// The configured boundary values
 /// </param>
 /// <param name="fieldName">The id of the boundary in question</param>
 /// <param name="result">
 /// On exit: The evaluator stored in <see cref="AppControl.BoundaryValues"/>
 /// for a boundary with id <paramref name="fieldName"/> if it exists
 /// </param>
 /// <returns>
 /// True, if a boundary value has been found; false otherwise
 /// </returns>
 private static bool TryGetBoundaryValueFunction(AppControl.BoundaryValueCollection boundaryValues, string fieldName, out Func <double[], double, double> result)
 {
     return(boundaryValues.Evaluators.TryGetValue(fieldName, out result));
 }