识别不同的颗粒VTK文件中相同颗粒的信息变化

本文目的是通过读取两个时刻的颗粒信息文件,识别这两个时刻下某个求解范围或进程内具有相同编号的颗粒的信息变化情况。

对于两个时刻的VTK文件而言,其包含的颗粒可能是不一致的,因此还需要对这两个时刻此求解范围或进程内包含的相同颗粒进行识别。颗粒的VTK文件格式可参考颗粒VTK文件格式总结

对应的求解程序如下(程序的解释已以注释的方式记录在cpp文件中;此外,由于这里需要对具有相同ID的颗粒在不同时刻下的不同信息进行对比,因而找到具有相同ID的颗粒之后将其不同时刻下的信息进行了整合并输出):

/**
 * @file    vtkpost.cpp
 * @brief
 * @version
 * @date    Fri 25 Jan 2019 08:22:00 AM CST
 ******************************************************************************/

#include <math.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
using namespace std;

/* The last space is necessary. */
const string idmarker = "SCALARS id float 1 ";
const string nmarker  = "DATASET POLYDATA ";
const string pmarker  = "DATASET POLYDATA ";
const string tmarker  = "SCALARS type float 1 ";
const string rmarker  = "SCALARS radius float 1 ";
const string vmarker  = "VECTORS velocity float ";
const string amarker  = "VECTORS omega float ";
const string fmarker  = "VECTORS force float ";
const string fdmarker = "VECTORS fdrag float ";
const string fcmarker = "VECTORS collide float ";

typedef struct {
    int id, type;
    double xo, yo, zo;  // old position
    double xn, yn, zn;  // new position
    double uo, vo, wo;  // old velocity
    double un, vn, wn;  // new velocity
    double du, dv, dw;  // velocity changes
    double mu;          // magitude of velocity changes
    double rp;          // radius
    double auo, avo, awo;   // old angular velocity
    double aun, avn, awn;   // new angular velocity
    double dau, dav, daw;   // angular velocity changes
    double fxo, fyo, fzo;   // old force
    double fxn, fyn, fzn;   // new force
    double fdxo, fdyo, fdzo;    // old drag force
    double fdxn, fdyn, fdzn;    // new drag force
    double fcxo, fcyo, fczo;    // old collide force
    double fcxn, fcyn, fczn;    // new collide force
} Vtkout;

/* Find the mapping relations between reading sequence and the particle id */
map<int, int> find_seq2ids(const char *name);

/* Extract indices from the mapping relations. */
set<int> extract_id(const map<int, int> &mapping);

/* Find common indices between ...1.vtk and ...2.vtk. */
set<int> find_comm_id(
        const set<int> &ids1,
        const set<int> &ids2);

/* Generate mapping relations from reading sequence to common indices */
map<int, int> generate_ids2seq(const set<int> &commids);

/* Read the information of the common partiles in ...1.vtk and ...2.vtk. */
vector<Vtkout> read_comm_info(
        const char *name1,
        const map<int, int> &map1,
        const char *name2,
        const map<int, int> &map2,
        const set<int> &commids,
        const map<int, int> &commids2seq);

/* Write all collected data to a dat file. */
void write_data(const vector<Vtkout> &data);

/*----------------------------------------------------------------------------*/

int main(int argc, char *argv[])
{
    /* Only file name should be modified if necessary. */
    const char *name1 = "./part120000001.vtk";
    const char *name2 = "./part120000002.vtk";

    /* Use map1 and map2 to record the mapping relations between reading
     * sequence and particle indices of file 1 and file2, respectively.*/
    const map<int, int> map1 = find_seq2ids(name1);
    const map<int, int> map2 = find_seq2ids(name2);

    const set<int> ids1 = extract_id(map1);
    const set<int> ids2 = extract_id(map2);
    const int np1 = ids1.size();
    const int np2 = ids2.size();

    cout << "Particle number in file " << name1 << " is " << np1 << endl;
    cout << "Particle number in file " << name2 << " is " << np2 << endl;

    const set<int> commids = find_comm_id(ids1, ids2);
    const map<int, int> ids2seq = generate_ids2seq(commids);
    const int comm_np = commids.size();

    cout << "Common particle number is " << comm_np << endl;

    vector<Vtkout> data =
        read_comm_info(name1, map1, name2, map2, commids, ids2seq);

    /* for (auto it = ids2seq.begin(); it != ids2seq.end(); it++) { */
    /*     cout << it->first << "\t" << it->second << endl; */
    /* } */

    /* for (int i = 0; i < 10; i++) { */
    /*     cout << data[i].xo << "\t" << data[i].yo << "\t" << data[i].zo << endl; */
    /* } */

    write_data(data);

    return 0;
}

/*----------------------------------------------------------------------------*/

/* Find the mapping relations between reading sequence and the particle id */
map<int, int> find_seq2ids(const char *name)
{

    map<int, int> seq2ids;
    ifstream fin;
    string stmp, line;
    int np, id;

    /* Read all indices in ...1.vtk. */
    fin.open(name, ios::in);

    while (getline(fin, line)) {
        /* Find the particle number in current vtk file. */
        if (line == nmarker) {
            fin >> stmp >> np >> stmp;
        }

        /* Read all indices and insert all indices to a set. */
        if (line == idmarker) {
            for (int i = 0; i < np; i++) {
                getline(fin, line);
                fin >> id;
                seq2ids.insert(pair<int, int>(i, id));
            }
        }
    }

    fin.close();

    return seq2ids;
}

/* Extract indices from the mapping relations. */
set<int> extract_id(const map<int, int> &mapping)
{
    set<int> ids;
    for (auto it = mapping.begin(); it != mapping.end(); it++) {
        ids.insert(it->second);
    }

    return ids;
}

/* Find common indices between ...1.vtk and ...2.vtk. */
set<int> find_comm_id(
        const set<int> &ids1,
        const set<int> &ids2)
{
    set<int> commids;

    for (auto it = ids2.begin(); it != ids2.end(); it++) {
        if (ids1.find(*it) != ids1.end()) {
            commids.insert(*it);
        }
    }

    return commids;
}

/* Generate mapping relations from reading sequence to common indices */
map<int, int> generate_ids2seq(const set<int> &commids)
{
    int count = 0;
    map<int, int> ids2seq;
    for (auto it = commids.begin(); it != commids.end(); it++) {
        ids2seq.insert(pair<int, int>(*it, count));
        count++;
    }

    return ids2seq;
}

/* Read the information of the common partiles in ...1.vtk and ...2.vtk. */
vector<Vtkout> read_comm_info(
        const char *name1,
        const map<int, int> &map1,
        const char *name2,
        const map<int, int> &map2,
        const set<int> &commids,
        const map<int, int> &commids2seq)
{
    const int np1 = map1.size();
    const int np2 = map2.size();
    const int comm_np = commids.size();

    int itmp;
    double xtmp, ytmp, ztmp, dtmp;
    string stmp, line;
    ifstream fin;
    vector<Vtkout> data(comm_np);

    /* Read all information from ...1.vtk */
    fin.open(name1, ios::in);

    while (getline(fin, line)) {
        if (line == pmarker) {
            cout << "Find pmarker" << endl;
            getline(fin, line);
            for (int i = 0; i < np1; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].id = m1it->second;
                    data[cit->second].xo = xtmp;
                    data[cit->second].yo = ytmp;
                    data[cit->second].zo = ztmp;
                }
            }
        }

        if (line == vmarker) {
            cout << "Find vmarker" << endl;
            for (int i = 0; i < np1; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].uo = xtmp;
                    data[cit->second].vo = ytmp;
                    data[cit->second].wo = ztmp;
                }
            }
        }

        if (line == amarker) {
            cout << "Find amarker" << endl;
            for (int i = 0; i < np1; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].auo = xtmp;
                    data[cit->second].avo = ytmp;
                    data[cit->second].awo = ztmp;
                }
            }
        }

        if (line == fmarker) {
            cout << "Find fmarker" << endl;
            for (int i = 0; i < np1; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].fxo = xtmp;
                    data[cit->second].fyo = ytmp;
                    data[cit->second].fzo = ztmp;
                }
            }
        }

        if (line == fdmarker) {
            cout << "Find fdmarker" << endl;
            for (int i = 0; i < np1; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].fdxo = xtmp;
                    data[cit->second].fdyo = ytmp;
                    data[cit->second].fdzo = ztmp;
                }
            }
        }

        if (line == fcmarker) {
            cout << "Find fcmarker" << endl;
            for (int i = 0; i < np1; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].fcxo = xtmp;
                    data[cit->second].fcyo = ytmp;
                    data[cit->second].fczo = ztmp;
                }
            }
        }

        if (line == tmarker) {
            cout << "Find tmarker" << endl;
            getline(fin, line);
            for (int i = 0; i < np1; i++) {
                fin >> itmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].type = itmp;
                }
            }
        }

        if (line == rmarker) {
            cout << "Find rmarker" << endl;
            getline(fin, line);
            for (int i = 0; i < np1; i++) {
                fin >> dtmp;
                map<int, int>::const_iterator m1it = map1.find(i);
                if (commids.find(m1it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m1it->second);
                    data[cit->second].rp = dtmp;
                }
            }
        }
    }

    fin.close();


    /* Read all information from ...2.vtk */
    fin.open(name2, ios::in);

    while (getline(fin, line)) {
        if (line == pmarker) {
            cout << "Find pmarker" << endl;
            getline(fin, line);
            for (int i = 0; i < np2; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m2it = map2.find(i);
                if (commids.find(m2it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m2it->second);
                    data[cit->second].xn = xtmp;
                    data[cit->second].yn = ytmp;
                    data[cit->second].zn = ztmp;
                }
            }
        }

        if (line == vmarker) {
            cout << "Find vmarker" << endl;
            for (int i = 0; i < np2; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m2it = map2.find(i);
                if (commids.find(m2it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m2it->second);
                    data[cit->second].un = xtmp;
                    data[cit->second].vn = ytmp;
                    data[cit->second].wn = ztmp;
                }
            }
        }

        if (line == amarker) {
            cout << "Find amarker" << endl;
            for (int i = 0; i < np2; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m2it = map2.find(i);
                if (commids.find(m2it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m2it->second);
                    data[cit->second].aun = xtmp;
                    data[cit->second].avn = ytmp;
                    data[cit->second].awn = ztmp;
                }
            }
        }

        if (line == fmarker) {
            cout << "Find fmarker" << endl;
            for (int i = 0; i < np2; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m2it = map2.find(i);
                if (commids.find(m2it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m2it->second);
                    data[cit->second].fxn = xtmp;
                    data[cit->second].fyn = ytmp;
                    data[cit->second].fzn = ztmp;
                }
            }
        }

        if (line == fdmarker) {
            cout << "Find fdmarker" << endl;
            for (int i = 0; i < np2; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m2it = map2.find(i);
                if (commids.find(m2it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m2it->second);
                    data[cit->second].fdxn = xtmp;
                    data[cit->second].fdyn = ytmp;
                    data[cit->second].fdzn = ztmp;
                }
            }
        }

        if (line == fcmarker) {
            cout << "Find fcmarker" << endl;
            for (int i = 0; i < np2; i++) {
                fin >> xtmp >> ytmp >> ztmp;
                map<int, int>::const_iterator m2it = map2.find(i);
                if (commids.find(m2it->second) != commids.end()) {
                    map<int, int>::const_iterator cit = commids2seq.find(m2it->second);
                    data[cit->second].fcxn = xtmp;
                    data[cit->second].fcyn = ytmp;
                    data[cit->second].fczn = ztmp;
                }
            }
        }
    }

    fin.close();

    for (auto it = data.begin(); it != data.end(); it++) {
        it->du = it->un - it->uo;
        it->dv = it->vn - it->vo;
        it->dw = it->wn - it->wo;
        it->mu = sqrt(pow(it->du, 2) + pow(it->dv, 2) + pow(it->dw, 2));

        it->dau = it->aun - it->auo;
        it->dav = it->avn - it->avo;
        it->daw = it->awn - it->awo;
    }

    return data;
}

void write_data(const vector<Vtkout> &data)
{
    ofstream fout;
    fout.open("result.dat");

    fout << "id" << "\t" << "type" << "\t" << "rp" << "\t"
         << "xo" << "\t" << "yo" << "\t" << "zo" << "\t"
         << "xn" << "\t" << "yn" << "\t" << "zn" << "\t"
         << "uo" << "\t" << "vo" << "\t" << "wo" << "\t"
         << "un" << "\t" << "vn" << "\t" << "wn" << "\t"
         << "du" << "\t" << "dv" << "\t" << "dw" << "\t"
         << "mu" << "\t"
         << "auo" << "\t" << "avo" << "\t" << "awo" << "\t"
         << "aun" << "\t" << "avn" << "\t" << "awn" << "\t"
         << "dau" << "\t" << "dav" << "\t" << "daw" << "\t"
         << "fxo" << "\t" << "fyo" << "\t" << "fzo" << "\t"
         << "fxn" << "\t" << "fyn" << "\t" << "fzn" << "\t"
         << "fdxo" << "\t" << "fdyo" << "\t" << "fdzo" << "\t"
         << "fdxn" << "\t" << "fdyn" << "\t" << "fdzn" << "\t"
         << "fcxo" << "\t" << "fcyo" << "\t" << "fczo" << "\t"
         << "fcxn" << "\t" << "fcyn" << "\t" << "fczn" << "\t"
         << endl;

    for (auto it = data.begin(); it != data.end(); it++) {
        fout << it->id << "\t" << it->type << "\t" << it->rp << "\t"
             << it->xo << "\t" << it->yo << "\t" << it->zo << "\t"
             << it->xn << "\t" << it->yn << "\t" << it->zn << "\t"
             << it->uo << "\t" << it->vo << "\t" << it->wo << "\t"
             << it->un << "\t" << it->vn << "\t" << it->wn << "\t"
             << it->du << "\t" << it->dv << "\t" << it->dw << "\t"
             << it->mu << "\t"
             << it->auo << "\t" << it->avo << "\t" << it->awo << "\t"
             << it->aun << "\t" << it->avn << "\t" << it->awn << "\t"
             << it->dau << "\t" << it->dav << "\t" << it->daw << "\t"
             << it->fxo << "\t" << it->fyo << "\t" << it->fzo << "\t"
             << it->fxn << "\t" << it->fyn << "\t" << it->fzn << "\t"
             << it->fdxo << "\t" << it->fdyo << "\t" << it->fdzo << "\t"
             << it->fdxn << "\t" << it->fdyn << "\t" << it->fdzn << "\t"
             << it->fcxo << "\t" << it->fcyo << "\t" << it->fczo << "\t"
             << it->fcxn << "\t" << it->fcyn << "\t" << it->fczn << "\t"
             << endl;
    }

    fout.close();
}

相关的编译和运行命令如下:

# Compile:
g++ vtkpost.cpp -std=c++11 -o vtkpost

# Run:
./vtkpost

# Abbr. in results:
#    postfix o: old
#    postfix n: new
#    prefix  d: change
#    f: force
#    fd: drag
#    fc: collide
#    ......
#    (also see from line 32 to line 48 in vtkpost.cpp)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值