/* 1.5 ~ToListExpr~ converts this MFaces-object to a RList-representation of a moving region over the given interval with the given restrictions. */ RList MFaces::ToListExpr(Interval iv, double start, double end) { RList ret; if (faces.empty()) return ret; if (start == 0 && end == 1) { // No restrictions, so we can start the real work // Build the ListExpr for the time-interval RList uregion, uregions; RList interval; interval.append(iv.startstr()); interval.append(iv.endstr()); interval.append(iv.lc); interval.append(iv.rc); uregion.append(interval); // Now convert the mface-objects one by one and put them into one list for (unsigned int i = 0; i < faces.size(); i++) { uregions.append(faces[i].ToListExpr()); } uregion.append(uregions); return uregion; } else { // We need to restrict the interval first MFaces f = divide(start, end); // and then recall this function with the new mfaces w/o restrictions. return f.ToListExpr(iv, 0, 1); } }
/* 1.7 ~fallback~ can used, when the construction of a valid moving region failed in the steps before. This can for example happen because of numerical instability and resulting errors in the intersection checks or because of bugs in the interpolation code. This function tries to create a moving region RList representation in such a simple manner, that no errors are to be expected in any case: * Divide the time-interval in two halves * The first half shows statically the source region * The second half shows statically the destination region If the source- and destination-faces are valid, this can only fail if the time interval is too short. One of the intervals must be half-open and so has to have a certain minimum duration. */ RList MFaces::fallback(vector<Face> *sfaces, vector<Face> *dfaces, Interval iv) { RList mreg; Interval startiv(iv.start, iv.start + (iv.end - iv.start) / 2, true, true); // Build the static MSegs of the source-faces MFaces start = Face::CreateMFaces(sfaces); mreg.append(start.ToListExpr(startiv, 0, 1)); // This interval is half-open on the left end, since the preceding interval // above is closed there Interval endiv(startiv.end, iv.end, false, true); // Build the static MSegs of the destination-faces MFaces end = Face::CreateMFaces(dfaces); mreg.append(end.ToListExpr(endiv, 0, 1)); return mreg; }
/* 1.6 ~ToMListExpr~ converts this MFaces-object to the RList representation of an moving region suitable for import into a dbms. It takes care of creating the correct intervals (evaporation, main and/or condensation), and the borderregions. */ RList MFaces::ToMListExpr(Interval iv) { RList mreg; // Determine if we need a start- or endregion. This is exactly the case when // one of the contained MFace-objects of this MFaces-object needs it. bool needStartRegion = false, needEndRegion = false; for (unsigned int i = 0; i < faces.size(); i++) { needStartRegion = needStartRegion || faces[i].needStartRegion; needEndRegion = needEndRegion || faces[i].needEndRegion; } // one-third of the whole interval is used for the evaporisation and/or // condensation-phase double onethird = (iv.end - iv.start) / 3; // Calculate the intervals Interval evaporIv, condensIv; Interval startRegIv, endRegIv; Interval mainIv; mainIv = iv; mainIv.lc = mainIv.rc = true; if (needSEvap) { // Create the evaporation interval // the left side of the evaporation interval is always open, since we // need a borderregion there evaporIv.lc = false; evaporIv.start = mainIv.start; mainIv.start = mainIv.start + onethird; evaporIv.end = mainIv.start; evaporIv.rc = false; } if (needDEvap) { // Create the condensation interval // the right side of the condensation interval is always open, since we // need a borderregion there condensIv.rc = false; condensIv.end = mainIv.end; mainIv.end = mainIv.end - onethird; condensIv.start = mainIv.end; condensIv.lc = false; } if (needStartRegion) { // Create the start-region interval startRegIv.lc = true; startRegIv.start = mainIv.start; mainIv.start = mainIv.start + MOMENTMS; startRegIv.end = mainIv.start; startRegIv.rc = true; mainIv.lc = false; } if (needEndRegion) { // Create the end-region interval endRegIv.rc = true; endRegIv.end = mainIv.end; mainIv.end = mainIv.end - MOMENTMS; endRegIv.start = mainIv.end; endRegIv.lc = true; mainIv.rc = false; } if (needSEvap) { // We need to perform an evaporations-phase Interval siv(evaporIv.start, evaporIv.start, true, true); MFaces s = Face::CreateMFaces(sregs); mreg.append(s.ToListExpr(siv, 0, 1)); MFaces fs; // Reconstruct the borderfaces at the start of the main interpolation .. vector<Face> borderfaces = CreateBorderFaces(true); // and interpolate them with the original sourceregion with // the evaporation-mode-flag set. fs = interpolate(sregs, &borderfaces, 0, true, ""); mreg.append(fs.ToListExpr(evaporIv, 0, 1)); } if (needStartRegion) { // Create the borderregion at the begin of the main interpolation // interval here and add it to the list. mreg.append(CreateBorderMFaces(true).ToListExpr(startRegIv, 0, 1)); } // Add the main-interpolation mreg.append(ToListExpr(mainIv, 0, 1)); if (needEndRegion) { // Create the borderregion at the end of the main interpolation // interval here and add it to the list. mreg.append(CreateBorderMFaces(false).ToListExpr(endRegIv, 0, 1)); } if (needDEvap) { // A condensation-phase is needed MFaces fs; // Reconstruct the borderfaces at the end of the main interpolation .. vector<Face> borderdregs = CreateBorderFaces(false); // and interpolate them with the original destinationregion with // the evaporation-mode-flag set. fs = interpolate(&borderdregs, dregs, 0, true, ""); mreg.append(fs.ToListExpr(condensIv, 0, 1)); Interval eiv(condensIv.end, condensIv.end, true, true); MFaces s = Face::CreateMFaces(dregs); mreg.append(s.ToListExpr(eiv, 0, 1)); } return mreg; }